Removing Prisma and Grapql-nestjs-prisma resolvers (#2574)
* Some cleaning * Fix seeds * Fix all sign in, sign up flow and apiKey optimistic rendering * Fix
This commit is contained in:
1
.vscode/extensions.json
vendored
1
.vscode/extensions.json
vendored
@ -7,7 +7,6 @@
|
|||||||
"ms-vscode.makefile-tools",
|
"ms-vscode.makefile-tools",
|
||||||
"esbenp.prettier-vscode",
|
"esbenp.prettier-vscode",
|
||||||
"GraphQL.vscode-graphql",
|
"GraphQL.vscode-graphql",
|
||||||
"prisma.prisma",
|
|
||||||
"yoavbls.pretty-ts-errors",
|
"yoavbls.pretty-ts-errors",
|
||||||
"graphql.vscode-graphql-syntax",
|
"graphql.vscode-graphql-syntax",
|
||||||
"graphql.vscode-graphql",
|
"graphql.vscode-graphql",
|
||||||
|
|||||||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -25,10 +25,6 @@
|
|||||||
"[json]": {
|
"[json]": {
|
||||||
"editor.formatOnSave": true
|
"editor.formatOnSave": true
|
||||||
},
|
},
|
||||||
"[prisma]": {
|
|
||||||
"editor.formatOnSave": true,
|
|
||||||
"editor.defaultFormatter": "Prisma.prisma"
|
|
||||||
},
|
|
||||||
"javascript.format.enable": false,
|
"javascript.format.enable": false,
|
||||||
"typescript.format.enable": false,
|
"typescript.format.enable": false,
|
||||||
"cSpell.enableFiletypes": [
|
"cSpell.enableFiletypes": [
|
||||||
|
|||||||
@ -94,7 +94,7 @@ Start the containers:
|
|||||||
make up
|
make up
|
||||||
```
|
```
|
||||||
|
|
||||||
Setup database, generate prisma client, run migrations, and seed:
|
Setup database, run migrations, and seed:
|
||||||
```bash
|
```bash
|
||||||
make server-database-init
|
make server-database-init
|
||||||
```
|
```
|
||||||
|
|||||||
@ -12,13 +12,9 @@ import { CreateProfile } from '~/pages/auth/CreateProfile';
|
|||||||
import { CreateWorkspace } from '~/pages/auth/CreateWorkspace';
|
import { CreateWorkspace } from '~/pages/auth/CreateWorkspace';
|
||||||
import { SignInUp } from '~/pages/auth/SignInUp';
|
import { SignInUp } from '~/pages/auth/SignInUp';
|
||||||
import { VerifyEffect } from '~/pages/auth/VerifyEffect';
|
import { VerifyEffect } from '~/pages/auth/VerifyEffect';
|
||||||
import { Companies } from '~/pages/companies/Companies';
|
|
||||||
import { CompanyShow } from '~/pages/companies/CompanyShow';
|
|
||||||
import { ImpersonateEffect } from '~/pages/impersonate/ImpersonateEffect';
|
import { ImpersonateEffect } from '~/pages/impersonate/ImpersonateEffect';
|
||||||
import { NotFound } from '~/pages/not-found/NotFound';
|
import { NotFound } from '~/pages/not-found/NotFound';
|
||||||
import { Opportunities } from '~/pages/opportunities/Opportunities';
|
import { Opportunities } from '~/pages/opportunities/Opportunities';
|
||||||
import { People } from '~/pages/people/People';
|
|
||||||
import { PersonShow } from '~/pages/people/PersonShow';
|
|
||||||
import { SettingsNewObject } from '~/pages/settings/data-model/SettingsNewObject';
|
import { SettingsNewObject } from '~/pages/settings/data-model/SettingsNewObject';
|
||||||
import { SettingsObjectDetail } from '~/pages/settings/data-model/SettingsObjectDetail';
|
import { SettingsObjectDetail } from '~/pages/settings/data-model/SettingsObjectDetail';
|
||||||
import { SettingsObjectEdit } from '~/pages/settings/data-model/SettingsObjectEdit';
|
import { SettingsObjectEdit } from '~/pages/settings/data-model/SettingsObjectEdit';
|
||||||
@ -40,7 +36,6 @@ import { SettingsObjectNewFieldStep2 } from './pages/settings/data-model/Setting
|
|||||||
export const App = () => {
|
export const App = () => {
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
const pageTitle = getPageTitleFromPath(pathname);
|
const pageTitle = getPageTitleFromPath(pathname);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageTitle title={pageTitle} />
|
<PageTitle title={pageTitle} />
|
||||||
@ -54,11 +49,7 @@ export const App = () => {
|
|||||||
<Route path={AppPath.Invite} element={<SignInUp />} />
|
<Route path={AppPath.Invite} element={<SignInUp />} />
|
||||||
<Route path={AppPath.CreateWorkspace} element={<CreateWorkspace />} />
|
<Route path={AppPath.CreateWorkspace} element={<CreateWorkspace />} />
|
||||||
<Route path={AppPath.CreateProfile} element={<CreateProfile />} />
|
<Route path={AppPath.CreateProfile} element={<CreateProfile />} />
|
||||||
<Route path="/" element={<Navigate to={AppPath.CompaniesPage} />} />
|
<Route path="/" element={<Navigate to="/objects/companies" />} />
|
||||||
<Route path={AppPath.PeoplePage} element={<People />} />
|
|
||||||
<Route path={AppPath.PersonShowPage} element={<PersonShow />} />
|
|
||||||
<Route path={AppPath.CompaniesPage} element={<Companies />} />
|
|
||||||
<Route path={AppPath.CompanyShowPage} element={<CompanyShow />} />
|
|
||||||
<Route path={AppPath.TasksPage} element={<Tasks />} />
|
<Route path={AppPath.TasksPage} element={<Tasks />} />
|
||||||
<Route path={AppPath.Impersonate} element={<ImpersonateEffect />} />
|
<Route path={AppPath.Impersonate} element={<ImpersonateEffect />} />
|
||||||
|
|
||||||
|
|||||||
@ -59,8 +59,8 @@ export const AppNavbar = () => {
|
|||||||
<ObjectMetadataNavItems />
|
<ObjectMetadataNavItems />
|
||||||
<NavItem
|
<NavItem
|
||||||
label="Opportunities"
|
label="Opportunities"
|
||||||
to="/opportunities"
|
to="/objects/opportunities"
|
||||||
active={currentPath === '/opportunities'}
|
active={currentPath === '/objects/opportunities'}
|
||||||
Icon={IconTargetArrow}
|
Icon={IconTargetArrow}
|
||||||
/>
|
/>
|
||||||
</MainNavbar>
|
</MainNavbar>
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
import { useGoToHotkeys } from '@/ui/utilities/hotkey/hooks/useGoToHotkeys';
|
import { useGoToHotkeys } from '@/ui/utilities/hotkey/hooks/useGoToHotkeys';
|
||||||
|
|
||||||
export const GotoHotkeysEffect = () => {
|
export const GotoHotkeysEffect = () => {
|
||||||
useGoToHotkeys('p', '/people');
|
useGoToHotkeys('p', '/objects/people');
|
||||||
useGoToHotkeys('c', '/companies');
|
useGoToHotkeys('c', '/objects/companies');
|
||||||
useGoToHotkeys('o', '/opportunities');
|
useGoToHotkeys('o', '/objects/opportunities');
|
||||||
useGoToHotkeys('s', '/settings/profile');
|
useGoToHotkeys('s', '/settings/profile');
|
||||||
useGoToHotkeys('t', '/tasks');
|
useGoToHotkeys('t', '/tasks');
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { useEffect, useState } from 'react';
|
|||||||
import { matchPath, useLocation, useNavigate } from 'react-router-dom';
|
import { matchPath, useLocation, useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
||||||
import { ActivityTargetableEntityType } from '@/activities/types/ActivityTargetableEntity';
|
|
||||||
import { useEventTracker } from '@/analytics/hooks/useEventTracker';
|
import { useEventTracker } from '@/analytics/hooks/useEventTracker';
|
||||||
import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus';
|
import { useOnboardingStatus } from '@/auth/hooks/useOnboardingStatus';
|
||||||
import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus';
|
import { OnboardingStatus } from '@/auth/utils/getOnboardingStatus';
|
||||||
@ -12,14 +11,11 @@ import { AppBasePath } from '@/types/AppBasePath';
|
|||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
|
import { PageHotkeyScope } from '@/types/PageHotkeyScope';
|
||||||
import { SettingsPath } from '@/types/SettingsPath';
|
import { SettingsPath } from '@/types/SettingsPath';
|
||||||
import { IconCheckbox, IconNotes } from '@/ui/display/icon';
|
import { IconCheckbox } from '@/ui/display/icon';
|
||||||
import { useSnackBar } from '@/ui/feedback/snack-bar/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/feedback/snack-bar/hooks/useSnackBar';
|
||||||
import { TableHotkeyScope } from '@/ui/object/record-table/types/TableHotkeyScope';
|
import { TableHotkeyScope } from '@/ui/object/record-table/types/TableHotkeyScope';
|
||||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||||
import {
|
import { useGetWorkspaceFromInviteHashLazyQuery } from '~/generated/graphql';
|
||||||
ActivityType,
|
|
||||||
useGetWorkspaceFromInviteHashLazyQuery,
|
|
||||||
} from '~/generated/graphql';
|
|
||||||
|
|
||||||
import { useIsMatchingLocation } from '../hooks/useIsMatchingLocation';
|
import { useIsMatchingLocation } from '../hooks/useIsMatchingLocation';
|
||||||
|
|
||||||
@ -114,22 +110,14 @@ export const PageChangeEffect = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case isMatchingLocation(AppPath.CompaniesPage): {
|
case isMatchingLocation(AppPath.RecordTablePage): {
|
||||||
setHotkeyScope(TableHotkeyScope.Table, { goto: true });
|
setHotkeyScope(TableHotkeyScope.Table, { goto: true });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isMatchingLocation(AppPath.PeoplePage): {
|
case isMatchingLocation(AppPath.RecordShowPage): {
|
||||||
setHotkeyScope(TableHotkeyScope.Table, { goto: true });
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case isMatchingLocation(AppPath.CompanyShowPage): {
|
|
||||||
setHotkeyScope(PageHotkeyScope.CompanyShowPage, { goto: true });
|
setHotkeyScope(PageHotkeyScope.CompanyShowPage, { goto: true });
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case isMatchingLocation(AppPath.PersonShowPage): {
|
|
||||||
setHotkeyScope(PageHotkeyScope.PersonShowPage, { goto: true });
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case isMatchingLocation(AppPath.OpportunitiesPage): {
|
case isMatchingLocation(AppPath.OpportunitiesPage): {
|
||||||
setHotkeyScope(PageHotkeyScope.OpportunitiesPage, { goto: true });
|
setHotkeyScope(PageHotkeyScope.OpportunitiesPage, { goto: true });
|
||||||
break;
|
break;
|
||||||
@ -173,93 +161,16 @@ export const PageChangeEffect = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setToIntitialCommandMenu();
|
setToIntitialCommandMenu();
|
||||||
switch (true) {
|
|
||||||
case isMatchingLocation(AppPath.CompanyShowPage): {
|
|
||||||
const companyId = matchPath(
|
|
||||||
{ path: '/companies/:id' },
|
|
||||||
location.pathname,
|
|
||||||
)?.params.id;
|
|
||||||
|
|
||||||
const entity = !!companyId
|
addToCommandMenu([
|
||||||
? {
|
{
|
||||||
id: companyId,
|
to: '',
|
||||||
type: 'Company' as ActivityTargetableEntityType,
|
label: 'Create Task',
|
||||||
}
|
type: CommandType.Create,
|
||||||
: undefined;
|
Icon: IconCheckbox,
|
||||||
|
onCommandClick: () => openCreateActivity({ type: 'Task' }),
|
||||||
addToCommandMenu([
|
},
|
||||||
{
|
]);
|
||||||
to: '',
|
|
||||||
label: 'Create Task',
|
|
||||||
type: CommandType.Create,
|
|
||||||
Icon: IconCheckbox,
|
|
||||||
onCommandClick: () =>
|
|
||||||
openCreateActivity({
|
|
||||||
type: 'Task',
|
|
||||||
targetableEntities: entity ? [entity] : undefined,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
to: '',
|
|
||||||
label: 'Create Note',
|
|
||||||
type: CommandType.Create,
|
|
||||||
Icon: IconNotes,
|
|
||||||
onCommandClick: () =>
|
|
||||||
openCreateActivity({
|
|
||||||
type: ActivityType.Note,
|
|
||||||
targetableEntities: entity ? [entity] : undefined,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case isMatchingLocation(AppPath.PersonShowPage): {
|
|
||||||
const personId = matchPath({ path: '/person/:id' }, location.pathname)
|
|
||||||
?.params.id;
|
|
||||||
|
|
||||||
const entity = !!personId
|
|
||||||
? { id: personId, type: 'Person' as ActivityTargetableEntityType }
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
addToCommandMenu([
|
|
||||||
{
|
|
||||||
to: '',
|
|
||||||
label: 'Create Task',
|
|
||||||
type: CommandType.Create,
|
|
||||||
Icon: IconCheckbox,
|
|
||||||
onCommandClick: () =>
|
|
||||||
openCreateActivity({
|
|
||||||
type: ActivityType.Task,
|
|
||||||
targetableEntities: entity ? [entity] : undefined,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
to: '',
|
|
||||||
label: 'Create Note',
|
|
||||||
type: CommandType.Create,
|
|
||||||
Icon: IconNotes,
|
|
||||||
onCommandClick: () =>
|
|
||||||
openCreateActivity({
|
|
||||||
type: ActivityType.Note,
|
|
||||||
targetableEntities: entity ? [entity] : undefined,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
addToCommandMenu([
|
|
||||||
{
|
|
||||||
to: '',
|
|
||||||
label: 'Create Task',
|
|
||||||
type: CommandType.Create,
|
|
||||||
Icon: IconCheckbox,
|
|
||||||
onCommandClick: () =>
|
|
||||||
openCreateActivity({ type: ActivityType.Task }),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
eventTracker('pageview', {
|
eventTracker('pageview', {
|
||||||
|
|||||||
@ -20,92 +20,8 @@ export type Scalars = {
|
|||||||
DateTime: { input: any; output: any; }
|
DateTime: { input: any; output: any; }
|
||||||
/** The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). */
|
/** The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). */
|
||||||
JSON: { input: any; output: any; }
|
JSON: { input: any; output: any; }
|
||||||
/** The `JSONObject` scalar type represents JSON objects as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). */
|
|
||||||
JSONObject: { input: any; output: any; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Activity = {
|
|
||||||
__typename?: 'Activity';
|
|
||||||
activityTargets?: Maybe<Array<ActivityTarget>>;
|
|
||||||
assignee?: Maybe<User>;
|
|
||||||
assigneeId?: Maybe<Scalars['String']['output']>;
|
|
||||||
attachments?: Maybe<Array<Attachment>>;
|
|
||||||
author: User;
|
|
||||||
authorId: Scalars['String']['output'];
|
|
||||||
body?: Maybe<Scalars['String']['output']>;
|
|
||||||
comments?: Maybe<Array<Comment>>;
|
|
||||||
completedAt?: Maybe<Scalars['DateTime']['output']>;
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
dueAt?: Maybe<Scalars['DateTime']['output']>;
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
reminderAt?: Maybe<Scalars['DateTime']['output']>;
|
|
||||||
title?: Maybe<Scalars['String']['output']>;
|
|
||||||
type: ActivityType;
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
workspaceMemberAssignee?: Maybe<WorkspaceMember>;
|
|
||||||
workspaceMemberAssigneeId?: Maybe<Scalars['String']['output']>;
|
|
||||||
workspaceMemberAuthor?: Maybe<WorkspaceMember>;
|
|
||||||
workspaceMemberAuthorId?: Maybe<Scalars['String']['output']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ActivityTarget = {
|
|
||||||
__typename?: 'ActivityTarget';
|
|
||||||
activity: Activity;
|
|
||||||
activityId: Scalars['String']['output'];
|
|
||||||
company?: Maybe<Company>;
|
|
||||||
companyId?: Maybe<Scalars['String']['output']>;
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
person?: Maybe<Person>;
|
|
||||||
personId?: Maybe<Scalars['String']['output']>;
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
};
|
|
||||||
|
|
||||||
export enum ActivityType {
|
|
||||||
Note = 'Note',
|
|
||||||
Task = 'Task'
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ApiKey = {
|
|
||||||
__typename?: 'ApiKey';
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
expiresAt?: Maybe<Scalars['DateTime']['output']>;
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
name: Scalars['String']['output'];
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Attachment = {
|
|
||||||
__typename?: 'Attachment';
|
|
||||||
activity?: Maybe<Activity>;
|
|
||||||
activityId?: Maybe<Scalars['String']['output']>;
|
|
||||||
author: User;
|
|
||||||
authorId: Scalars['String']['output'];
|
|
||||||
company?: Maybe<Company>;
|
|
||||||
companyId?: Maybe<Scalars['String']['output']>;
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
fullPath: Scalars['String']['output'];
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
name: Scalars['String']['output'];
|
|
||||||
person?: Maybe<Person>;
|
|
||||||
personId?: Maybe<Scalars['String']['output']>;
|
|
||||||
type: AttachmentType;
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
workspace: Workspace;
|
|
||||||
workspaceMemberAuthor?: Maybe<WorkspaceMember>;
|
|
||||||
workspaceMemberAuthorId?: Maybe<Scalars['String']['output']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export enum AttachmentType {
|
|
||||||
Archive = 'Archive',
|
|
||||||
Audio = 'Audio',
|
|
||||||
Image = 'Image',
|
|
||||||
Other = 'Other',
|
|
||||||
Spreadsheet = 'Spreadsheet',
|
|
||||||
TextDocument = 'TextDocument',
|
|
||||||
Video = 'Video'
|
|
||||||
}
|
|
||||||
|
|
||||||
export type AuthProviders = {
|
export type AuthProviders = {
|
||||||
__typename?: 'AuthProviders';
|
__typename?: 'AuthProviders';
|
||||||
google: Scalars['Boolean']['output'];
|
google: Scalars['Boolean']['output'];
|
||||||
@ -130,53 +46,8 @@ export type BooleanFieldComparison = {
|
|||||||
isNot?: InputMaybe<Scalars['Boolean']['input']>;
|
isNot?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum ColorScheme {
|
|
||||||
Dark = 'Dark',
|
|
||||||
Light = 'Light',
|
|
||||||
System = 'System'
|
|
||||||
}
|
|
||||||
|
|
||||||
export type Comment = {
|
|
||||||
__typename?: 'Comment';
|
|
||||||
activity?: Maybe<Activity>;
|
|
||||||
activityId?: Maybe<Scalars['String']['output']>;
|
|
||||||
author: User;
|
|
||||||
authorId: Scalars['String']['output'];
|
|
||||||
body: Scalars['String']['output'];
|
|
||||||
commentThreadId?: Maybe<Scalars['String']['output']>;
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
workspaceMemberAuthor?: Maybe<WorkspaceMember>;
|
|
||||||
workspaceMemberAuthorId?: Maybe<Scalars['String']['output']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Company = {
|
|
||||||
__typename?: 'Company';
|
|
||||||
ActivityTarget?: Maybe<Array<ActivityTarget>>;
|
|
||||||
Attachment?: Maybe<Array<Attachment>>;
|
|
||||||
Favorite?: Maybe<Array<Favorite>>;
|
|
||||||
PipelineProgress?: Maybe<Array<PipelineProgress>>;
|
|
||||||
accountOwner?: Maybe<User>;
|
|
||||||
accountOwnerId?: Maybe<Scalars['String']['output']>;
|
|
||||||
address: Scalars['String']['output'];
|
|
||||||
annualRecurringRevenue?: Maybe<Scalars['Int']['output']>;
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
domainName: Scalars['String']['output'];
|
|
||||||
employees?: Maybe<Scalars['Int']['output']>;
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
idealCustomerProfile: Scalars['Boolean']['output'];
|
|
||||||
linkedinUrl?: Maybe<Scalars['String']['output']>;
|
|
||||||
name: Scalars['String']['output'];
|
|
||||||
people?: Maybe<Array<Person>>;
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
workspaceMemberAccountOwner?: Maybe<WorkspaceMember>;
|
|
||||||
workspaceMemberAccountOwnerId?: Maybe<Scalars['String']['output']>;
|
|
||||||
xUrl?: Maybe<Scalars['String']['output']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CreateFieldInput = {
|
export type CreateFieldInput = {
|
||||||
defaultValue?: InputMaybe<Scalars['JSONObject']['input']>;
|
defaultValue?: InputMaybe<Scalars['JSON']['input']>;
|
||||||
description?: InputMaybe<Scalars['String']['input']>;
|
description?: InputMaybe<Scalars['String']['input']>;
|
||||||
icon?: InputMaybe<Scalars['String']['input']>;
|
icon?: InputMaybe<Scalars['String']['input']>;
|
||||||
isNullable?: InputMaybe<Scalars['Boolean']['input']>;
|
isNullable?: InputMaybe<Scalars['Boolean']['input']>;
|
||||||
@ -223,177 +94,6 @@ export type CreateRelationInput = {
|
|||||||
toObjectMetadataId: Scalars['String']['input'];
|
toObjectMetadataId: Scalars['String']['input'];
|
||||||
};
|
};
|
||||||
|
|
||||||
export enum CurrencyCode {
|
|
||||||
Aed = 'AED',
|
|
||||||
Afn = 'AFN',
|
|
||||||
All = 'ALL',
|
|
||||||
Amd = 'AMD',
|
|
||||||
Ang = 'ANG',
|
|
||||||
Aoa = 'AOA',
|
|
||||||
Ars = 'ARS',
|
|
||||||
Aud = 'AUD',
|
|
||||||
Awg = 'AWG',
|
|
||||||
Azn = 'AZN',
|
|
||||||
Bam = 'BAM',
|
|
||||||
Bbd = 'BBD',
|
|
||||||
Bdt = 'BDT',
|
|
||||||
Bgn = 'BGN',
|
|
||||||
Bhd = 'BHD',
|
|
||||||
Bif = 'BIF',
|
|
||||||
Bmd = 'BMD',
|
|
||||||
Bnd = 'BND',
|
|
||||||
Bob = 'BOB',
|
|
||||||
Bov = 'BOV',
|
|
||||||
Brl = 'BRL',
|
|
||||||
Bsd = 'BSD',
|
|
||||||
Btn = 'BTN',
|
|
||||||
Bwp = 'BWP',
|
|
||||||
Byn = 'BYN',
|
|
||||||
Bzd = 'BZD',
|
|
||||||
Cad = 'CAD',
|
|
||||||
Cdf = 'CDF',
|
|
||||||
Chf = 'CHF',
|
|
||||||
Clf = 'CLF',
|
|
||||||
Clp = 'CLP',
|
|
||||||
Cny = 'CNY',
|
|
||||||
Cop = 'COP',
|
|
||||||
Cou = 'COU',
|
|
||||||
Crc = 'CRC',
|
|
||||||
Cuc = 'CUC',
|
|
||||||
Cup = 'CUP',
|
|
||||||
Cve = 'CVE',
|
|
||||||
Czk = 'CZK',
|
|
||||||
Djf = 'DJF',
|
|
||||||
Dkk = 'DKK',
|
|
||||||
Dop = 'DOP',
|
|
||||||
Dzd = 'DZD',
|
|
||||||
Egp = 'EGP',
|
|
||||||
Ern = 'ERN',
|
|
||||||
Etb = 'ETB',
|
|
||||||
Eur = 'EUR',
|
|
||||||
Fjd = 'FJD',
|
|
||||||
Fkp = 'FKP',
|
|
||||||
Gbp = 'GBP',
|
|
||||||
Gel = 'GEL',
|
|
||||||
Ghs = 'GHS',
|
|
||||||
Gip = 'GIP',
|
|
||||||
Gmd = 'GMD',
|
|
||||||
Gnf = 'GNF',
|
|
||||||
Gtq = 'GTQ',
|
|
||||||
Gyd = 'GYD',
|
|
||||||
Hkd = 'HKD',
|
|
||||||
Hnl = 'HNL',
|
|
||||||
Hrk = 'HRK',
|
|
||||||
Htg = 'HTG',
|
|
||||||
Huf = 'HUF',
|
|
||||||
Idr = 'IDR',
|
|
||||||
Ils = 'ILS',
|
|
||||||
Inr = 'INR',
|
|
||||||
Iqd = 'IQD',
|
|
||||||
Irr = 'IRR',
|
|
||||||
Isk = 'ISK',
|
|
||||||
Jmd = 'JMD',
|
|
||||||
Jod = 'JOD',
|
|
||||||
Jpy = 'JPY',
|
|
||||||
Kes = 'KES',
|
|
||||||
Kgs = 'KGS',
|
|
||||||
Khr = 'KHR',
|
|
||||||
Kmf = 'KMF',
|
|
||||||
Kpw = 'KPW',
|
|
||||||
Krw = 'KRW',
|
|
||||||
Kwd = 'KWD',
|
|
||||||
Kyd = 'KYD',
|
|
||||||
Kzt = 'KZT',
|
|
||||||
Lak = 'LAK',
|
|
||||||
Lbp = 'LBP',
|
|
||||||
Lkr = 'LKR',
|
|
||||||
Lrd = 'LRD',
|
|
||||||
Lsl = 'LSL',
|
|
||||||
Lyd = 'LYD',
|
|
||||||
Mad = 'MAD',
|
|
||||||
Mdl = 'MDL',
|
|
||||||
Mga = 'MGA',
|
|
||||||
Mkd = 'MKD',
|
|
||||||
Mmk = 'MMK',
|
|
||||||
Mnt = 'MNT',
|
|
||||||
Mop = 'MOP',
|
|
||||||
Mro = 'MRO',
|
|
||||||
Mru = 'MRU',
|
|
||||||
Mur = 'MUR',
|
|
||||||
Mvr = 'MVR',
|
|
||||||
Mwk = 'MWK',
|
|
||||||
Mxn = 'MXN',
|
|
||||||
Mxv = 'MXV',
|
|
||||||
Myr = 'MYR',
|
|
||||||
Mzn = 'MZN',
|
|
||||||
Nad = 'NAD',
|
|
||||||
Ngn = 'NGN',
|
|
||||||
Nio = 'NIO',
|
|
||||||
Nok = 'NOK',
|
|
||||||
Npr = 'NPR',
|
|
||||||
Nzd = 'NZD',
|
|
||||||
Omr = 'OMR',
|
|
||||||
Pab = 'PAB',
|
|
||||||
Pen = 'PEN',
|
|
||||||
Pgk = 'PGK',
|
|
||||||
Php = 'PHP',
|
|
||||||
Pkr = 'PKR',
|
|
||||||
Pln = 'PLN',
|
|
||||||
Pyg = 'PYG',
|
|
||||||
Qar = 'QAR',
|
|
||||||
Ron = 'RON',
|
|
||||||
Rsd = 'RSD',
|
|
||||||
Rub = 'RUB',
|
|
||||||
Rwf = 'RWF',
|
|
||||||
Sar = 'SAR',
|
|
||||||
Sbd = 'SBD',
|
|
||||||
Scr = 'SCR',
|
|
||||||
Sdd = 'SDD',
|
|
||||||
Sdg = 'SDG',
|
|
||||||
Sek = 'SEK',
|
|
||||||
Sgd = 'SGD',
|
|
||||||
Shp = 'SHP',
|
|
||||||
Sll = 'SLL',
|
|
||||||
Sos = 'SOS',
|
|
||||||
Srd = 'SRD',
|
|
||||||
Ssp = 'SSP',
|
|
||||||
Std = 'STD',
|
|
||||||
Stn = 'STN',
|
|
||||||
Svc = 'SVC',
|
|
||||||
Syp = 'SYP',
|
|
||||||
Szl = 'SZL',
|
|
||||||
Thb = 'THB',
|
|
||||||
Tjs = 'TJS',
|
|
||||||
Tmm = 'TMM',
|
|
||||||
Tmt = 'TMT',
|
|
||||||
Tnd = 'TND',
|
|
||||||
Top = 'TOP',
|
|
||||||
Try = 'TRY',
|
|
||||||
Ttd = 'TTD',
|
|
||||||
Twd = 'TWD',
|
|
||||||
Tzs = 'TZS',
|
|
||||||
Uah = 'UAH',
|
|
||||||
Ugx = 'UGX',
|
|
||||||
Usd = 'USD',
|
|
||||||
Uyu = 'UYU',
|
|
||||||
Uzs = 'UZS',
|
|
||||||
Vef = 'VEF',
|
|
||||||
Ves = 'VES',
|
|
||||||
Vnd = 'VND',
|
|
||||||
Vuv = 'VUV',
|
|
||||||
Wst = 'WST',
|
|
||||||
Xaf = 'XAF',
|
|
||||||
Xcd = 'XCD',
|
|
||||||
Xof = 'XOF',
|
|
||||||
Xpf = 'XPF',
|
|
||||||
Xsu = 'XSU',
|
|
||||||
Xua = 'XUA',
|
|
||||||
Yer = 'YER',
|
|
||||||
Zar = 'ZAR',
|
|
||||||
Zmw = 'ZMW',
|
|
||||||
Zwl = 'ZWL'
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CursorPaging = {
|
export type CursorPaging = {
|
||||||
/** Paginate after opaque cursor */
|
/** Paginate after opaque cursor */
|
||||||
after?: InputMaybe<Scalars['ConnectionCursor']['input']>;
|
after?: InputMaybe<Scalars['ConnectionCursor']['input']>;
|
||||||
@ -420,19 +120,6 @@ export type DeleteOneRelationInput = {
|
|||||||
id: Scalars['ID']['input'];
|
id: Scalars['ID']['input'];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Favorite = {
|
|
||||||
__typename?: 'Favorite';
|
|
||||||
company?: Maybe<Company>;
|
|
||||||
companyId?: Maybe<Scalars['String']['output']>;
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
person?: Maybe<Person>;
|
|
||||||
personId?: Maybe<Scalars['String']['output']>;
|
|
||||||
position: Scalars['Float']['output'];
|
|
||||||
workspaceId?: Maybe<Scalars['String']['output']>;
|
|
||||||
workspaceMember?: Maybe<WorkspaceMember>;
|
|
||||||
workspaceMemberId?: Maybe<Scalars['String']['output']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type FieldConnection = {
|
export type FieldConnection = {
|
||||||
__typename?: 'FieldConnection';
|
__typename?: 'FieldConnection';
|
||||||
/** Array of edges. */
|
/** Array of edges. */
|
||||||
@ -596,81 +283,6 @@ export type PageInfo = {
|
|||||||
startCursor?: Maybe<Scalars['ConnectionCursor']['output']>;
|
startCursor?: Maybe<Scalars['ConnectionCursor']['output']>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Person = {
|
|
||||||
__typename?: 'Person';
|
|
||||||
ActivityTarget?: Maybe<Array<ActivityTarget>>;
|
|
||||||
Attachment?: Maybe<Array<Attachment>>;
|
|
||||||
Favorite?: Maybe<Array<Favorite>>;
|
|
||||||
PipelineProgress?: Maybe<Array<PipelineProgress>>;
|
|
||||||
avatarUrl?: Maybe<Scalars['String']['output']>;
|
|
||||||
city?: Maybe<Scalars['String']['output']>;
|
|
||||||
company?: Maybe<Company>;
|
|
||||||
companyId?: Maybe<Scalars['String']['output']>;
|
|
||||||
contactPipelineProgresses?: Maybe<Array<PipelineProgress>>;
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
email?: Maybe<Scalars['String']['output']>;
|
|
||||||
firstName?: Maybe<Scalars['String']['output']>;
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
jobTitle?: Maybe<Scalars['String']['output']>;
|
|
||||||
lastName?: Maybe<Scalars['String']['output']>;
|
|
||||||
linkedinUrl?: Maybe<Scalars['String']['output']>;
|
|
||||||
phone?: Maybe<Scalars['String']['output']>;
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
xUrl?: Maybe<Scalars['String']['output']>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Pipeline = {
|
|
||||||
__typename?: 'Pipeline';
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
currency: CurrencyCode;
|
|
||||||
icon: Scalars['String']['output'];
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
name: Scalars['String']['output'];
|
|
||||||
pipelineProgressableType: PipelineProgressableType;
|
|
||||||
pipelineProgresses?: Maybe<Array<PipelineProgress>>;
|
|
||||||
pipelineStages?: Maybe<Array<PipelineStage>>;
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type PipelineProgress = {
|
|
||||||
__typename?: 'PipelineProgress';
|
|
||||||
amount?: Maybe<Scalars['Int']['output']>;
|
|
||||||
closeDate?: Maybe<Scalars['DateTime']['output']>;
|
|
||||||
company?: Maybe<Company>;
|
|
||||||
companyId?: Maybe<Scalars['String']['output']>;
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
person?: Maybe<Person>;
|
|
||||||
personId?: Maybe<Scalars['String']['output']>;
|
|
||||||
pipeline: Pipeline;
|
|
||||||
pipelineId: Scalars['String']['output'];
|
|
||||||
pipelineStage: PipelineStage;
|
|
||||||
pipelineStageId: Scalars['String']['output'];
|
|
||||||
pointOfContact?: Maybe<Person>;
|
|
||||||
pointOfContactId?: Maybe<Scalars['String']['output']>;
|
|
||||||
probability?: Maybe<Scalars['Int']['output']>;
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
};
|
|
||||||
|
|
||||||
export enum PipelineProgressableType {
|
|
||||||
Company = 'Company',
|
|
||||||
Person = 'Person'
|
|
||||||
}
|
|
||||||
|
|
||||||
export type PipelineStage = {
|
|
||||||
__typename?: 'PipelineStage';
|
|
||||||
color: Scalars['String']['output'];
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
name: Scalars['String']['output'];
|
|
||||||
pipeline: Pipeline;
|
|
||||||
pipelineId: Scalars['String']['output'];
|
|
||||||
pipelineProgresses?: Maybe<Array<PipelineProgress>>;
|
|
||||||
position?: Maybe<Scalars['Int']['output']>;
|
|
||||||
type: Scalars['String']['output'];
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Query = {
|
export type Query = {
|
||||||
__typename?: 'Query';
|
__typename?: 'Query';
|
||||||
field: Field;
|
field: Field;
|
||||||
@ -713,6 +325,22 @@ export type QueryRelationsArgs = {
|
|||||||
paging?: CursorPaging;
|
paging?: CursorPaging;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type RefreshToken = {
|
||||||
|
__typename?: 'RefreshToken';
|
||||||
|
createdAt: Scalars['DateTime']['output'];
|
||||||
|
expiresAt: Scalars['DateTime']['output'];
|
||||||
|
id: Scalars['ID']['output'];
|
||||||
|
updatedAt: Scalars['DateTime']['output'];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RefreshTokenEdge = {
|
||||||
|
__typename?: 'RefreshTokenEdge';
|
||||||
|
/** Cursor for this node. */
|
||||||
|
cursor: Scalars['ConnectionCursor']['output'];
|
||||||
|
/** The node containing the RefreshToken */
|
||||||
|
node: RefreshToken;
|
||||||
|
};
|
||||||
|
|
||||||
export type RelationConnection = {
|
export type RelationConnection = {
|
||||||
__typename?: 'RelationConnection';
|
__typename?: 'RelationConnection';
|
||||||
/** Array of edges. */
|
/** Array of edges. */
|
||||||
@ -788,86 +416,49 @@ export type UpdateOneObjectInput = {
|
|||||||
|
|
||||||
export type User = {
|
export type User = {
|
||||||
__typename?: 'User';
|
__typename?: 'User';
|
||||||
assignedActivities?: Maybe<Array<Activity>>;
|
avatarUrl: Scalars['String']['output'];
|
||||||
authoredActivities?: Maybe<Array<Activity>>;
|
|
||||||
authoredAttachments?: Maybe<Array<Attachment>>;
|
|
||||||
avatarUrl?: Maybe<Scalars['String']['output']>;
|
|
||||||
canImpersonate: Scalars['Boolean']['output'];
|
canImpersonate: Scalars['Boolean']['output'];
|
||||||
comments?: Maybe<Array<Comment>>;
|
|
||||||
companies?: Maybe<Array<Company>>;
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
createdAt: Scalars['DateTime']['output'];
|
||||||
defaultWorkspaceId?: Maybe<Scalars['String']['output']>;
|
deletedAt?: Maybe<Scalars['DateTime']['output']>;
|
||||||
disabled: Scalars['Boolean']['output'];
|
disabled?: Maybe<Scalars['Boolean']['output']>;
|
||||||
email: Scalars['String']['output'];
|
email: Scalars['String']['output'];
|
||||||
emailVerified: Scalars['Boolean']['output'];
|
emailVerified: Scalars['Boolean']['output'];
|
||||||
firstName?: Maybe<Scalars['String']['output']>;
|
firstName: Scalars['String']['output'];
|
||||||
id: Scalars['ID']['output'];
|
id: Scalars['ID']['output'];
|
||||||
lastName?: Maybe<Scalars['String']['output']>;
|
lastName: Scalars['String']['output'];
|
||||||
lastSeen?: Maybe<Scalars['DateTime']['output']>;
|
lastSeen?: Maybe<Scalars['DateTime']['output']>;
|
||||||
locale: Scalars['String']['output'];
|
locale: Scalars['String']['output'];
|
||||||
metadata?: Maybe<Scalars['JSON']['output']>;
|
passwordHash?: Maybe<Scalars['String']['output']>;
|
||||||
phoneNumber?: Maybe<Scalars['String']['output']>;
|
phoneNumber?: Maybe<Scalars['String']['output']>;
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
updatedAt: Scalars['DateTime']['output'];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UserSettings = {
|
export type UserEdge = {
|
||||||
__typename?: 'UserSettings';
|
__typename?: 'UserEdge';
|
||||||
WorkspaceMember?: Maybe<Array<WorkspaceMember>>;
|
/** Cursor for this node. */
|
||||||
colorScheme: ColorScheme;
|
cursor: Scalars['ConnectionCursor']['output'];
|
||||||
createdAt: Scalars['DateTime']['output'];
|
/** The node containing the User */
|
||||||
id: Scalars['ID']['output'];
|
node: User;
|
||||||
locale: Scalars['String']['output'];
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type WebHook = {
|
|
||||||
__typename?: 'WebHook';
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
operation: Scalars['String']['output'];
|
|
||||||
targetUrl: Scalars['String']['output'];
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Workspace = {
|
export type Workspace = {
|
||||||
__typename?: 'Workspace';
|
__typename?: 'Workspace';
|
||||||
Attachment?: Maybe<Array<Attachment>>;
|
|
||||||
activities?: Maybe<Array<Activity>>;
|
|
||||||
activityTargets?: Maybe<Array<ActivityTarget>>;
|
|
||||||
apiKeys?: Maybe<Array<ApiKey>>;
|
|
||||||
comments?: Maybe<Array<Comment>>;
|
|
||||||
companies?: Maybe<Array<Company>>;
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
createdAt: Scalars['DateTime']['output'];
|
||||||
|
deletedAt?: Maybe<Scalars['DateTime']['output']>;
|
||||||
displayName?: Maybe<Scalars['String']['output']>;
|
displayName?: Maybe<Scalars['String']['output']>;
|
||||||
domainName?: Maybe<Scalars['String']['output']>;
|
domainName?: Maybe<Scalars['String']['output']>;
|
||||||
id: Scalars['ID']['output'];
|
id: Scalars['ID']['output'];
|
||||||
inviteHash?: Maybe<Scalars['String']['output']>;
|
inviteHash?: Maybe<Scalars['String']['output']>;
|
||||||
logo?: Maybe<Scalars['String']['output']>;
|
logo?: Maybe<Scalars['String']['output']>;
|
||||||
people?: Maybe<Array<Person>>;
|
|
||||||
pipelineProgresses?: Maybe<Array<PipelineProgress>>;
|
|
||||||
pipelineStages?: Maybe<Array<PipelineStage>>;
|
|
||||||
pipelines?: Maybe<Array<Pipeline>>;
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
updatedAt: Scalars['DateTime']['output'];
|
||||||
webHooks?: Maybe<Array<WebHook>>;
|
|
||||||
workspaceMember?: Maybe<Array<WorkspaceMember>>;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WorkspaceMember = {
|
export type WorkspaceEdge = {
|
||||||
__typename?: 'WorkspaceMember';
|
__typename?: 'WorkspaceEdge';
|
||||||
Favorite?: Maybe<Array<Favorite>>;
|
/** Cursor for this node. */
|
||||||
allowImpersonation: Scalars['Boolean']['output'];
|
cursor: Scalars['ConnectionCursor']['output'];
|
||||||
assignedActivities?: Maybe<Array<Activity>>;
|
/** The node containing the Workspace */
|
||||||
authoredActivities?: Maybe<Array<Activity>>;
|
node: Workspace;
|
||||||
authoredAttachments?: Maybe<Array<Attachment>>;
|
|
||||||
comments?: Maybe<Array<Comment>>;
|
|
||||||
companies?: Maybe<Array<Company>>;
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
settings?: Maybe<UserSettings>;
|
|
||||||
settingsId?: Maybe<Scalars['String']['output']>;
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
userId: Scalars['String']['output'];
|
|
||||||
workspace: Workspace;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type Field = {
|
export type Field = {
|
||||||
@ -948,22 +539,6 @@ export type ObjectFilter = {
|
|||||||
or?: InputMaybe<Array<ObjectFilter>>;
|
or?: InputMaybe<Array<ObjectFilter>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type RefreshTokenV2 = {
|
|
||||||
__typename?: 'refreshTokenV2';
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
expiresAt: Scalars['DateTime']['output'];
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RefreshTokenV2Edge = {
|
|
||||||
__typename?: 'refreshTokenV2Edge';
|
|
||||||
/** Cursor for this node. */
|
|
||||||
cursor: Scalars['ConnectionCursor']['output'];
|
|
||||||
/** The node containing the refreshTokenV2 */
|
|
||||||
node: RefreshTokenV2;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Relation = {
|
export type Relation = {
|
||||||
__typename?: 'relation';
|
__typename?: 'relation';
|
||||||
createdAt: Scalars['DateTime']['output'];
|
createdAt: Scalars['DateTime']['output'];
|
||||||
@ -986,54 +561,6 @@ export type RelationEdge = {
|
|||||||
node: Relation;
|
node: Relation;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type UserV2 = {
|
|
||||||
__typename?: 'userV2';
|
|
||||||
avatarUrl: Scalars['String']['output'];
|
|
||||||
canImpersonate: Scalars['Boolean']['output'];
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
deletedAt?: Maybe<Scalars['DateTime']['output']>;
|
|
||||||
disabled?: Maybe<Scalars['Boolean']['output']>;
|
|
||||||
email: Scalars['String']['output'];
|
|
||||||
emailVerified: Scalars['Boolean']['output'];
|
|
||||||
firstName: Scalars['String']['output'];
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
lastName: Scalars['String']['output'];
|
|
||||||
lastSeen?: Maybe<Scalars['DateTime']['output']>;
|
|
||||||
locale: Scalars['String']['output'];
|
|
||||||
metadata?: Maybe<Scalars['JSONObject']['output']>;
|
|
||||||
passwordHash?: Maybe<Scalars['String']['output']>;
|
|
||||||
phoneNumber?: Maybe<Scalars['String']['output']>;
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type UserV2Edge = {
|
|
||||||
__typename?: 'userV2Edge';
|
|
||||||
/** Cursor for this node. */
|
|
||||||
cursor: Scalars['ConnectionCursor']['output'];
|
|
||||||
/** The node containing the userV2 */
|
|
||||||
node: UserV2;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type WorkspaceV2 = {
|
|
||||||
__typename?: 'workspaceV2';
|
|
||||||
createdAt: Scalars['DateTime']['output'];
|
|
||||||
deletedAt?: Maybe<Scalars['DateTime']['output']>;
|
|
||||||
displayName?: Maybe<Scalars['String']['output']>;
|
|
||||||
domainName?: Maybe<Scalars['String']['output']>;
|
|
||||||
id: Scalars['ID']['output'];
|
|
||||||
inviteHash?: Maybe<Scalars['String']['output']>;
|
|
||||||
logo?: Maybe<Scalars['String']['output']>;
|
|
||||||
updatedAt: Scalars['DateTime']['output'];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type WorkspaceV2Edge = {
|
|
||||||
__typename?: 'workspaceV2Edge';
|
|
||||||
/** Cursor for this node. */
|
|
||||||
cursor: Scalars['ConnectionCursor']['output'];
|
|
||||||
/** The node containing the workspaceV2 */
|
|
||||||
node: WorkspaceV2;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CreateOneObjectMetadataItemMutationVariables = Exact<{
|
export type CreateOneObjectMetadataItemMutationVariables = Exact<{
|
||||||
input: CreateOneObjectInput;
|
input: CreateOneObjectInput;
|
||||||
}>;
|
}>;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -8,6 +8,7 @@ import { ApolloProvider } from '@/apollo/components/ApolloProvider';
|
|||||||
import { ClientConfigProvider } from '@/client-config/components/ClientConfigProvider';
|
import { ClientConfigProvider } from '@/client-config/components/ClientConfigProvider';
|
||||||
import { RecoilDebugObserverEffect } from '@/debug/components/RecoilDebugObserver';
|
import { RecoilDebugObserverEffect } from '@/debug/components/RecoilDebugObserver';
|
||||||
import { ApolloMetadataClientProvider } from '@/object-metadata/components/ApolloMetadataClientProvider';
|
import { ApolloMetadataClientProvider } from '@/object-metadata/components/ApolloMetadataClientProvider';
|
||||||
|
import { ObjectMetadataItemsProvider } from '@/object-metadata/components/ObjectMetadataItemsProvider';
|
||||||
import { DialogManager } from '@/ui/feedback/dialog-manager/components/DialogManager';
|
import { DialogManager } from '@/ui/feedback/dialog-manager/components/DialogManager';
|
||||||
import { DialogManagerScope } from '@/ui/feedback/dialog-manager/scopes/DialogManagerScope';
|
import { DialogManagerScope } from '@/ui/feedback/dialog-manager/scopes/DialogManagerScope';
|
||||||
import { SnackBarProvider } from '@/ui/feedback/snack-bar/components/SnackBarProvider';
|
import { SnackBarProvider } from '@/ui/feedback/snack-bar/components/SnackBarProvider';
|
||||||
@ -36,18 +37,20 @@ root.render(
|
|||||||
<ClientConfigProvider>
|
<ClientConfigProvider>
|
||||||
<UserProvider>
|
<UserProvider>
|
||||||
<ApolloMetadataClientProvider>
|
<ApolloMetadataClientProvider>
|
||||||
<PageChangeEffect />
|
<ObjectMetadataItemsProvider>
|
||||||
<AppThemeProvider>
|
<PageChangeEffect />
|
||||||
<SnackBarProvider>
|
<AppThemeProvider>
|
||||||
<DialogManagerScope dialogManagerScopeId="dialog-manager">
|
<SnackBarProvider>
|
||||||
<DialogManager>
|
<DialogManagerScope dialogManagerScopeId="dialog-manager">
|
||||||
<StrictMode>
|
<DialogManager>
|
||||||
<App />
|
<StrictMode>
|
||||||
</StrictMode>
|
<App />
|
||||||
</DialogManager>
|
</StrictMode>
|
||||||
</DialogManagerScope>
|
</DialogManager>
|
||||||
</SnackBarProvider>
|
</DialogManagerScope>
|
||||||
</AppThemeProvider>
|
</SnackBarProvider>
|
||||||
|
</AppThemeProvider>
|
||||||
|
</ObjectMetadataItemsProvider>
|
||||||
</ApolloMetadataClientProvider>
|
</ApolloMetadataClientProvider>
|
||||||
</UserProvider>
|
</UserProvider>
|
||||||
</ClientConfigProvider>
|
</ClientConfigProvider>
|
||||||
|
|||||||
@ -1,99 +0,0 @@
|
|||||||
import { Activity } from '@/activities/types/Activity';
|
|
||||||
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
|
|
||||||
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
|
||||||
import { SingleEntitySelect } from '@/ui/input/relation-picker/components/SingleEntitySelect';
|
|
||||||
import { relationPickerSearchFilterScopedState } from '@/ui/input/relation-picker/states/relationPickerSearchFilterScopedState';
|
|
||||||
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
|
|
||||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
|
||||||
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
|
||||||
import {
|
|
||||||
useGetWorkspaceMembersLazyQuery,
|
|
||||||
useSearchUserQuery,
|
|
||||||
} from '~/generated/graphql';
|
|
||||||
|
|
||||||
export type ActivityAssigneePickerProps = {
|
|
||||||
activity: Pick<Activity, 'id'> & {
|
|
||||||
accountOwner?: Pick<WorkspaceMember, 'id' | 'name'> | null;
|
|
||||||
};
|
|
||||||
onSubmit?: () => void;
|
|
||||||
onCancel?: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
type UserForSelect = EntityForSelect & {
|
|
||||||
entityType: Entity.User;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ActivityAssigneePicker = ({
|
|
||||||
activity,
|
|
||||||
onSubmit,
|
|
||||||
onCancel,
|
|
||||||
}: ActivityAssigneePickerProps) => {
|
|
||||||
const [relationPickerSearchFilter] = useRecoilScopedState(
|
|
||||||
relationPickerSearchFilterScopedState,
|
|
||||||
);
|
|
||||||
const { updateOneObject } = useUpdateOneObjectRecord({
|
|
||||||
objectNameSingular: 'ActivityV2',
|
|
||||||
});
|
|
||||||
const [getWorkspaceMember] = useGetWorkspaceMembersLazyQuery();
|
|
||||||
|
|
||||||
const users = useFilteredSearchEntityQuery({
|
|
||||||
queryHook: useSearchUserQuery,
|
|
||||||
filters: [
|
|
||||||
{
|
|
||||||
fieldNames: ['firstName', 'lastName'],
|
|
||||||
filter: relationPickerSearchFilter,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
orderByField: 'firstName',
|
|
||||||
mappingFunction: (user) => ({
|
|
||||||
entityType: Entity.User,
|
|
||||||
id: user.id,
|
|
||||||
name: user.displayName,
|
|
||||||
firstName: user.firstName,
|
|
||||||
lastName: user.lastName,
|
|
||||||
avatarType: 'rounded',
|
|
||||||
avatarUrl: user.avatarUrl ?? '',
|
|
||||||
originalEntity: user,
|
|
||||||
}),
|
|
||||||
selectedIds: activity?.accountOwner?.id ? [activity?.accountOwner?.id] : [],
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleEntitySelected = async (
|
|
||||||
selectedUser: UserForSelect | null | undefined,
|
|
||||||
) => {
|
|
||||||
if (selectedUser) {
|
|
||||||
const workspaceMemberAssignee = (
|
|
||||||
await getWorkspaceMember({
|
|
||||||
variables: {
|
|
||||||
where: {
|
|
||||||
userId: { equals: selectedUser.id },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
).data?.workspaceMembers?.[0];
|
|
||||||
|
|
||||||
updateOneObject?.({
|
|
||||||
idToUpdate: activity.id,
|
|
||||||
input: {
|
|
||||||
assignee: { connect: { id: selectedUser.id } },
|
|
||||||
workspaceMemberAssignee: {
|
|
||||||
connect: { id: workspaceMemberAssignee?.id },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onSubmit?.();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<SingleEntitySelect
|
|
||||||
entitiesToSelect={users.entitiesToSelect}
|
|
||||||
loading={users.loading}
|
|
||||||
onCancel={onCancel}
|
|
||||||
onEntitySelected={handleEntitySelected}
|
|
||||||
selectedEntity={users.selectedEntities[0]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -23,7 +23,7 @@ export const ActivityBodyEditor = ({
|
|||||||
}: ActivityBodyEditorProps) => {
|
}: ActivityBodyEditorProps) => {
|
||||||
const [body, setBody] = useState<string | null>(null);
|
const [body, setBody] = useState<string | null>(null);
|
||||||
const { updateOneObject } = useUpdateOneObjectRecord({
|
const { updateOneObject } = useUpdateOneObjectRecord({
|
||||||
objectNameSingular: 'ActivityV2',
|
objectNameSingular: 'Activity',
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@ -63,7 +63,7 @@ export const ActivityComments = ({
|
|||||||
}: ActivityCommentsProps) => {
|
}: ActivityCommentsProps) => {
|
||||||
const currentUser = useRecoilValue(currentUserState);
|
const currentUser = useRecoilValue(currentUserState);
|
||||||
const { createOneObject } = useCreateOneObjectRecord({
|
const { createOneObject } = useCreateOneObjectRecord({
|
||||||
objectNameSingular: 'commentV2',
|
objectNameSingular: 'comment',
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!currentUser) {
|
if (!currentUser) {
|
||||||
|
|||||||
@ -9,13 +9,10 @@ import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
|||||||
import { Comment } from '@/activities/types/Comment';
|
import { Comment } from '@/activities/types/Comment';
|
||||||
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
|
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
|
||||||
import { PropertyBox } from '@/ui/object/record-inline-cell/property-box/components/PropertyBox';
|
import { PropertyBox } from '@/ui/object/record-inline-cell/property-box/components/PropertyBox';
|
||||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
|
||||||
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
|
||||||
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
||||||
import { debounce } from '~/utils/debounce';
|
import { debounce } from '~/utils/debounce';
|
||||||
|
|
||||||
import { ActivityAssigneeEditableField } from '../editable-fields/components/ActivityAssigneeEditableField';
|
|
||||||
import { ActivityEditorDateField } from '../editable-fields/components/ActivityEditorDateField';
|
|
||||||
import { ActivityRelationEditableField } from '../editable-fields/components/ActivityRelationEditableField';
|
import { ActivityRelationEditableField } from '../editable-fields/components/ActivityRelationEditableField';
|
||||||
|
|
||||||
import { ActivityTitle } from './ActivityTitle';
|
import { ActivityTitle } from './ActivityTitle';
|
||||||
@ -84,7 +81,7 @@ export const ActivityEditor = ({
|
|||||||
);
|
);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
const { updateOneObject } = useUpdateOneObjectRecord<Activity>({
|
const { updateOneObject } = useUpdateOneObjectRecord<Activity>({
|
||||||
objectNameSingular: 'activityV2',
|
objectNameSingular: 'activity',
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateTitle = useCallback(
|
const updateTitle = useCallback(
|
||||||
@ -144,12 +141,12 @@ export const ActivityEditor = ({
|
|||||||
<PropertyBox>
|
<PropertyBox>
|
||||||
{activity.type === 'Task' && (
|
{activity.type === 'Task' && (
|
||||||
<>
|
<>
|
||||||
<RecoilScope>
|
{/* <RecoilScope>
|
||||||
<ActivityEditorDateField activityId={activity.id} />
|
<ActivityEditorDateField activityId={activity.id} />
|
||||||
</RecoilScope>
|
</RecoilScope>
|
||||||
<RecoilScope>
|
<RecoilScope>
|
||||||
<ActivityAssigneeEditableField activity={activity} />
|
<ActivityAssigneeEditableField activity={activity} />
|
||||||
</RecoilScope>
|
</RecoilScope> */}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
<ActivityRelationEditableField activity={activity} />
|
<ActivityRelationEditableField activity={activity} />
|
||||||
|
|||||||
@ -2,8 +2,9 @@ import styled from '@emotion/styled';
|
|||||||
|
|
||||||
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
||||||
import { CompanyChip } from '@/companies/components/CompanyChip';
|
import { CompanyChip } from '@/companies/components/CompanyChip';
|
||||||
|
import { Company } from '@/companies/types/Company';
|
||||||
import { PersonChip } from '@/people/components/PersonChip';
|
import { PersonChip } from '@/people/components/PersonChip';
|
||||||
import { Company, Person } from '~/generated/graphql';
|
import { Person } from '@/people/types/Person';
|
||||||
import { getLogoUrlFromDomainName } from '~/utils';
|
import { getLogoUrlFromDomainName } from '~/utils';
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
@ -17,10 +18,7 @@ export const ActivityTargetChips = ({
|
|||||||
}: {
|
}: {
|
||||||
targets?: Array<
|
targets?: Array<
|
||||||
Pick<ActivityTarget, 'id'> & {
|
Pick<ActivityTarget, 'id'> & {
|
||||||
person?: Pick<
|
person?: Pick<Person, 'id' | 'name' | 'avatarUrl'> | null;
|
||||||
Person,
|
|
||||||
'id' | 'firstName' | 'lastName' | 'avatarUrl'
|
|
||||||
> | null;
|
|
||||||
company?: Pick<Company, 'id' | 'domainName' | 'name'> | null;
|
company?: Pick<Company, 'id' | 'domainName' | 'name'> | null;
|
||||||
}
|
}
|
||||||
> | null;
|
> | null;
|
||||||
@ -47,7 +45,7 @@ export const ActivityTargetChips = ({
|
|||||||
<PersonChip
|
<PersonChip
|
||||||
key={person.id}
|
key={person.id}
|
||||||
id={person.id}
|
id={person.id}
|
||||||
name={person.firstName + ' ' + person.lastName}
|
name={person.name.firstName + ' ' + person.name.lastName}
|
||||||
pictureUrl={person.avatarUrl ?? undefined}
|
pictureUrl={person.avatarUrl ?? undefined}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,78 +0,0 @@
|
|||||||
import React, { useMemo } from 'react';
|
|
||||||
|
|
||||||
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
|
|
||||||
import { IconUserCircle } from '@/ui/display/icon';
|
|
||||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
|
||||||
import { FieldContext } from '@/ui/object/field/contexts/FieldContext';
|
|
||||||
import { FieldDefinition } from '@/ui/object/field/types/FieldDefinition';
|
|
||||||
import { FieldRelationMetadata } from '@/ui/object/field/types/FieldMetadata';
|
|
||||||
import { RecordInlineCell } from '@/ui/object/record-inline-cell/components/RecordInlineCell';
|
|
||||||
import { InlineCellHotkeyScope } from '@/ui/object/record-inline-cell/types/InlineCellHotkeyScope';
|
|
||||||
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
|
||||||
import { Company, User } from '~/generated/graphql';
|
|
||||||
|
|
||||||
type ActivityAssigneeEditableFieldProps = {
|
|
||||||
activity: Pick<Company, 'id' | 'accountOwnerId'> & {
|
|
||||||
assignee?: Pick<WorkspaceMember, 'id' | 'name' | 'avatarUrl'> | null;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ActivityAssigneeEditableField = ({
|
|
||||||
activity,
|
|
||||||
}: ActivityAssigneeEditableFieldProps) => {
|
|
||||||
const useUpdateOneObjectMutation: () => [(params: any) => any, any] = () => {
|
|
||||||
const { updateOneObject } = useUpdateOneObjectRecord({
|
|
||||||
objectNameSingular: 'activityV2',
|
|
||||||
});
|
|
||||||
|
|
||||||
const updateEntity = ({
|
|
||||||
variables,
|
|
||||||
}: {
|
|
||||||
variables: {
|
|
||||||
where: { id: string };
|
|
||||||
data: {
|
|
||||||
[fieldName: string]: any;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}) => {
|
|
||||||
updateOneObject?.({
|
|
||||||
idToUpdate: variables.where.id,
|
|
||||||
input: variables.data,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return [updateEntity, { loading: false }];
|
|
||||||
};
|
|
||||||
const value = useMemo(
|
|
||||||
() => ({
|
|
||||||
entityId: activity.id,
|
|
||||||
recoilScopeId: 'assignee',
|
|
||||||
fieldDefinition: {
|
|
||||||
fieldMetadataId: 'assignee',
|
|
||||||
label: 'Assignee',
|
|
||||||
Icon: IconUserCircle,
|
|
||||||
type: 'RELATION',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'assignee',
|
|
||||||
relationType: Entity.User,
|
|
||||||
},
|
|
||||||
entityChipDisplayMapper: (dataObject: User) => {
|
|
||||||
return {
|
|
||||||
name: dataObject?.displayName,
|
|
||||||
pictureUrl: dataObject?.avatarUrl ?? undefined,
|
|
||||||
avatarType: 'rounded',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
} satisfies FieldDefinition<FieldRelationMetadata>,
|
|
||||||
useUpdateEntityMutation: useUpdateOneObjectMutation,
|
|
||||||
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
|
||||||
}),
|
|
||||||
[activity.id],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FieldContext.Provider value={value}>
|
|
||||||
<RecordInlineCell />
|
|
||||||
</FieldContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,47 +0,0 @@
|
|||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
import { ActivityAssigneePicker } from '@/activities/components/ActivityAssigneePicker';
|
|
||||||
import { useInlineCell } from '@/ui/object/record-inline-cell/hooks/useInlineCell';
|
|
||||||
import { Activity, User } from '~/generated/graphql';
|
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
|
||||||
left: 0px;
|
|
||||||
position: absolute;
|
|
||||||
top: -8px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export type ActivityAssigneeEditableFieldEditModeProps = {
|
|
||||||
activity: Pick<Activity, 'id'> & {
|
|
||||||
assignee?: Pick<User, 'id' | 'displayName'> | null;
|
|
||||||
};
|
|
||||||
onSubmit?: () => void;
|
|
||||||
onCancel?: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ActivityAssigneeEditableFieldEditMode = ({
|
|
||||||
activity,
|
|
||||||
onSubmit,
|
|
||||||
onCancel,
|
|
||||||
}: ActivityAssigneeEditableFieldEditModeProps) => {
|
|
||||||
const { closeInlineCell: closeEditableField } = useInlineCell();
|
|
||||||
|
|
||||||
const handleSubmit = () => {
|
|
||||||
closeEditableField();
|
|
||||||
onSubmit?.();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
|
||||||
closeEditableField();
|
|
||||||
onCancel?.();
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<StyledContainer>
|
|
||||||
<ActivityAssigneePicker
|
|
||||||
activity={activity}
|
|
||||||
onCancel={handleCancel}
|
|
||||||
onSubmit={handleSubmit}
|
|
||||||
/>
|
|
||||||
</StyledContainer>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
|
|
||||||
import { IconCalendar } from '@/ui/display/icon/index';
|
|
||||||
import { FieldContext } from '@/ui/object/field/contexts/FieldContext';
|
|
||||||
import { FieldDefinition } from '@/ui/object/field/types/FieldDefinition';
|
|
||||||
import { FieldDateMetadata } from '@/ui/object/field/types/FieldMetadata';
|
|
||||||
import { RecordInlineCell } from '@/ui/object/record-inline-cell/components/RecordInlineCell';
|
|
||||||
import { InlineCellHotkeyScope } from '@/ui/object/record-inline-cell/types/InlineCellHotkeyScope';
|
|
||||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
|
||||||
|
|
||||||
type ActivityEditorDateFieldProps = {
|
|
||||||
activityId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const ActivityEditorDateField = ({
|
|
||||||
activityId,
|
|
||||||
}: ActivityEditorDateFieldProps) => {
|
|
||||||
const useUpdateOneObjectMutation: () => [(params: any) => any, any] = () => {
|
|
||||||
const { updateOneObject } = useUpdateOneObjectRecord({
|
|
||||||
objectNameSingular: 'activityV2',
|
|
||||||
});
|
|
||||||
|
|
||||||
const updateEntity = ({
|
|
||||||
variables,
|
|
||||||
}: {
|
|
||||||
variables: {
|
|
||||||
where: { id: string };
|
|
||||||
data: {
|
|
||||||
[fieldName: string]: any;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}) => {
|
|
||||||
updateOneObject?.({
|
|
||||||
idToUpdate: variables.where.id,
|
|
||||||
input: variables.data,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return [updateEntity, { loading: false }];
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<RecoilScope>
|
|
||||||
<FieldContext.Provider
|
|
||||||
value={{
|
|
||||||
entityId: activityId,
|
|
||||||
recoilScopeId: 'activityDueAt',
|
|
||||||
fieldDefinition: {
|
|
||||||
fieldMetadataId: 'activityDueAt',
|
|
||||||
label: 'Due date',
|
|
||||||
Icon: IconCalendar,
|
|
||||||
type: 'DATE',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'dueAt',
|
|
||||||
},
|
|
||||||
} satisfies FieldDefinition<FieldDateMetadata>,
|
|
||||||
useUpdateEntityMutation: useUpdateOneObjectMutation,
|
|
||||||
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<RecordInlineCell />
|
|
||||||
</FieldContext.Provider>
|
|
||||||
</RecoilScope>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,12 +1,13 @@
|
|||||||
import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips';
|
import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips';
|
||||||
import { Activity } from '@/activities/types/Activity';
|
import { Activity } from '@/activities/types/Activity';
|
||||||
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
import { ActivityTarget } from '@/activities/types/ActivityTarget';
|
||||||
|
import { Company } from '@/companies/types/Company';
|
||||||
|
import { Person } from '@/people/types/Person';
|
||||||
import { IconArrowUpRight, IconPencil } from '@/ui/display/icon';
|
import { IconArrowUpRight, IconPencil } from '@/ui/display/icon';
|
||||||
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
import { RecordInlineCellContainer } from '@/ui/object/record-inline-cell/components/RecordInlineCellContainer';
|
import { RecordInlineCellContainer } from '@/ui/object/record-inline-cell/components/RecordInlineCellContainer';
|
||||||
import { FieldRecoilScopeContext } from '@/ui/object/record-inline-cell/states/recoil-scope-contexts/FieldRecoilScopeContext';
|
import { FieldRecoilScopeContext } from '@/ui/object/record-inline-cell/states/recoil-scope-contexts/FieldRecoilScopeContext';
|
||||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||||
import { Company, Person } from '~/generated/graphql';
|
|
||||||
|
|
||||||
import { ActivityRelationEditableFieldEditMode } from './ActivityRelationEditableFieldEditMode';
|
import { ActivityRelationEditableFieldEditMode } from './ActivityRelationEditableFieldEditMode';
|
||||||
|
|
||||||
@ -14,7 +15,7 @@ type ActivityRelationEditableFieldProps = {
|
|||||||
activity?: Pick<Activity, 'id'> & {
|
activity?: Pick<Activity, 'id'> & {
|
||||||
activityTargets?: Array<
|
activityTargets?: Array<
|
||||||
Pick<ActivityTarget, 'id' | 'personId' | 'companyId'> & {
|
Pick<ActivityTarget, 'id' | 'personId' | 'companyId'> & {
|
||||||
person?: Pick<Person, 'id' | 'firstName' | 'lastName'> | null;
|
person?: Pick<Person, 'id' | 'name' | 'avatarUrl'> | null;
|
||||||
company?: Pick<Company, 'id' | 'domainName' | 'name'> | null;
|
company?: Pick<Company, 'id' | 'domainName' | 'name'> | null;
|
||||||
}
|
}
|
||||||
> | null;
|
> | null;
|
||||||
|
|||||||
@ -92,14 +92,9 @@ export const ActivityRelationEditableFieldEditMode = ({
|
|||||||
const { closeInlineCell: closeEditableField } = useInlineCell();
|
const { closeInlineCell: closeEditableField } = useInlineCell();
|
||||||
|
|
||||||
const handleSubmit = useCallback(() => {
|
const handleSubmit = useCallback(() => {
|
||||||
handleCheckItemsChange(selectedEntityIds, entitiesToSelect);
|
//handleCheckItemsChange(selectedEntityIds, entitiesToSelect);
|
||||||
closeEditableField();
|
closeEditableField();
|
||||||
}, [
|
}, [closeEditableField]);
|
||||||
handleCheckItemsChange,
|
|
||||||
selectedEntityIds,
|
|
||||||
entitiesToSelect,
|
|
||||||
closeEditableField,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const handleCancel = () => {
|
const handleCancel = () => {
|
||||||
closeEditableField();
|
closeEditableField();
|
||||||
|
|||||||
@ -17,10 +17,10 @@ export const useHandleCheckableActivityTargetChange = ({
|
|||||||
};
|
};
|
||||||
}) => {
|
}) => {
|
||||||
const { createOneObject } = useCreateOneObjectRecord<ActivityTarget>({
|
const { createOneObject } = useCreateOneObjectRecord<ActivityTarget>({
|
||||||
objectNameSingular: 'activityTargetV2',
|
objectNameSingular: 'activityTarget',
|
||||||
});
|
});
|
||||||
const { deleteOneObject } = useDeleteOneObjectRecord({
|
const { deleteOneObject } = useDeleteOneObjectRecord({
|
||||||
objectNameSingular: 'activityTargetV2',
|
objectNameSingular: 'activityTarget',
|
||||||
});
|
});
|
||||||
|
|
||||||
return async (
|
return async (
|
||||||
|
|||||||
@ -18,11 +18,11 @@ export const useOpenCreateActivityDrawer = () => {
|
|||||||
const { openRightDrawer } = useRightDrawer();
|
const { openRightDrawer } = useRightDrawer();
|
||||||
const { createOneObject: createOneActivityTarget } =
|
const { createOneObject: createOneActivityTarget } =
|
||||||
useCreateOneObjectRecord<ActivityTarget>({
|
useCreateOneObjectRecord<ActivityTarget>({
|
||||||
objectNameSingular: 'activityTargetV2',
|
objectNameSingular: 'activityTarget',
|
||||||
});
|
});
|
||||||
const { createOneObject: createOneActivity } =
|
const { createOneObject: createOneActivity } =
|
||||||
useCreateOneObjectRecord<Activity>({
|
useCreateOneObjectRecord<Activity>({
|
||||||
objectNameSingular: 'activityV2',
|
objectNameSingular: 'activity',
|
||||||
});
|
});
|
||||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||||
const setHotkeyScope = useSetHotkeyScope();
|
const setHotkeyScope = useSetHotkeyScope();
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import { useNotes } from '@/activities/notes/hooks/useNotes';
|
|||||||
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { IconPlus } from '@/ui/display/icon';
|
import { IconPlus } from '@/ui/display/icon';
|
||||||
import { Button } from '@/ui/input/button/components/Button';
|
import { Button } from '@/ui/input/button/components/Button';
|
||||||
import { ActivityType } from '~/generated/graphql';
|
|
||||||
|
|
||||||
const StyledTaskGroupEmptyContainer = styled.div`
|
const StyledTaskGroupEmptyContainer = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -61,7 +60,7 @@ export const Notes = ({ entity }: { entity: ActivityTargetableEntity }) => {
|
|||||||
variant="secondary"
|
variant="secondary"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
openCreateActivity({
|
openCreateActivity({
|
||||||
type: ActivityType.Note,
|
type: 'Note',
|
||||||
targetableEntities: [entity],
|
targetableEntities: [entity],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -83,7 +82,7 @@ export const Notes = ({ entity }: { entity: ActivityTargetableEntity }) => {
|
|||||||
title="Add note"
|
title="Add note"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
openCreateActivity({
|
openCreateActivity({
|
||||||
type: ActivityType.Note,
|
type: 'Note',
|
||||||
targetableEntities: [entity],
|
targetableEntities: [entity],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { ActivityTargetableEntity } from '../../types/ActivityTargetableEntity';
|
|||||||
|
|
||||||
export const useNotes = (entity: ActivityTargetableEntity) => {
|
export const useNotes = (entity: ActivityTargetableEntity) => {
|
||||||
const { objects: notes } = useFindManyObjectRecords({
|
const { objects: notes } = useFindManyObjectRecords({
|
||||||
objectNamePlural: 'activitiesV2',
|
objectNamePlural: 'activities',
|
||||||
filter: {
|
filter: {
|
||||||
type: { equals: 'None' },
|
type: { equals: 'None' },
|
||||||
activityTargets: {
|
activityTargets: {
|
||||||
|
|||||||
@ -12,7 +12,7 @@ type ActivityActionBarProps = {
|
|||||||
export const ActivityActionBar = ({ activityId }: ActivityActionBarProps) => {
|
export const ActivityActionBar = ({ activityId }: ActivityActionBarProps) => {
|
||||||
const [, setIsRightDrawerOpen] = useRecoilState(isRightDrawerOpenState);
|
const [, setIsRightDrawerOpen] = useRecoilState(isRightDrawerOpenState);
|
||||||
const { deleteOneObject } = useDeleteOneObjectRecord({
|
const { deleteOneObject } = useDeleteOneObjectRecord({
|
||||||
objectNameSingular: 'activityV2',
|
objectNameSingular: 'activity',
|
||||||
});
|
});
|
||||||
|
|
||||||
const deleteActivity = () => {
|
const deleteActivity = () => {
|
||||||
|
|||||||
@ -2,7 +2,6 @@ import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateAct
|
|||||||
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { IconPlus } from '@/ui/display/icon';
|
import { IconPlus } from '@/ui/display/icon';
|
||||||
import { Button } from '@/ui/input/button/components/Button';
|
import { Button } from '@/ui/input/button/components/Button';
|
||||||
import { ActivityType } from '~/generated/graphql';
|
|
||||||
|
|
||||||
export const AddTaskButton = ({
|
export const AddTaskButton = ({
|
||||||
activityTargetEntity,
|
activityTargetEntity,
|
||||||
@ -23,7 +22,7 @@ export const AddTaskButton = ({
|
|||||||
title="Add task"
|
title="Add task"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
openCreateActivity({
|
openCreateActivity({
|
||||||
type: ActivityType.Task,
|
type: 'Task',
|
||||||
targetableEntities: [activityTargetEntity],
|
targetableEntities: [activityTargetEntity],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
|
||||||
import { PageAddButton } from '@/ui/layout/page/PageAddButton';
|
import { PageAddButton } from '@/ui/layout/page/PageAddButton';
|
||||||
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
|
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
|
||||||
import { ActivityType } from '~/generated/graphql';
|
|
||||||
|
|
||||||
export const PageAddTaskButton = () => {
|
export const PageAddTaskButton = () => {
|
||||||
const { selectedFilter } = useFilter();
|
const { selectedFilter } = useFilter();
|
||||||
@ -9,7 +8,7 @@ export const PageAddTaskButton = () => {
|
|||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
openCreateActivity({
|
openCreateActivity({
|
||||||
type: ActivityType.Task,
|
type: 'Task',
|
||||||
assigneeId: selectedFilter?.value,
|
assigneeId: selectedFilter?.value,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -8,7 +8,6 @@ import { IconPlus } from '@/ui/display/icon';
|
|||||||
import { Button } from '@/ui/input/button/components/Button';
|
import { Button } from '@/ui/input/button/components/Button';
|
||||||
import { activeTabIdScopedState } from '@/ui/layout/tab/states/activeTabIdScopedState';
|
import { activeTabIdScopedState } from '@/ui/layout/tab/states/activeTabIdScopedState';
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { ActivityType } from '~/generated/graphql';
|
|
||||||
|
|
||||||
import { AddTaskButton } from './AddTaskButton';
|
import { AddTaskButton } from './AddTaskButton';
|
||||||
import { TaskList } from './TaskList';
|
import { TaskList } from './TaskList';
|
||||||
@ -84,7 +83,7 @@ export const TaskGroups = ({ entity, showAddButton }: TaskGroupsProps) => {
|
|||||||
variant={'secondary'}
|
variant={'secondary'}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
openCreateActivity({
|
openCreateActivity({
|
||||||
type: ActivityType.Task,
|
type: 'Task',
|
||||||
targetableEntities: entity ? [entity] : undefined,
|
targetableEntities: entity ? [entity] : undefined,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { Activity } from '@/activities/types/Activity';
|
||||||
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
|
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
|
||||||
import { Activity } from '~/generated/graphql';
|
|
||||||
|
|
||||||
type Task = Pick<Activity, 'id' | 'completedAt'>;
|
type Task = Pick<Activity, 'id' | 'completedAt'>;
|
||||||
|
|
||||||
export const useCompleteTask = (task: Task) => {
|
export const useCompleteTask = (task: Task) => {
|
||||||
const { updateOneObject } = useUpdateOneObjectRecord({
|
const { updateOneObject } = useUpdateOneObjectRecord({
|
||||||
objectNameSingular: 'activityV2',
|
objectNameSingular: 'activity',
|
||||||
});
|
});
|
||||||
|
|
||||||
const completeTask = useCallback(
|
const completeTask = useCallback(
|
||||||
|
|||||||
@ -9,7 +9,7 @@ export const useCurrentUserTaskCount = () => {
|
|||||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||||
|
|
||||||
const { objects } = useFindManyObjectRecords({
|
const { objects } = useFindManyObjectRecords({
|
||||||
objectNamePlural: 'activitiesV2',
|
objectNamePlural: 'activities',
|
||||||
filter: {
|
filter: {
|
||||||
type: { eq: 'Task' },
|
type: { eq: 'Task' },
|
||||||
completedAt: { eq: null },
|
completedAt: { eq: null },
|
||||||
|
|||||||
@ -4,8 +4,7 @@ import { Activity } from '@/activities/types/Activity';
|
|||||||
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
|
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
|
||||||
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
||||||
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
|
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
|
||||||
import { turnFilterIntoWhereClause } from '@/ui/object/object-filter-dropdown/utils/turnFilterIntoWhereClause';
|
import { turnFiltersIntoWhereClauseV2 } from '@/ui/object/object-filter-dropdown/utils/turnFiltersIntoWhereClauseV2';
|
||||||
import { SortOrder } from '~/generated/graphql';
|
|
||||||
import { parseDate } from '~/utils/date-utils';
|
import { parseDate } from '~/utils/date-utils';
|
||||||
|
|
||||||
export const useTasks = (entity?: ActivityTargetableEntity) => {
|
export const useTasks = (entity?: ActivityTargetableEntity) => {
|
||||||
@ -22,10 +21,10 @@ export const useTasks = (entity?: ActivityTargetableEntity) => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: Object.assign({}, turnFilterIntoWhereClause(selectedFilter));
|
: Object.assign({}, turnFiltersIntoWhereClauseV2([], []));
|
||||||
|
|
||||||
const { objects: completeTasksData } = useFindManyObjectRecords({
|
const { objects: completeTasksData } = useFindManyObjectRecords({
|
||||||
objectNamePlural: 'activitiesV2',
|
objectNamePlural: 'activities',
|
||||||
skip: !entity && !selectedFilter,
|
skip: !entity && !selectedFilter,
|
||||||
filter: {
|
filter: {
|
||||||
type: { equals: 'Task' },
|
type: { equals: 'Task' },
|
||||||
@ -34,13 +33,13 @@ export const useTasks = (entity?: ActivityTargetableEntity) => {
|
|||||||
},
|
},
|
||||||
orderBy: [
|
orderBy: [
|
||||||
{
|
{
|
||||||
createdAt: SortOrder.Desc,
|
createdAt: 'AscNullIsFirst',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const { objects: incompleteTaskData } = useFindManyObjectRecords({
|
const { objects: incompleteTaskData } = useFindManyObjectRecords({
|
||||||
objectNamePlural: 'activitiesV2',
|
objectNamePlural: 'activities',
|
||||||
skip: !entity && !selectedFilter,
|
skip: !entity && !selectedFilter,
|
||||||
filter: {
|
filter: {
|
||||||
type: { equals: 'Task' },
|
type: { equals: 'Task' },
|
||||||
@ -49,7 +48,7 @@ export const useTasks = (entity?: ActivityTargetableEntity) => {
|
|||||||
},
|
},
|
||||||
orderBy: [
|
orderBy: [
|
||||||
{
|
{
|
||||||
createdAt: SortOrder.Desc,
|
createdAt: 'DescNullIsFirst',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|||||||
@ -49,7 +49,7 @@ const StyledEmptyTimelineSubTitle = styled.div`
|
|||||||
|
|
||||||
export const Timeline = ({ entity }: { entity: ActivityTargetableEntity }) => {
|
export const Timeline = ({ entity }: { entity: ActivityTargetableEntity }) => {
|
||||||
const { objects: activityTargets, loading } = useFindManyObjectRecords({
|
const { objects: activityTargets, loading } = useFindManyObjectRecords({
|
||||||
objectNamePlural: 'activityTargetsV2',
|
objectNamePlural: 'activityTargets',
|
||||||
filter: {
|
filter: {
|
||||||
or: {
|
or: {
|
||||||
companyId: { eq: entity.id },
|
companyId: { eq: entity.id },
|
||||||
@ -60,7 +60,7 @@ export const Timeline = ({ entity }: { entity: ActivityTargetableEntity }) => {
|
|||||||
|
|
||||||
const { objects: activities } = useFindManyObjectRecords({
|
const { objects: activities } = useFindManyObjectRecords({
|
||||||
skip: !activityTargets?.length,
|
skip: !activityTargets?.length,
|
||||||
objectNamePlural: 'activitiesV2',
|
objectNamePlural: 'activities',
|
||||||
filter: {
|
filter: {
|
||||||
activityTargets: { in: activityTargets?.map((at) => at.id) },
|
activityTargets: { in: activityTargets?.map((at) => at.id) },
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { Activity } from '@/activities/types/Activity';
|
import { Activity } from '@/activities/types/Activity';
|
||||||
import { Company, Person } from '~/generated-metadata/graphql';
|
import { Company } from '@/companies/types/Company';
|
||||||
|
import { Person } from '@/people/types/Person';
|
||||||
|
|
||||||
export type ActivityTarget = {
|
export type ActivityTarget = {
|
||||||
id: string;
|
id: string;
|
||||||
@ -8,7 +9,7 @@ export type ActivityTarget = {
|
|||||||
companyId: string | null;
|
companyId: string | null;
|
||||||
personId: string | null;
|
personId: string | null;
|
||||||
activity: Pick<Activity, 'id' | 'createdAt' | 'updatedAt'>;
|
activity: Pick<Activity, 'id' | 'createdAt' | 'updatedAt'>;
|
||||||
person?: Pick<Person, 'id' | 'firstName' | 'lastName' | 'avatarUrl'> | null;
|
person?: Pick<Person, 'id' | 'name' | 'avatarUrl'> | null;
|
||||||
company?: Pick<Company, 'id' | 'name' | 'domainName'> | null;
|
company?: Pick<Company, 'id' | 'name' | 'domainName'> | null;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import { tokenPairState } from '@/auth/states/tokenPairState';
|
|||||||
import { isDebugModeState } from '@/client-config/states/isDebugModeState';
|
import { isDebugModeState } from '@/client-config/states/isDebugModeState';
|
||||||
import { AppPath } from '@/types/AppPath';
|
import { AppPath } from '@/types/AppPath';
|
||||||
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
import { REACT_APP_SERVER_BASE_URL } from '~/config';
|
||||||
import { ActivityTarget } from '~/generated/graphql';
|
|
||||||
import { useIsMatchingLocation } from '~/hooks/useIsMatchingLocation';
|
import { useIsMatchingLocation } from '~/hooks/useIsMatchingLocation';
|
||||||
import { useUpdateEffect } from '~/hooks/useUpdateEffect';
|
import { useUpdateEffect } from '~/hooks/useUpdateEffect';
|
||||||
|
|
||||||
@ -25,23 +24,7 @@ export const useApolloFactory = () => {
|
|||||||
const apolloClient = useMemo(() => {
|
const apolloClient = useMemo(() => {
|
||||||
apolloRef.current = new ApolloFactory({
|
apolloRef.current = new ApolloFactory({
|
||||||
uri: `${REACT_APP_SERVER_BASE_URL}/graphql`,
|
uri: `${REACT_APP_SERVER_BASE_URL}/graphql`,
|
||||||
cache: new InMemoryCache({
|
cache: new InMemoryCache(),
|
||||||
typePolicies: {
|
|
||||||
Activity: {
|
|
||||||
fields: {
|
|
||||||
activityTargets: {
|
|
||||||
merge: (
|
|
||||||
_existing: ActivityTarget[] = [],
|
|
||||||
incoming: ActivityTarget[],
|
|
||||||
) => {
|
|
||||||
return [...incoming];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ViewField: { keyFields: ['viewId', 'key'] },
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
defaultOptions: {
|
defaultOptions: {
|
||||||
query: {
|
query: {
|
||||||
fetchPolicy: 'cache-first',
|
fetchPolicy: 'cache-first',
|
||||||
|
|||||||
@ -7,19 +7,11 @@ import {
|
|||||||
import { isNonEmptyArray } from '@sniptt/guards';
|
import { isNonEmptyArray } from '@sniptt/guards';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
import { GET_COMPANIES } from '@/companies/graphql/queries/getCompanies';
|
|
||||||
import {
|
import {
|
||||||
EMPTY_QUERY,
|
EMPTY_QUERY,
|
||||||
useFindOneObjectMetadataItem,
|
useFindOneObjectMetadataItem,
|
||||||
} from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
} from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { GET_PEOPLE } from '@/people/graphql/queries/getPeople';
|
|
||||||
import { GET_API_KEYS } from '@/settings/developers/graphql/queries/getApiKeys';
|
|
||||||
import {
|
|
||||||
GetApiKeysQuery,
|
|
||||||
GetCompaniesQuery,
|
|
||||||
GetPeopleQuery,
|
|
||||||
} from '~/generated/graphql';
|
|
||||||
|
|
||||||
import { optimisticEffectState } from '../states/optimisticEffectState';
|
import { optimisticEffectState } from '../states/optimisticEffectState';
|
||||||
import { OptimisticEffect } from '../types/internal/OptimisticEffect';
|
import { OptimisticEffect } from '../types/internal/OptimisticEffect';
|
||||||
@ -59,7 +51,6 @@ export const useOptimisticEffect = ({
|
|||||||
newData,
|
newData,
|
||||||
query,
|
query,
|
||||||
variables,
|
variables,
|
||||||
isUsingFlexibleBackend,
|
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
}: {
|
}: {
|
||||||
cache: ApolloCache<unknown>;
|
cache: ApolloCache<unknown>;
|
||||||
@ -69,7 +60,7 @@ export const useOptimisticEffect = ({
|
|||||||
isUsingFlexibleBackend?: boolean;
|
isUsingFlexibleBackend?: boolean;
|
||||||
objectMetadataItem?: ObjectMetadataItem;
|
objectMetadataItem?: ObjectMetadataItem;
|
||||||
}) => {
|
}) => {
|
||||||
if (isUsingFlexibleBackend && objectMetadataItem) {
|
if (objectMetadataItem) {
|
||||||
const existingData = cache.readQuery({
|
const existingData = cache.readQuery({
|
||||||
query: findManyQuery,
|
query: findManyQuery,
|
||||||
variables,
|
variables,
|
||||||
@ -104,50 +95,6 @@ export const useOptimisticEffect = ({
|
|||||||
if (!existingData) {
|
if (!existingData) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query === GET_PEOPLE) {
|
|
||||||
cache.writeQuery({
|
|
||||||
query,
|
|
||||||
variables,
|
|
||||||
data: {
|
|
||||||
people: definition.resolver({
|
|
||||||
currentData: (existingData as GetPeopleQuery).people as T[],
|
|
||||||
newData: newData as T[],
|
|
||||||
variables,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query === GET_COMPANIES) {
|
|
||||||
cache.writeQuery({
|
|
||||||
query,
|
|
||||||
variables,
|
|
||||||
data: {
|
|
||||||
companies: definition.resolver({
|
|
||||||
currentData: (existingData as GetCompaniesQuery)
|
|
||||||
.companies as T[],
|
|
||||||
newData: newData as T[],
|
|
||||||
variables,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query === GET_API_KEYS) {
|
|
||||||
cache.writeQuery({
|
|
||||||
query,
|
|
||||||
variables,
|
|
||||||
data: {
|
|
||||||
findManyApiKey: definition.resolver({
|
|
||||||
currentData: (existingData as GetApiKeysQuery)
|
|
||||||
.findManyApiKey as T[],
|
|
||||||
newData: newData as T[],
|
|
||||||
variables,
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const optimisticEffect = {
|
const optimisticEffect = {
|
||||||
|
|||||||
6
front/src/modules/attachments/types/Attachment.ts
Normal file
6
front/src/modules/attachments/types/Attachment.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export type Attachment = {
|
||||||
|
id: string;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
deletedAt: Date | null;
|
||||||
|
};
|
||||||
@ -1,13 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const USER_QUERY_FRAGMENT = gql`
|
|
||||||
fragment UserQueryFragment on User {
|
|
||||||
id
|
|
||||||
email
|
|
||||||
displayName
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
canImpersonate
|
|
||||||
supportUserHash
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
|
export const GENERATE_ONE_API_KEY_TOKEN = gql`
|
||||||
|
mutation GenerateApiKeyToken($apiKeyId: String!, $expiresAt: String!) {
|
||||||
|
generateApiKeyToken(apiKeyId: $apiKeyId, expiresAt: $expiresAt) {
|
||||||
|
token
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
@ -10,13 +10,11 @@ import {
|
|||||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||||
import { isVerifyPendingState } from '@/auth/states/isVerifyPendingState';
|
import { isVerifyPendingState } from '@/auth/states/isVerifyPendingState';
|
||||||
import { CREATE_ONE_WORKSPACE_MEMBER_V2 } from '@/object-record/graphql/mutation/createOneWorkspaceMember';
|
import { ColorScheme } from '@/workspace-member/types/WorkspaceMember';
|
||||||
import { FIND_ONE_WORKSPACE_MEMBER_V2 } from '@/object-record/graphql/queries/findOneWorkspaceMember';
|
|
||||||
import { REACT_APP_SERVER_AUTH_URL } from '~/config';
|
import { REACT_APP_SERVER_AUTH_URL } from '~/config';
|
||||||
import {
|
import {
|
||||||
useChallengeMutation,
|
useChallengeMutation,
|
||||||
useCheckUserExistsLazyQuery,
|
useCheckUserExistsLazyQuery,
|
||||||
useGetCurrentWorkspaceLazyQuery,
|
|
||||||
useSignUpMutation,
|
useSignUpMutation,
|
||||||
useVerifyMutation,
|
useVerifyMutation,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
@ -38,7 +36,6 @@ export const useAuth = () => {
|
|||||||
const [verify] = useVerifyMutation();
|
const [verify] = useVerifyMutation();
|
||||||
const [checkUserExistsQuery, { data: checkUserExistsData }] =
|
const [checkUserExistsQuery, { data: checkUserExistsData }] =
|
||||||
useCheckUserExistsLazyQuery();
|
useCheckUserExistsLazyQuery();
|
||||||
const [getCurrentWorkspaceQuery] = useGetCurrentWorkspaceLazyQuery();
|
|
||||||
|
|
||||||
const client = useApolloClient();
|
const client = useApolloClient();
|
||||||
|
|
||||||
@ -81,31 +78,26 @@ export const useAuth = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setTokenPair(verifyResult.data?.verify.tokens);
|
setTokenPair(verifyResult.data?.verify.tokens);
|
||||||
const workspaceMember = await client.query({
|
|
||||||
query: FIND_ONE_WORKSPACE_MEMBER_V2,
|
|
||||||
variables: {
|
|
||||||
filter: {
|
|
||||||
userId: { eq: verifyResult.data?.verify.user.id },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const currentWorkspace = await getCurrentWorkspaceQuery();
|
|
||||||
|
|
||||||
setCurrentUser(verifyResult.data?.verify.user);
|
const user = verifyResult.data?.verify.user;
|
||||||
setCurrentWorkspaceMember(workspaceMember.data?.findMany);
|
const workspaceMember = {
|
||||||
setCurrentWorkspace(currentWorkspace.data?.currentWorkspace ?? null);
|
...user.workspaceMember,
|
||||||
|
colorScheme: user.workspaceMember?.colorScheme as ColorScheme,
|
||||||
|
};
|
||||||
|
const workspace = user.defaultWorkspace ?? null;
|
||||||
|
setCurrentUser(user);
|
||||||
|
setCurrentWorkspaceMember(workspaceMember);
|
||||||
|
setCurrentWorkspace(workspace);
|
||||||
return {
|
return {
|
||||||
user: verifyResult.data?.verify.user,
|
user,
|
||||||
workspaceMember: workspaceMember.data?.findMany,
|
workspaceMember,
|
||||||
workspace: currentWorkspace.data?.currentWorkspace,
|
workspace,
|
||||||
tokens: verifyResult.data?.verify.tokens,
|
tokens: verifyResult.data?.verify.tokens,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
verify,
|
verify,
|
||||||
setTokenPair,
|
setTokenPair,
|
||||||
client,
|
|
||||||
getCurrentWorkspaceQuery,
|
|
||||||
setCurrentUser,
|
setCurrentUser,
|
||||||
setCurrentWorkspaceMember,
|
setCurrentWorkspaceMember,
|
||||||
setCurrentWorkspace,
|
setCurrentWorkspace,
|
||||||
@ -161,38 +153,15 @@ export const useAuth = () => {
|
|||||||
throw new Error('No login token');
|
throw new Error('No login token');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { user, workspace } = await handleVerify(
|
const { user, workspace, workspaceMember } = await handleVerify(
|
||||||
signUpResult.data?.signUp.loginToken.token,
|
signUpResult.data?.signUp.loginToken.token,
|
||||||
);
|
);
|
||||||
|
|
||||||
const workspaceMember = await client.mutate({
|
|
||||||
mutation: CREATE_ONE_WORKSPACE_MEMBER_V2,
|
|
||||||
variables: {
|
|
||||||
input: {
|
|
||||||
name: {
|
|
||||||
firstName: user.firstName ?? '',
|
|
||||||
lastName: user.lastName ?? '',
|
|
||||||
},
|
|
||||||
colorScheme: 'Light',
|
|
||||||
userId: user.id,
|
|
||||||
allowImpersonation: true,
|
|
||||||
locale: 'en',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
setCurrentWorkspaceMember(workspaceMember.data?.createWorkspaceMemberV2);
|
|
||||||
|
|
||||||
setIsVerifyPendingState(false);
|
setIsVerifyPendingState(false);
|
||||||
|
|
||||||
return { user, workspaceMember, workspace };
|
return { user, workspaceMember, workspace };
|
||||||
},
|
},
|
||||||
[
|
[setIsVerifyPendingState, signUp, handleVerify],
|
||||||
setIsVerifyPendingState,
|
|
||||||
signUp,
|
|
||||||
handleVerify,
|
|
||||||
client,
|
|
||||||
setCurrentWorkspaceMember,
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleGoogleLogin = useCallback((workspaceInviteHash?: string) => {
|
const handleGoogleLogin = useCallback((workspaceInviteHash?: string) => {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { useRecoilState, useSetRecoilState } from 'recoil';
|
import { useSetRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { authProvidersState } from '@/client-config/states/authProvidersState';
|
import { authProvidersState } from '@/client-config/states/authProvidersState';
|
||||||
import { isDebugModeState } from '@/client-config/states/isDebugModeState';
|
import { isDebugModeState } from '@/client-config/states/isDebugModeState';
|
||||||
@ -11,13 +11,12 @@ import { useGetClientConfigQuery } from '~/generated/graphql';
|
|||||||
export const ClientConfigProvider: React.FC<React.PropsWithChildren> = ({
|
export const ClientConfigProvider: React.FC<React.PropsWithChildren> = ({
|
||||||
children,
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
const [, setAuthProviders] = useRecoilState(authProvidersState);
|
const setAuthProviders = useSetRecoilState(authProvidersState);
|
||||||
const [, setIsDebugMode] = useRecoilState(isDebugModeState);
|
const setIsDebugMode = useSetRecoilState(isDebugModeState);
|
||||||
|
|
||||||
const [, setIsSignInPrefilled] = useRecoilState(isSignInPrefilledState);
|
const setIsSignInPrefilled = useSetRecoilState(isSignInPrefilledState);
|
||||||
|
|
||||||
const [, setTelemetry] = useRecoilState(telemetryState);
|
const setTelemetry = useSetRecoilState(telemetryState);
|
||||||
const [setIsLoading] = useState(true);
|
|
||||||
const setSupportChat = useSetRecoilState(supportChatState);
|
const setSupportChat = useSetRecoilState(supportChatState);
|
||||||
|
|
||||||
const { data, loading } = useGetClientConfigQuery();
|
const { data, loading } = useGetClientConfigQuery();
|
||||||
@ -41,10 +40,8 @@ export const ClientConfigProvider: React.FC<React.PropsWithChildren> = ({
|
|||||||
setIsDebugMode,
|
setIsDebugMode,
|
||||||
setIsSignInPrefilled,
|
setIsSignInPrefilled,
|
||||||
setTelemetry,
|
setTelemetry,
|
||||||
setIsLoading,
|
|
||||||
loading,
|
|
||||||
setSupportChat,
|
setSupportChat,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return <>{children}</>;
|
return loading ? <></> : <>{children}</>;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,17 +2,8 @@ import { useState } from 'react';
|
|||||||
import { useRecoilValue } from 'recoil';
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
|
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
|
||||||
import { IconNotes } from '@/ui/display/icon';
|
|
||||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||||
import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
|
import { AppHotkeyScope } from '@/ui/utilities/hotkey/types/AppHotkeyScope';
|
||||||
import { Avatar } from '@/users/components/Avatar';
|
|
||||||
import {
|
|
||||||
QueryMode,
|
|
||||||
useSearchActivityQuery,
|
|
||||||
useSearchCompanyQuery,
|
|
||||||
useSearchPeopleQuery,
|
|
||||||
} from '~/generated/graphql';
|
|
||||||
import { getLogoUrlFromDomainName } from '~/utils';
|
|
||||||
|
|
||||||
import { useCommandMenu } from '../hooks/useCommandMenu';
|
import { useCommandMenu } from '../hooks/useCommandMenu';
|
||||||
import { commandMenuCommandsState } from '../states/commandMenuCommandsState';
|
import { commandMenuCommandsState } from '../states/commandMenuCommandsState';
|
||||||
@ -45,47 +36,47 @@ export const CommandMenu = () => {
|
|||||||
[openCommandMenu, setSearch],
|
[openCommandMenu, setSearch],
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data: peopleData } = useSearchPeopleQuery({
|
// const { data: peopleData } = useSearchPeopleQuery({
|
||||||
skip: !isCommandMenuOpened,
|
// skip: !isCommandMenuOpened,
|
||||||
variables: {
|
// variables: {
|
||||||
where: {
|
// where: {
|
||||||
OR: [
|
// OR: [
|
||||||
{ firstName: { contains: search, mode: QueryMode.Insensitive } },
|
// { firstName: { contains: search, mode: QueryMode.Insensitive } },
|
||||||
{ lastName: { contains: search, mode: QueryMode.Insensitive } },
|
// { lastName: { contains: search, mode: QueryMode.Insensitive } },
|
||||||
],
|
// ],
|
||||||
},
|
// },
|
||||||
limit: 3,
|
// limit: 3,
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
|
|
||||||
const people = peopleData?.searchResults ?? [];
|
// const people = peopleData?.searchResults ?? [];
|
||||||
|
|
||||||
const { data: companyData } = useSearchCompanyQuery({
|
// const { data: companyData } = useSearchCompanyQuery({
|
||||||
skip: !isCommandMenuOpened,
|
// skip: !isCommandMenuOpened,
|
||||||
variables: {
|
// variables: {
|
||||||
where: {
|
// where: {
|
||||||
OR: [{ name: { contains: search, mode: QueryMode.Insensitive } }],
|
// OR: [{ name: { contains: search, mode: QueryMode.Insensitive } }],
|
||||||
},
|
// },
|
||||||
limit: 3,
|
// limit: 3,
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
|
|
||||||
const companies = companyData?.searchResults ?? [];
|
// const companies = companyData?.searchResults ?? [];
|
||||||
|
|
||||||
const { data: activityData } = useSearchActivityQuery({
|
// const { data: activityData } = useSearchActivityQuery({
|
||||||
skip: !isCommandMenuOpened,
|
// skip: !isCommandMenuOpened,
|
||||||
variables: {
|
// variables: {
|
||||||
where: {
|
// where: {
|
||||||
OR: [
|
// OR: [
|
||||||
{ title: { contains: search, mode: QueryMode.Insensitive } },
|
// { title: { contains: search, mode: QueryMode.Insensitive } },
|
||||||
{ body: { contains: search, mode: QueryMode.Insensitive } },
|
// { body: { contains: search, mode: QueryMode.Insensitive } },
|
||||||
],
|
// ],
|
||||||
},
|
// },
|
||||||
limit: 3,
|
// limit: 3,
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
|
|
||||||
const activities = activityData?.searchResults ?? [];
|
// const activities = activityData?.searchResults ?? [];
|
||||||
|
|
||||||
const checkInShortcuts = (cmd: Command, search: string) => {
|
const checkInShortcuts = (cmd: Command, search: string) => {
|
||||||
return (cmd.firstHotKey + (cmd.secondHotKey ?? ''))
|
return (cmd.firstHotKey + (cmd.secondHotKey ?? ''))
|
||||||
@ -158,7 +149,7 @@ export const CommandMenu = () => {
|
|||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</CommandGroup>
|
</CommandGroup>
|
||||||
<CommandGroup heading="People">
|
{/* <CommandGroup heading="People">
|
||||||
{people.map((person) => (
|
{people.map((person) => (
|
||||||
<CommandMenuItem
|
<CommandMenuItem
|
||||||
key={person.id}
|
key={person.id}
|
||||||
@ -200,7 +191,7 @@ export const CommandMenu = () => {
|
|||||||
onClick={() => openActivityRightDrawer(activity.id)}
|
onClick={() => openActivityRightDrawer(activity.id)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</CommandGroup>
|
</CommandGroup> */}
|
||||||
</StyledList>
|
</StyledList>
|
||||||
</StyledDialog>
|
</StyledDialog>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import { Command, CommandType } from '../types/Command';
|
|||||||
|
|
||||||
export const commandMenuCommands: Command[] = [
|
export const commandMenuCommands: Command[] = [
|
||||||
{
|
{
|
||||||
to: '/people',
|
to: '/objects/people',
|
||||||
label: 'Go to People',
|
label: 'Go to People',
|
||||||
type: CommandType.Navigate,
|
type: CommandType.Navigate,
|
||||||
firstHotKey: 'G',
|
firstHotKey: 'G',
|
||||||
@ -18,7 +18,7 @@ export const commandMenuCommands: Command[] = [
|
|||||||
Icon: IconUser,
|
Icon: IconUser,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: '/companies',
|
to: '/objects/companies',
|
||||||
label: 'Go to Companies',
|
label: 'Go to Companies',
|
||||||
type: CommandType.Navigate,
|
type: CommandType.Navigate,
|
||||||
firstHotKey: 'G',
|
firstHotKey: 'G',
|
||||||
@ -26,7 +26,7 @@ export const commandMenuCommands: Command[] = [
|
|||||||
Icon: IconBuildingSkyscraper,
|
Icon: IconBuildingSkyscraper,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
to: '/opportunities',
|
to: '/objects/opportunities',
|
||||||
label: 'Go to Opportunities',
|
label: 'Go to Opportunities',
|
||||||
type: CommandType.Navigate,
|
type: CommandType.Navigate,
|
||||||
firstHotKey: 'G',
|
firstHotKey: 'G',
|
||||||
|
|||||||
@ -1,74 +0,0 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
import { MemoryRouter } from 'react-router-dom';
|
|
||||||
import { Meta, StoryObj } from '@storybook/react';
|
|
||||||
|
|
||||||
import { CompanyBoardCard } from '@/companies/components/CompanyBoardCard';
|
|
||||||
import { pipelineAvailableFieldDefinitions } from '@/pipeline/constants/pipelineAvailableFieldDefinitions';
|
|
||||||
import { BoardCardIdContext } from '@/ui/layout/board/contexts/BoardCardIdContext';
|
|
||||||
import { boardCardFieldsScopedState } from '@/ui/layout/board/states/boardCardFieldsScopedState';
|
|
||||||
import { BoardColumnRecoilScopeContext } from '@/ui/layout/board/states/recoil-scope-contexts/BoardColumnRecoilScopeContext';
|
|
||||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
|
||||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
|
||||||
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
|
|
||||||
import { ComponentWithRecoilScopeDecorator } from '~/testing/decorators/ComponentWithRecoilScopeDecorator';
|
|
||||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
|
||||||
import { mockedPipelineProgressData } from '~/testing/mock-data/pipeline-progress';
|
|
||||||
|
|
||||||
import { HooksCompanyBoardEffect } from '../components/HooksCompanyBoardEffect';
|
|
||||||
import { BoardContext } from '../states/contexts/BoardContext';
|
|
||||||
import { CompanyBoardRecoilScopeContext } from '../states/recoil-scope-contexts/CompanyBoardRecoilScopeContext';
|
|
||||||
|
|
||||||
const meta: Meta<typeof CompanyBoardCard> = {
|
|
||||||
title: 'Modules/Companies/CompanyBoardCard',
|
|
||||||
component: CompanyBoardCard,
|
|
||||||
decorators: [
|
|
||||||
(Story, context) => {
|
|
||||||
const [, setBoardCardFields] = useRecoilScopedState(
|
|
||||||
boardCardFieldsScopedState,
|
|
||||||
context.parameters.customRecoilScopeContext,
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setBoardCardFields(pipelineAvailableFieldDefinitions);
|
|
||||||
}, [setBoardCardFields]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<MemoryRouter>
|
|
||||||
<ViewScope viewScopeId="company-board-view">
|
|
||||||
<RecoilScope
|
|
||||||
CustomRecoilScopeContext={BoardColumnRecoilScopeContext}
|
|
||||||
>
|
|
||||||
<BoardContext.Provider
|
|
||||||
value={{
|
|
||||||
BoardRecoilScopeContext:
|
|
||||||
context.parameters.customRecoilScopeContext,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<HooksCompanyBoardEffect />
|
|
||||||
<BoardCardIdContext.Provider
|
|
||||||
value={mockedPipelineProgressData[1].id}
|
|
||||||
>
|
|
||||||
<Story />
|
|
||||||
</BoardCardIdContext.Provider>
|
|
||||||
</BoardContext.Provider>
|
|
||||||
</RecoilScope>
|
|
||||||
</ViewScope>
|
|
||||||
</MemoryRouter>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
ComponentWithRecoilScopeDecorator,
|
|
||||||
ComponentDecorator,
|
|
||||||
],
|
|
||||||
args: {},
|
|
||||||
argTypes: {},
|
|
||||||
parameters: {
|
|
||||||
msw: graphqlMocks,
|
|
||||||
customRecoilScopeContext: CompanyBoardRecoilScopeContext,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default meta;
|
|
||||||
type Story = StoryObj<typeof CompanyBoardCard>;
|
|
||||||
|
|
||||||
export const Default: Story = {};
|
|
||||||
@ -1,38 +1,34 @@
|
|||||||
import { Pipeline } from '~/generated/graphql';
|
import { PipelineStep } from '@/pipeline/types/PipelineStep';
|
||||||
|
|
||||||
export const pipeline = {
|
export const pipelineSteps = [
|
||||||
id: 'pipeline-1',
|
{
|
||||||
name: 'pipeline-1',
|
id: 'pipeline-stage-1',
|
||||||
pipelineStages: [
|
name: 'New',
|
||||||
{
|
position: 0,
|
||||||
id: 'pipeline-stage-1',
|
color: 'red',
|
||||||
name: 'New',
|
},
|
||||||
position: 0,
|
{
|
||||||
color: 'red',
|
id: 'pipeline-stage-2',
|
||||||
},
|
name: 'Screening',
|
||||||
{
|
position: 1,
|
||||||
id: 'pipeline-stage-2',
|
color: 'purple',
|
||||||
name: 'Screening',
|
},
|
||||||
position: 1,
|
{
|
||||||
color: 'purple',
|
id: 'pipeline-stage-3',
|
||||||
},
|
name: 'Meeting',
|
||||||
{
|
position: 2,
|
||||||
id: 'pipeline-stage-3',
|
color: 'sky',
|
||||||
name: 'Meeting',
|
},
|
||||||
position: 2,
|
{
|
||||||
color: 'sky',
|
id: 'pipeline-stage-4',
|
||||||
},
|
name: 'Proposal',
|
||||||
{
|
position: 3,
|
||||||
id: 'pipeline-stage-4',
|
color: 'turquoise',
|
||||||
name: 'Proposal',
|
},
|
||||||
position: 3,
|
{
|
||||||
color: 'turquoise',
|
id: 'pipeline-stage-5',
|
||||||
},
|
name: 'Customer',
|
||||||
{
|
position: 4,
|
||||||
id: 'pipeline-stage-5',
|
color: 'yellow',
|
||||||
name: 'Customer',
|
},
|
||||||
position: 4,
|
] as PipelineStep[];
|
||||||
color: 'yellow',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
} as Pipeline;
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { getOperationName } from '@apollo/client/utilities';
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { flip, offset, useFloating } from '@floating-ui/react';
|
import { flip, offset, useFloating } from '@floating-ui/react';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
@ -8,7 +7,6 @@ import {
|
|||||||
PeoplePicker,
|
PeoplePicker,
|
||||||
PersonForSelect,
|
PersonForSelect,
|
||||||
} from '@/people/components/PeoplePicker';
|
} from '@/people/components/PeoplePicker';
|
||||||
import { GET_PEOPLE } from '@/people/graphql/queries/getPeople';
|
|
||||||
import { IconPlus } from '@/ui/display/icon';
|
import { IconPlus } from '@/ui/display/icon';
|
||||||
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
|
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
|
||||||
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
|
||||||
@ -16,10 +14,6 @@ import { DoubleTextInput } from '@/ui/object/field/meta-types/input/components/i
|
|||||||
import { FieldDoubleText } from '@/ui/object/field/types/FieldDoubleText';
|
import { FieldDoubleText } from '@/ui/object/field/types/FieldDoubleText';
|
||||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||||
import {
|
|
||||||
useInsertOnePersonMutation,
|
|
||||||
useUpdateOnePersonMutation,
|
|
||||||
} from '~/generated/graphql';
|
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
position: static;
|
position: static;
|
||||||
@ -56,8 +50,6 @@ export const AddPersonToCompany = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
||||||
const [isCreationDropdownOpen, setIsCreationDropdownOpen] = useState(false);
|
const [isCreationDropdownOpen, setIsCreationDropdownOpen] = useState(false);
|
||||||
const [updatePerson] = useUpdateOnePersonMutation();
|
|
||||||
const [insertOnePerson] = useInsertOnePersonMutation();
|
|
||||||
const { refs, floatingStyles } = useFloating({
|
const { refs, floatingStyles } = useFloating({
|
||||||
open: isDropdownOpen,
|
open: isDropdownOpen,
|
||||||
placement: 'right-start',
|
placement: 'right-start',
|
||||||
@ -77,17 +69,17 @@ export const AddPersonToCompany = ({
|
|||||||
const handlePersonSelected =
|
const handlePersonSelected =
|
||||||
(companyId: string) => async (newPerson: PersonForSelect | null) => {
|
(companyId: string) => async (newPerson: PersonForSelect | null) => {
|
||||||
if (newPerson) {
|
if (newPerson) {
|
||||||
await updatePerson({
|
// await updatePerson({
|
||||||
variables: {
|
// variables: {
|
||||||
where: {
|
// where: {
|
||||||
id: newPerson.id,
|
// id: newPerson.id,
|
||||||
},
|
// },
|
||||||
data: {
|
// data: {
|
||||||
company: { connect: { id: companyId } },
|
// company: { connect: { id: companyId } },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
refetchQueries: [getOperationName(GET_PEOPLE) ?? ''],
|
// refetchQueries: [getOperationName(GET_PEOPLE) ?? ''],
|
||||||
});
|
// });
|
||||||
handleClosePicker();
|
handleClosePicker();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -114,17 +106,17 @@ export const AddPersonToCompany = ({
|
|||||||
}: FieldDoubleText) => {
|
}: FieldDoubleText) => {
|
||||||
if (!firstValue && !secondValue) return;
|
if (!firstValue && !secondValue) return;
|
||||||
const newPersonId = v4();
|
const newPersonId = v4();
|
||||||
await insertOnePerson({
|
// await insertOnePerson({
|
||||||
variables: {
|
// variables: {
|
||||||
data: {
|
// data: {
|
||||||
company: { connect: { id: companyId } },
|
// company: { connect: { id: companyId } },
|
||||||
id: newPersonId,
|
// id: newPersonId,
|
||||||
firstName: firstValue,
|
// firstName: firstValue,
|
||||||
lastName: secondValue,
|
// lastName: secondValue,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
refetchQueries: [getOperationName(GET_PEOPLE) ?? ''],
|
// refetchQueries: [getOperationName(GET_PEOPLE) ?? ''],
|
||||||
});
|
// });
|
||||||
setIsCreationDropdownOpen(false);
|
setIsCreationDropdownOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -152,7 +152,7 @@ export const CompanyBoardCard = () => {
|
|||||||
|
|
||||||
const useUpdateOneObjectMutation: () => [(params: any) => any, any] = () => {
|
const useUpdateOneObjectMutation: () => [(params: any) => any, any] = () => {
|
||||||
const { updateOneObject } = useUpdateOneObjectRecord({
|
const { updateOneObject } = useUpdateOneObjectRecord({
|
||||||
objectNameSingular: 'opportunityV2',
|
objectNameSingular: 'opportunity',
|
||||||
});
|
});
|
||||||
|
|
||||||
const updateEntity = ({
|
const updateEntity = ({
|
||||||
@ -242,7 +242,7 @@ export const CompanyBoardCard = () => {
|
|||||||
fieldDefinition: {
|
fieldDefinition: {
|
||||||
fieldMetadataId: viewField.fieldMetadataId,
|
fieldMetadataId: viewField.fieldMetadataId,
|
||||||
label: viewField.label,
|
label: viewField.label,
|
||||||
Icon: viewField.Icon,
|
iconName: viewField.iconName,
|
||||||
type: viewField.type,
|
type: viewField.type,
|
||||||
metadata: viewField.metadata,
|
metadata: viewField.metadata,
|
||||||
entityChipDisplayMapper:
|
entityChipDisplayMapper:
|
||||||
|
|||||||
@ -18,7 +18,7 @@ export const CompanyChip = ({
|
|||||||
}: CompanyChipProps) => (
|
}: CompanyChipProps) => (
|
||||||
<EntityChip
|
<EntityChip
|
||||||
entityId={id}
|
entityId={id}
|
||||||
linkToEntity={`/companies/${id}`}
|
linkToEntity={`/objects/companies/${id}`}
|
||||||
name={name}
|
name={name}
|
||||||
avatarType="squared"
|
avatarType="squared"
|
||||||
pictureUrl={pictureUrl}
|
pictureUrl={pictureUrl}
|
||||||
|
|||||||
@ -33,7 +33,7 @@ export const CompanyPicker = ({
|
|||||||
}, [initialSearchFilter, setRelationPickerSearchFilter]);
|
}, [initialSearchFilter, setRelationPickerSearchFilter]);
|
||||||
|
|
||||||
const { findManyQuery } = useFindOneObjectMetadataItem({
|
const { findManyQuery } = useFindOneObjectMetadataItem({
|
||||||
objectNamePlural: 'companiesV2',
|
objectNamePlural: 'companies',
|
||||||
});
|
});
|
||||||
|
|
||||||
const useFindManyCompanies = (options: any) =>
|
const useFindManyCompanies = (options: any) =>
|
||||||
@ -57,7 +57,7 @@ export const CompanyPicker = ({
|
|||||||
originalEntity: company,
|
originalEntity: company,
|
||||||
}),
|
}),
|
||||||
selectedIds: companyId ? [companyId] : [],
|
selectedIds: companyId ? [companyId] : [],
|
||||||
objectNamePlural: 'companiesV2',
|
objectNamePlural: 'companies',
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleEntitySelected = async (
|
const handleEntitySelected = async (
|
||||||
|
|||||||
@ -73,7 +73,7 @@ export const CompanyProgressPicker = ({
|
|||||||
const selectedPipelineStage = useMemo(
|
const selectedPipelineStage = useMemo(
|
||||||
() =>
|
() =>
|
||||||
currentPipelineStages.find(
|
currentPipelineStages.find(
|
||||||
(pipelineStage) => pipelineStage.id === selectedPipelineStageId,
|
(pipelineStage: any) => pipelineStage.id === selectedPipelineStageId,
|
||||||
),
|
),
|
||||||
[currentPipelineStages, selectedPipelineStageId],
|
[currentPipelineStages, selectedPipelineStageId],
|
||||||
);
|
);
|
||||||
@ -85,7 +85,7 @@ export const CompanyProgressPicker = ({
|
|||||||
>
|
>
|
||||||
{isProgressSelectionUnfolded ? (
|
{isProgressSelectionUnfolded ? (
|
||||||
<DropdownMenuItemsContainer>
|
<DropdownMenuItemsContainer>
|
||||||
{currentPipelineStages.map((pipelineStage, index) => (
|
{currentPipelineStages.map((pipelineStage: any, index: number) => (
|
||||||
<MenuItem
|
<MenuItem
|
||||||
key={pipelineStage.id}
|
key={pipelineStage.id}
|
||||||
testId={`select-pipeline-stage-${index}`}
|
testId={`select-pipeline-stage-${index}`}
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
import { Company } from '@/companies/types/Company';
|
||||||
import { PeopleCard } from '@/people/components/PeopleCard';
|
import { PeopleCard } from '@/people/components/PeopleCard';
|
||||||
import { Company, useGetPeopleQuery } from '~/generated/graphql';
|
import { Person } from '@/people/types/Person';
|
||||||
|
|
||||||
import { AddPersonToCompany } from './AddPersonToCompany';
|
import { AddPersonToCompany } from './AddPersonToCompany';
|
||||||
|
|
||||||
@ -43,16 +44,19 @@ const StyledTitle = styled.div`
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export const CompanyTeam = ({ company }: CompanyTeamProps) => {
|
export const CompanyTeam = ({ company }: CompanyTeamProps) => {
|
||||||
const { data } = useGetPeopleQuery({
|
// const { data } = useGetPeopleQuery({
|
||||||
variables: {
|
// variables: {
|
||||||
orderBy: [],
|
// orderBy: [],
|
||||||
where: {
|
// where: {
|
||||||
companyId: {
|
// companyId: {
|
||||||
equals: company.id,
|
// equals: company.id,
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
|
const data = {
|
||||||
|
people: [],
|
||||||
|
};
|
||||||
|
|
||||||
const peopleIds = data?.people?.map(({ id }) => id);
|
const peopleIds = data?.people?.map(({ id }) => id);
|
||||||
|
|
||||||
@ -65,7 +69,7 @@ export const CompanyTeam = ({ company }: CompanyTeamProps) => {
|
|||||||
<AddPersonToCompany companyId={company.id} peopleIds={peopleIds} />
|
<AddPersonToCompany companyId={company.id} peopleIds={peopleIds} />
|
||||||
</StyledTitleContainer>
|
</StyledTitleContainer>
|
||||||
<StyledListContainer>
|
<StyledListContainer>
|
||||||
{data?.people?.map((person, id) => (
|
{data?.people?.map((person: Person, id) => (
|
||||||
<PeopleCard
|
<PeopleCard
|
||||||
key={person.id}
|
key={person.id}
|
||||||
person={person}
|
person={person}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
|||||||
import { useSearchParams } from 'react-router-dom';
|
import { useSearchParams } from 'react-router-dom';
|
||||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { Company } from '@/companies/types/Company';
|
||||||
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
||||||
import { PaginatedObjectTypeResults } from '@/object-record/types/PaginatedObjectTypeResults';
|
import { PaginatedObjectTypeResults } from '@/object-record/types/PaginatedObjectTypeResults';
|
||||||
import { pipelineAvailableFieldDefinitions } from '@/pipeline/constants/pipelineAvailableFieldDefinitions';
|
import { pipelineAvailableFieldDefinitions } from '@/pipeline/constants/pipelineAvailableFieldDefinitions';
|
||||||
@ -13,13 +14,11 @@ import { useBoardContextMenuEntries } from '@/ui/layout/board/hooks/useBoardCont
|
|||||||
import { availableBoardCardFieldsScopedState } from '@/ui/layout/board/states/availableBoardCardFieldsScopedState';
|
import { availableBoardCardFieldsScopedState } from '@/ui/layout/board/states/availableBoardCardFieldsScopedState';
|
||||||
import { boardCardFieldsScopedState } from '@/ui/layout/board/states/boardCardFieldsScopedState';
|
import { boardCardFieldsScopedState } from '@/ui/layout/board/states/boardCardFieldsScopedState';
|
||||||
import { isBoardLoadedState } from '@/ui/layout/board/states/isBoardLoadedState';
|
import { isBoardLoadedState } from '@/ui/layout/board/states/isBoardLoadedState';
|
||||||
import { turnFilterIntoWhereClause } from '@/ui/object/object-filter-dropdown/utils/turnFilterIntoWhereClause';
|
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
|
||||||
import { useView } from '@/views/hooks/useView';
|
import { useView } from '@/views/hooks/useView';
|
||||||
import { ViewType } from '@/views/types/ViewType';
|
import { ViewType } from '@/views/types/ViewType';
|
||||||
import { mapViewFieldsToBoardFieldDefinitions } from '@/views/utils/mapViewFieldsToBoardFieldDefinitions';
|
import { mapViewFieldsToBoardFieldDefinitions } from '@/views/utils/mapViewFieldsToBoardFieldDefinitions';
|
||||||
import { Company } from '~/generated-metadata/graphql';
|
|
||||||
import { opportunitiesBoardOptions } from '~/pages/opportunities/opportunitiesBoardOptions';
|
import { opportunitiesBoardOptions } from '~/pages/opportunities/opportunitiesBoardOptions';
|
||||||
|
|
||||||
import { useUpdateCompanyBoardCardIds } from '../hooks/useUpdateBoardCardIds';
|
import { useUpdateCompanyBoardCardIds } from '../hooks/useUpdateBoardCardIds';
|
||||||
@ -62,7 +61,7 @@ export const HooksCompanyBoardEffect = () => {
|
|||||||
const updateCompanyBoard = useUpdateCompanyBoard();
|
const updateCompanyBoard = useUpdateCompanyBoard();
|
||||||
|
|
||||||
useFindManyObjectRecords({
|
useFindManyObjectRecords({
|
||||||
objectNamePlural: 'pipelineStepsV2',
|
objectNamePlural: 'pipelineSteps',
|
||||||
filter: {},
|
filter: {},
|
||||||
onCompleted: useCallback(
|
onCompleted: useCallback(
|
||||||
(data: PaginatedObjectTypeResults<PipelineStep>) => {
|
(data: PaginatedObjectTypeResults<PipelineStep>) => {
|
||||||
@ -80,14 +79,14 @@ export const HooksCompanyBoardEffect = () => {
|
|||||||
in: pipelineSteps.map((pipelineStep) => pipelineStep.id),
|
in: pipelineSteps.map((pipelineStep) => pipelineStep.id),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
...(currentViewFilters?.map(turnFilterIntoWhereClause) || []),
|
...[],
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}, [currentViewFilters, pipelineSteps]) as any;
|
}, [pipelineSteps]) as any;
|
||||||
|
|
||||||
useFindManyObjectRecords({
|
useFindManyObjectRecords({
|
||||||
skip: !pipelineSteps.length,
|
skip: !pipelineSteps.length,
|
||||||
objectNamePlural: 'opportunitiesV2',
|
objectNamePlural: 'opportunities',
|
||||||
filter: whereFilters,
|
filter: whereFilters,
|
||||||
onCompleted: useCallback(
|
onCompleted: useCallback(
|
||||||
(_data: PaginatedObjectTypeResults<Opportunity>) => {
|
(_data: PaginatedObjectTypeResults<Opportunity>) => {
|
||||||
@ -104,7 +103,7 @@ export const HooksCompanyBoardEffect = () => {
|
|||||||
|
|
||||||
useFindManyObjectRecords({
|
useFindManyObjectRecords({
|
||||||
skip: !opportunities.length,
|
skip: !opportunities.length,
|
||||||
objectNamePlural: 'companiesV2',
|
objectNamePlural: 'companies',
|
||||||
filter: {
|
filter: {
|
||||||
id: {
|
id: {
|
||||||
in: opportunities.map((opportuntiy) => opportuntiy.companyId || ''),
|
in: opportunities.map((opportuntiy) => opportuntiy.companyId || ''),
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import { BoardColumnContext } from '@/ui/layout/board/contexts/BoardColumnContex
|
|||||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
|
|
||||||
import { useCreateCompanyProgress } from '../hooks/useCreateCompanyProgress';
|
|
||||||
import { useFilteredSearchCompanyQuery } from '../hooks/useFilteredSearchCompanyQuery';
|
import { useFilteredSearchCompanyQuery } from '../hooks/useFilteredSearchCompanyQuery';
|
||||||
|
|
||||||
export const NewCompanyProgressButton = () => {
|
export const NewCompanyProgressButton = () => {
|
||||||
@ -25,8 +24,6 @@ export const NewCompanyProgressButton = () => {
|
|||||||
setHotkeyScopeAndMemorizePreviousScope,
|
setHotkeyScopeAndMemorizePreviousScope,
|
||||||
} = usePreviousHotkeyScope();
|
} = usePreviousHotkeyScope();
|
||||||
|
|
||||||
const createCompanyProgress = useCreateCompanyProgress();
|
|
||||||
|
|
||||||
const handleEntitySelect = (company: any) => {
|
const handleEntitySelect = (company: any) => {
|
||||||
setIsCreatingCard(false);
|
setIsCreatingCard(false);
|
||||||
goBackToPreviousHotkeyScope();
|
goBackToPreviousHotkeyScope();
|
||||||
@ -39,7 +36,7 @@ export const NewCompanyProgressButton = () => {
|
|||||||
throw new Error('Pipeline stage id is not defined');
|
throw new Error('Pipeline stage id is not defined');
|
||||||
}
|
}
|
||||||
|
|
||||||
createCompanyProgress(company.id, pipelineStageId);
|
//createCompanyProgress(company.id, pipelineStageId);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleNewClick = useCallback(() => {
|
const handleNewClick = useCallback(() => {
|
||||||
|
|||||||
@ -1,182 +0,0 @@
|
|||||||
import {
|
|
||||||
IconBrandLinkedin,
|
|
||||||
IconBrandX,
|
|
||||||
IconBuildingSkyscraper,
|
|
||||||
IconCalendarEvent,
|
|
||||||
IconLink,
|
|
||||||
IconMap,
|
|
||||||
IconMoneybag,
|
|
||||||
IconTarget,
|
|
||||||
IconUserCircle,
|
|
||||||
IconUsers,
|
|
||||||
} from '@/ui/display/icon/index';
|
|
||||||
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
|
||||||
import {
|
|
||||||
FieldBooleanMetadata,
|
|
||||||
FieldChipMetadata,
|
|
||||||
FieldDateMetadata,
|
|
||||||
FieldMetadata,
|
|
||||||
FieldMoneyMetadata,
|
|
||||||
FieldNumberMetadata,
|
|
||||||
FieldRelationMetadata,
|
|
||||||
FieldTextMetadata,
|
|
||||||
FieldURLMetadata,
|
|
||||||
} from '@/ui/object/field/types/FieldMetadata';
|
|
||||||
import { ColumnDefinition } from '@/ui/object/record-table/types/ColumnDefinition';
|
|
||||||
import { User } from '~/generated/graphql';
|
|
||||||
|
|
||||||
export const companiesAvailableFieldDefinitions: ColumnDefinition<FieldMetadata>[] =
|
|
||||||
[
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'name',
|
|
||||||
label: 'Name',
|
|
||||||
Icon: IconBuildingSkyscraper,
|
|
||||||
size: 180,
|
|
||||||
position: 0,
|
|
||||||
type: 'CHIP',
|
|
||||||
metadata: {
|
|
||||||
urlFieldName: 'domainName',
|
|
||||||
contentFieldName: 'name',
|
|
||||||
relationType: Entity.Company,
|
|
||||||
placeHolder: 'Company Name',
|
|
||||||
},
|
|
||||||
isVisible: true,
|
|
||||||
infoTooltipContent: 'The company name.',
|
|
||||||
basePathToShowPage: '/companies/',
|
|
||||||
} satisfies ColumnDefinition<FieldChipMetadata>,
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'domainName',
|
|
||||||
label: 'URL',
|
|
||||||
Icon: IconLink,
|
|
||||||
size: 100,
|
|
||||||
position: 1,
|
|
||||||
type: 'URL',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'domainName',
|
|
||||||
placeHolder: 'example.com',
|
|
||||||
},
|
|
||||||
isVisible: true,
|
|
||||||
infoTooltipContent:
|
|
||||||
'The company website URL. We use this url to fetch the company icon.',
|
|
||||||
} satisfies ColumnDefinition<FieldURLMetadata>,
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'accountOwner',
|
|
||||||
label: 'Account Owner',
|
|
||||||
Icon: IconUserCircle,
|
|
||||||
size: 150,
|
|
||||||
position: 2,
|
|
||||||
type: 'RELATION',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'accountOwner',
|
|
||||||
relationType: Entity.User,
|
|
||||||
},
|
|
||||||
isVisible: true,
|
|
||||||
infoTooltipContent:
|
|
||||||
'Your team member responsible for managing the company account.',
|
|
||||||
entityChipDisplayMapper: (dataObject: User) => {
|
|
||||||
return {
|
|
||||||
name: dataObject?.displayName,
|
|
||||||
pictureUrl: dataObject?.avatarUrl ?? undefined,
|
|
||||||
avatarType: 'rounded',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
} satisfies ColumnDefinition<FieldRelationMetadata>,
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'createdAt',
|
|
||||||
label: 'Creation',
|
|
||||||
Icon: IconCalendarEvent,
|
|
||||||
size: 150,
|
|
||||||
position: 3,
|
|
||||||
type: 'DATE',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'createdAt',
|
|
||||||
},
|
|
||||||
isVisible: true,
|
|
||||||
infoTooltipContent: "Date when the company's record was created.",
|
|
||||||
} satisfies ColumnDefinition<FieldDateMetadata>,
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'employees',
|
|
||||||
label: 'Employees',
|
|
||||||
Icon: IconUsers,
|
|
||||||
size: 150,
|
|
||||||
position: 4,
|
|
||||||
type: 'NUMBER',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'employees',
|
|
||||||
isPositive: true,
|
|
||||||
placeHolder: 'Employees',
|
|
||||||
},
|
|
||||||
isVisible: true,
|
|
||||||
infoTooltipContent: 'Number of employees in the company.',
|
|
||||||
} satisfies ColumnDefinition<FieldNumberMetadata>,
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'linkedin',
|
|
||||||
label: 'LinkedIn',
|
|
||||||
Icon: IconBrandLinkedin,
|
|
||||||
size: 170,
|
|
||||||
position: 5,
|
|
||||||
type: 'URL',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'linkedinUrl',
|
|
||||||
placeHolder: 'LinkedIn URL',
|
|
||||||
},
|
|
||||||
isVisible: true,
|
|
||||||
infoTooltipContent: 'The company Linkedin account.',
|
|
||||||
} satisfies ColumnDefinition<FieldURLMetadata>,
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'address',
|
|
||||||
label: 'Address',
|
|
||||||
Icon: IconMap,
|
|
||||||
size: 170,
|
|
||||||
position: 6,
|
|
||||||
type: 'TEXT',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'address',
|
|
||||||
placeHolder: 'Address', // Hack: Fake character to prevent password-manager from filling the field
|
|
||||||
},
|
|
||||||
isVisible: true,
|
|
||||||
infoTooltipContent: 'The company address.',
|
|
||||||
} satisfies ColumnDefinition<FieldTextMetadata>,
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'idealCustomerProfile',
|
|
||||||
label: 'ICP',
|
|
||||||
Icon: IconTarget,
|
|
||||||
size: 150,
|
|
||||||
position: 7,
|
|
||||||
type: 'BOOLEAN',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'idealCustomerProfile',
|
|
||||||
},
|
|
||||||
isVisible: false,
|
|
||||||
infoTooltipContent:
|
|
||||||
'Ideal Customer Profile: Indicates whether the company is the most suitable and valuable customer for you.',
|
|
||||||
} satisfies ColumnDefinition<FieldBooleanMetadata>,
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'annualRecurringRevenue',
|
|
||||||
label: 'ARR',
|
|
||||||
Icon: IconMoneybag,
|
|
||||||
size: 150,
|
|
||||||
position: 8,
|
|
||||||
type: 'MONEY_AMOUNT',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'annualRecurringRevenue',
|
|
||||||
placeHolder: 'ARR',
|
|
||||||
},
|
|
||||||
infoTooltipContent:
|
|
||||||
'Annual Recurring Revenue: The actual or estimated annual revenue of the company.',
|
|
||||||
} satisfies ColumnDefinition<FieldMoneyMetadata>,
|
|
||||||
{
|
|
||||||
fieldMetadataId: 'xUrl',
|
|
||||||
label: 'Twitter',
|
|
||||||
Icon: IconBrandX,
|
|
||||||
size: 150,
|
|
||||||
position: 9,
|
|
||||||
type: 'URL',
|
|
||||||
metadata: {
|
|
||||||
fieldName: 'xUrl',
|
|
||||||
placeHolder: 'X',
|
|
||||||
},
|
|
||||||
isVisible: false,
|
|
||||||
infoTooltipContent: 'The company Twitter account.',
|
|
||||||
} satisfies ColumnDefinition<FieldURLMetadata>,
|
|
||||||
];
|
|
||||||
@ -1,90 +0,0 @@
|
|||||||
import { useEffect, useState } from 'react';
|
|
||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
import { FieldRecoilScopeContext } from '@/ui/object/record-inline-cell/states/recoil-scope-contexts/FieldRecoilScopeContext';
|
|
||||||
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
|
|
||||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
|
||||||
import { Company, useUpdateOneCompanyMutation } from '~/generated/graphql';
|
|
||||||
|
|
||||||
import { EditableFieldHotkeyScope } from '../types/EditableFieldHotkeyScope';
|
|
||||||
|
|
||||||
type CompanyNameEditableFieldProps = {
|
|
||||||
company: Pick<Company, 'id' | 'name'>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const StyledEditableTitleInput = styled.input<{
|
|
||||||
value: string;
|
|
||||||
}>`
|
|
||||||
background: transparent;
|
|
||||||
|
|
||||||
border: none;
|
|
||||||
color: ${({ theme, value }) =>
|
|
||||||
value ? theme.font.color.primary : theme.font.color.light};
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
font-size: ${({ theme }) => theme.font.size.xl};
|
|
||||||
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
line-height: ${({ theme }) => theme.text.lineHeight.md};
|
|
||||||
outline: none;
|
|
||||||
&::placeholder {
|
|
||||||
color: ${({ theme }) => theme.font.color.light};
|
|
||||||
}
|
|
||||||
text-align: center;
|
|
||||||
width: calc(100% - ${({ theme }) => theme.spacing(2)});
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const CompanyNameEditableField = ({
|
|
||||||
company,
|
|
||||||
}: CompanyNameEditableFieldProps) => {
|
|
||||||
const [internalValue, setInternalValue] = useState(company.name);
|
|
||||||
|
|
||||||
const [updateCompany] = useUpdateOneCompanyMutation();
|
|
||||||
|
|
||||||
const {
|
|
||||||
goBackToPreviousHotkeyScope,
|
|
||||||
setHotkeyScopeAndMemorizePreviousScope,
|
|
||||||
} = usePreviousHotkeyScope();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setInternalValue(company.name);
|
|
||||||
}, [company.name]);
|
|
||||||
|
|
||||||
const handleChange = async (newValue: string) => {
|
|
||||||
setInternalValue(newValue);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = async () => {
|
|
||||||
goBackToPreviousHotkeyScope();
|
|
||||||
await updateCompany({
|
|
||||||
variables: {
|
|
||||||
where: {
|
|
||||||
id: company.id,
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
name: internalValue ?? '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleFocus = async () => {
|
|
||||||
setHotkeyScopeAndMemorizePreviousScope(
|
|
||||||
EditableFieldHotkeyScope.EditableField,
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<RecoilScope CustomRecoilScopeContext={FieldRecoilScopeContext}>
|
|
||||||
<StyledEditableTitleInput
|
|
||||||
autoComplete="off"
|
|
||||||
onChange={(event) => handleChange(event.target.value)}
|
|
||||||
onBlur={handleSubmit}
|
|
||||||
onFocus={handleFocus}
|
|
||||||
value={internalValue}
|
|
||||||
/>
|
|
||||||
</RecoilScope>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const BASE_COMPANY_FIELDS_FRAGMENT = gql`
|
|
||||||
fragment baseCompanyFieldsFragment on Company {
|
|
||||||
address
|
|
||||||
annualRecurringRevenue
|
|
||||||
createdAt
|
|
||||||
domainName
|
|
||||||
employees
|
|
||||||
id
|
|
||||||
idealCustomerProfile
|
|
||||||
linkedinUrl
|
|
||||||
name
|
|
||||||
xUrl
|
|
||||||
_activityCount
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const BASE_ACCOUNT_OWNER_FRAGMENT = gql`
|
|
||||||
fragment baseAccountOwnerFragment on User {
|
|
||||||
id
|
|
||||||
email
|
|
||||||
displayName
|
|
||||||
avatarUrl
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const COMPANY_FIELDS_FRAGMENT = gql`
|
|
||||||
${BASE_COMPANY_FIELDS_FRAGMENT}
|
|
||||||
${BASE_ACCOUNT_OWNER_FRAGMENT}
|
|
||||||
fragment companyFieldsFragment on Company {
|
|
||||||
accountOwner {
|
|
||||||
...baseAccountOwnerFragment
|
|
||||||
}
|
|
||||||
...baseCompanyFieldsFragment
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const DELETE_MANY_COMPANIES = gql`
|
|
||||||
mutation DeleteManyCompanies($ids: [String!]) {
|
|
||||||
deleteManyCompany(where: { id: { in: $ids } }) {
|
|
||||||
count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const INSERT_MANY_COMPANY = gql`
|
|
||||||
mutation InsertManyCompany($data: [CompanyCreateManyInput!]!) {
|
|
||||||
createManyCompany(data: $data) {
|
|
||||||
count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const INSERT_ONE_COMPANY = gql`
|
|
||||||
mutation InsertOneCompany($data: CompanyCreateInput!) {
|
|
||||||
createOneCompany(data: $data) {
|
|
||||||
...companyFieldsFragment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const UPDATE_ONE_COMPANY = gql`
|
|
||||||
mutation UpdateOneCompany(
|
|
||||||
$where: CompanyWhereUniqueInput!
|
|
||||||
$data: CompanyUpdateInput!
|
|
||||||
) {
|
|
||||||
updateOneCompany(data: $data, where: $where) {
|
|
||||||
...companyFieldsFragment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
import { Company } from '~/generated/graphql';
|
|
||||||
|
|
||||||
import { GET_COMPANIES } from '../queries/getCompanies';
|
|
||||||
|
|
||||||
export const getCompaniesOptimisticEffectDefinition = {
|
|
||||||
key: 'generic-entity-table-data-companies',
|
|
||||||
typename: 'Company',
|
|
||||||
query: GET_COMPANIES,
|
|
||||||
resolver: ({
|
|
||||||
currentData,
|
|
||||||
newData,
|
|
||||||
}: {
|
|
||||||
currentData: Company[];
|
|
||||||
newData: Company[];
|
|
||||||
}) => {
|
|
||||||
return [...newData, ...currentData];
|
|
||||||
},
|
|
||||||
};
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
import { COMPANY_FIELDS_FRAGMENT } from '../fragments/companyFieldsFragment';
|
|
||||||
|
|
||||||
export const GET_COMPANIES = gql`
|
|
||||||
${COMPANY_FIELDS_FRAGMENT}
|
|
||||||
query GetCompanies(
|
|
||||||
$orderBy: [CompanyOrderByWithRelationInput!]
|
|
||||||
$where: CompanyWhereInput
|
|
||||||
) {
|
|
||||||
companies: findManyCompany(orderBy: $orderBy, where: $where) {
|
|
||||||
...companyFieldsFragment
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const GET_COMPANY = gql`
|
|
||||||
query GetCompany($where: CompanyWhereUniqueInput!) {
|
|
||||||
findUniqueCompany(where: $where) {
|
|
||||||
...companyFieldsFragment
|
|
||||||
Favorite {
|
|
||||||
id
|
|
||||||
person {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
company {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
import { useSetRecoilState } from 'recoil';
|
|
||||||
|
|
||||||
import { entityFieldsFamilyState } from '@/ui/object/field/states/entityFieldsFamilyState';
|
|
||||||
import { useGetCompanyQuery } from '~/generated/graphql';
|
|
||||||
|
|
||||||
export const useCompanyQuery = (id: string) => {
|
|
||||||
const updateCompanyShowPage = useSetRecoilState(entityFieldsFamilyState(id));
|
|
||||||
|
|
||||||
return useGetCompanyQuery({
|
|
||||||
variables: { where: { id } },
|
|
||||||
onCompleted: (data) => {
|
|
||||||
updateCompanyShowPage(data?.findUniqueCompany);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
@ -1,157 +0,0 @@
|
|||||||
import { getOperationName } from '@apollo/client/utilities';
|
|
||||||
import { useRecoilCallback, useSetRecoilState } from 'recoil';
|
|
||||||
|
|
||||||
import { useFavorites } from '@/favorites/hooks/useFavorites';
|
|
||||||
import {
|
|
||||||
IconCheckbox,
|
|
||||||
IconHeart,
|
|
||||||
IconHeartOff,
|
|
||||||
IconNotes,
|
|
||||||
IconTrash,
|
|
||||||
} from '@/ui/display/icon';
|
|
||||||
import { actionBarEntriesState } from '@/ui/navigation/action-bar/states/actionBarEntriesState';
|
|
||||||
import { contextMenuEntriesState } from '@/ui/navigation/context-menu/states/contextMenuEntriesState';
|
|
||||||
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
|
||||||
import { selectedRowIdsSelector } from '@/ui/object/record-table/states/selectors/selectedRowIdsSelector';
|
|
||||||
import { tableRowIdsState } from '@/ui/object/record-table/states/tableRowIdsState';
|
|
||||||
import {
|
|
||||||
ActivityType,
|
|
||||||
useDeleteManyCompaniesMutation,
|
|
||||||
useGetFavoritesQuery,
|
|
||||||
} from '~/generated/graphql';
|
|
||||||
|
|
||||||
import { GET_COMPANY } from '../graphql/queries/getCompany';
|
|
||||||
|
|
||||||
import { useCreateActivityForCompany } from './useCreateActivityForCompany';
|
|
||||||
|
|
||||||
export const useCompanyTableContextMenuEntries = () => {
|
|
||||||
const setContextMenuEntries = useSetRecoilState(contextMenuEntriesState);
|
|
||||||
const setActionBarEntriesState = useSetRecoilState(actionBarEntriesState);
|
|
||||||
const createActivityForCompany = useCreateActivityForCompany();
|
|
||||||
|
|
||||||
const setTableRowIds = useSetRecoilState(tableRowIdsState);
|
|
||||||
const { resetTableRowSelection } = useRecordTable({
|
|
||||||
recordTableScopeId: 'companies',
|
|
||||||
});
|
|
||||||
|
|
||||||
const { data } = useGetFavoritesQuery();
|
|
||||||
const favorites = data?.findFavorites;
|
|
||||||
const { createFavorite, deleteFavorite } = useFavorites({
|
|
||||||
objectNamePlural: 'companies',
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleFavoriteButtonClick = useRecoilCallback(({ snapshot }) => () => {
|
|
||||||
const selectedRowIds = snapshot
|
|
||||||
.getLoadable(selectedRowIdsSelector)
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
const selectedCompanyId =
|
|
||||||
selectedRowIds.length === 1 ? selectedRowIds[0] : '';
|
|
||||||
|
|
||||||
const isFavorite =
|
|
||||||
!!selectedCompanyId &&
|
|
||||||
!!favorites?.find(
|
|
||||||
(favorite) => favorite.company?.id === selectedCompanyId,
|
|
||||||
);
|
|
||||||
|
|
||||||
resetTableRowSelection();
|
|
||||||
if (isFavorite) deleteFavorite(selectedCompanyId);
|
|
||||||
else createFavorite('company', selectedCompanyId);
|
|
||||||
});
|
|
||||||
|
|
||||||
const [deleteManyCompany] = useDeleteManyCompaniesMutation({
|
|
||||||
refetchQueries: [getOperationName(GET_COMPANY) ?? ''],
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleDeleteClick = useRecoilCallback(({ snapshot }) => async () => {
|
|
||||||
const rowIdsToDelete = snapshot
|
|
||||||
.getLoadable(selectedRowIdsSelector)
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
resetTableRowSelection();
|
|
||||||
|
|
||||||
await deleteManyCompany({
|
|
||||||
variables: {
|
|
||||||
ids: rowIdsToDelete,
|
|
||||||
},
|
|
||||||
optimisticResponse: {
|
|
||||||
__typename: 'Mutation',
|
|
||||||
deleteManyCompany: {
|
|
||||||
count: rowIdsToDelete.length,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
update: () => {
|
|
||||||
setTableRowIds((tableRowIds) =>
|
|
||||||
tableRowIds.filter((id) => !rowIdsToDelete.includes(id)),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
setContextMenuEntries: useRecoilCallback(({ snapshot }) => () => {
|
|
||||||
const selectedRowIds = snapshot
|
|
||||||
.getLoadable(selectedRowIdsSelector)
|
|
||||||
.getValue();
|
|
||||||
|
|
||||||
const selectedCompanyId =
|
|
||||||
selectedRowIds.length === 1 ? selectedRowIds[0] : '';
|
|
||||||
|
|
||||||
const isFavorite =
|
|
||||||
!!selectedCompanyId &&
|
|
||||||
!!favorites?.find(
|
|
||||||
(favorite) => favorite.company?.id === selectedCompanyId,
|
|
||||||
);
|
|
||||||
|
|
||||||
setContextMenuEntries([
|
|
||||||
{
|
|
||||||
label: 'New task',
|
|
||||||
Icon: IconCheckbox,
|
|
||||||
onClick: () => createActivityForCompany(ActivityType.Task),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'New note',
|
|
||||||
Icon: IconNotes,
|
|
||||||
onClick: () => createActivityForCompany(ActivityType.Note),
|
|
||||||
},
|
|
||||||
...(!!selectedCompanyId
|
|
||||||
? [
|
|
||||||
{
|
|
||||||
label: isFavorite
|
|
||||||
? 'Remove from favorites'
|
|
||||||
: 'Add to favorites',
|
|
||||||
Icon: isFavorite ? IconHeartOff : IconHeart,
|
|
||||||
onClick: () => handleFavoriteButtonClick(),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
: []),
|
|
||||||
{
|
|
||||||
label: 'Delete',
|
|
||||||
Icon: IconTrash,
|
|
||||||
accent: 'danger',
|
|
||||||
onClick: () => handleDeleteClick(),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}),
|
|
||||||
setActionBarEntries: useRecoilCallback(() => () => {
|
|
||||||
setActionBarEntriesState([
|
|
||||||
{
|
|
||||||
label: 'Task',
|
|
||||||
Icon: IconCheckbox,
|
|
||||||
onClick: () => createActivityForCompany(ActivityType.Task),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Note',
|
|
||||||
Icon: IconNotes,
|
|
||||||
onClick: () => createActivityForCompany(ActivityType.Note),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Delete',
|
|
||||||
Icon: IconTrash,
|
|
||||||
accent: 'danger',
|
|
||||||
onClick: () => handleDeleteClick(),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { useOpenCreateActivityDrawerForSelectedRowIds } from '@/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds';
|
|
||||||
import { ActivityType } from '@/activities/types/Activity';
|
|
||||||
|
|
||||||
export const useCreateActivityForCompany = () => {
|
|
||||||
const openCreateActivityRightDrawer =
|
|
||||||
useOpenCreateActivityDrawerForSelectedRowIds();
|
|
||||||
|
|
||||||
return useRecoilCallback(
|
|
||||||
() => (type: ActivityType) => {
|
|
||||||
openCreateActivityRightDrawer(type, 'Company');
|
|
||||||
},
|
|
||||||
[openCreateActivityRightDrawer],
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
import { useRecoilCallback, useRecoilState } from 'recoil';
|
|
||||||
import { v4 } from 'uuid';
|
|
||||||
|
|
||||||
import { useCreateOneObjectRecord } from '@/object-record/hooks/useCreateOneObjectRecord';
|
|
||||||
import { currentPipelineState } from '@/pipeline/states/currentPipelineState';
|
|
||||||
import { Opportunity } from '@/pipeline/types/Opportunity';
|
|
||||||
import { boardCardIdsByColumnIdFamilyState } from '@/ui/layout/board/states/boardCardIdsByColumnIdFamilyState';
|
|
||||||
|
|
||||||
export const useCreateCompanyProgress = () => {
|
|
||||||
const { createOneObject: createOneOpportunity } =
|
|
||||||
useCreateOneObjectRecord<Opportunity>({
|
|
||||||
objectNameSingular: 'opportunityV2',
|
|
||||||
});
|
|
||||||
|
|
||||||
const [currentPipeline] = useRecoilState(currentPipelineState);
|
|
||||||
|
|
||||||
return useRecoilCallback(
|
|
||||||
({ set }) =>
|
|
||||||
async (companyId: string, pipelineStageId: string) => {
|
|
||||||
if (!currentPipeline?.id) {
|
|
||||||
throw new Error('Pipeline not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
const newUuid = v4();
|
|
||||||
|
|
||||||
set(boardCardIdsByColumnIdFamilyState(pipelineStageId), (oldValue) => [
|
|
||||||
...oldValue,
|
|
||||||
newUuid,
|
|
||||||
]);
|
|
||||||
|
|
||||||
await createOneOpportunity?.({
|
|
||||||
pipelineStepId: pipelineStageId,
|
|
||||||
companyId: companyId,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
[createOneOpportunity, currentPipeline?.id],
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,6 +1,8 @@
|
|||||||
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
import { useQuery } from '@apollo/client';
|
||||||
import { useSearchCompanyQuery } from '~/generated/graphql';
|
|
||||||
import { getLogoUrlFromDomainName } from '~/utils';
|
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
||||||
|
import { useFilteredSearchEntityQueryV2 } from '@/search/hooks/useFilteredSearchEntityQueryV2';
|
||||||
|
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
||||||
|
|
||||||
export const useFilteredSearchCompanyQuery = ({
|
export const useFilteredSearchCompanyQuery = ({
|
||||||
searchFilter,
|
searchFilter,
|
||||||
@ -11,25 +13,32 @@ export const useFilteredSearchCompanyQuery = ({
|
|||||||
selectedIds?: string[];
|
selectedIds?: string[];
|
||||||
limit?: number;
|
limit?: number;
|
||||||
}) => {
|
}) => {
|
||||||
return useFilteredSearchEntityQuery({
|
const { findManyQuery } = useFindOneObjectMetadataItem({
|
||||||
queryHook: useSearchCompanyQuery,
|
objectNameSingular: 'company',
|
||||||
|
});
|
||||||
|
|
||||||
|
const useFindManyCompanies = (options: any) =>
|
||||||
|
useQuery(findManyQuery, options);
|
||||||
|
|
||||||
|
return useFilteredSearchEntityQueryV2({
|
||||||
|
queryHook: useFindManyCompanies,
|
||||||
filters: [
|
filters: [
|
||||||
{
|
{
|
||||||
fieldNames: ['name'],
|
fieldNames: ['name.firstName', 'name.lastName'],
|
||||||
filter: searchFilter,
|
filter: searchFilter,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
orderByField: 'name',
|
orderByField: 'createdAt',
|
||||||
mappingFunction: (company) => ({
|
mappingFunction: (company) => ({
|
||||||
|
entityType: Entity.Company,
|
||||||
id: company.id,
|
id: company.id,
|
||||||
entityType: 'Company',
|
|
||||||
name: company.name,
|
name: company.name,
|
||||||
avatarUrl: getLogoUrlFromDomainName(company.domainName),
|
|
||||||
domainName: company.domainName,
|
|
||||||
avatarType: 'squared',
|
avatarType: 'squared',
|
||||||
|
avatarUrl: '',
|
||||||
originalEntity: company,
|
originalEntity: company,
|
||||||
}),
|
}),
|
||||||
selectedIds: selectedIds,
|
selectedIds: selectedIds,
|
||||||
|
objectNamePlural: 'workspaceMembers',
|
||||||
limit,
|
limit,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,59 +0,0 @@
|
|||||||
import { v4 as uuidv4 } from 'uuid';
|
|
||||||
|
|
||||||
import { useSpreadsheetImport } from '@/spreadsheet-import/hooks/useSpreadsheetImport';
|
|
||||||
import { SpreadsheetOptions } from '@/spreadsheet-import/types';
|
|
||||||
import { useSnackBar } from '@/ui/feedback/snack-bar/hooks/useSnackBar';
|
|
||||||
import { useInsertManyCompanyMutation } from '~/generated/graphql';
|
|
||||||
|
|
||||||
import { fieldsForCompany } from '../utils/fieldsForCompany';
|
|
||||||
|
|
||||||
export type FieldCompanyMapping = (typeof fieldsForCompany)[number]['key'];
|
|
||||||
|
|
||||||
export const useSpreadsheetCompanyImport = () => {
|
|
||||||
const { openSpreadsheetImport } = useSpreadsheetImport<FieldCompanyMapping>();
|
|
||||||
const { enqueueSnackBar } = useSnackBar();
|
|
||||||
|
|
||||||
const [createManyCompany] = useInsertManyCompanyMutation();
|
|
||||||
|
|
||||||
const openCompanySpreadsheetImport = (
|
|
||||||
options?: Omit<
|
|
||||||
SpreadsheetOptions<FieldCompanyMapping>,
|
|
||||||
'fields' | 'isOpen' | 'onClose'
|
|
||||||
>,
|
|
||||||
) => {
|
|
||||||
openSpreadsheetImport({
|
|
||||||
...options,
|
|
||||||
onSubmit: async (data) => {
|
|
||||||
// TODO: Add better type checking in spreadsheet import later
|
|
||||||
const createInputs = data.validData.map((company) => ({
|
|
||||||
id: uuidv4(),
|
|
||||||
name: (company.name ?? '') as string,
|
|
||||||
domainName: (company.domainName ?? '') as string,
|
|
||||||
address: (company.address ?? '') as string,
|
|
||||||
employees: parseInt((company.employees ?? '') as string, 10),
|
|
||||||
linkedinUrl: (company.linkedinUrl ?? '') as string | undefined,
|
|
||||||
}));
|
|
||||||
|
|
||||||
try {
|
|
||||||
const result = await createManyCompany({
|
|
||||||
variables: {
|
|
||||||
data: createInputs,
|
|
||||||
},
|
|
||||||
refetchQueries: 'active',
|
|
||||||
});
|
|
||||||
|
|
||||||
if (result.errors) {
|
|
||||||
throw result.errors;
|
|
||||||
}
|
|
||||||
} catch (error: any) {
|
|
||||||
enqueueSnackBar(error?.message || 'Something went wrong', {
|
|
||||||
variant: 'error',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fields: fieldsForCompany,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return { openCompanySpreadsheetImport };
|
|
||||||
};
|
|
||||||
@ -1,149 +0,0 @@
|
|||||||
import styled from '@emotion/styled';
|
|
||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { companiesAvailableFieldDefinitions } from '@/companies/constants/companiesAvailableFieldDefinitions';
|
|
||||||
import { getCompaniesOptimisticEffectDefinition } from '@/companies/graphql/optimistic-effect-definitions/getCompaniesOptimisticEffectDefinition';
|
|
||||||
import { useCompanyTableContextMenuEntries } from '@/companies/hooks/useCompanyTableContextMenuEntries';
|
|
||||||
import { useSpreadsheetCompanyImport } from '@/companies/hooks/useSpreadsheetCompanyImport';
|
|
||||||
import { RecordTableEffect } from '@/ui/object/record-table/components/RecordTableEffect';
|
|
||||||
import { RecordTableV1 } from '@/ui/object/record-table/components/RecordTableV1';
|
|
||||||
import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId';
|
|
||||||
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
|
||||||
import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown';
|
|
||||||
import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
|
|
||||||
import { ViewBar } from '@/views/components/ViewBar';
|
|
||||||
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
|
||||||
import { useView } from '@/views/hooks/useView';
|
|
||||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
|
||||||
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
|
|
||||||
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
|
|
||||||
import { mapViewFiltersToFilters } from '@/views/utils/mapViewFiltersToFilters';
|
|
||||||
import { mapViewSortsToSorts } from '@/views/utils/mapViewSortsToSorts';
|
|
||||||
import {
|
|
||||||
UpdateOneCompanyMutationVariables,
|
|
||||||
useGetCompaniesQuery,
|
|
||||||
useGetWorkspaceMembersLazyQuery,
|
|
||||||
useUpdateOneCompanyMutation,
|
|
||||||
} from '~/generated/graphql';
|
|
||||||
import { companyTableFilterDefinitions } from '~/pages/companies/constants/companyTableFilterDefinitions';
|
|
||||||
import { companyTableSortDefinitions } from '~/pages/companies/constants/companyTableSortDefinitions';
|
|
||||||
|
|
||||||
import CompanyTableEffect from './CompanyTableEffect';
|
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
overflow: auto;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const CompanyTable = () => {
|
|
||||||
const viewScopeId = 'company-table-view';
|
|
||||||
const tableScopeId = 'companies';
|
|
||||||
|
|
||||||
const {
|
|
||||||
setTableFilters,
|
|
||||||
setTableSorts,
|
|
||||||
setTableColumns,
|
|
||||||
upsertRecordTableItem,
|
|
||||||
} = useRecordTable({
|
|
||||||
recordTableScopeId: tableScopeId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const [updateEntityMutation] = useUpdateOneCompanyMutation();
|
|
||||||
|
|
||||||
const [getWorkspaceMember] = useGetWorkspaceMembersLazyQuery();
|
|
||||||
const { persistViewFields } = useViewFields(viewScopeId);
|
|
||||||
const { setEntityCountInCurrentView } = useView({ viewScopeId });
|
|
||||||
|
|
||||||
const { setContextMenuEntries, setActionBarEntries } =
|
|
||||||
useCompanyTableContextMenuEntries();
|
|
||||||
|
|
||||||
const updateCompany = async (
|
|
||||||
variables: UpdateOneCompanyMutationVariables,
|
|
||||||
) => {
|
|
||||||
if (variables.data.accountOwner?.connect?.id) {
|
|
||||||
const workspaceMemberAccountOwner = (
|
|
||||||
await getWorkspaceMember({
|
|
||||||
variables: {
|
|
||||||
where: {
|
|
||||||
userId: { equals: variables.data.accountOwner.connect?.id },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
).data?.workspaceMembers?.[0];
|
|
||||||
variables.data.workspaceMemberAccountOwner = {
|
|
||||||
connect: { id: workspaceMemberAccountOwner?.id },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
updateEntityMutation({
|
|
||||||
variables: variables,
|
|
||||||
onCompleted: (data) => {
|
|
||||||
if (!data.updateOneCompany) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
upsertRecordTableItem(data.updateOneCompany);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const { openCompanySpreadsheetImport: onImport } =
|
|
||||||
useSpreadsheetCompanyImport();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ViewScope
|
|
||||||
viewScopeId={viewScopeId}
|
|
||||||
onViewFieldsChange={(viewFields) => {
|
|
||||||
setTableColumns(
|
|
||||||
mapViewFieldsToColumnDefinitions(
|
|
||||||
viewFields,
|
|
||||||
companiesAvailableFieldDefinitions,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}}
|
|
||||||
onViewFiltersChange={(viewFilters) => {
|
|
||||||
setTableFilters(mapViewFiltersToFilters(viewFilters));
|
|
||||||
}}
|
|
||||||
onViewSortsChange={(viewSorts) => {
|
|
||||||
setTableSorts(mapViewSortsToSorts(viewSorts));
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<StyledContainer>
|
|
||||||
<RecordTableScope
|
|
||||||
recordTableScopeId={tableScopeId}
|
|
||||||
onColumnsChange={useRecoilCallback(() => (columns) => {
|
|
||||||
persistViewFields(mapColumnDefinitionsToViewFields(columns));
|
|
||||||
})}
|
|
||||||
onEntityCountChange={useRecoilCallback(() => (entityCount) => {
|
|
||||||
setEntityCountInCurrentView(entityCount);
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<ViewBar
|
|
||||||
optionsDropdownButton={<TableOptionsDropdown onImport={onImport} />}
|
|
||||||
optionsDropdownScopeId={TableOptionsDropdownId}
|
|
||||||
/>
|
|
||||||
<CompanyTableEffect />
|
|
||||||
<RecordTableEffect
|
|
||||||
getRequestResultKey="companies"
|
|
||||||
useGetRequest={useGetCompaniesQuery}
|
|
||||||
getRequestOptimisticEffectDefinition={
|
|
||||||
getCompaniesOptimisticEffectDefinition
|
|
||||||
}
|
|
||||||
filterDefinitionArray={companyTableFilterDefinitions}
|
|
||||||
sortDefinitionArray={companyTableSortDefinitions}
|
|
||||||
setContextMenuEntries={setContextMenuEntries}
|
|
||||||
setActionBarEntries={setActionBarEntries}
|
|
||||||
/>
|
|
||||||
<RecordTableV1
|
|
||||||
updateEntityMutation={({
|
|
||||||
variables,
|
|
||||||
}: {
|
|
||||||
variables: UpdateOneCompanyMutationVariables;
|
|
||||||
}) => updateCompany(variables)}
|
|
||||||
/>
|
|
||||||
</RecordTableScope>
|
|
||||||
</StyledContainer>
|
|
||||||
</ViewScope>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
import { companiesAvailableFieldDefinitions } from '@/companies/constants/companiesAvailableFieldDefinitions';
|
|
||||||
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
|
||||||
import { useView } from '@/views/hooks/useView';
|
|
||||||
import { ViewType } from '@/views/types/ViewType';
|
|
||||||
import { companyTableFilterDefinitions } from '~/pages/companies/constants/companyTableFilterDefinitions';
|
|
||||||
import { companyTableSortDefinitions } from '~/pages/companies/constants/companyTableSortDefinitions';
|
|
||||||
|
|
||||||
const CompanyTableEffect = () => {
|
|
||||||
const {
|
|
||||||
setAvailableSortDefinitions,
|
|
||||||
setAvailableFilterDefinitions,
|
|
||||||
setAvailableFieldDefinitions,
|
|
||||||
setViewType,
|
|
||||||
setViewObjectMetadataId,
|
|
||||||
} = useView();
|
|
||||||
|
|
||||||
const { setAvailableTableColumns } = useRecordTable();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setAvailableSortDefinitions?.(companyTableSortDefinitions);
|
|
||||||
setAvailableFilterDefinitions?.(companyTableFilterDefinitions);
|
|
||||||
setAvailableFieldDefinitions?.(companiesAvailableFieldDefinitions);
|
|
||||||
setViewObjectMetadataId?.('company');
|
|
||||||
setViewType?.(ViewType.Table);
|
|
||||||
|
|
||||||
setAvailableTableColumns(companiesAvailableFieldDefinitions);
|
|
||||||
}, [
|
|
||||||
setAvailableFieldDefinitions,
|
|
||||||
setAvailableFilterDefinitions,
|
|
||||||
setAvailableSortDefinitions,
|
|
||||||
setAvailableTableColumns,
|
|
||||||
setViewObjectMetadataId,
|
|
||||||
setViewType,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default CompanyTableEffect;
|
|
||||||
@ -1,17 +0,0 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
import { companiesAvailableFieldDefinitions } from '@/companies/constants/companiesAvailableFieldDefinitions';
|
|
||||||
import { useRecordTable } from '@/ui/object/record-table/hooks/useRecordTable';
|
|
||||||
|
|
||||||
import { mockedCompaniesData } from './companies-mock-data';
|
|
||||||
|
|
||||||
export const CompanyTableMockDataEffect = () => {
|
|
||||||
const { setRecordTableData, setTableColumns } = useRecordTable();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setRecordTableData(mockedCompaniesData);
|
|
||||||
setTableColumns(companiesAvailableFieldDefinitions);
|
|
||||||
}, [setRecordTableData, setTableColumns]);
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
};
|
|
||||||
@ -1,42 +0,0 @@
|
|||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
import { RecordTable } from '@/ui/object/record-table/components/RecordTable';
|
|
||||||
import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId';
|
|
||||||
import { TableOptionsDropdown } from '@/ui/object/record-table/options/components/TableOptionsDropdown';
|
|
||||||
import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
|
|
||||||
import { ViewBar } from '@/views/components/ViewBar';
|
|
||||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
|
||||||
import { useUpdateOneCompanyMutation } from '~/generated/graphql';
|
|
||||||
|
|
||||||
import CompanyTableEffect from './CompanyTableEffect';
|
|
||||||
import { CompanyTableMockDataEffect } from './CompanyTableMockDataEffect';
|
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
overflow: auto;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const CompanyTableMockMode = () => {
|
|
||||||
return (
|
|
||||||
<StyledContainer>
|
|
||||||
<ViewScope viewScopeId="company-table-mock-mode">
|
|
||||||
<RecordTableScope
|
|
||||||
recordTableScopeId="company-table-mock-mode-table"
|
|
||||||
onColumnsChange={() => {}}
|
|
||||||
onEntityCountChange={() => {}}
|
|
||||||
>
|
|
||||||
<CompanyTableEffect />
|
|
||||||
<CompanyTableMockDataEffect />
|
|
||||||
<ViewBar
|
|
||||||
optionsDropdownButton={<TableOptionsDropdown />}
|
|
||||||
optionsDropdownScopeId={TableOptionsDropdownId}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<RecordTable updateEntityMutation={useUpdateOneCompanyMutation} />
|
|
||||||
</RecordTableScope>
|
|
||||||
</ViewScope>
|
|
||||||
</StyledContainer>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
import { Favorite } from '@/favorites/types/Favorite';
|
|
||||||
import { WorkspaceMember } from '@/workspace-member/types/WorkspaceMember';
|
|
||||||
|
|
||||||
import { Company } from '../../../../generated/graphql';
|
|
||||||
|
|
||||||
type MockedCompany = Pick<
|
|
||||||
Company,
|
|
||||||
| 'id'
|
|
||||||
| 'name'
|
|
||||||
| 'domainName'
|
|
||||||
| '__typename'
|
|
||||||
| 'createdAt'
|
|
||||||
| 'address'
|
|
||||||
| 'employees'
|
|
||||||
| 'linkedinUrl'
|
|
||||||
| 'xUrl'
|
|
||||||
| 'annualRecurringRevenue'
|
|
||||||
| 'idealCustomerProfile'
|
|
||||||
| '_activityCount'
|
|
||||||
> & {
|
|
||||||
accountOwner: Pick<WorkspaceMember, 'id' | 'avatarUrl' | 'name'> | null;
|
|
||||||
} & { Favorite: Pick<Favorite, 'id'> | null };
|
|
||||||
|
|
||||||
export const mockedCompaniesData: Array<MockedCompany> = [
|
|
||||||
{
|
|
||||||
id: '89bb825c-171e-4bcc-9cf7-43448d6fb278',
|
|
||||||
domainName: 'airbnb.com',
|
|
||||||
name: 'Airbnb',
|
|
||||||
linkedinUrl: 'https://www.linkedin.com/company/airbnb/',
|
|
||||||
xUrl: 'https://twitter.com/airbnb',
|
|
||||||
annualRecurringRevenue: 500000,
|
|
||||||
idealCustomerProfile: true,
|
|
||||||
createdAt: '2023-04-26T10:08:54.724515+00:00',
|
|
||||||
address: 'San Francisco, CA',
|
|
||||||
employees: 5000,
|
|
||||||
Favorite: null,
|
|
||||||
_activityCount: 0,
|
|
||||||
accountOwner: {
|
|
||||||
name: {
|
|
||||||
firstName: 'Charles',
|
|
||||||
lastName: 'Test',
|
|
||||||
},
|
|
||||||
avatarUrl: null,
|
|
||||||
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b',
|
|
||||||
},
|
|
||||||
__typename: 'Company',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'b396e6b9-dc5c-4643-bcff-61b6cf7523ae',
|
|
||||||
domainName: 'qonto.com',
|
|
||||||
name: 'Qonto',
|
|
||||||
linkedinUrl: 'https://www.linkedin.com/company/qonto/',
|
|
||||||
xUrl: 'https://twitter.com/qonto',
|
|
||||||
annualRecurringRevenue: 500000,
|
|
||||||
idealCustomerProfile: false,
|
|
||||||
createdAt: '2023-04-26T10:12:42.33625+00:00',
|
|
||||||
address: 'Paris, France',
|
|
||||||
employees: 800,
|
|
||||||
Favorite: null,
|
|
||||||
_activityCount: 0,
|
|
||||||
accountOwner: null,
|
|
||||||
__typename: 'Company',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'a674fa6c-1455-4c57-afaf-dd5dc086361d',
|
|
||||||
domainName: 'stripe.com',
|
|
||||||
name: 'Stripe',
|
|
||||||
linkedinUrl: 'https://www.linkedin.com/company/stripe/',
|
|
||||||
xUrl: 'https://twitter.com/stripe',
|
|
||||||
annualRecurringRevenue: 5000000,
|
|
||||||
idealCustomerProfile: false,
|
|
||||||
createdAt: '2023-04-26T10:10:32.530184+00:00',
|
|
||||||
address: 'San Francisco, CA',
|
|
||||||
employees: 8000,
|
|
||||||
Favorite: null,
|
|
||||||
_activityCount: 0,
|
|
||||||
accountOwner: null,
|
|
||||||
__typename: 'Company',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'b1cfd51b-a831-455f-ba07-4e30671e1dc3',
|
|
||||||
domainName: 'figma.com',
|
|
||||||
linkedinUrl: 'https://www.linkedin.com/company/figma/',
|
|
||||||
xUrl: 'https://twitter.com/figma',
|
|
||||||
annualRecurringRevenue: 50000,
|
|
||||||
idealCustomerProfile: true,
|
|
||||||
name: 'Figma',
|
|
||||||
createdAt: '2023-03-21T06:30:25.39474+00:00',
|
|
||||||
address: 'San Francisco, CA',
|
|
||||||
employees: 800,
|
|
||||||
Favorite: null,
|
|
||||||
_activityCount: 0,
|
|
||||||
accountOwner: null,
|
|
||||||
__typename: 'Company',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: '5c21e19e-e049-4393-8c09-3e3f8fb09ecb',
|
|
||||||
domainName: 'notion.com',
|
|
||||||
linkedinUrl: 'https://www.linkedin.com/company/notion/',
|
|
||||||
xUrl: 'https://twitter.com/notion',
|
|
||||||
annualRecurringRevenue: 500000,
|
|
||||||
idealCustomerProfile: false,
|
|
||||||
name: 'Notion',
|
|
||||||
createdAt: '2023-04-26T10:13:29.712485+00:00',
|
|
||||||
address: 'San Francisco, CA',
|
|
||||||
employees: 400,
|
|
||||||
Favorite: null,
|
|
||||||
_activityCount: 0,
|
|
||||||
accountOwner: null,
|
|
||||||
__typename: 'Company',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
15
front/src/modules/companies/types/Company.ts
Normal file
15
front/src/modules/companies/types/Company.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export type Company = {
|
||||||
|
id: string;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
deletedAt: string | null;
|
||||||
|
name: string;
|
||||||
|
domainName: string;
|
||||||
|
address: string;
|
||||||
|
accountOwnerId: string | null;
|
||||||
|
linkedinUrl: { url: string; label: string };
|
||||||
|
xUrl: { url: string; label: string };
|
||||||
|
annualRecurringRevenue: { amountMicros: number | null; currencyCode: string };
|
||||||
|
employees: number | null;
|
||||||
|
idealCustomerProfile: boolean;
|
||||||
|
};
|
||||||
@ -1,5 +1,5 @@
|
|||||||
|
import { Company } from '@/companies/types/Company';
|
||||||
import { Opportunity } from '@/pipeline/types/Opportunity';
|
import { Opportunity } from '@/pipeline/types/Opportunity';
|
||||||
import { Company } from '~/generated/graphql';
|
|
||||||
|
|
||||||
export type CompanyForBoard = Pick<Company, 'id' | 'name' | 'domainName'>;
|
export type CompanyForBoard = Pick<Company, 'id' | 'name' | 'domainName'>;
|
||||||
export type PipelineProgressForBoard = Opportunity;
|
export type PipelineProgressForBoard = Opportunity;
|
||||||
|
|||||||
@ -18,7 +18,7 @@ const StyledContainer = styled.div`
|
|||||||
export const Favorites = () => {
|
export const Favorites = () => {
|
||||||
// This is only temporary and will be refactored once we have main identifiers
|
// This is only temporary and will be refactored once we have main identifiers
|
||||||
const { favorites, handleReorderFavorite } = useFavorites({
|
const { favorites, handleReorderFavorite } = useFavorites({
|
||||||
objectNamePlural: 'companiesV2',
|
objectNamePlural: 'companies',
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!favorites || favorites.length === 0) return <></>;
|
if (!favorites || favorites.length === 0) return <></>;
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const DELETE_FAVORITE = gql`
|
|
||||||
mutation DeleteFavorite($where: FavoriteWhereInput!) {
|
|
||||||
deleteFavorite(where: $where) {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const INSERT_COMPANY_FAVORITE = gql`
|
|
||||||
mutation InsertCompanyFavorite($data: FavoriteMutationForCompanyArgs!) {
|
|
||||||
createFavoriteForCompany(data: $data) {
|
|
||||||
id
|
|
||||||
company {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
domainName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const INSERT_PERSON_FAVORITE = gql`
|
|
||||||
mutation InsertPersonFavorite($data: FavoriteMutationForPersonArgs!) {
|
|
||||||
createFavoriteForPerson(data: $data) {
|
|
||||||
id
|
|
||||||
person {
|
|
||||||
id
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
displayName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const UPDATE_FAVORITE = gql`
|
|
||||||
mutation UpdateOneFavorite(
|
|
||||||
$data: FavoriteUpdateInput!
|
|
||||||
$where: FavoriteWhereUniqueInput!
|
|
||||||
) {
|
|
||||||
updateOneFavorites(data: $data, where: $where) {
|
|
||||||
id
|
|
||||||
person {
|
|
||||||
id
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
avatarUrl
|
|
||||||
}
|
|
||||||
company {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
domainName
|
|
||||||
accountOwner {
|
|
||||||
id
|
|
||||||
displayName
|
|
||||||
avatarUrl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
import { gql } from '@apollo/client';
|
|
||||||
|
|
||||||
export const GET_FAVORITES = gql`
|
|
||||||
query GetFavorites {
|
|
||||||
findFavorites {
|
|
||||||
id
|
|
||||||
position
|
|
||||||
person {
|
|
||||||
id
|
|
||||||
firstName
|
|
||||||
lastName
|
|
||||||
avatarUrl
|
|
||||||
}
|
|
||||||
company {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
domainName
|
|
||||||
accountOwner {
|
|
||||||
id
|
|
||||||
displayName
|
|
||||||
avatarUrl
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
@ -4,12 +4,12 @@ import { OnDragEndResponder } from '@hello-pangea/dnd';
|
|||||||
import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
|
import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||||
|
import { Company } from '@/companies/types/Company';
|
||||||
import { Favorite } from '@/favorites/types/Favorite';
|
import { Favorite } from '@/favorites/types/Favorite';
|
||||||
import { mapFavorites } from '@/favorites/utils/mapFavorites';
|
import { mapFavorites } from '@/favorites/utils/mapFavorites';
|
||||||
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
||||||
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
||||||
import { PaginatedObjectTypeResults } from '@/object-record/types/PaginatedObjectTypeResults';
|
import { PaginatedObjectTypeResults } from '@/object-record/types/PaginatedObjectTypeResults';
|
||||||
import { Company } from '~/generated/graphql';
|
|
||||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||||
|
|
||||||
import { favoritesState } from '../states/favoritesState';
|
import { favoritesState } from '../states/favoritesState';
|
||||||
@ -25,7 +25,7 @@ export const useFavorites = ({
|
|||||||
|
|
||||||
const { updateOneMutation, createOneMutation, deleteOneMutation } =
|
const { updateOneMutation, createOneMutation, deleteOneMutation } =
|
||||||
useFindOneObjectMetadataItem({
|
useFindOneObjectMetadataItem({
|
||||||
objectNamePlural: 'favoritesV2',
|
objectNamePlural: 'favorites',
|
||||||
});
|
});
|
||||||
|
|
||||||
const { foundObjectMetadataItem: favoriteTargetObjectMetadataItem } =
|
const { foundObjectMetadataItem: favoriteTargetObjectMetadataItem } =
|
||||||
@ -44,7 +44,7 @@ export const useFavorites = ({
|
|||||||
|
|
||||||
// This is only temporary and will be refactored once we have main identifiers
|
// This is only temporary and will be refactored once we have main identifiers
|
||||||
const { loading: companiesLoading } = useFindManyObjectRecords({
|
const { loading: companiesLoading } = useFindManyObjectRecords({
|
||||||
objectNamePlural: 'companiesV2',
|
objectNamePlural: 'companies',
|
||||||
onCompleted: async (
|
onCompleted: async (
|
||||||
data: PaginatedObjectTypeResults<Required<Company>>,
|
data: PaginatedObjectTypeResults<Required<Company>>,
|
||||||
) => {
|
) => {
|
||||||
@ -64,7 +64,7 @@ export const useFavorites = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const { loading: peopleLoading } = useFindManyObjectRecords({
|
const { loading: peopleLoading } = useFindManyObjectRecords({
|
||||||
objectNamePlural: 'peopleV2',
|
objectNamePlural: 'people',
|
||||||
onCompleted: async (data) => {
|
onCompleted: async (data) => {
|
||||||
setAllPeople(
|
setAllPeople(
|
||||||
data.edges.reduce(
|
data.edges.reduce(
|
||||||
@ -84,7 +84,7 @@ export const useFavorites = ({
|
|||||||
|
|
||||||
useFindManyObjectRecords({
|
useFindManyObjectRecords({
|
||||||
skip: companiesLoading || peopleLoading,
|
skip: companiesLoading || peopleLoading,
|
||||||
objectNamePlural: 'favoritesV2',
|
objectNamePlural: 'favorites',
|
||||||
onCompleted: useRecoilCallback(
|
onCompleted: useRecoilCallback(
|
||||||
({ snapshot, set }) =>
|
({ snapshot, set }) =>
|
||||||
async (data: PaginatedObjectTypeResults<Required<Favorite>>) => {
|
async (data: PaginatedObjectTypeResults<Required<Favorite>>) => {
|
||||||
@ -112,8 +112,7 @@ export const useFavorites = ({
|
|||||||
const favorites = snapshot.getLoadable(favoritesState).getValue();
|
const favorites = snapshot.getLoadable(favoritesState).getValue();
|
||||||
|
|
||||||
const targetObjectName =
|
const targetObjectName =
|
||||||
favoriteTargetObjectMetadataItem?.nameSingular.replace('V2', '') ??
|
favoriteTargetObjectMetadataItem?.nameSingular ?? '';
|
||||||
'';
|
|
||||||
|
|
||||||
const result = await apolloClient.mutate({
|
const result = await apolloClient.mutate({
|
||||||
mutation: createOneMutation,
|
mutation: createOneMutation,
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { Company, Person } from '~/generated/graphql';
|
import { Company } from '@/companies/types/Company';
|
||||||
|
import { Person } from '@/people/types/Person';
|
||||||
import { getLogoUrlFromDomainName } from '~/utils';
|
import { getLogoUrlFromDomainName } from '~/utils';
|
||||||
import { assertNotNull } from '~/utils/assert';
|
import { assertNotNull } from '~/utils/assert';
|
||||||
import { isDefined } from '~/utils/isDefined';
|
import { isDefined } from '~/utils/isDefined';
|
||||||
@ -7,8 +8,8 @@ export const mapFavorites = (
|
|||||||
favorites: any,
|
favorites: any,
|
||||||
recordsDict: {
|
recordsDict: {
|
||||||
[key: string]: {
|
[key: string]: {
|
||||||
firstName?: Person['firstName'];
|
firstName?: Person['name']['firstName'];
|
||||||
lastName?: Person['lastName'];
|
lastName?: Person['name']['lastName'];
|
||||||
avatarUrl?: Person['avatarUrl'];
|
avatarUrl?: Person['avatarUrl'];
|
||||||
name?: Company['name'];
|
name?: Company['name'];
|
||||||
domainName?: Company['domainName'];
|
domainName?: Company['domainName'];
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
import { useFindManyObjectMetadataItems } from '@/object-metadata/hooks/useFindManyObjectMetadataItems';
|
||||||
|
|
||||||
|
export const ObjectMetadataItemsProvider = ({
|
||||||
|
children,
|
||||||
|
}: React.PropsWithChildren) => {
|
||||||
|
const { loading } = useFindManyObjectMetadataItems();
|
||||||
|
|
||||||
|
return loading ? <></> : <>{children}</>;
|
||||||
|
};
|
||||||
@ -1,28 +1,19 @@
|
|||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
|
import { useObjectMetadataItemForSettings } from '@/object-metadata/hooks/useObjectMetadataItemForSettings';
|
||||||
import { Icon123 } from '@/ui/input/constants/icons';
|
import { Icon123 } from '@/ui/input/constants/icons';
|
||||||
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
|
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
|
||||||
import NavItem from '@/ui/navigation/navbar/components/NavItem';
|
import NavItem from '@/ui/navigation/navbar/components/NavItem';
|
||||||
|
|
||||||
import { useFindManyObjectMetadataItems } from '../hooks/useFindManyObjectMetadataItems';
|
|
||||||
|
|
||||||
export const ObjectMetadataNavItems = () => {
|
export const ObjectMetadataNavItems = () => {
|
||||||
const { objectMetadataItems } = useFindManyObjectMetadataItems({
|
const { activeObjectMetadataItems } = useObjectMetadataItemForSettings();
|
||||||
objectFilter: {
|
|
||||||
isSystem: { is: false },
|
|
||||||
},
|
|
||||||
fieldFilter: {
|
|
||||||
isSystem: { is: false },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { icons } = useLazyLoadIcons();
|
const { icons } = useLazyLoadIcons();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{objectMetadataItems.map((objectMetadataItem) => {
|
{activeObjectMetadataItems.map((objectMetadataItem) => {
|
||||||
if (objectMetadataItem.nameSingular === 'opportunityV2') return null;
|
if (objectMetadataItem.nameSingular === 'opportunity') return null;
|
||||||
return (
|
return (
|
||||||
<NavItem
|
<NavItem
|
||||||
key={objectMetadataItem.id}
|
key={objectMetadataItem.id}
|
||||||
|
|||||||
@ -0,0 +1,46 @@
|
|||||||
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
|
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
|
||||||
|
import { ColumnDefinition } from '@/ui/object/record-table/types/ColumnDefinition';
|
||||||
|
|
||||||
|
import { formatFieldMetadataItemAsColumnDefinition } from '../utils/formatFieldMetadataItemAsColumnDefinition';
|
||||||
|
import { formatFieldMetadataItemsAsFilterDefinitions } from '../utils/formatFieldMetadataItemsAsFilterDefinitions';
|
||||||
|
import { formatFieldMetadataItemsAsSortDefinitions } from '../utils/formatFieldMetadataItemsAsSortDefinitions';
|
||||||
|
|
||||||
|
export const useComputeDefinitionsFromFieldMetadata = (
|
||||||
|
objectMetadataItem?: ObjectMetadataItem,
|
||||||
|
) => {
|
||||||
|
if (!objectMetadataItem) {
|
||||||
|
return {
|
||||||
|
columnDefinitions: [],
|
||||||
|
filterDefinitions: [],
|
||||||
|
sortDefinitions: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const activeFieldMetadataItems = objectMetadataItem.fields.filter(
|
||||||
|
({ isActive }) => isActive,
|
||||||
|
);
|
||||||
|
|
||||||
|
const columnDefinitions: ColumnDefinition<FieldMetadata>[] =
|
||||||
|
activeFieldMetadataItems.map((field, index) =>
|
||||||
|
formatFieldMetadataItemAsColumnDefinition({
|
||||||
|
position: index,
|
||||||
|
field,
|
||||||
|
objectMetadataItem: objectMetadataItem,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const filterDefinitions = formatFieldMetadataItemsAsFilterDefinitions({
|
||||||
|
fields: activeFieldMetadataItems,
|
||||||
|
});
|
||||||
|
|
||||||
|
const sortDefinitions = formatFieldMetadataItemsAsSortDefinitions({
|
||||||
|
fields: activeFieldMetadataItems,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
columnDefinitions,
|
||||||
|
filterDefinitions,
|
||||||
|
sortDefinitions,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -5,14 +5,8 @@ import { useGenerateDeleteOneObjectMutation } from '@/object-record/utils/useGen
|
|||||||
import { useGenerateFindManyCustomObjectsQuery } from '@/object-record/utils/useGenerateFindManyCustomObjectsQuery';
|
import { useGenerateFindManyCustomObjectsQuery } from '@/object-record/utils/useGenerateFindManyCustomObjectsQuery';
|
||||||
import { useGenerateFindOneCustomObjectQuery } from '@/object-record/utils/useGenerateFindOneCustomObjectQuery';
|
import { useGenerateFindOneCustomObjectQuery } from '@/object-record/utils/useGenerateFindOneCustomObjectQuery';
|
||||||
import { useGenerateUpdateOneObjectMutation } from '@/object-record/utils/useGenerateUpdateOneObjectMutation';
|
import { useGenerateUpdateOneObjectMutation } from '@/object-record/utils/useGenerateUpdateOneObjectMutation';
|
||||||
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
|
|
||||||
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
|
|
||||||
import { ColumnDefinition } from '@/ui/object/record-table/types/ColumnDefinition';
|
|
||||||
|
|
||||||
import { ObjectMetadataItemIdentifier } from '../types/ObjectMetadataItemIdentifier';
|
import { ObjectMetadataItemIdentifier } from '../types/ObjectMetadataItemIdentifier';
|
||||||
import { formatFieldMetadataItemAsColumnDefinition } from '../utils/formatFieldMetadataItemAsColumnDefinition';
|
|
||||||
import { formatFieldMetadataItemsAsFilterDefinitions } from '../utils/formatFieldMetadataItemsAsFilterDefinitions';
|
|
||||||
import { formatFieldMetadataItemsAsSortDefinitions } from '../utils/formatFieldMetadataItemsAsSortDefinitions';
|
|
||||||
|
|
||||||
import { useFindManyObjectMetadataItems } from './useFindManyObjectMetadataItems';
|
import { useFindManyObjectMetadataItems } from './useFindManyObjectMetadataItems';
|
||||||
|
|
||||||
@ -43,37 +37,10 @@ export const useFindOneObjectMetadataItem = ({
|
|||||||
object.nameSingular === objectNameSingular,
|
object.nameSingular === objectNameSingular,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { icons } = useLazyLoadIcons();
|
|
||||||
|
|
||||||
const objectNotFoundInMetadata =
|
const objectNotFoundInMetadata =
|
||||||
objectMetadataItems.length === 0 ||
|
objectMetadataItems.length === 0 ||
|
||||||
(objectMetadataItems.length > 0 && !foundObjectMetadataItem);
|
(objectMetadataItems.length > 0 && !foundObjectMetadataItem);
|
||||||
|
|
||||||
const activeFields =
|
|
||||||
foundObjectMetadataItem?.fields.filter(({ isActive }) => isActive) ?? [];
|
|
||||||
|
|
||||||
const columnDefinitions: ColumnDefinition<FieldMetadata>[] =
|
|
||||||
foundObjectMetadataItem
|
|
||||||
? activeFields.map((field, index) =>
|
|
||||||
formatFieldMetadataItemAsColumnDefinition({
|
|
||||||
position: index,
|
|
||||||
field,
|
|
||||||
objectMetadataItem: foundObjectMetadataItem,
|
|
||||||
icons,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
: [];
|
|
||||||
|
|
||||||
const filterDefinitions = formatFieldMetadataItemsAsFilterDefinitions({
|
|
||||||
fields: activeFields,
|
|
||||||
icons,
|
|
||||||
});
|
|
||||||
|
|
||||||
const sortDefinitions = formatFieldMetadataItemsAsSortDefinitions({
|
|
||||||
fields: activeFields,
|
|
||||||
icons,
|
|
||||||
});
|
|
||||||
|
|
||||||
const findManyQuery = useGenerateFindManyCustomObjectsQuery({
|
const findManyQuery = useGenerateFindManyCustomObjectsQuery({
|
||||||
objectMetadataItem: foundObjectMetadataItem,
|
objectMetadataItem: foundObjectMetadataItem,
|
||||||
});
|
});
|
||||||
@ -97,9 +64,6 @@ export const useFindOneObjectMetadataItem = ({
|
|||||||
return {
|
return {
|
||||||
foundObjectMetadataItem,
|
foundObjectMetadataItem,
|
||||||
objectNotFoundInMetadata,
|
objectNotFoundInMetadata,
|
||||||
columnDefinitions,
|
|
||||||
filterDefinitions,
|
|
||||||
sortDefinitions,
|
|
||||||
findManyQuery,
|
findManyQuery,
|
||||||
findOneQuery,
|
findOneQuery,
|
||||||
createOneMutation,
|
createOneMutation,
|
||||||
|
|||||||
@ -8,20 +8,13 @@ import { useFindManyObjectMetadataItems } from './useFindManyObjectMetadataItems
|
|||||||
import { useUpdateOneObjectMetadataItem } from './useUpdateOneObjectMetadataItem';
|
import { useUpdateOneObjectMetadataItem } from './useUpdateOneObjectMetadataItem';
|
||||||
|
|
||||||
export const useObjectMetadataItemForSettings = () => {
|
export const useObjectMetadataItemForSettings = () => {
|
||||||
const { objectMetadataItems, loading } = useFindManyObjectMetadataItems({
|
const { objectMetadataItems, loading } = useFindManyObjectMetadataItems();
|
||||||
objectFilter: {
|
|
||||||
isSystem: { is: false },
|
|
||||||
},
|
|
||||||
fieldFilter: {
|
|
||||||
isSystem: { is: false },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const activeObjectMetadataItems = objectMetadataItems.filter(
|
const activeObjectMetadataItems = objectMetadataItems.filter(
|
||||||
({ isActive }) => isActive,
|
({ isActive, isSystem }) => isActive && !isSystem,
|
||||||
);
|
);
|
||||||
const disabledObjectMetadataItems = objectMetadataItems.filter(
|
const disabledObjectMetadataItems = objectMetadataItems.filter(
|
||||||
({ isActive }) => !isActive,
|
({ isActive, isSystem }) => !isActive && !isSystem,
|
||||||
);
|
);
|
||||||
|
|
||||||
const findActiveObjectMetadataItemBySlug = (slug: string) =>
|
const findActiveObjectMetadataItemBySlug = (slug: string) =>
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
import { atom } from 'recoil';
|
|
||||||
|
|
||||||
import { ObjectMetadataItem } from '../types/ObjectMetadataItem';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use `useFindManyObjectMetadataItems` instead.
|
|
||||||
*/
|
|
||||||
export const objectMetadataItemsState = atom<ObjectMetadataItem[]>({
|
|
||||||
key: 'objectMetadataItemsState',
|
|
||||||
default: [],
|
|
||||||
});
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { selector } from 'recoil';
|
|
||||||
|
|
||||||
import { ObjectMetadataItem } from '../../types/ObjectMetadataItem';
|
|
||||||
import { objectMetadataItemsState } from '../objectMetadataItemsState';
|
|
||||||
|
|
||||||
export const activeObjectMetadataItemsSelector = selector<ObjectMetadataItem[]>(
|
|
||||||
{
|
|
||||||
key: 'activeObjectMetadataItemsSelector',
|
|
||||||
get: ({ get }) =>
|
|
||||||
get(objectMetadataItemsState).filter(({ isActive }) => isActive),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { selector } from 'recoil';
|
|
||||||
|
|
||||||
import { ObjectMetadataItem } from '../../types/ObjectMetadataItem';
|
|
||||||
import { objectMetadataItemsState } from '../objectMetadataItemsState';
|
|
||||||
|
|
||||||
export const disabledObjectMetadataItemsSelector = selector<
|
|
||||||
ObjectMetadataItem[]
|
|
||||||
>({
|
|
||||||
key: 'disabledObjectMetadataItemsSelector',
|
|
||||||
get: ({ get }) =>
|
|
||||||
get(objectMetadataItemsState).filter(({ isActive }) => !isActive),
|
|
||||||
});
|
|
||||||
@ -1,5 +1,4 @@
|
|||||||
import { parseFieldRelationType } from '@/object-metadata/utils/parseFieldRelationType';
|
import { parseFieldRelationType } from '@/object-metadata/utils/parseFieldRelationType';
|
||||||
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
|
|
||||||
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
|
import { FieldMetadata } from '@/ui/object/field/types/FieldMetadata';
|
||||||
import { ColumnDefinition } from '@/ui/object/record-table/types/ColumnDefinition';
|
import { ColumnDefinition } from '@/ui/object/record-table/types/ColumnDefinition';
|
||||||
|
|
||||||
@ -12,12 +11,10 @@ export const formatFieldMetadataItemAsColumnDefinition = ({
|
|||||||
position,
|
position,
|
||||||
field,
|
field,
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
icons,
|
|
||||||
}: {
|
}: {
|
||||||
position: number;
|
position: number;
|
||||||
field: FieldMetadataItem;
|
field: FieldMetadataItem;
|
||||||
objectMetadataItem: Omit<ObjectMetadataItem, 'fields'>;
|
objectMetadataItem: Omit<ObjectMetadataItem, 'fields'>;
|
||||||
icons: Record<string, IconComponent>;
|
|
||||||
}): ColumnDefinition<FieldMetadata> => ({
|
}): ColumnDefinition<FieldMetadata> => ({
|
||||||
position,
|
position,
|
||||||
fieldMetadataId: field.id,
|
fieldMetadataId: field.id,
|
||||||
@ -28,7 +25,7 @@ export const formatFieldMetadataItemAsColumnDefinition = ({
|
|||||||
fieldName: field.name,
|
fieldName: field.name,
|
||||||
placeHolder: field.label,
|
placeHolder: field.label,
|
||||||
},
|
},
|
||||||
Icon: icons[field.icon ?? 'Icon123'],
|
iconName: field.icon ?? 'Icon123',
|
||||||
isVisible: true,
|
isVisible: true,
|
||||||
basePathToShowPage: `/object/${objectMetadataItem.nameSingular}/`,
|
basePathToShowPage: `/object/${objectMetadataItem.nameSingular}/`,
|
||||||
relationType: parseFieldRelationType(field),
|
relationType: parseFieldRelationType(field),
|
||||||
|
|||||||
@ -5,10 +5,8 @@ import { ObjectMetadataItem } from '../types/ObjectMetadataItem';
|
|||||||
|
|
||||||
export const formatFieldMetadataItemsAsFilterDefinitions = ({
|
export const formatFieldMetadataItemsAsFilterDefinitions = ({
|
||||||
fields,
|
fields,
|
||||||
icons,
|
|
||||||
}: {
|
}: {
|
||||||
fields: Array<ObjectMetadataItem['fields'][0]>;
|
fields: Array<ObjectMetadataItem['fields'][0]>;
|
||||||
icons: Record<string, any>;
|
|
||||||
}): FilterDefinition[] =>
|
}): FilterDefinition[] =>
|
||||||
fields.reduce((acc, field) => {
|
fields.reduce((acc, field) => {
|
||||||
if (
|
if (
|
||||||
@ -20,22 +18,17 @@ export const formatFieldMetadataItemsAsFilterDefinitions = ({
|
|||||||
) {
|
) {
|
||||||
return acc;
|
return acc;
|
||||||
}
|
}
|
||||||
return [
|
return [...acc, formatFieldMetadataItemAsFilterDefinition({ field })];
|
||||||
...acc,
|
|
||||||
formatFieldMetadataItemAsFilterDefinition({ field, icons }),
|
|
||||||
];
|
|
||||||
}, [] as FilterDefinition[]);
|
}, [] as FilterDefinition[]);
|
||||||
|
|
||||||
const formatFieldMetadataItemAsFilterDefinition = ({
|
const formatFieldMetadataItemAsFilterDefinition = ({
|
||||||
field,
|
field,
|
||||||
icons,
|
|
||||||
}: {
|
}: {
|
||||||
field: ObjectMetadataItem['fields'][0];
|
field: ObjectMetadataItem['fields'][0];
|
||||||
icons: Record<string, any>;
|
|
||||||
}): FilterDefinition => ({
|
}): FilterDefinition => ({
|
||||||
fieldMetadataId: field.id,
|
fieldMetadataId: field.id,
|
||||||
label: field.label,
|
label: field.label,
|
||||||
Icon: icons[field.icon ?? 'Icon123'],
|
iconName: field.icon ?? 'Icon123',
|
||||||
type:
|
type:
|
||||||
field.type === FieldMetadataType.Date
|
field.type === FieldMetadataType.Date
|
||||||
? 'DATE'
|
? 'DATE'
|
||||||
|
|||||||
@ -5,10 +5,8 @@ import { ObjectMetadataItem } from '../types/ObjectMetadataItem';
|
|||||||
|
|
||||||
export const formatFieldMetadataItemsAsSortDefinitions = ({
|
export const formatFieldMetadataItemsAsSortDefinitions = ({
|
||||||
fields,
|
fields,
|
||||||
icons,
|
|
||||||
}: {
|
}: {
|
||||||
fields: Array<ObjectMetadataItem['fields'][0]>;
|
fields: Array<ObjectMetadataItem['fields'][0]>;
|
||||||
icons: Record<string, any>;
|
|
||||||
}): SortDefinition[] =>
|
}): SortDefinition[] =>
|
||||||
fields.reduce((acc, field) => {
|
fields.reduce((acc, field) => {
|
||||||
if (
|
if (
|
||||||
@ -27,7 +25,7 @@ export const formatFieldMetadataItemsAsSortDefinitions = ({
|
|||||||
{
|
{
|
||||||
fieldMetadataId: field.id,
|
fieldMetadataId: field.id,
|
||||||
label: field.label,
|
label: field.label,
|
||||||
Icon: icons[field.icon ?? 'Icon123'],
|
iconName: field.icon ?? 'Icon123',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}, [] as SortDefinition[]);
|
}, [] as SortDefinition[]);
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOne
|
|||||||
import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition';
|
import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition';
|
||||||
import { filterAvailableFieldMetadataItem } from '@/object-record/utils/filterAvailableFieldMetadataItem';
|
import { filterAvailableFieldMetadataItem } from '@/object-record/utils/filterAvailableFieldMetadataItem';
|
||||||
import { IconBuildingSkyscraper } from '@/ui/display/icon';
|
import { IconBuildingSkyscraper } from '@/ui/display/icon';
|
||||||
import { useLazyLoadIcons } from '@/ui/input/hooks/useLazyLoadIcons';
|
|
||||||
import { PageBody } from '@/ui/layout/page/PageBody';
|
import { PageBody } from '@/ui/layout/page/PageBody';
|
||||||
import { PageContainer } from '@/ui/layout/page/PageContainer';
|
import { PageContainer } from '@/ui/layout/page/PageContainer';
|
||||||
import { PageFavoriteButton } from '@/ui/layout/page/PageFavoriteButton';
|
import { PageFavoriteButton } from '@/ui/layout/page/PageFavoriteButton';
|
||||||
@ -36,8 +35,6 @@ export const RecordShowPage = () => {
|
|||||||
objectMetadataId: string;
|
objectMetadataId: string;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const { icons } = useLazyLoadIcons();
|
|
||||||
|
|
||||||
const { foundObjectMetadataItem } = useFindOneObjectMetadataItem({
|
const { foundObjectMetadataItem } = useFindOneObjectMetadataItem({
|
||||||
objectNameSingular,
|
objectNameSingular,
|
||||||
});
|
});
|
||||||
@ -91,7 +88,7 @@ export const RecordShowPage = () => {
|
|||||||
if (isFavorite) deleteFavorite(object?.id);
|
if (isFavorite) deleteFavorite(object?.id);
|
||||||
else {
|
else {
|
||||||
const additionalData =
|
const additionalData =
|
||||||
objectNameSingular === 'personV2'
|
objectNameSingular === 'person'
|
||||||
? {
|
? {
|
||||||
labelIdentifier:
|
labelIdentifier:
|
||||||
object.name.firstName + ' ' + object.name.lastName,
|
object.name.firstName + ' ' + object.name.lastName,
|
||||||
@ -100,7 +97,7 @@ export const RecordShowPage = () => {
|
|||||||
link: `/object/personV2/${object.id}`,
|
link: `/object/personV2/${object.id}`,
|
||||||
recordId: object.id,
|
recordId: object.id,
|
||||||
}
|
}
|
||||||
: objectNameSingular === 'companyV2'
|
: objectNameSingular === 'company'
|
||||||
? {
|
? {
|
||||||
labelIdentifier: object.name,
|
labelIdentifier: object.name,
|
||||||
avatarUrl: getLogoUrlFromDomainName(object.domainName ?? ''),
|
avatarUrl: getLogoUrlFromDomainName(object.domainName ?? ''),
|
||||||
@ -116,7 +113,7 @@ export const RecordShowPage = () => {
|
|||||||
if (!object) return <></>;
|
if (!object) return <></>;
|
||||||
|
|
||||||
const pageName =
|
const pageName =
|
||||||
objectNameSingular === 'personV2'
|
objectNameSingular === 'person'
|
||||||
? object.name.firstName + ' ' + object.name.lastName
|
? object.name.firstName + ' ' + object.name.lastName
|
||||||
: object.name;
|
: object.name;
|
||||||
|
|
||||||
@ -173,7 +170,6 @@ export const RecordShowPage = () => {
|
|||||||
field: metadataField,
|
field: metadataField,
|
||||||
position: index,
|
position: index,
|
||||||
objectMetadataItem: foundObjectMetadataItem,
|
objectMetadataItem: foundObjectMetadataItem,
|
||||||
icons,
|
|
||||||
}),
|
}),
|
||||||
useUpdateEntityMutation: useUpdateOneObjectMutation,
|
useUpdateEntityMutation: useUpdateOneObjectMutation,
|
||||||
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
hotkeyScope: InlineCellHotkeyScope.InlineCell,
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRecoilCallback } from 'recoil';
|
import { useRecoilCallback } from 'recoil';
|
||||||
|
|
||||||
|
import { useComputeDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useComputeDefinitionsFromFieldMetadata';
|
||||||
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
||||||
import { RecordTable } from '@/ui/object/record-table/components/RecordTable';
|
import { RecordTable } from '@/ui/object/record-table/components/RecordTable';
|
||||||
import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId';
|
import { TableOptionsDropdownId } from '@/ui/object/record-table/constants/TableOptionsDropdownId';
|
||||||
@ -9,7 +10,6 @@ import { TableOptionsDropdown } from '@/ui/object/record-table/options/component
|
|||||||
import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
|
import { RecordTableScope } from '@/ui/object/record-table/scopes/RecordTableScope';
|
||||||
import { ViewBar } from '@/views/components/ViewBar';
|
import { ViewBar } from '@/views/components/ViewBar';
|
||||||
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
import { useViewFields } from '@/views/hooks/internal/useViewFields';
|
||||||
import { useView } from '@/views/hooks/useView';
|
|
||||||
import { ViewScope } from '@/views/scopes/ViewScope';
|
import { ViewScope } from '@/views/scopes/ViewScope';
|
||||||
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
|
import { mapColumnDefinitionsToViewFields } from '@/views/utils/mapColumnDefinitionToViewField';
|
||||||
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
|
import { mapViewFieldsToColumnDefinitions } from '@/views/utils/mapViewFieldsToColumnDefinitions';
|
||||||
@ -32,10 +32,12 @@ export const RecordTableContainer = ({
|
|||||||
}: {
|
}: {
|
||||||
objectNamePlural: string;
|
objectNamePlural: string;
|
||||||
}) => {
|
}) => {
|
||||||
const { columnDefinitions, foundObjectMetadataItem } =
|
const { foundObjectMetadataItem } = useFindOneObjectMetadataItem({
|
||||||
useFindOneObjectMetadataItem({
|
objectNamePlural,
|
||||||
objectNamePlural,
|
});
|
||||||
});
|
const { columnDefinitions } = useComputeDefinitionsFromFieldMetadata(
|
||||||
|
foundObjectMetadataItem,
|
||||||
|
);
|
||||||
|
|
||||||
const { updateOneObject } = useUpdateOneObjectRecord({
|
const { updateOneObject } = useUpdateOneObjectRecord({
|
||||||
objectNameSingular: foundObjectMetadataItem?.nameSingular,
|
objectNameSingular: foundObjectMetadataItem?.nameSingular,
|
||||||
@ -50,8 +52,6 @@ export const RecordTableContainer = ({
|
|||||||
recordTableScopeId: tableScopeId,
|
recordTableScopeId: tableScopeId,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { setEntityCountInCurrentView } = useView({ viewScopeId });
|
|
||||||
|
|
||||||
const updateEntity = ({
|
const updateEntity = ({
|
||||||
variables,
|
variables,
|
||||||
}: {
|
}: {
|
||||||
@ -89,9 +89,6 @@ export const RecordTableContainer = ({
|
|||||||
onColumnsChange={useRecoilCallback(() => (columns) => {
|
onColumnsChange={useRecoilCallback(() => (columns) => {
|
||||||
persistViewFields(mapColumnDefinitionsToViewFields(columns));
|
persistViewFields(mapColumnDefinitionsToViewFields(columns));
|
||||||
})}
|
})}
|
||||||
onEntityCountChange={(entityCount) => {
|
|
||||||
setEntityCountInCurrentView(entityCount);
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<ViewBar
|
<ViewBar
|
||||||
optionsDropdownButton={<TableOptionsDropdown />}
|
optionsDropdownButton={<TableOptionsDropdown />}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
|
import { useComputeDefinitionsFromFieldMetadata } from '@/object-metadata/hooks/useComputeDefinitionsFromFieldMetadata';
|
||||||
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
import { useFindOneObjectMetadataItem } from '@/object-metadata/hooks/useFindOneObjectMetadataItem';
|
||||||
import { useRecordTableContextMenuEntries } from '@/object-record/hooks/useRecordTableContextMenuEntries';
|
import { useRecordTableContextMenuEntries } from '@/object-record/hooks/useRecordTableContextMenuEntries';
|
||||||
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
|
import { filterAvailableTableColumns } from '@/object-record/utils/filterAvailableTableColumns';
|
||||||
@ -8,24 +9,26 @@ import { useView } from '@/views/hooks/useView';
|
|||||||
import { ViewType } from '@/views/types/ViewType';
|
import { ViewType } from '@/views/types/ViewType';
|
||||||
|
|
||||||
export const RecordTableEffect = () => {
|
export const RecordTableEffect = () => {
|
||||||
const { scopeId: objectNamePlural, setAvailableTableColumns } =
|
|
||||||
useRecordTable();
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
columnDefinitions,
|
scopeId: objectNamePlural,
|
||||||
filterDefinitions,
|
setAvailableTableColumns,
|
||||||
sortDefinitions,
|
setOnEntityCountChange,
|
||||||
foundObjectMetadataItem,
|
} = useRecordTable();
|
||||||
} = useFindOneObjectMetadataItem({
|
|
||||||
|
const { foundObjectMetadataItem } = useFindOneObjectMetadataItem({
|
||||||
objectNamePlural,
|
objectNamePlural,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { columnDefinitions, filterDefinitions, sortDefinitions } =
|
||||||
|
useComputeDefinitionsFromFieldMetadata(foundObjectMetadataItem);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
setAvailableSortDefinitions,
|
setAvailableSortDefinitions,
|
||||||
setAvailableFilterDefinitions,
|
setAvailableFilterDefinitions,
|
||||||
setAvailableFieldDefinitions,
|
setAvailableFieldDefinitions,
|
||||||
setViewType,
|
setViewType,
|
||||||
setViewObjectMetadataId,
|
setViewObjectMetadataId,
|
||||||
|
setEntityCountInCurrentView,
|
||||||
} = useView();
|
} = useView();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -65,5 +68,11 @@ export const RecordTableEffect = () => {
|
|||||||
setContextMenuEntries?.();
|
setContextMenuEntries?.();
|
||||||
}, [setActionBarEntries, setContextMenuEntries]);
|
}, [setActionBarEntries, setContextMenuEntries]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setOnEntityCountChange(
|
||||||
|
() => (entityCount: number) => setEntityCountInCurrentView(entityCount),
|
||||||
|
);
|
||||||
|
}, [setEntityCountInCurrentView, setOnEntityCountChange]);
|
||||||
|
|
||||||
return <></>;
|
return <></>;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import { RecordTableContainer } from './RecordTableContainer';
|
|||||||
|
|
||||||
const StyledTableContainer = styled.div`
|
const StyledTableContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -48,7 +49,8 @@ export const RecordTablePage = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleAddButtonClick = async () => {
|
const handleAddButtonClick = async () => {
|
||||||
createOneObject?.({});
|
const createdObject = await createOneObject?.({});
|
||||||
|
console.log(createdObject);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { gql } from '@apollo/client';
|
import { gql } from '@apollo/client';
|
||||||
|
|
||||||
export const CREATE_ONE_WORKSPACE_MEMBER_V2 = gql`
|
export const CREATE_ONE_WORKSPACE_MEMBER_V2 = gql`
|
||||||
mutation CreateOneWorkspaceMemberV2($input: WorkspaceMemberV2CreateInput!) {
|
mutation CreateOneWorkspaceMember($input: WorkspaceMemberCreateInput!) {
|
||||||
createWorkspaceMemberV2(data: $input) {
|
createWorkspaceMember(data: $input) {
|
||||||
id
|
id
|
||||||
name {
|
name {
|
||||||
firstName
|
firstName
|
||||||
|
|||||||
@ -23,6 +23,17 @@ export const getRecordOptimisticEffectDefinition = ({
|
|||||||
const newRecordPaginatedCacheField = produce<
|
const newRecordPaginatedCacheField = produce<
|
||||||
PaginatedObjectTypeResults<any>
|
PaginatedObjectTypeResults<any>
|
||||||
>(currentData as PaginatedObjectTypeResults<any>, (draft) => {
|
>(currentData as PaginatedObjectTypeResults<any>, (draft) => {
|
||||||
|
if (!draft) {
|
||||||
|
return {
|
||||||
|
edges: [{ node: newData, cursor: '' }],
|
||||||
|
pageInfo: {
|
||||||
|
endCursor: '',
|
||||||
|
hasNextPage: false,
|
||||||
|
hasPreviousPage: false,
|
||||||
|
startCursor: '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
draft.edges.unshift({ node: newData, cursor: '' });
|
draft.edges.unshift({ node: newData, cursor: '' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user