Opportunity fields (#744)
* Add opportunity probability and point of contact * Have requests sent properly * Add probaility field
This commit is contained in:
@ -992,6 +992,7 @@ export type NullableStringFieldUpdateOperationsInput = {
|
||||
|
||||
export type Person = {
|
||||
__typename?: 'Person';
|
||||
PipelineProgress?: Maybe<Array<PipelineProgress>>;
|
||||
_commentThreadCount: Scalars['Int'];
|
||||
city: Scalars['String'];
|
||||
commentThreads: Array<CommentThread>;
|
||||
@ -1009,6 +1010,7 @@ export type Person = {
|
||||
};
|
||||
|
||||
export type PersonCreateInput = {
|
||||
PipelineProgress?: InputMaybe<PipelineProgressCreateNestedManyWithoutPointOfContactInput>;
|
||||
city: Scalars['String'];
|
||||
company?: InputMaybe<CompanyCreateNestedOneWithoutPeopleInput>;
|
||||
createdAt?: InputMaybe<Scalars['DateTime']>;
|
||||
@ -1024,6 +1026,10 @@ export type PersonCreateNestedManyWithoutCompanyInput = {
|
||||
connect?: InputMaybe<Array<PersonWhereUniqueInput>>;
|
||||
};
|
||||
|
||||
export type PersonCreateNestedOneWithoutPipelineProgressInput = {
|
||||
connect?: InputMaybe<PersonWhereUniqueInput>;
|
||||
};
|
||||
|
||||
export type PersonListRelationFilter = {
|
||||
every?: InputMaybe<PersonWhereInput>;
|
||||
none?: InputMaybe<PersonWhereInput>;
|
||||
@ -1035,6 +1041,7 @@ export type PersonOrderByRelationAggregateInput = {
|
||||
};
|
||||
|
||||
export type PersonOrderByWithRelationInput = {
|
||||
PipelineProgress?: InputMaybe<PipelineProgressOrderByRelationAggregateInput>;
|
||||
city?: InputMaybe<SortOrder>;
|
||||
company?: InputMaybe<CompanyOrderByWithRelationInput>;
|
||||
companyId?: InputMaybe<SortOrder>;
|
||||
@ -1047,6 +1054,11 @@ export type PersonOrderByWithRelationInput = {
|
||||
updatedAt?: InputMaybe<SortOrder>;
|
||||
};
|
||||
|
||||
export type PersonRelationFilter = {
|
||||
is?: InputMaybe<PersonWhereInput>;
|
||||
isNot?: InputMaybe<PersonWhereInput>;
|
||||
};
|
||||
|
||||
export enum PersonScalarFieldEnum {
|
||||
City = 'city',
|
||||
CompanyId = 'companyId',
|
||||
@ -1062,6 +1074,7 @@ export enum PersonScalarFieldEnum {
|
||||
}
|
||||
|
||||
export type PersonUpdateInput = {
|
||||
PipelineProgress?: InputMaybe<PipelineProgressUpdateManyWithoutPointOfContactNestedInput>;
|
||||
city?: InputMaybe<StringFieldUpdateOperationsInput>;
|
||||
company?: InputMaybe<CompanyUpdateOneWithoutPeopleNestedInput>;
|
||||
createdAt?: InputMaybe<DateTimeFieldUpdateOperationsInput>;
|
||||
@ -1085,10 +1098,16 @@ export type PersonUpdateManyWithoutWorkspaceNestedInput = {
|
||||
set?: InputMaybe<Array<PersonWhereUniqueInput>>;
|
||||
};
|
||||
|
||||
export type PersonUpdateOneWithoutPipelineProgressNestedInput = {
|
||||
connect?: InputMaybe<PersonWhereUniqueInput>;
|
||||
disconnect?: InputMaybe<Scalars['Boolean']>;
|
||||
};
|
||||
|
||||
export type PersonWhereInput = {
|
||||
AND?: InputMaybe<Array<PersonWhereInput>>;
|
||||
NOT?: InputMaybe<Array<PersonWhereInput>>;
|
||||
OR?: InputMaybe<Array<PersonWhereInput>>;
|
||||
PipelineProgress?: InputMaybe<PipelineProgressListRelationFilter>;
|
||||
city?: InputMaybe<StringFilter>;
|
||||
company?: InputMaybe<CompanyRelationFilter>;
|
||||
companyId?: InputMaybe<StringNullableFilter>;
|
||||
@ -1142,6 +1161,9 @@ export type PipelineProgress = {
|
||||
pipelineId: Scalars['String'];
|
||||
pipelineStage: PipelineStage;
|
||||
pipelineStageId: Scalars['String'];
|
||||
pointOfContact?: Maybe<Person>;
|
||||
pointOfContactId?: Maybe<Scalars['String']>;
|
||||
probability?: Maybe<Scalars['Int']>;
|
||||
progressableId: Scalars['String'];
|
||||
progressableType: PipelineProgressableType;
|
||||
updatedAt: Scalars['DateTime'];
|
||||
@ -1154,11 +1176,17 @@ export type PipelineProgressCreateInput = {
|
||||
id?: InputMaybe<Scalars['String']>;
|
||||
pipeline: PipelineCreateNestedOneWithoutPipelineProgressesInput;
|
||||
pipelineStage: PipelineStageCreateNestedOneWithoutPipelineProgressesInput;
|
||||
pointOfContact?: InputMaybe<PersonCreateNestedOneWithoutPipelineProgressInput>;
|
||||
probability?: InputMaybe<Scalars['Int']>;
|
||||
progressableId: Scalars['String'];
|
||||
progressableType: PipelineProgressableType;
|
||||
updatedAt?: InputMaybe<Scalars['DateTime']>;
|
||||
};
|
||||
|
||||
export type PipelineProgressCreateNestedManyWithoutPointOfContactInput = {
|
||||
connect?: InputMaybe<Array<PipelineProgressWhereUniqueInput>>;
|
||||
};
|
||||
|
||||
export type PipelineProgressListRelationFilter = {
|
||||
every?: InputMaybe<PipelineProgressWhereInput>;
|
||||
none?: InputMaybe<PipelineProgressWhereInput>;
|
||||
@ -1178,6 +1206,9 @@ export type PipelineProgressOrderByWithRelationInput = {
|
||||
pipelineId?: InputMaybe<SortOrder>;
|
||||
pipelineStage?: InputMaybe<PipelineStageOrderByWithRelationInput>;
|
||||
pipelineStageId?: InputMaybe<SortOrder>;
|
||||
pointOfContact?: InputMaybe<PersonOrderByWithRelationInput>;
|
||||
pointOfContactId?: InputMaybe<SortOrder>;
|
||||
probability?: InputMaybe<SortOrder>;
|
||||
progressableId?: InputMaybe<SortOrder>;
|
||||
progressableType?: InputMaybe<SortOrder>;
|
||||
updatedAt?: InputMaybe<SortOrder>;
|
||||
@ -1191,6 +1222,8 @@ export enum PipelineProgressScalarFieldEnum {
|
||||
Id = 'id',
|
||||
PipelineId = 'pipelineId',
|
||||
PipelineStageId = 'pipelineStageId',
|
||||
PointOfContactId = 'pointOfContactId',
|
||||
Probability = 'probability',
|
||||
ProgressableId = 'progressableId',
|
||||
ProgressableType = 'progressableType',
|
||||
UpdatedAt = 'updatedAt',
|
||||
@ -1204,6 +1237,8 @@ export type PipelineProgressUpdateInput = {
|
||||
id?: InputMaybe<StringFieldUpdateOperationsInput>;
|
||||
pipeline?: InputMaybe<PipelineUpdateOneRequiredWithoutPipelineProgressesNestedInput>;
|
||||
pipelineStage?: InputMaybe<PipelineStageUpdateOneRequiredWithoutPipelineProgressesNestedInput>;
|
||||
pointOfContact?: InputMaybe<PersonUpdateOneWithoutPipelineProgressNestedInput>;
|
||||
probability?: InputMaybe<NullableIntFieldUpdateOperationsInput>;
|
||||
progressableId?: InputMaybe<StringFieldUpdateOperationsInput>;
|
||||
progressableType?: InputMaybe<EnumPipelineProgressableTypeFieldUpdateOperationsInput>;
|
||||
updatedAt?: InputMaybe<DateTimeFieldUpdateOperationsInput>;
|
||||
@ -1215,6 +1250,12 @@ export type PipelineProgressUpdateManyWithoutPipelineStageNestedInput = {
|
||||
set?: InputMaybe<Array<PipelineProgressWhereUniqueInput>>;
|
||||
};
|
||||
|
||||
export type PipelineProgressUpdateManyWithoutPointOfContactNestedInput = {
|
||||
connect?: InputMaybe<Array<PipelineProgressWhereUniqueInput>>;
|
||||
disconnect?: InputMaybe<Array<PipelineProgressWhereUniqueInput>>;
|
||||
set?: InputMaybe<Array<PipelineProgressWhereUniqueInput>>;
|
||||
};
|
||||
|
||||
export type PipelineProgressUpdateManyWithoutWorkspaceNestedInput = {
|
||||
connect?: InputMaybe<Array<PipelineProgressWhereUniqueInput>>;
|
||||
disconnect?: InputMaybe<Array<PipelineProgressWhereUniqueInput>>;
|
||||
@ -1233,6 +1274,9 @@ export type PipelineProgressWhereInput = {
|
||||
pipelineId?: InputMaybe<StringFilter>;
|
||||
pipelineStage?: InputMaybe<PipelineStageRelationFilter>;
|
||||
pipelineStageId?: InputMaybe<StringFilter>;
|
||||
pointOfContact?: InputMaybe<PersonRelationFilter>;
|
||||
pointOfContactId?: InputMaybe<StringNullableFilter>;
|
||||
probability?: InputMaybe<IntNullableFilter>;
|
||||
progressableId?: InputMaybe<StringFilter>;
|
||||
progressableType?: InputMaybe<EnumPipelineProgressableTypeFilter>;
|
||||
updatedAt?: InputMaybe<DateTimeFilter>;
|
||||
@ -2165,12 +2209,14 @@ export type GetPipelineProgressQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetPipelineProgressQuery = { __typename?: 'Query', findManyPipelineProgress: Array<{ __typename?: 'PipelineProgress', id: string, pipelineStageId: string, progressableType: PipelineProgressableType, progressableId: string, amount?: number | null, closeDate?: string | null }> };
|
||||
export type GetPipelineProgressQuery = { __typename?: 'Query', findManyPipelineProgress: Array<{ __typename?: 'PipelineProgress', id: string, pipelineStageId: string, progressableType: PipelineProgressableType, progressableId: string, amount?: number | null, closeDate?: string | null, pointOfContactId?: string | null, probability?: number | null, pointOfContact?: { __typename?: 'Person', id: string, firstName: string, lastName: string } | null }> };
|
||||
|
||||
export type UpdateOnePipelineProgressMutationVariables = Exact<{
|
||||
id?: InputMaybe<Scalars['String']>;
|
||||
amount?: InputMaybe<Scalars['Int']>;
|
||||
closeDate?: InputMaybe<Scalars['DateTime']>;
|
||||
probability?: InputMaybe<Scalars['Int']>;
|
||||
pointOfContactId?: InputMaybe<Scalars['String']>;
|
||||
}>;
|
||||
|
||||
|
||||
@ -3809,6 +3855,13 @@ export const GetPipelineProgressDocument = gql`
|
||||
progressableId
|
||||
amount
|
||||
closeDate
|
||||
pointOfContactId
|
||||
pointOfContact {
|
||||
id
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
probability
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -3842,10 +3895,10 @@ export type GetPipelineProgressQueryHookResult = ReturnType<typeof useGetPipelin
|
||||
export type GetPipelineProgressLazyQueryHookResult = ReturnType<typeof useGetPipelineProgressLazyQuery>;
|
||||
export type GetPipelineProgressQueryResult = Apollo.QueryResult<GetPipelineProgressQuery, GetPipelineProgressQueryVariables>;
|
||||
export const UpdateOnePipelineProgressDocument = gql`
|
||||
mutation UpdateOnePipelineProgress($id: String, $amount: Int, $closeDate: DateTime) {
|
||||
mutation UpdateOnePipelineProgress($id: String, $amount: Int, $closeDate: DateTime, $probability: Int, $pointOfContactId: String) {
|
||||
updateOnePipelineProgress(
|
||||
where: {id: $id}
|
||||
data: {amount: {set: $amount}, closeDate: {set: $closeDate}}
|
||||
data: {amount: {set: $amount}, closeDate: {set: $closeDate}, probability: {set: $probability}, pointOfContact: {connect: {id: $pointOfContactId}}}
|
||||
) {
|
||||
id
|
||||
amount
|
||||
@ -3871,6 +3924,8 @@ export type UpdateOnePipelineProgressMutationFn = Apollo.MutationFunction<Update
|
||||
* id: // value for 'id'
|
||||
* amount: // value for 'amount'
|
||||
* closeDate: // value for 'closeDate'
|
||||
* probability: // value for 'probability'
|
||||
* pointOfContactId: // value for 'pointOfContactId'
|
||||
* },
|
||||
* });
|
||||
*/
|
||||
|
||||
@ -12,17 +12,15 @@ import { selectedBoardCardsState } from '@/pipeline/states/selectedBoardCardsSta
|
||||
import { BoardCardEditableFieldDate } from '@/ui/board/card-field/components/BoardCardEditableFieldDate';
|
||||
import { ChipVariant } from '@/ui/chip/components/EntityChip';
|
||||
import { NumberEditableField } from '@/ui/editable-field/variants/components/NumberEditableField';
|
||||
import { IconCurrencyDollar } from '@/ui/icon';
|
||||
import { IconCheck, IconCurrencyDollar } from '@/ui/icon';
|
||||
import { IconCalendarEvent } from '@/ui/icon';
|
||||
import { Checkbox } from '@/ui/input/components/Checkbox';
|
||||
import { useRecoilScopedState } from '@/ui/recoil-scope/hooks/useRecoilScopedState';
|
||||
import {
|
||||
PipelineProgress,
|
||||
useUpdateOnePipelineProgressMutation,
|
||||
} from '~/generated/graphql';
|
||||
import { useUpdateOnePipelineProgressMutation } from '~/generated/graphql';
|
||||
import { getLogoUrlFromDomainName } from '~/utils';
|
||||
|
||||
import { CompanyAccountOwnerEditableField } from '../editable-field/components/CompanyAccountOwnerEditableField';
|
||||
import { PipelineProgressForBoard } from '../types/CompanyProgress';
|
||||
|
||||
import { CompanyChip } from './CompanyChip';
|
||||
|
||||
@ -104,14 +102,14 @@ export function CompanyBoardCard() {
|
||||
}
|
||||
|
||||
const handleCardUpdate = useCallback(
|
||||
async (
|
||||
pipelineProgress: Pick<PipelineProgress, 'id' | 'amount' | 'closeDate'>,
|
||||
) => {
|
||||
async (pipelineProgress: PipelineProgressForBoard) => {
|
||||
await updatePipelineProgress({
|
||||
variables: {
|
||||
id: pipelineProgress.id,
|
||||
amount: pipelineProgress.amount,
|
||||
closeDate: pipelineProgress.closeDate || null,
|
||||
closeDate: pipelineProgress.closeDate,
|
||||
probability: pipelineProgress.probability,
|
||||
pointOfContactId: pipelineProgress.pointOfContactId || undefined,
|
||||
},
|
||||
refetchQueries: [
|
||||
getOperationName(GET_PIPELINE_PROGRESS) ?? '',
|
||||
@ -169,6 +167,17 @@ export function CompanyBoardCard() {
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
<NumberEditableField
|
||||
icon={<IconCheck />}
|
||||
placeholder="Opportunity probability for closing"
|
||||
value={pipelineProgress.probability}
|
||||
onSubmit={(value) =>
|
||||
handleCardUpdate({
|
||||
...pipelineProgress,
|
||||
probability: value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</StyledBoardCardBody>
|
||||
</StyledBoardCard>
|
||||
</StyledBoardCardWrapper>
|
||||
|
||||
@ -1,10 +1,17 @@
|
||||
import { Company, PipelineProgress } from '~/generated/graphql';
|
||||
import { Company, Person, PipelineProgress } from '~/generated/graphql';
|
||||
|
||||
export type CompanyForBoard = Pick<Company, 'id' | 'name' | 'domainName'>;
|
||||
export type PipelineProgressForBoard = Pick<
|
||||
PipelineProgress,
|
||||
'id' | 'amount' | 'closeDate' | 'progressableId'
|
||||
>;
|
||||
| 'id'
|
||||
| 'amount'
|
||||
| 'closeDate'
|
||||
| 'progressableId'
|
||||
| 'probability'
|
||||
| 'pointOfContactId'
|
||||
> & {
|
||||
pointOfContact?: Pick<Person, 'id' | 'firstName' | 'lastName'> | null;
|
||||
};
|
||||
|
||||
export type CompanyProgress = {
|
||||
company: CompanyForBoard;
|
||||
|
||||
@ -37,6 +37,13 @@ export const GET_PIPELINE_PROGRESS = gql`
|
||||
progressableId
|
||||
amount
|
||||
closeDate
|
||||
pointOfContactId
|
||||
pointOfContact {
|
||||
id
|
||||
firstName
|
||||
lastName
|
||||
}
|
||||
probability
|
||||
}
|
||||
}
|
||||
`;
|
||||
@ -46,10 +53,17 @@ export const UPDATE_PIPELINE_PROGRESS = gql`
|
||||
$id: String
|
||||
$amount: Int
|
||||
$closeDate: DateTime
|
||||
$probability: Int
|
||||
$pointOfContactId: String
|
||||
) {
|
||||
updateOnePipelineProgress(
|
||||
where: { id: $id }
|
||||
data: { amount: { set: $amount }, closeDate: { set: $closeDate } }
|
||||
data: {
|
||||
amount: { set: $amount }
|
||||
closeDate: { set: $closeDate }
|
||||
probability: { set: $probability }
|
||||
pointOfContact: { connect: { id: $pointOfContactId } }
|
||||
}
|
||||
) {
|
||||
id
|
||||
amount
|
||||
|
||||
@ -68,6 +68,20 @@ export class PipelineProgressResolver {
|
||||
@PrismaSelector({ modelName: 'PipelineProgress' })
|
||||
prismaSelect: PrismaSelect<'PipelineProgress'>,
|
||||
): Promise<Partial<PipelineProgress> | null> {
|
||||
// TODO: Do a proper check with recursion testing on args in a more generic place
|
||||
for (const key in args.data) {
|
||||
if (args.data[key]) {
|
||||
for (const subKey in args.data[key]) {
|
||||
if (JSON.stringify(args.data[key][subKey]) === '{}') {
|
||||
delete args.data[key][subKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (JSON.stringify(args.data[key]) === '{}') {
|
||||
delete args.data[key];
|
||||
}
|
||||
}
|
||||
return this.pipelineProgressService.update({
|
||||
where: args.where,
|
||||
data: args.data,
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
/*
|
||||
Warnings:
|
||||
|
||||
- Made the column `settingsId` on table `users` required. This step will fail if there are existing NULL values in that column.
|
||||
|
||||
*/
|
||||
-- AlterTable
|
||||
ALTER TABLE "pipeline_progresses" ADD COLUMN "pointOfContactId" TEXT,
|
||||
ADD COLUMN "probability" INTEGER;
|
||||
|
||||
-- AlterTable
|
||||
ALTER TABLE "users" ALTER COLUMN "settingsId" SET NOT NULL;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "pipeline_progresses" ADD CONSTRAINT "pipeline_progresses_pointOfContactId_fkey" FOREIGN KEY ("pointOfContactId") REFERENCES "people"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@ -251,8 +251,9 @@ model Person {
|
||||
/// @TypeGraphQL.omit(input: true, output: true)
|
||||
deletedAt DateTime?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
PipelineProgress PipelineProgress[]
|
||||
|
||||
@@map("people")
|
||||
}
|
||||
@ -436,14 +437,17 @@ enum PipelineProgressableType {
|
||||
model PipelineProgress {
|
||||
/// @Validator.IsString()
|
||||
/// @Validator.IsOptional()
|
||||
id String @id @default(uuid())
|
||||
amount Int?
|
||||
closeDate DateTime?
|
||||
id String @id @default(uuid())
|
||||
amount Int?
|
||||
closeDate DateTime?
|
||||
probability Int?
|
||||
|
||||
pipeline Pipeline @relation(fields: [pipelineId], references: [id])
|
||||
pipelineId String
|
||||
pipelineStage PipelineStage @relation(fields: [pipelineStageId], references: [id])
|
||||
pipelineStageId String
|
||||
pointOfContact Person? @relation(fields: [pointOfContactId], references: [id])
|
||||
pointOfContactId String?
|
||||
progressableType PipelineProgressableType
|
||||
progressableId String
|
||||
/// @TypeGraphQL.omit(input: true, output: true)
|
||||
|
||||
Reference in New Issue
Block a user