Improve provisionning new accounts (#757)
* Improve provisionning new accounts * Fix lint
This commit is contained in:
@ -75,7 +75,7 @@ export function App() {
|
|||||||
<Routes>
|
<Routes>
|
||||||
<Route
|
<Route
|
||||||
path=""
|
path=""
|
||||||
element={<Navigate to={AppPath.PeoplePage} replace />}
|
element={<Navigate to={AppPath.CompaniesPage} replace />}
|
||||||
/>
|
/>
|
||||||
<Route path={AppPath.PeoplePage} element={<People />} />
|
<Route path={AppPath.PeoplePage} element={<People />} />
|
||||||
<Route
|
<Route
|
||||||
|
|||||||
@ -47,18 +47,18 @@ export function AppNavbar() {
|
|||||||
icon={<IconSettings size={theme.icon.size.md} />}
|
icon={<IconSettings size={theme.icon.size.md} />}
|
||||||
/>
|
/>
|
||||||
<NavTitle label="Workspace" />
|
<NavTitle label="Workspace" />
|
||||||
<NavItem
|
|
||||||
label="People"
|
|
||||||
to="/people"
|
|
||||||
icon={<IconUser size={theme.icon.size.md} />}
|
|
||||||
active={currentPath === '/people'}
|
|
||||||
/>
|
|
||||||
<NavItem
|
<NavItem
|
||||||
label="Companies"
|
label="Companies"
|
||||||
to="/companies"
|
to="/companies"
|
||||||
icon={<IconBuildingSkyscraper size={theme.icon.size.md} />}
|
icon={<IconBuildingSkyscraper size={theme.icon.size.md} />}
|
||||||
active={currentPath === '/companies'}
|
active={currentPath === '/companies'}
|
||||||
/>
|
/>
|
||||||
|
<NavItem
|
||||||
|
label="People"
|
||||||
|
to="/people"
|
||||||
|
icon={<IconUser size={theme.icon.size.md} />}
|
||||||
|
active={currentPath === '/people'}
|
||||||
|
/>
|
||||||
<NavItem
|
<NavItem
|
||||||
label="Opportunities"
|
label="Opportunities"
|
||||||
to="/opportunities"
|
to="/opportunities"
|
||||||
|
|||||||
@ -16,7 +16,10 @@ import { filtersScopedState } from '@/ui/filter-n-sort/states/filtersScopedState
|
|||||||
import { FilterDefinition } from '@/ui/filter-n-sort/types/FilterDefinition';
|
import { FilterDefinition } from '@/ui/filter-n-sort/types/FilterDefinition';
|
||||||
import { turnFilterIntoWhereClause } from '@/ui/filter-n-sort/utils/turnFilterIntoWhereClause';
|
import { turnFilterIntoWhereClause } from '@/ui/filter-n-sort/utils/turnFilterIntoWhereClause';
|
||||||
import { useRecoilScopedValue } from '@/ui/recoil-scope/hooks/useRecoilScopedValue';
|
import { useRecoilScopedValue } from '@/ui/recoil-scope/hooks/useRecoilScopedValue';
|
||||||
import { PipelineProgressOrderByWithRelationInput as PipelineProgresses_Order_By } from '~/generated/graphql';
|
import {
|
||||||
|
PipelineProgressableType,
|
||||||
|
PipelineProgressOrderByWithRelationInput as PipelineProgresses_Order_By,
|
||||||
|
} from '~/generated/graphql';
|
||||||
import {
|
import {
|
||||||
Pipeline,
|
Pipeline,
|
||||||
useGetCompaniesQuery,
|
useGetCompaniesQuery,
|
||||||
@ -39,11 +42,16 @@ export function HooksCompanyBoard({
|
|||||||
const [currentPipeline, setCurrentPipeline] =
|
const [currentPipeline, setCurrentPipeline] =
|
||||||
useRecoilState(currentPipelineState);
|
useRecoilState(currentPipelineState);
|
||||||
|
|
||||||
const [, setBoard] = useRecoilState(boardState);
|
const [board, setBoard] = useRecoilState(boardState);
|
||||||
|
|
||||||
const [, setIsBoardLoaded] = useRecoilState(isBoardLoadedState);
|
const [, setIsBoardLoaded] = useRecoilState(isBoardLoadedState);
|
||||||
|
|
||||||
useGetPipelinesQuery({
|
useGetPipelinesQuery({
|
||||||
|
variables: {
|
||||||
|
where: {
|
||||||
|
pipelineProgressableType: { equals: PipelineProgressableType.Company },
|
||||||
|
},
|
||||||
|
},
|
||||||
onCompleted: async (data) => {
|
onCompleted: async (data) => {
|
||||||
const pipeline = data?.findManyPipeline[0] as Pipeline;
|
const pipeline = data?.findManyPipeline[0] as Pipeline;
|
||||||
setCurrentPipeline(pipeline);
|
setCurrentPipeline(pipeline);
|
||||||
@ -55,12 +63,12 @@ export function HooksCompanyBoard({
|
|||||||
})
|
})
|
||||||
: [];
|
: [];
|
||||||
const initialBoard: BoardPipelineStageColumn[] =
|
const initialBoard: BoardPipelineStageColumn[] =
|
||||||
orderedPipelineStages?.map((pipelineStage) => ({
|
orderedPipelineStages?.map((pipelineStage, i) => ({
|
||||||
pipelineStageId: pipelineStage.id,
|
pipelineStageId: pipelineStage.id,
|
||||||
title: pipelineStage.name,
|
title: pipelineStage.name,
|
||||||
colorCode: pipelineStage.color,
|
colorCode: pipelineStage.color,
|
||||||
index: pipelineStage.index || 0,
|
index: pipelineStage.index || 0,
|
||||||
pipelineProgressIds: [],
|
pipelineProgressIds: board?.[i].pipelineProgressIds || [],
|
||||||
})) || [];
|
})) || [];
|
||||||
setBoard(initialBoard);
|
setBoard(initialBoard);
|
||||||
},
|
},
|
||||||
|
|||||||
@ -14,6 +14,8 @@ import {
|
|||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
import { logError } from '~/utils/logError';
|
import { logError } from '~/utils/logError';
|
||||||
|
|
||||||
|
import { SEARCH_COMPANY_QUERY } from '../../search/queries/search';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
people: Pick<Person, 'id'>;
|
people: Pick<Person, 'id'>;
|
||||||
};
|
};
|
||||||
@ -51,7 +53,10 @@ export function PeopleCompanyCreateCell({ people }: OwnProps) {
|
|||||||
address: '',
|
address: '',
|
||||||
createdAt: new Date().toISOString(),
|
createdAt: new Date().toISOString(),
|
||||||
},
|
},
|
||||||
refetchQueries: [getOperationName(GET_COMPANIES) || ''],
|
refetchQueries: [
|
||||||
|
getOperationName(GET_COMPANIES) ?? '',
|
||||||
|
getOperationName(SEARCH_COMPANY_QUERY) ?? '',
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
await updatePeople({
|
await updatePeople({
|
||||||
|
|||||||
@ -17,6 +17,8 @@ import {
|
|||||||
useInsertCompanyMutation,
|
useInsertCompanyMutation,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
|
import { SEARCH_COMPANY_QUERY } from '../../modules/search/queries/search';
|
||||||
|
|
||||||
const StyledTableContainer = styled.div`
|
const StyledTableContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -37,7 +39,10 @@ export function Companies() {
|
|||||||
|
|
||||||
await insertCompany({
|
await insertCompany({
|
||||||
variables: newCompany,
|
variables: newCompany,
|
||||||
refetchQueries: [getOperationName(GET_COMPANIES) ?? ''],
|
refetchQueries: [
|
||||||
|
getOperationName(GET_COMPANIES) ?? '',
|
||||||
|
getOperationName(SEARCH_COMPANY_QUERY) ?? '',
|
||||||
|
],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
import { PrismaService } from 'src/database/prisma.service';
|
import { PrismaService } from 'src/database/prisma.service';
|
||||||
|
import companiesSeed from 'src/core/company/seed-data/companies.json';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CompanyService {
|
export class CompanyService {
|
||||||
@ -36,4 +37,15 @@ export class CompanyService {
|
|||||||
|
|
||||||
// GroupBy
|
// GroupBy
|
||||||
groupBy = this.prismaService.company.groupBy;
|
groupBy = this.prismaService.company.groupBy;
|
||||||
|
async createDefaultCompanies({ workspaceId }: { workspaceId: string }) {
|
||||||
|
const companies = companiesSeed.map((company) => ({
|
||||||
|
...company,
|
||||||
|
workspaceId,
|
||||||
|
}));
|
||||||
|
await this.createMany({
|
||||||
|
data: companies,
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.findMany({ where: { workspaceId }});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
33
server/src/core/company/seed-data/companies.json
Normal file
33
server/src/core/company/seed-data/companies.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "Rudderstack",
|
||||||
|
"domainName": "rudderstack.com",
|
||||||
|
"address": "San Francisco",
|
||||||
|
"employees": 195
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Medusa",
|
||||||
|
"domainName": "medusajs.com",
|
||||||
|
"address": "Copenhagen",
|
||||||
|
"employees": 57
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Metabase",
|
||||||
|
"domainName": "metabase.com",
|
||||||
|
"address": "San Francisco",
|
||||||
|
"employees": 68
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Strapi",
|
||||||
|
"domainName": "strapi.com",
|
||||||
|
"address": "Paris",
|
||||||
|
"employees": 95
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Posthog",
|
||||||
|
"domainName": "posthog.com",
|
||||||
|
"address": "San Francisco",
|
||||||
|
"employees": 34
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
@ -1,6 +1,9 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { Company } from '@prisma/client';
|
||||||
|
|
||||||
import { PrismaService } from 'src/database/prisma.service';
|
import { PrismaService } from 'src/database/prisma.service';
|
||||||
|
import peopleSeed from 'src/core/person/seed-data/people.json';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PersonService {
|
export class PersonService {
|
||||||
@ -36,4 +39,20 @@ export class PersonService {
|
|||||||
|
|
||||||
// GroupBy
|
// GroupBy
|
||||||
groupBy = this.prismaService.person.groupBy;
|
groupBy = this.prismaService.person.groupBy;
|
||||||
|
async createDefaultPeople({
|
||||||
|
workspaceId,
|
||||||
|
companies,
|
||||||
|
}: {
|
||||||
|
workspaceId: string;
|
||||||
|
companies: Company[];
|
||||||
|
}) {
|
||||||
|
const people = peopleSeed.map((person, i) => ({
|
||||||
|
...person,
|
||||||
|
companyId: companies[i].id || null,
|
||||||
|
workspaceId,
|
||||||
|
}));
|
||||||
|
return this.createMany({
|
||||||
|
data: people,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
38
server/src/core/person/seed-data/people.json
Normal file
38
server/src/core/person/seed-data/people.json
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"firstName": "Soumyadeb",
|
||||||
|
"lastName": "Mitra",
|
||||||
|
"city": "San Francisco",
|
||||||
|
"email": "soumyadeb@rudderstack.com",
|
||||||
|
"phone": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"firstName": "Sebastian",
|
||||||
|
"lastName": "Rindom",
|
||||||
|
"city": "Copenhagen",
|
||||||
|
"email": "sebastian@medusajs.com",
|
||||||
|
"phone": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"firstName": "Sameer",
|
||||||
|
"lastName": "Al-Sakran",
|
||||||
|
"city": "San Francisco",
|
||||||
|
"email": "sameer@metabase.com",
|
||||||
|
"phone": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"firstName": "Pierre",
|
||||||
|
"lastName": "Burgy",
|
||||||
|
"city": "Paris",
|
||||||
|
"email": "pierre@strapi.com",
|
||||||
|
"phone": ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"firstName": "James",
|
||||||
|
"lastName": "Hawkins",
|
||||||
|
"city": "San Francisco",
|
||||||
|
"email": "james@posthog.com",
|
||||||
|
"phone": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
@ -4,6 +4,8 @@ import { PrismaService } from 'src/database/prisma.service';
|
|||||||
import { prismaMock } from 'src/database/client-mock/jest-prisma-singleton';
|
import { prismaMock } from 'src/database/client-mock/jest-prisma-singleton';
|
||||||
import { PipelineService } from 'src/core/pipeline/services/pipeline.service';
|
import { PipelineService } from 'src/core/pipeline/services/pipeline.service';
|
||||||
import { PipelineStageService } from 'src/core/pipeline/services/pipeline-stage.service';
|
import { PipelineStageService } from 'src/core/pipeline/services/pipeline-stage.service';
|
||||||
|
import { PersonService } from 'src/core/person/person.service';
|
||||||
|
import { CompanyService } from 'src/core/company/company.service';
|
||||||
|
|
||||||
import { WorkspaceService } from './workspace.service';
|
import { WorkspaceService } from './workspace.service';
|
||||||
|
|
||||||
@ -26,6 +28,14 @@ describe('WorkspaceService', () => {
|
|||||||
provide: PipelineStageService,
|
provide: PipelineStageService,
|
||||||
useValue: {},
|
useValue: {},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: PersonService,
|
||||||
|
useValue: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: CompanyService,
|
||||||
|
useValue: {},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}).compile();
|
}).compile();
|
||||||
|
|
||||||
|
|||||||
@ -1,14 +1,20 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
import { PipelineStageService } from 'src/core/pipeline/services/pipeline-stage.service';
|
import { PipelineStageService } from 'src/core/pipeline/services/pipeline-stage.service';
|
||||||
import { PipelineService } from 'src/core/pipeline/services/pipeline.service';
|
import { PipelineService } from 'src/core/pipeline/services/pipeline.service';
|
||||||
import { PrismaService } from 'src/database/prisma.service';
|
import { PrismaService } from 'src/database/prisma.service';
|
||||||
|
import { CompanyService } from 'src/core/company/company.service';
|
||||||
|
import { PersonService } from 'src/core/person/person.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkspaceService {
|
export class WorkspaceService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly prismaService: PrismaService,
|
private readonly prismaService: PrismaService,
|
||||||
private readonly pipelineService: PipelineService,
|
private readonly pipelineService: PipelineService,
|
||||||
|
private readonly companyService: CompanyService,
|
||||||
|
private readonly personService: PersonService,
|
||||||
private readonly pipelineStageService: PipelineStageService,
|
private readonly pipelineStageService: PipelineStageService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@ -45,7 +51,22 @@ export class WorkspaceService {
|
|||||||
|
|
||||||
// Customs
|
// Customs
|
||||||
async createDefaultWorkspace() {
|
async createDefaultWorkspace() {
|
||||||
const workspace = await this.create({ data: {} });
|
const workspace = await this.create({
|
||||||
|
data: {
|
||||||
|
inviteHash: v4(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create default companies
|
||||||
|
const companies = await this.companyService.createDefaultCompanies({
|
||||||
|
workspaceId: workspace.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create default people
|
||||||
|
await this.personService.createDefaultPeople({
|
||||||
|
workspaceId: workspace.id,
|
||||||
|
companies,
|
||||||
|
});
|
||||||
|
|
||||||
// Create default pipeline
|
// Create default pipeline
|
||||||
const pipeline = await this.pipelineService.createDefaultPipeline({
|
const pipeline = await this.pipelineService.createDefaultPipeline({
|
||||||
|
|||||||
@ -2,6 +2,8 @@ import { Module } from '@nestjs/common';
|
|||||||
|
|
||||||
import { FileUploadService } from 'src/core/file/services/file-upload.service';
|
import { FileUploadService } from 'src/core/file/services/file-upload.service';
|
||||||
import { PipelineModule } from 'src/core/pipeline/pipeline.module';
|
import { PipelineModule } from 'src/core/pipeline/pipeline.module';
|
||||||
|
import { CompanyModule } from 'src/core/company/company.module';
|
||||||
|
import { PersonModule } from 'src/core/person/person.module';
|
||||||
|
|
||||||
import { WorkspaceService } from './services/workspace.service';
|
import { WorkspaceService } from './services/workspace.service';
|
||||||
import { WorkspaceMemberService } from './services/workspace-member.service';
|
import { WorkspaceMemberService } from './services/workspace-member.service';
|
||||||
@ -9,7 +11,7 @@ import { WorkspaceMemberResolver } from './resolvers/workspace-member.resolver';
|
|||||||
import { WorkspaceResolver } from './resolvers/workspace.resolver';
|
import { WorkspaceResolver } from './resolvers/workspace.resolver';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [PipelineModule],
|
imports: [PipelineModule, CompanyModule, PersonModule],
|
||||||
providers: [
|
providers: [
|
||||||
WorkspaceService,
|
WorkspaceService,
|
||||||
FileUploadService,
|
FileUploadService,
|
||||||
|
|||||||
Reference in New Issue
Block a user