Fix/opportunities board (#2610)
* WIP * wip * update pipelineStepId * rename pipeline stage to pipeline step * rename pipelineProgress to Opportunity * fix UUID type not queried * fix boardColumnTotal * fix micros * fixing filters, sorts and fields * wip * wip * Fix opportunity board re-render --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com> Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
This commit is contained in:
@ -143,7 +143,7 @@ export const CompanyBoardCard = () => {
|
||||
|
||||
const showCompactView = isCompactViewEnabled && isCardInCompactView;
|
||||
|
||||
const { pipelineProgress, company } = companyProgress ?? {};
|
||||
const { opportunity, company } = companyProgress ?? {};
|
||||
|
||||
const visibleBoardCardFields = useRecoilScopedValue(
|
||||
visibleBoardCardFieldsScopedSelector,
|
||||
@ -175,7 +175,7 @@ export const CompanyBoardCard = () => {
|
||||
};
|
||||
|
||||
// boardCardId check can be moved to a wrapper to avoid unnecessary logic above
|
||||
if (!company || !pipelineProgress || !boardCardId) {
|
||||
if (!company || !opportunity || !boardCardId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ export type CompanyProgressPickerProps = {
|
||||
companyId: string | null;
|
||||
onSubmit: (
|
||||
newCompanyId: EntityForSelect | null,
|
||||
newPipelineStageId: string | null,
|
||||
newPipelineStepId: string | null,
|
||||
) => void;
|
||||
onCancel?: () => void;
|
||||
};
|
||||
@ -39,40 +39,40 @@ export const CompanyProgressPicker = ({
|
||||
const [isProgressSelectionUnfolded, setIsProgressSelectionUnfolded] =
|
||||
useState(false);
|
||||
|
||||
const [selectedPipelineStageId, setSelectedPipelineStageId] = useState<
|
||||
const [selectedPipelineStepId, setSelectedPipelineStepId] = useState<
|
||||
string | null
|
||||
>(null);
|
||||
|
||||
const [currentPipeline] = useRecoilState(currentPipelineState);
|
||||
|
||||
const currentPipelineStages = useMemo(
|
||||
() => currentPipeline?.pipelineStages ?? [],
|
||||
const currentPipelineSteps = useMemo(
|
||||
() => currentPipeline?.pipelineSteps ?? [],
|
||||
[currentPipeline],
|
||||
);
|
||||
|
||||
const handlePipelineStageChange = (newPipelineStageId: string) => {
|
||||
setSelectedPipelineStageId(newPipelineStageId);
|
||||
const handlePipelineStepChange = (newPipelineStepId: string) => {
|
||||
setSelectedPipelineStepId(newPipelineStepId);
|
||||
setIsProgressSelectionUnfolded(false);
|
||||
};
|
||||
|
||||
const handleEntitySelected = async (
|
||||
selectedCompany: EntityForSelect | null | undefined,
|
||||
) => {
|
||||
onSubmit(selectedCompany ?? null, selectedPipelineStageId);
|
||||
onSubmit(selectedCompany ?? null, selectedPipelineStepId);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (currentPipelineStages?.[0]?.id) {
|
||||
setSelectedPipelineStageId(currentPipelineStages?.[0]?.id);
|
||||
if (currentPipelineSteps?.[0]?.id) {
|
||||
setSelectedPipelineStepId(currentPipelineSteps?.[0]?.id);
|
||||
}
|
||||
}, [currentPipelineStages]);
|
||||
}, [currentPipelineSteps]);
|
||||
|
||||
const selectedPipelineStage = useMemo(
|
||||
const selectedPipelineStep = useMemo(
|
||||
() =>
|
||||
currentPipelineStages.find(
|
||||
(pipelineStage: any) => pipelineStage.id === selectedPipelineStageId,
|
||||
currentPipelineSteps.find(
|
||||
(pipelineStep: any) => pipelineStep.id === selectedPipelineStepId,
|
||||
),
|
||||
[currentPipelineStages, selectedPipelineStageId],
|
||||
[currentPipelineSteps, selectedPipelineStepId],
|
||||
);
|
||||
|
||||
return (
|
||||
@ -82,14 +82,14 @@ export const CompanyProgressPicker = ({
|
||||
>
|
||||
{isProgressSelectionUnfolded ? (
|
||||
<DropdownMenuItemsContainer>
|
||||
{currentPipelineStages.map((pipelineStage: any, index: number) => (
|
||||
{currentPipelineSteps.map((pipelineStep: any, index: number) => (
|
||||
<MenuItem
|
||||
key={pipelineStage.id}
|
||||
key={pipelineStep.id}
|
||||
testId={`select-pipeline-stage-${index}`}
|
||||
onClick={() => {
|
||||
handlePipelineStageChange(pipelineStage.id);
|
||||
handlePipelineStepChange(pipelineStep.id);
|
||||
}}
|
||||
text={pipelineStage.name}
|
||||
text={pipelineStep.name}
|
||||
/>
|
||||
))}
|
||||
</DropdownMenuItemsContainer>
|
||||
@ -100,7 +100,7 @@ export const CompanyProgressPicker = ({
|
||||
EndIcon={IconChevronDown}
|
||||
onClick={() => setIsProgressSelectionUnfolded(true)}
|
||||
>
|
||||
{selectedPipelineStage?.name}
|
||||
{selectedPipelineStep?.name}
|
||||
</DropdownMenuHeader>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuSearchInput
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
|
||||
|
||||
import { Company } from '@/companies/types/Company';
|
||||
import { useComputeDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useComputeDefinitionsFromFieldMetadata';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
||||
import { PaginatedObjectTypeResults } from '@/object-record/types/PaginatedObjectTypeResults';
|
||||
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
|
||||
import { Opportunity } from '@/pipeline/types/Opportunity';
|
||||
import { PipelineStep } from '@/pipeline/types/PipelineStep';
|
||||
import { useBoardActionBarEntries } from '@/ui/layout/board/hooks/useBoardActionBarEntries';
|
||||
@ -14,11 +17,12 @@ import { availableBoardCardFieldsScopedState } from '@/ui/layout/board/states/av
|
||||
import { boardCardFieldsScopedState } from '@/ui/layout/board/states/boardCardFieldsScopedState';
|
||||
import { isBoardLoadedState } from '@/ui/layout/board/states/isBoardLoadedState';
|
||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||
import { useRecoilScopedStateV2 } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedStateV2';
|
||||
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
||||
import { useView } from '@/views/hooks/useView';
|
||||
import { ViewType } from '@/views/types/ViewType';
|
||||
import { mapViewFieldsToBoardFieldDefinitions } from '@/views/utils/mapViewFieldsToBoardFieldDefinitions';
|
||||
import { opportunitiesBoardOptions } from '~/pages/opportunities/opportunitiesBoardOptions';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
import { useUpdateCompanyBoardCardIds } from '../hooks/useUpdateBoardCardIds';
|
||||
import { useUpdateCompanyBoard } from '../hooks/useUpdateCompanyBoardColumns';
|
||||
@ -41,6 +45,13 @@ export const HooksCompanyBoardEffect = () => {
|
||||
|
||||
const currentViewFields = useRecoilValue(currentViewFieldsState);
|
||||
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
objectNamePlural: 'opportunities',
|
||||
});
|
||||
|
||||
const { columnDefinitions, filterDefinitions, sortDefinitions } =
|
||||
useComputeDefinitionsFromFieldMetadata(objectMetadataItem);
|
||||
|
||||
const [, setIsBoardLoaded] = useRecoilState(isBoardLoadedState);
|
||||
|
||||
const { BoardRecoilScopeContext } = useBoardContext();
|
||||
@ -50,10 +61,6 @@ export const HooksCompanyBoardEffect = () => {
|
||||
BoardRecoilScopeContext,
|
||||
);
|
||||
|
||||
const [, setAvailableBoardCardFields] = useRecoilScopedState(
|
||||
availableBoardCardFieldsScopedState,
|
||||
BoardRecoilScopeContext,
|
||||
);
|
||||
const updateCompanyBoardCardIds = useUpdateCompanyBoardCardIds();
|
||||
const updateCompanyBoard = useUpdateCompanyBoard();
|
||||
|
||||
@ -70,9 +77,9 @@ export const HooksCompanyBoardEffect = () => {
|
||||
|
||||
const whereFilters = useMemo(() => {
|
||||
return {
|
||||
AND: [
|
||||
and: [
|
||||
{
|
||||
pipelineStageId: {
|
||||
pipelineStepId: {
|
||||
in: pipelineSteps.map((pipelineStep) => pipelineStep.id),
|
||||
},
|
||||
},
|
||||
@ -86,8 +93,10 @@ export const HooksCompanyBoardEffect = () => {
|
||||
objectNamePlural: 'opportunities',
|
||||
filter: whereFilters,
|
||||
onCompleted: useCallback(
|
||||
(_data: PaginatedObjectTypeResults<Opportunity>) => {
|
||||
const pipelineProgresses: Array<Opportunity> = [];
|
||||
(data: PaginatedObjectTypeResults<Opportunity>) => {
|
||||
const pipelineProgresses: Array<Opportunity> = data.edges.map(
|
||||
(edge) => edge.node,
|
||||
);
|
||||
|
||||
updateCompanyBoardCardIds(pipelineProgresses);
|
||||
|
||||
@ -112,15 +121,63 @@ export const HooksCompanyBoardEffect = () => {
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setAvailableFilterDefinitions(opportunitiesBoardOptions.filterDefinitions);
|
||||
setAvailableSortDefinitions?.(opportunitiesBoardOptions.sortDefinitions);
|
||||
setAvailableFieldDefinitions?.([]);
|
||||
if (!objectMetadataItem) {
|
||||
return;
|
||||
}
|
||||
setAvailableFilterDefinitions?.(filterDefinitions);
|
||||
setAvailableSortDefinitions?.(sortDefinitions);
|
||||
setAvailableFieldDefinitions?.(columnDefinitions);
|
||||
}, [
|
||||
columnDefinitions,
|
||||
filterDefinitions,
|
||||
objectMetadataItem,
|
||||
setAvailableFieldDefinitions,
|
||||
setAvailableFilterDefinitions,
|
||||
setAvailableSortDefinitions,
|
||||
sortDefinitions,
|
||||
]);
|
||||
|
||||
const setAvailableBoardCardFields = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
(availableBoardCardFields: any) => {
|
||||
const availableBoardCardFieldsFromState = snapshot
|
||||
.getLoadable(
|
||||
availableBoardCardFieldsScopedState({
|
||||
scopeId: 'company-board-view',
|
||||
}),
|
||||
)
|
||||
.getValue();
|
||||
|
||||
if (
|
||||
!isDeeplyEqual(
|
||||
availableBoardCardFieldsFromState,
|
||||
availableBoardCardFields,
|
||||
)
|
||||
) {
|
||||
set(
|
||||
availableBoardCardFieldsScopedState({
|
||||
scopeId: 'company-board-view',
|
||||
}),
|
||||
availableBoardCardFields,
|
||||
);
|
||||
}
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
useRecoilScopedStateV2(
|
||||
availableBoardCardFieldsScopedState,
|
||||
'company-board-view',
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const availableTableColumns = columnDefinitions.filter(
|
||||
filterAvailableTableColumns,
|
||||
);
|
||||
|
||||
setAvailableBoardCardFields(availableTableColumns);
|
||||
}, [columnDefinitions, setAvailableBoardCardFields]);
|
||||
|
||||
useEffect(() => {
|
||||
setViewObjectMetadataId?.('company');
|
||||
setViewType?.(ViewType.Kanban);
|
||||
@ -137,21 +194,19 @@ export const HooksCompanyBoardEffect = () => {
|
||||
if (!loading && opportunities && companies) {
|
||||
setActionBarEntries();
|
||||
setContextMenuEntries();
|
||||
setAvailableBoardCardFields([]);
|
||||
|
||||
updateCompanyBoard(pipelineSteps, opportunities, companies);
|
||||
setEntityCountInCurrentView(companies.length);
|
||||
}
|
||||
}, [
|
||||
companies,
|
||||
loading,
|
||||
updateCompanyBoard,
|
||||
opportunities,
|
||||
pipelineSteps,
|
||||
setActionBarEntries,
|
||||
setContextMenuEntries,
|
||||
searchParams,
|
||||
setEntityCountInCurrentView,
|
||||
setAvailableBoardCardFields,
|
||||
opportunities,
|
||||
companies,
|
||||
pipelineSteps,
|
||||
updateCompanyBoard,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@ -12,7 +12,7 @@ export const NewCompanyProgressButton = () => {
|
||||
const [isCreatingCard, setIsCreatingCard] = useState(false);
|
||||
const column = useContext(BoardColumnContext);
|
||||
|
||||
const pipelineStageId = column?.columnDefinition.id || '';
|
||||
const pipelineStepId = column?.columnDefinition.id || '';
|
||||
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
|
||||
@ -25,7 +25,7 @@ export const NewCompanyProgressButton = () => {
|
||||
setIsCreatingCard(false);
|
||||
goBackToPreviousHotkeyScope();
|
||||
|
||||
if (!pipelineStageId) {
|
||||
if (!pipelineStepId) {
|
||||
enqueueSnackBar('Pipeline stage id is not defined', {
|
||||
variant: 'error',
|
||||
});
|
||||
@ -33,7 +33,7 @@ export const NewCompanyProgressButton = () => {
|
||||
throw new Error('Pipeline stage id is not defined');
|
||||
}
|
||||
|
||||
//createCompanyProgress(company.id, pipelineStageId);
|
||||
//createCompanyProgress(company.id, pipelineStepId);
|
||||
};
|
||||
|
||||
const handleNewClick = useCallback(() => {
|
||||
|
||||
Reference in New Issue
Block a user