diff --git a/.ergomake/docker-compose.yml b/.ergomake/docker-compose.yml new file mode 100644 index 0000000000000..f657ad711c30f --- /dev/null +++ b/.ergomake/docker-compose.yml @@ -0,0 +1,36 @@ +version: "3.9" +services: + front: + build: + context: .. + dockerfile: ./infra/prod/front/Dockerfile + args: + REACT_APP_SERVER_BASE_URL: "http://localhost:3000" + ports: + - "3001:3000" + labels: + dev.ergomake.env.replace-arg.REACT_APP_SERVER_BASE_URL: "https://{{ services.server.url }}" + server: + build: + context: .. + dockerfile: ./infra/prod/server/Dockerfile + command: sh -c "yarn prisma migrate reset --force && node dist/src/main" + ports: + - "3000:3000" + environment: + DEBUG_MODE: false + SIGN_IN_PREFILLED: true + ACCESS_TOKEN_SECRET: "secret_jwt" + LOGIN_TOKEN_SECRET: "secret_login_token" + REFRESH_TOKEN_SECRET: "secret_refresh_token" + PG_DATABASE_URL: "postgres://postgres:postgrespassword@postgres:5432/default?connection_limit=1" + FRONT_BASE_URL: "http://localhost:3000" + labels: + dev.ergomake.env.replace-env.FRONT_BASE_URL: "https://{{ services.server.url }}" + postgres: + build: ../infra/dev/postgres + environment: + POSTGRES_PASSWORD: postgrespassword + ports: + - "5432" + diff --git a/.github/workflows/ci-chromatic.yaml b/.github/workflows/ci-chromatic.yaml index fec4c44918e82..16cabdcaaac34 100644 --- a/.github/workflows/ci-chromatic.yaml +++ b/.github/workflows/ci-chromatic.yaml @@ -5,13 +5,13 @@ on: branches: - main pull_request_target: + types: [labeled] jobs: chromatic-deployment: + if: ${{ contains(github.event.*.labels.*.name, 'run-chromatic') }} || github.event_name == 'push' }} runs-on: ubuntu-latest env: - REACT_APP_API_URL: http://127.0.0.1:3000/graphql - REACT_APP_AUTH_URL: http://127.0.0.1:3000/auth - REACT_APP_FILES_URL: http://127.0.0.1:3000/files + REACT_APP_SERVER_BASE_URL: http://127.0.0.1:3000 steps: - uses: actions/checkout@v3 if: github.event_name == 'push' @@ -31,9 +31,7 @@ jobs: run: | cd front touch .env - echo "REACT_APP_API_URL: $REACT_APP_API_URL" >> .env - echo "REACT_APP_AUTH_URL: $REACT_APP_AUTH_URL" >> .env - echo "REACT_APP_FILES_URL: $REACT_APP_FILES_URL" >> .env + echo "REACT_APP_SERVER_BASE_URL: $REACT_APP_SERVER_BASE_URL" >> .env - name: Front / Install Dependencies run: cd front && yarn - name: Publish to Chromatic diff --git a/.github/workflows/ci-front.yaml b/.github/workflows/ci-front.yaml index 76eb041fb886d..a5b149a5d817c 100644 --- a/.github/workflows/ci-front.yaml +++ b/.github/workflows/ci-front.yaml @@ -8,9 +8,7 @@ jobs: front-test: runs-on: ubuntu-latest env: - REACT_APP_API_URL: http://localhost:3000/graphql - REACT_APP_AUTH_URL: http://localhost:3000/auth - REACT_APP_FILES_URL: http://localhost:3000/files + REACT_APP_SERVER_BASE_URL: http://localhost:3000 steps: - uses: actions/checkout@v3 if: github.event_name == 'push' diff --git a/.github/workflows/ci-server.yaml b/.github/workflows/ci-server.yaml index 82c24cac9a8e6..34a79899ee0a7 100644 --- a/.github/workflows/ci-server.yaml +++ b/.github/workflows/ci-server.yaml @@ -7,6 +7,21 @@ on: jobs: server-test: runs-on: ubuntu-latest + services: + postgres: + image: postgres + env: + POSTGRES_HOST: postgres + POSTGRES_PASSWORD: postgrespassword + POSTGRES_DB: test + POSTGRES_PORT: 5432 + ports: + - 5432:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 steps: - uses: actions/checkout@v3 if: github.event_name == 'push' @@ -27,3 +42,6 @@ jobs: - name: Server / Run jest tests run: | cd server && yarn test + - name: Server / Run e2e tests + run: | + cd server && yarn test:e2e diff --git a/docs/docs/developer/local-setup.mdx b/docs/docs/developer/local-setup.mdx index 4f4cf2ef669e8..5a096f42b995d 100644 --- a/docs/docs/developer/local-setup.mdx +++ b/docs/docs/developer/local-setup.mdx @@ -1,7 +1,7 @@ --- sidebar_position: 0 sidebar_custom_props: - icon: TbArrowBigRight + icon: TbDeviceDesktop --- # Local Setup @@ -157,16 +157,14 @@ make server-prisma-reset ### 6. Start Twenty -Run the project with the following commands: +Run the project with the following commands from `root folder`: -In `/front`: ```bash -make front-start +make server-start ``` -In `/server`: ```bash -make server-start +make front-start ``` You should now have: diff --git a/docs/docs/hosting/self-hosting.mdx b/docs/docs/hosting/self-hosting.mdx index cb15efdcb88e6..6b48e5adc2b76 100644 --- a/docs/docs/hosting/self-hosting.mdx +++ b/docs/docs/hosting/self-hosting.mdx @@ -19,9 +19,7 @@ You will find these in the [infra/prod/front/Dockerfile](https://github.com/twen ```bash docker build \ - --build-arg REACT_APP_API_URL=REPLACE_ME \ - --build-arg REACT_APP_AUTH_URL=REPLACE_ME \ - --build-arg REACT_APP_FILES_URL=REPLACE_ME \ + --build-arg REACT_APP_SERVER_BASE_URL=REPLACE_ME \ -t twenty-front:latest \ -f ./infra/prod/front/Dockerfile . ``` @@ -36,10 +34,19 @@ docker build \ -f ./infra/prod/server/Dockerfile . ``` +## Render + +[![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/twentyhq/twenty) + + ## AWS Elastic Beanstalk (soon) We are working on providing a joint Docker image - containing both the Twenty frontend and server - that you can deploy using [AWS Elastic Beanstalk](https://aws.amazon.com/elasticbeanstalk/). -## Railway (soon) -[Railway](https://railway.app) is an infrastructure platform that lets you deploy to the cloud in one click. We are currently working on making it available. \ No newline at end of file + \ No newline at end of file diff --git a/docs/docs/others/CLI.mdx b/docs/docs/others/CLI.mdx index 0279037d64239..275e8024c8987 100644 --- a/docs/docs/others/CLI.mdx +++ b/docs/docs/others/CLI.mdx @@ -4,6 +4,6 @@ sidebar_custom_props: icon: TbTerminal2 --- -# CLI (soon) +# CLI Available soon! \ No newline at end of file diff --git a/docs/src/theme/DocSidebarItem/Link/index.js b/docs/src/theme/DocSidebarItem/Link/index.js index aaa820801cb23..5cc231aeed94c 100644 --- a/docs/src/theme/DocSidebarItem/Link/index.js +++ b/docs/src/theme/DocSidebarItem/Link/index.js @@ -6,7 +6,7 @@ import Link from '@docusaurus/Link'; import isInternalUrl from '@docusaurus/isInternalUrl'; import IconExternalLink from '@theme/Icon/ExternalLink'; import styles from './styles.module.css'; -import { TbFaceIdError, TbTerminal2, TbCloud, TbServer, TbBolt, TbApps, TbTopologyStar, TbChartDots, TbBug, TbVocabulary, TbArrowBigRight } from "react-icons/tb"; +import { TbFaceIdError, TbTerminal2, TbCloud, TbServer, TbBolt, TbApps, TbTopologyStar, TbChartDots, TbBug, TbVocabulary, TbArrowBigRight, TbDeviceDesktop } from "react-icons/tb"; export default function DocSidebarItemLink({ @@ -30,7 +30,8 @@ export default function DocSidebarItemLink({ 'TbTopologyStar': TbTopologyStar, 'TbChartDots': TbChartDots, 'TbBug': TbBug, - 'TbVocabulary': TbVocabulary + 'TbVocabulary': TbVocabulary, + 'TbDeviceDesktop': TbDeviceDesktop, }; let IconComponent = customProps && customProps.icon ? icons[customProps.icon] : TbFaceIdError; diff --git a/front/.env.example b/front/.env.example index 33094934828b3..02a33b5371a22 100644 --- a/front/.env.example +++ b/front/.env.example @@ -1,5 +1,6 @@ -REACT_APP_API_URL=http://localhost:3000/graphql -REACT_APP_AUTH_URL=http://localhost:3000/auth -REACT_APP_FILES_URL=http://localhost:3000/files +REACT_APP_SERVER_BASE_URL=http://localhost:3000 -CHROMATIC_PROJECT_TOKEN=REPLACE_ME \ No newline at end of file +# ———————— Optional ———————— +# REACT_APP_SERVER_AUTH_URL=http://localhost:3000/auth +# REACT_APP_SERVER_FILES_URL=http://localhost:3000/files +# CHROMATIC_PROJECT_TOKEN= diff --git a/front/.nvmrc b/front/.nvmrc index 807e541706b0c..3c79f30eca253 100644 --- a/front/.nvmrc +++ b/front/.nvmrc @@ -1 +1 @@ -18.6.0 \ No newline at end of file +18.16.0 \ No newline at end of file diff --git a/front/.storybook/preview.ts b/front/.storybook/preview.ts index 70e33a8a66c2f..56edada6c0f66 100644 --- a/front/.storybook/preview.ts +++ b/front/.storybook/preview.ts @@ -2,7 +2,7 @@ import { initialize, mswDecorator } from 'msw-storybook-addon'; import { Preview } from '@storybook/react'; import { ThemeProvider } from '@emotion/react'; import { withThemeFromJSXProvider } from '@storybook/addon-styling'; -import { lightTheme, darkTheme } from '../src/modules/ui/themes/themes'; +import { lightTheme, darkTheme } from '../src/modules/ui/theme/constants/theme'; import { RootDecorator } from '../src/testing/decorators/RootDecorator'; import 'react-loading-skeleton/dist/skeleton.css'; import { mockedUserJWT } from '../src/testing/mock-data/jwt'; diff --git a/front/codegen.js b/front/codegen.js index 3d41513711033..818affe05a6fb 100644 --- a/front/codegen.js +++ b/front/codegen.js @@ -1,5 +1,5 @@ module.exports = { - schema: process.env.REACT_APP_API_URL, + schema: process.env.REACT_APP_SERVER_BASE_URL + "/graphql", documents: ['./src/**/*.tsx', './src/**/*.ts'], overwrite: true, generates: { diff --git a/front/package.json b/front/package.json index 9f2d671f7ee96..7b17a8f2812c3 100644 --- a/front/package.json +++ b/front/package.json @@ -167,8 +167,8 @@ "workerDirectory": "public" }, "nyc": { - "statements": 70, - "lines": 70, + "statements": 65, + "lines": 65, "functions": 60, "exclude": [ "src/generated/**/*" diff --git a/front/src/App.tsx b/front/src/App.tsx index aaeedffd77189..609aa1c41b6ae 100644 --- a/front/src/App.tsx +++ b/front/src/App.tsx @@ -5,9 +5,11 @@ import { SettingsPath } from '@/types/SettingsPath'; import { DefaultLayout } from '@/ui/layout/components/DefaultLayout'; import { CreateProfile } from '~/pages/auth/CreateProfile'; import { CreateWorkspace } from '~/pages/auth/CreateWorkspace'; +import { SignInUp } from '~/pages/auth/SignInUp'; import { Verify } from '~/pages/auth/Verify'; import { Companies } from '~/pages/companies/Companies'; import { CompanyShow } from '~/pages/companies/CompanyShow'; +import { Impersonate } from '~/pages/impersonate/Impersonate'; import { Opportunities } from '~/pages/opportunities/Opportunities'; import { People } from '~/pages/people/People'; import { PersonShow } from '~/pages/people/PersonShow'; @@ -15,9 +17,11 @@ import { SettingsExperience } from '~/pages/settings/SettingsExperience'; import { SettingsProfile } from '~/pages/settings/SettingsProfile'; import { SettingsWorksapce } from '~/pages/settings/SettingsWorkspace'; import { SettingsWorkspaceMembers } from '~/pages/settings/SettingsWorkspaceMembers'; +import { Tasks } from '~/pages/tasks/Tasks'; import { AppInternalHooks } from '~/sync-hooks/AppInternalHooks'; -import { SignInUp } from './pages/auth/SignInUp'; +// TEMP FEATURE FLAG FOR VIEW FIELDS +export const ACTIVATE_VIEW_FIELDS = true; export function App() { return ( @@ -36,6 +40,8 @@ export function App() { } /> } /> } /> + } /> + } /> } /> + } + /> + + >; + assignee?: Maybe; + assigneeId?: Maybe; + attachments?: Maybe>; + author: User; + authorId: Scalars['String']; + body?: Maybe; + comments?: Maybe>; + completedAt?: Maybe; + createdAt: Scalars['DateTime']; + dueAt?: Maybe; + id: Scalars['ID']; + reminderAt?: Maybe; + title?: Maybe; + type: ActivityType; + updatedAt: Scalars['DateTime']; +}; + +export type ActivityCreateInput = { + activityTargets?: InputMaybe; + assignee?: InputMaybe; + attachments?: InputMaybe; + author: UserCreateNestedOneWithoutAuthoredActivitiesInput; + body?: InputMaybe; + comments?: InputMaybe; + completedAt?: InputMaybe; + createdAt?: InputMaybe; + dueAt?: InputMaybe; + id?: InputMaybe; + reminderAt?: InputMaybe; + title?: InputMaybe; + type?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityCreateNestedOneWithoutActivityTargetsInput = { + connect?: InputMaybe; +}; + +export type ActivityCreateNestedOneWithoutCommentsInput = { + connect?: InputMaybe; +}; + +export type ActivityListRelationFilter = { + every?: InputMaybe; + none?: InputMaybe; + some?: InputMaybe; +}; + +export type ActivityOrderByRelationAggregateInput = { + _count?: InputMaybe; +}; + +export type ActivityOrderByWithRelationInput = { + activityTargets?: InputMaybe; + assignee?: InputMaybe; + assigneeId?: InputMaybe; + attachments?: InputMaybe; + author?: InputMaybe; + authorId?: InputMaybe; + body?: InputMaybe; + comments?: InputMaybe; + completedAt?: InputMaybe; + createdAt?: InputMaybe; + dueAt?: InputMaybe; + id?: InputMaybe; + reminderAt?: InputMaybe; + title?: InputMaybe; + type?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityRelationFilter = { + is?: InputMaybe; + isNot?: InputMaybe; +}; + +export enum ActivityScalarFieldEnum { + AssigneeId = 'assigneeId', + AuthorId = 'authorId', + Body = 'body', + CompletedAt = 'completedAt', + CreatedAt = 'createdAt', + DeletedAt = 'deletedAt', + DueAt = 'dueAt', + Id = 'id', + ReminderAt = 'reminderAt', + Title = 'title', + Type = 'type', + UpdatedAt = 'updatedAt', + WorkspaceId = 'workspaceId' +} + +export type ActivityTarget = { + __typename?: 'ActivityTarget'; + activity: Activity; + activityId: Scalars['String']; + commentableId?: Maybe; + commentableType?: Maybe; + company?: Maybe; + companyId?: Maybe; + createdAt: Scalars['DateTime']; + id: Scalars['ID']; + person?: Maybe; + personId?: Maybe; + updatedAt: Scalars['DateTime']; +}; + +export type ActivityTargetCreateManyActivityInput = { + commentableId?: InputMaybe; + commentableType?: InputMaybe; + companyId?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + personId?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityTargetCreateManyActivityInputEnvelope = { + data: Array; + skipDuplicates?: InputMaybe; +}; + +export type ActivityTargetCreateManyCompanyInput = { + activityId: Scalars['String']; + commentableId?: InputMaybe; + commentableType?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + personId?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityTargetCreateManyCompanyInputEnvelope = { + data: Array; + skipDuplicates?: InputMaybe; +}; + +export type ActivityTargetCreateManyPersonInput = { + activityId: Scalars['String']; + commentableId?: InputMaybe; + commentableType?: InputMaybe; + companyId?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityTargetCreateManyPersonInputEnvelope = { + data: Array; + skipDuplicates?: InputMaybe; +}; + +export type ActivityTargetCreateManyWorkspaceInput = { + activityId: Scalars['String']; + commentableId?: InputMaybe; + commentableType?: InputMaybe; + companyId?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + personId?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityTargetCreateManyWorkspaceInputEnvelope = { + data: Array; + skipDuplicates?: InputMaybe; +}; + +export type ActivityTargetCreateNestedManyWithoutActivityInput = { + connect?: InputMaybe>; + connectOrCreate?: InputMaybe>; + create?: InputMaybe>; + createMany?: InputMaybe; +}; + +export type ActivityTargetCreateNestedManyWithoutCompanyInput = { + connect?: InputMaybe>; + connectOrCreate?: InputMaybe>; + create?: InputMaybe>; + createMany?: InputMaybe; +}; + +export type ActivityTargetCreateNestedManyWithoutPersonInput = { + connect?: InputMaybe>; + connectOrCreate?: InputMaybe>; + create?: InputMaybe>; + createMany?: InputMaybe; +}; + +export type ActivityTargetCreateOrConnectWithoutActivityInput = { + create: ActivityTargetCreateWithoutActivityInput; + where: ActivityTargetWhereUniqueInput; +}; + +export type ActivityTargetCreateOrConnectWithoutCompanyInput = { + create: ActivityTargetCreateWithoutCompanyInput; + where: ActivityTargetWhereUniqueInput; +}; + +export type ActivityTargetCreateOrConnectWithoutPersonInput = { + create: ActivityTargetCreateWithoutPersonInput; + where: ActivityTargetWhereUniqueInput; +}; + +export type ActivityTargetCreateOrConnectWithoutWorkspaceInput = { + create: ActivityTargetCreateWithoutWorkspaceInput; + where: ActivityTargetWhereUniqueInput; +}; + +export type ActivityTargetCreateWithoutActivityInput = { + commentableId?: InputMaybe; + commentableType?: InputMaybe; + company?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + person?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityTargetCreateWithoutCompanyInput = { + activity: ActivityCreateNestedOneWithoutActivityTargetsInput; + commentableId?: InputMaybe; + commentableType?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + person?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityTargetCreateWithoutPersonInput = { + activity: ActivityCreateNestedOneWithoutActivityTargetsInput; + commentableId?: InputMaybe; + commentableType?: InputMaybe; + company?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityTargetCreateWithoutWorkspaceInput = { + activity: ActivityCreateNestedOneWithoutActivityTargetsInput; + commentableId?: InputMaybe; + commentableType?: InputMaybe; + company?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + person?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityTargetListRelationFilter = { + every?: InputMaybe; + none?: InputMaybe; + some?: InputMaybe; +}; + +export type ActivityTargetOrderByRelationAggregateInput = { + _count?: InputMaybe; +}; + +export type ActivityTargetScalarWhereInput = { + AND?: InputMaybe>; + NOT?: InputMaybe>; + OR?: InputMaybe>; + activityId?: InputMaybe; + commentableId?: InputMaybe; + commentableType?: InputMaybe; + companyId?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + personId?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityTargetUpdateManyWithoutActivityNestedInput = { + connect?: InputMaybe>; + connectOrCreate?: InputMaybe>; + create?: InputMaybe>; + createMany?: InputMaybe; + delete?: InputMaybe>; + deleteMany?: InputMaybe>; + disconnect?: InputMaybe>; + set?: InputMaybe>; +}; + +export type ActivityTargetUpdateManyWithoutCompanyNestedInput = { + connect?: InputMaybe>; + connectOrCreate?: InputMaybe>; + create?: InputMaybe>; + createMany?: InputMaybe; + delete?: InputMaybe>; + deleteMany?: InputMaybe>; + disconnect?: InputMaybe>; + set?: InputMaybe>; +}; + +export type ActivityTargetUpdateManyWithoutPersonNestedInput = { + connect?: InputMaybe>; + connectOrCreate?: InputMaybe>; + create?: InputMaybe>; + createMany?: InputMaybe; + delete?: InputMaybe>; + deleteMany?: InputMaybe>; + disconnect?: InputMaybe>; + set?: InputMaybe>; +}; + +export type ActivityTargetUpdateManyWithoutWorkspaceNestedInput = { + connect?: InputMaybe>; + connectOrCreate?: InputMaybe>; + create?: InputMaybe>; + createMany?: InputMaybe; + delete?: InputMaybe>; + deleteMany?: InputMaybe>; + disconnect?: InputMaybe>; + set?: InputMaybe>; +}; + +export type ActivityTargetWhereInput = { + AND?: InputMaybe>; + NOT?: InputMaybe>; + OR?: InputMaybe>; + activity?: InputMaybe; + activityId?: InputMaybe; + commentableId?: InputMaybe; + commentableType?: InputMaybe; + company?: InputMaybe; + companyId?: InputMaybe; + createdAt?: InputMaybe; + id?: InputMaybe; + person?: InputMaybe; + personId?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityTargetWhereUniqueInput = { + id?: InputMaybe; +}; + export enum ActivityType { Note = 'Note', Task = 'Task' } +export type ActivityUpdateInput = { + activityTargets?: InputMaybe; + assignee?: InputMaybe; + attachments?: InputMaybe; + author?: InputMaybe; + body?: InputMaybe; + comments?: InputMaybe; + completedAt?: InputMaybe; + createdAt?: InputMaybe; + dueAt?: InputMaybe; + id?: InputMaybe; + reminderAt?: InputMaybe; + title?: InputMaybe; + type?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityUpdateManyWithoutAssigneeNestedInput = { + connect?: InputMaybe>; + disconnect?: InputMaybe>; + set?: InputMaybe>; +}; + +export type ActivityUpdateManyWithoutAuthorNestedInput = { + connect?: InputMaybe>; + disconnect?: InputMaybe>; + set?: InputMaybe>; +}; + +export type ActivityUpdateManyWithoutWorkspaceNestedInput = { + connect?: InputMaybe>; + disconnect?: InputMaybe>; + set?: InputMaybe>; +}; + +export type ActivityWhereInput = { + AND?: InputMaybe>; + NOT?: InputMaybe>; + OR?: InputMaybe>; + activityTargets?: InputMaybe; + assignee?: InputMaybe; + assigneeId?: InputMaybe; + attachments?: InputMaybe; + author?: InputMaybe; + authorId?: InputMaybe; + body?: InputMaybe; + comments?: InputMaybe; + completedAt?: InputMaybe; + createdAt?: InputMaybe; + dueAt?: InputMaybe; + id?: InputMaybe; + reminderAt?: InputMaybe; + title?: InputMaybe; + type?: InputMaybe; + updatedAt?: InputMaybe; +}; + +export type ActivityWhereUniqueInput = { + id?: InputMaybe; +}; + export type AffectedRows = { __typename?: 'AffectedRows'; count: Scalars['Int']; @@ -36,7 +439,7 @@ export type Analytics = { export type Attachment = { __typename?: 'Attachment'; - activity: CommentThread; + activity: Activity; activityId: Scalars['String']; author: User; authorId: Scalars['String']; @@ -95,7 +498,7 @@ export type AttachmentWhereInput = { AND?: InputMaybe>; NOT?: InputMaybe>; OR?: InputMaybe>; - activity?: InputMaybe; + activity?: InputMaybe; activityId?: InputMaybe; author?: InputMaybe; authorId?: InputMaybe; @@ -144,7 +547,7 @@ export type ClientConfig = { __typename?: 'ClientConfig'; authProviders: AuthProviders; debugMode: Scalars['Boolean']; - demoMode: Scalars['Boolean']; + signInPrefilled: Scalars['Boolean']; telemetry: Telemetry; }; @@ -156,26 +559,28 @@ export enum ColorScheme { export type Comment = { __typename?: 'Comment'; + activity?: Maybe; + activityId?: Maybe; author: User; authorId: Scalars['String']; body: Scalars['String']; - commentThread: CommentThread; - commentThreadId: Scalars['String']; + commentThreadId?: Maybe; createdAt: Scalars['DateTime']; id: Scalars['ID']; updatedAt: Scalars['DateTime']; }; export type CommentCreateInput = { + activity?: InputMaybe; author: UserCreateNestedOneWithoutCommentsInput; body: Scalars['String']; - commentThread: CommentThreadCreateNestedOneWithoutCommentsInput; + commentThreadId?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; updatedAt?: InputMaybe; }; -export type CommentCreateNestedManyWithoutCommentThreadInput = { +export type CommentCreateNestedManyWithoutActivityInput = { connect?: InputMaybe>; }; @@ -485,7 +890,7 @@ export type CommentUpdateManyWithoutAuthorNestedInput = { set?: InputMaybe>; }; -export type CommentUpdateManyWithoutCommentThreadNestedInput = { +export type CommentUpdateManyWithoutAuthorNestedInput = { connect?: InputMaybe>; disconnect?: InputMaybe>; set?: InputMaybe>; @@ -501,11 +906,12 @@ export type CommentWhereInput = { AND?: InputMaybe>; NOT?: InputMaybe>; OR?: InputMaybe>; + activity?: InputMaybe; + activityId?: InputMaybe; author?: InputMaybe; authorId?: InputMaybe; body?: InputMaybe; - commentThread?: InputMaybe; - commentThreadId?: InputMaybe; + commentThreadId?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; updatedAt?: InputMaybe; @@ -524,10 +930,15 @@ export type Company = { __typename?: 'Company'; Favorite?: Maybe>; _commentThreadCount: Scalars['Int']; + ActivityTarget?: Maybe>; + PipelineProgress?: Maybe>; + _activityCount: Scalars['Int']; + Favorite?: Maybe>; + _commentThreadCount: Scalars['Int']; accountOwner?: Maybe; accountOwnerId?: Maybe; + activities: Array; address: Scalars['String']; - commentThreads: Array; comments: Array; createdAt: Scalars['DateTime']; domainName: Scalars['String']; @@ -540,6 +951,9 @@ export type Company = { }; export type CompanyCreateInput = { + Favorite?: InputMaybe; + ActivityTarget?: InputMaybe; + PipelineProgress?: InputMaybe; Favorite?: InputMaybe; accountOwner?: InputMaybe; address: Scalars['String']; @@ -553,10 +967,18 @@ export type CompanyCreateInput = { updatedAt?: InputMaybe; }; +export type CompanyCreateNestedOneWithoutActivityTargetInput = { + connect?: InputMaybe; +}; + export type CompanyCreateNestedOneWithoutPeopleInput = { connect?: InputMaybe; }; +export type CompanyCreateNestedOneWithoutPipelineProgressInput = { + connect?: InputMaybe; +}; + export type CompanyListRelationFilter = { every?: InputMaybe; none?: InputMaybe; @@ -568,6 +990,9 @@ export type CompanyOrderByRelationAggregateInput = { }; export type CompanyOrderByWithRelationInput = { + Favorite?: InputMaybe; + ActivityTarget?: InputMaybe; + PipelineProgress?: InputMaybe; Favorite?: InputMaybe; accountOwner?: InputMaybe; accountOwnerId?: InputMaybe; @@ -602,6 +1027,9 @@ export enum CompanyScalarFieldEnum { } export type CompanyUpdateInput = { + Favorite?: InputMaybe; + ActivityTarget?: InputMaybe; + PipelineProgress?: InputMaybe; Favorite?: InputMaybe; accountOwner?: InputMaybe; address?: InputMaybe; @@ -632,11 +1060,19 @@ export type CompanyUpdateOneWithoutPeopleNestedInput = { disconnect?: InputMaybe; }; +export type CompanyUpdateOneWithoutPipelineProgressNestedInput = { + connect?: InputMaybe; + disconnect?: InputMaybe; +}; + export type CompanyWhereInput = { AND?: InputMaybe>; Favorite?: InputMaybe; + ActivityTarget?: InputMaybe; + Favorite?: InputMaybe; NOT?: InputMaybe>; OR?: InputMaybe>; + PipelineProgress?: InputMaybe; accountOwner?: InputMaybe; accountOwnerId?: InputMaybe; address?: InputMaybe; @@ -697,10 +1133,10 @@ export type EnumColorSchemeFilter = { notIn?: InputMaybe>; }; -export type EnumCommentableTypeFilter = { +export type EnumCommentableTypeNullableFilter = { equals?: InputMaybe; in?: InputMaybe>; - not?: InputMaybe; + not?: InputMaybe; notIn?: InputMaybe>; }; @@ -789,6 +1225,17 @@ export enum FileFolder { WorkspaceLogo = 'WorkspaceLogo' } +export type IntFilter = { + equals?: InputMaybe; + gt?: InputMaybe; + gte?: InputMaybe; + in?: InputMaybe>; + lt?: InputMaybe; + lte?: InputMaybe; + not?: InputMaybe; + notIn?: InputMaybe>; +}; + export type IntNullableFilter = { equals?: InputMaybe; gt?: InputMaybe; @@ -823,26 +1270,33 @@ export type LoginToken = { export type Mutation = { __typename?: 'Mutation'; + allowImpersonation: WorkspaceMember; challenge: LoginToken; createEvent: Analytics; createFavorites: Array; + createManyViewField: AffectedRows; + createOneActivity: Activity; + createFavorites: Array; createOneComment: Comment; - createOneCommentThread: CommentThread; createOneCompany: Company; createOnePerson: Person; createOnePipelineProgress: PipelineProgress; - deleteManyCommentThreads: AffectedRows; + deleteCurrentWorkspace: Workspace; + deleteManyActivities: AffectedRows; deleteManyCompany: AffectedRows; deleteManyPerson: AffectedRows; deleteManyPipelineProgress: AffectedRows; + deleteUserAccount: User; deleteWorkspaceMember: WorkspaceMember; + impersonate: Verify; renewToken: AuthTokens; signUp: LoginToken; - updateOneCommentThread: CommentThread; + updateOneActivity: Activity; updateOneCompany?: Maybe; updateOnePerson?: Maybe; updateOnePipelineProgress?: Maybe; updateOnePipelineStage?: Maybe; + updateOneViewField: ViewField; updateUser: User; updateWorkspace: Workspace; uploadAttachment: Scalars['String']; @@ -854,6 +1308,11 @@ export type Mutation = { }; +export type MutationAllowImpersonationArgs = { + allowImpersonation: Scalars['Boolean']; +}; + + export type MutationChallengeArgs = { email: Scalars['String']; password: Scalars['String']; @@ -868,17 +1327,33 @@ export type MutationCreateEventArgs = { export type MutationCreateFavoritesArgs = { data: Array; +} +export type MutationCreateManyViewFieldArgs = { + data: Array; skipDuplicates?: InputMaybe; -}; +} + +export type MutationCreateFavoritesArgs = { + data: Array; + skipDuplicates?: InputMaybe; +}; + +export type MutationCreateOneCommentArgs = { + data: CommentCreateInput; +}; export type MutationCreateOneCommentArgs = { data: CommentCreateInput; +} + +export type MutationCreateOneActivityArgs = { + data: ActivityCreateInput; }; -export type MutationCreateOneCommentThreadArgs = { - data: CommentThreadCreateInput; +export type MutationCreateOneCommentArgs = { + data: CommentCreateInput; }; @@ -897,8 +1372,8 @@ export type MutationCreateOnePipelineProgressArgs = { }; -export type MutationDeleteManyCommentThreadsArgs = { - where?: InputMaybe; +export type MutationDeleteManyActivitiesArgs = { + where?: InputMaybe; }; @@ -922,6 +1397,11 @@ export type MutationDeleteWorkspaceMemberArgs = { }; +export type MutationImpersonateArgs = { + userId: Scalars['String']; +}; + + export type MutationRenewTokenArgs = { refreshToken: Scalars['String']; }; @@ -934,9 +1414,9 @@ export type MutationSignUpArgs = { }; -export type MutationUpdateOneCommentThreadArgs = { - data: CommentThreadUpdateInput; - where: CommentThreadWhereUniqueInput; +export type MutationUpdateOneActivityArgs = { + data: ActivityUpdateInput; + where: ActivityWhereUniqueInput; }; @@ -964,6 +1444,12 @@ export type MutationUpdateOnePipelineStageArgs = { }; +export type MutationUpdateOneViewFieldArgs = { + data: ViewFieldUpdateInput; + where: ViewFieldWhereUniqueInput; +}; + + export type MutationUpdateUserArgs = { data: UserUpdateInput; where: UserWhereUniqueInput; @@ -1055,10 +1541,10 @@ export type NestedEnumColorSchemeFilter = { notIn?: InputMaybe>; }; -export type NestedEnumCommentableTypeFilter = { +export type NestedEnumCommentableTypeNullableFilter = { equals?: InputMaybe; in?: InputMaybe>; - not?: InputMaybe; + not?: InputMaybe; notIn?: InputMaybe>; }; @@ -1069,6 +1555,17 @@ export type NestedEnumPipelineProgressableTypeFilter = { notIn?: InputMaybe>; }; +export type NestedIntFilter = { + equals?: InputMaybe; + gt?: InputMaybe; + gte?: InputMaybe; + in?: InputMaybe>; + lt?: InputMaybe; + lte?: InputMaybe; + not?: InputMaybe; + notIn?: InputMaybe>; +}; + export type NestedIntNullableFilter = { equals?: InputMaybe; gt?: InputMaybe; @@ -1112,11 +1609,18 @@ export type Person = { __typename?: 'Person'; Favorite?: Maybe>; _commentThreadCount: Scalars['Int']; + ActivityTarget?: Maybe>; + PipelineProgress?: Maybe>; + _activityCount: Scalars['Int']; + activities: Array; + avatarUrl?: Maybe; + Favorite?: Maybe>; + _commentThreadCount: Scalars['Int']; city?: Maybe; - commentThreads: Array; comments: Array; company?: Maybe; companyId?: Maybe; + contactPipelineProgresses?: Maybe>; createdAt: Scalars['DateTime']; displayName: Scalars['String']; email?: Maybe; @@ -1126,14 +1630,18 @@ export type Person = { lastName?: Maybe; linkedinUrl?: Maybe; phone?: Maybe; - pipelineProgresses?: Maybe>; updatedAt: Scalars['DateTime']; }; export type PersonCreateInput = { + Favorite?: InputMaybe; + ActivityTarget?: InputMaybe; + PipelineProgress?: InputMaybe; + avatarUrl?: InputMaybe; Favorite?: InputMaybe; city?: InputMaybe; company?: InputMaybe; + contactPipelineProgresses?: InputMaybe; createdAt?: InputMaybe; email?: InputMaybe; firstName?: InputMaybe; @@ -1142,7 +1650,6 @@ export type PersonCreateInput = { lastName?: InputMaybe; linkedinUrl?: InputMaybe; phone?: InputMaybe; - pipelineProgresses?: InputMaybe; updatedAt?: InputMaybe; }; @@ -1150,7 +1657,15 @@ export type PersonCreateNestedManyWithoutCompanyInput = { connect?: InputMaybe>; }; -export type PersonCreateNestedOneWithoutPipelineProgressesInput = { +export type PersonCreateNestedOneWithoutActivityTargetInput = { + connect?: InputMaybe; +}; + +export type PersonCreateNestedOneWithoutContactPipelineProgressesInput = { + connect?: InputMaybe; +}; + +export type PersonCreateNestedOneWithoutPipelineProgressInput = { connect?: InputMaybe; }; @@ -1165,10 +1680,15 @@ export type PersonOrderByRelationAggregateInput = { }; export type PersonOrderByWithRelationInput = { + Favorite?: InputMaybe; + ActivityTarget?: InputMaybe; + PipelineProgress?: InputMaybe; + avatarUrl?: InputMaybe; Favorite?: InputMaybe; city?: InputMaybe; company?: InputMaybe; companyId?: InputMaybe; + contactPipelineProgresses?: InputMaybe; createdAt?: InputMaybe; email?: InputMaybe; firstName?: InputMaybe; @@ -1177,7 +1697,6 @@ export type PersonOrderByWithRelationInput = { lastName?: InputMaybe; linkedinUrl?: InputMaybe; phone?: InputMaybe; - pipelineProgresses?: InputMaybe; updatedAt?: InputMaybe; }; @@ -1187,6 +1706,7 @@ export type PersonRelationFilter = { }; export enum PersonScalarFieldEnum { + AvatarUrl = 'avatarUrl', City = 'city', CompanyId = 'companyId', CreatedAt = 'createdAt', @@ -1203,9 +1723,14 @@ export enum PersonScalarFieldEnum { } export type PersonUpdateInput = { + Favorite?: InputMaybe; + ActivityTarget?: InputMaybe; + PipelineProgress?: InputMaybe; + avatarUrl?: InputMaybe; Favorite?: InputMaybe; city?: InputMaybe; company?: InputMaybe; + contactPipelineProgresses?: InputMaybe; createdAt?: InputMaybe; email?: InputMaybe; firstName?: InputMaybe; @@ -1214,7 +1739,6 @@ export type PersonUpdateInput = { lastName?: InputMaybe; linkedinUrl?: InputMaybe; phone?: InputMaybe; - pipelineProgresses?: InputMaybe; updatedAt?: InputMaybe; }; @@ -1230,7 +1754,12 @@ export type PersonUpdateManyWithoutWorkspaceNestedInput = { set?: InputMaybe>; }; -export type PersonUpdateOneWithoutPipelineProgressesNestedInput = { +export type PersonUpdateOneWithoutContactPipelineProgressesNestedInput = { + connect?: InputMaybe; + disconnect?: InputMaybe; +}; + +export type PersonUpdateOneWithoutPipelineProgressNestedInput = { connect?: InputMaybe; disconnect?: InputMaybe; }; @@ -1238,11 +1767,16 @@ export type PersonUpdateOneWithoutPipelineProgressesNestedInput = { export type PersonWhereInput = { AND?: InputMaybe>; Favorite?: InputMaybe; + ActivityTarget?: InputMaybe; + Favorite?: InputMaybe; NOT?: InputMaybe>; OR?: InputMaybe>; + PipelineProgress?: InputMaybe; + avatarUrl?: InputMaybe; city?: InputMaybe; company?: InputMaybe; companyId?: InputMaybe; + contactPipelineProgresses?: InputMaybe; createdAt?: InputMaybe; email?: InputMaybe; firstName?: InputMaybe; @@ -1251,7 +1785,6 @@ export type PersonWhereInput = { lastName?: InputMaybe; linkedinUrl?: InputMaybe; phone?: InputMaybe; - pipelineProgresses?: InputMaybe; updatedAt?: InputMaybe; }; @@ -1290,8 +1823,12 @@ export type PipelineProgress = { __typename?: 'PipelineProgress'; amount?: Maybe; closeDate?: Maybe; + company?: Maybe; + companyId?: Maybe; createdAt: Scalars['DateTime']; id: Scalars['ID']; + person?: Maybe; + personId?: Maybe; pipeline: Pipeline; pipelineId: Scalars['String']; pipelineStage: PipelineStage; @@ -1299,25 +1836,31 @@ export type PipelineProgress = { pointOfContact?: Maybe; pointOfContactId?: Maybe; probability?: Maybe; - progressableId: Scalars['String']; - progressableType: PipelineProgressableType; updatedAt: Scalars['DateTime']; }; export type PipelineProgressCreateInput = { amount?: InputMaybe; closeDate?: InputMaybe; + company?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; + person?: InputMaybe; pipeline: PipelineCreateNestedOneWithoutPipelineProgressesInput; pipelineStage: PipelineStageCreateNestedOneWithoutPipelineProgressesInput; - pointOfContact?: InputMaybe; + pointOfContact?: InputMaybe; probability?: InputMaybe; - progressableId: Scalars['String']; - progressableType: PipelineProgressableType; updatedAt?: InputMaybe; }; +export type PipelineProgressCreateNestedManyWithoutCompanyInput = { + connect?: InputMaybe>; +}; + +export type PipelineProgressCreateNestedManyWithoutPersonInput = { + connect?: InputMaybe>; +}; + export type PipelineProgressCreateNestedManyWithoutPointOfContactInput = { connect?: InputMaybe>; }; @@ -1335,8 +1878,12 @@ export type PipelineProgressOrderByRelationAggregateInput = { export type PipelineProgressOrderByWithRelationInput = { amount?: InputMaybe; closeDate?: InputMaybe; + company?: InputMaybe; + companyId?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; + person?: InputMaybe; + personId?: InputMaybe; pipeline?: InputMaybe; pipelineId?: InputMaybe; pipelineStage?: InputMaybe; @@ -1344,23 +1891,21 @@ export type PipelineProgressOrderByWithRelationInput = { pointOfContact?: InputMaybe; pointOfContactId?: InputMaybe; probability?: InputMaybe; - progressableId?: InputMaybe; - progressableType?: InputMaybe; updatedAt?: InputMaybe; }; export enum PipelineProgressScalarFieldEnum { Amount = 'amount', CloseDate = 'closeDate', + CompanyId = 'companyId', CreatedAt = 'createdAt', DeletedAt = 'deletedAt', Id = 'id', + PersonId = 'personId', PipelineId = 'pipelineId', PipelineStageId = 'pipelineStageId', PointOfContactId = 'pointOfContactId', Probability = 'probability', - ProgressableId = 'progressableId', - ProgressableType = 'progressableType', UpdatedAt = 'updatedAt', WorkspaceId = 'workspaceId' } @@ -1368,17 +1913,29 @@ export enum PipelineProgressScalarFieldEnum { export type PipelineProgressUpdateInput = { amount?: InputMaybe; closeDate?: InputMaybe; + company?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; + person?: InputMaybe; pipeline?: InputMaybe; pipelineStage?: InputMaybe; - pointOfContact?: InputMaybe; + pointOfContact?: InputMaybe; probability?: InputMaybe; - progressableId?: InputMaybe; - progressableType?: InputMaybe; updatedAt?: InputMaybe; }; +export type PipelineProgressUpdateManyWithoutCompanyNestedInput = { + connect?: InputMaybe>; + disconnect?: InputMaybe>; + set?: InputMaybe>; +}; + +export type PipelineProgressUpdateManyWithoutPersonNestedInput = { + connect?: InputMaybe>; + disconnect?: InputMaybe>; + set?: InputMaybe>; +}; + export type PipelineProgressUpdateManyWithoutPipelineStageNestedInput = { connect?: InputMaybe>; disconnect?: InputMaybe>; @@ -1403,8 +1960,12 @@ export type PipelineProgressWhereInput = { OR?: InputMaybe>; amount?: InputMaybe; closeDate?: InputMaybe; + company?: InputMaybe; + companyId?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; + person?: InputMaybe; + personId?: InputMaybe; pipeline?: InputMaybe; pipelineId?: InputMaybe; pipelineStage?: InputMaybe; @@ -1412,8 +1973,6 @@ export type PipelineProgressWhereInput = { pointOfContact?: InputMaybe; pointOfContactId?: InputMaybe; probability?: InputMaybe; - progressableId?: InputMaybe; - progressableType?: InputMaybe; updatedAt?: InputMaybe; }; @@ -1584,12 +2143,16 @@ export type Query = { currentWorkspace: Workspace; findFavorites: Array; findManyCommentThreads: Array; + findManyActivities: Array; + findFavorites: Array; + findManyCommentThreads: Array; findManyCompany: Array; findManyPerson: Array; findManyPipeline: Array; findManyPipelineProgress: Array; findManyPipelineStage: Array; findManyUser: Array; + findManyViewField: Array; findManyWorkspaceMember: Array; findUniqueCompany: Company; findUniquePerson: Person; @@ -1606,13 +2169,13 @@ export type QueryCheckWorkspaceInviteHashIsValidArgs = { }; -export type QueryFindManyCommentThreadsArgs = { - cursor?: InputMaybe; - distinct?: InputMaybe>; - orderBy?: InputMaybe>; +export type QueryFindManyActivitiesArgs = { + cursor?: InputMaybe; + distinct?: InputMaybe>; + orderBy?: InputMaybe>; skip?: InputMaybe; take?: InputMaybe; - where?: InputMaybe; + where?: InputMaybe; }; @@ -1676,6 +2239,16 @@ export type QueryFindManyUserArgs = { }; +export type QueryFindManyViewFieldArgs = { + cursor?: InputMaybe; + distinct?: InputMaybe>; + orderBy?: InputMaybe>; + skip?: InputMaybe; + take?: InputMaybe; + where?: InputMaybe; +}; + + export type QueryFindManyWorkspaceMemberArgs = { cursor?: InputMaybe; distinct?: InputMaybe>; @@ -1687,7 +2260,7 @@ export type QueryFindManyWorkspaceMemberArgs = { export type QueryFindUniqueCompanyArgs = { - id: Scalars['String']; + where: CompanyWhereUniqueInput; }; @@ -1745,9 +2318,13 @@ export type User = { __typename?: 'User'; Favorite?: Maybe>; assignedCommentThreads?: Maybe>; + assignedActivities?: Maybe>; + authoredActivities?: Maybe>; + Favorite?: Maybe>; + assignedCommentThreads?: Maybe>; authoredAttachments?: Maybe>; - authoredCommentThreads?: Maybe>; avatarUrl?: Maybe; + canImpersonate: Scalars['Boolean']; comments?: Maybe>; companies?: Maybe>; createdAt: Scalars['DateTime']; @@ -1768,11 +2345,11 @@ export type User = { workspaceMember?: Maybe; }; -export type UserCreateNestedOneWithoutAssignedCommentThreadsInput = { +export type UserCreateNestedOneWithoutAssignedActivitiesInput = { connect?: InputMaybe; }; -export type UserCreateNestedOneWithoutAuthoredCommentThreadsInput = { +export type UserCreateNestedOneWithoutAuthoredActivitiesInput = { connect?: InputMaybe; }; @@ -1790,11 +2367,15 @@ export type UserExists = { }; export type UserOrderByWithRelationInput = { + Favorite?: InputMaybe; + assignedCommentThreads?: InputMaybe; + assignedActivities?: InputMaybe; + authoredActivities?: InputMaybe; Favorite?: InputMaybe; assignedCommentThreads?: InputMaybe; authoredAttachments?: InputMaybe; - authoredCommentThreads?: InputMaybe; avatarUrl?: InputMaybe; + canImpersonate?: InputMaybe; comments?: InputMaybe; companies?: InputMaybe; createdAt?: InputMaybe; @@ -1820,6 +2401,7 @@ export type UserRelationFilter = { export enum UserScalarFieldEnum { AvatarUrl = 'avatarUrl', + CanImpersonate = 'canImpersonate', CreatedAt = 'createdAt', DeletedAt = 'deletedAt', Disabled = 'disabled', @@ -1886,11 +2468,15 @@ export type UserSettingsWhereInput = { }; export type UserUpdateInput = { + Favorite?: InputMaybe; + assignedCommentThreads?: InputMaybe; + assignedActivities?: InputMaybe; + authoredActivities?: InputMaybe; Favorite?: InputMaybe; assignedCommentThreads?: InputMaybe; authoredAttachments?: InputMaybe; - authoredCommentThreads?: InputMaybe; avatarUrl?: InputMaybe; + canImpersonate?: InputMaybe; comments?: InputMaybe; companies?: InputMaybe; createdAt?: InputMaybe; @@ -1908,11 +2494,11 @@ export type UserUpdateInput = { updatedAt?: InputMaybe; }; -export type UserUpdateOneRequiredWithoutAuthoredCommentThreadsNestedInput = { +export type UserUpdateOneRequiredWithoutAuthoredActivitiesNestedInput = { connect?: InputMaybe; }; -export type UserUpdateOneWithoutAssignedCommentThreadsNestedInput = { +export type UserUpdateOneWithoutAssignedActivitiesNestedInput = { connect?: InputMaybe; disconnect?: InputMaybe; }; @@ -1927,10 +2513,11 @@ export type UserWhereInput = { Favorite?: InputMaybe; NOT?: InputMaybe>; OR?: InputMaybe>; - assignedCommentThreads?: InputMaybe; + assignedActivities?: InputMaybe; + authoredActivities?: InputMaybe; authoredAttachments?: InputMaybe; - authoredCommentThreads?: InputMaybe; avatarUrl?: InputMaybe; + canImpersonate?: InputMaybe; comments?: InputMaybe; companies?: InputMaybe; createdAt?: InputMaybe; @@ -1961,11 +2548,80 @@ export type Verify = { user: User; }; +export type ViewField = { + __typename?: 'ViewField'; + fieldName: Scalars['String']; + id: Scalars['ID']; + index: Scalars['Int']; + isVisible: Scalars['Boolean']; + objectName: Scalars['String']; + sizeInPx: Scalars['Int']; +}; + +export type ViewFieldCreateManyInput = { + fieldName: Scalars['String']; + id?: InputMaybe; + index: Scalars['Int']; + isVisible: Scalars['Boolean']; + objectName: Scalars['String']; + sizeInPx: Scalars['Int']; +}; + +export type ViewFieldOrderByWithRelationInput = { + fieldName?: InputMaybe; + id?: InputMaybe; + index?: InputMaybe; + isVisible?: InputMaybe; + objectName?: InputMaybe; + sizeInPx?: InputMaybe; +}; + +export enum ViewFieldScalarFieldEnum { + FieldName = 'fieldName', + Id = 'id', + Index = 'index', + IsVisible = 'isVisible', + ObjectName = 'objectName', + SizeInPx = 'sizeInPx', + WorkspaceId = 'workspaceId' +} + +export type ViewFieldUpdateInput = { + fieldName?: InputMaybe; + id?: InputMaybe; + index?: InputMaybe; + isVisible?: InputMaybe; + objectName?: InputMaybe; + sizeInPx?: InputMaybe; +}; + +export type ViewFieldUpdateManyWithoutWorkspaceNestedInput = { + connect?: InputMaybe>; + disconnect?: InputMaybe>; + set?: InputMaybe>; +}; + +export type ViewFieldWhereInput = { + AND?: InputMaybe>; + NOT?: InputMaybe>; + OR?: InputMaybe>; + fieldName?: InputMaybe; + id?: InputMaybe; + index?: InputMaybe; + isVisible?: InputMaybe; + objectName?: InputMaybe; + sizeInPx?: InputMaybe; +}; + +export type ViewFieldWhereUniqueInput = { + id?: InputMaybe; +}; + export type Workspace = { __typename?: 'Workspace'; Attachment?: Maybe>; - CommentThreadTarget?: Maybe>; - commentThreads?: Maybe>; + activities?: Maybe>; + activityTargets?: Maybe>; comments?: Maybe>; companies?: Maybe>; createdAt: Scalars['DateTime']; @@ -1979,6 +2635,7 @@ export type Workspace = { pipelineStages?: Maybe>; pipelines?: Maybe>; updatedAt: Scalars['DateTime']; + viewFields?: Maybe>; workspaceMember?: Maybe>; }; @@ -1989,6 +2646,7 @@ export type WorkspaceInviteHashValid = { export type WorkspaceMember = { __typename?: 'WorkspaceMember'; + allowImpersonation: Scalars['Boolean']; createdAt: Scalars['DateTime']; id: Scalars['ID']; updatedAt: Scalars['DateTime']; @@ -1998,6 +2656,7 @@ export type WorkspaceMember = { }; export type WorkspaceMemberOrderByWithRelationInput = { + allowImpersonation?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; updatedAt?: InputMaybe; @@ -2006,6 +2665,7 @@ export type WorkspaceMemberOrderByWithRelationInput = { }; export enum WorkspaceMemberScalarFieldEnum { + AllowImpersonation = 'allowImpersonation', CreatedAt = 'createdAt', DeletedAt = 'deletedAt', Id = 'id', @@ -2024,6 +2684,7 @@ export type WorkspaceMemberWhereInput = { AND?: InputMaybe>; NOT?: InputMaybe>; OR?: InputMaybe>; + allowImpersonation?: InputMaybe; createdAt?: InputMaybe; id?: InputMaybe; updatedAt?: InputMaybe; @@ -2038,8 +2699,8 @@ export type WorkspaceMemberWhereUniqueInput = { export type WorkspaceUpdateInput = { Attachment?: InputMaybe; - CommentThreadTarget?: InputMaybe; - commentThreads?: InputMaybe; + activities?: InputMaybe; + activityTargets?: InputMaybe; comments?: InputMaybe; companies?: InputMaybe; createdAt?: InputMaybe; @@ -2053,6 +2714,7 @@ export type WorkspaceUpdateInput = { pipelineStages?: InputMaybe; pipelines?: InputMaybe; updatedAt?: InputMaybe; + viewFields?: InputMaybe; workspaceMember?: InputMaybe; }; @@ -2060,74 +2722,79 @@ export type CreateCommentMutationVariables = Exact<{ commentId: Scalars['String']; commentText: Scalars['String']; authorId: Scalars['String']; - commentThreadId: Scalars['String']; + activityId: Scalars['String']; createdAt: Scalars['DateTime']; }>; -export type CreateCommentMutation = { __typename?: 'Mutation', createOneComment: { __typename?: 'Comment', id: string, createdAt: string, body: string, commentThreadId: string, author: { __typename?: 'User', id: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } } }; +export type CreateCommentMutation = { __typename?: 'Mutation', createOneComment: { __typename?: 'Comment', id: string, createdAt: string, body: string, activityId?: string | null, author: { __typename?: 'User', id: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } } }; -export type CreateCommentThreadMutationVariables = Exact<{ - commentThreadId: Scalars['String']; +export type CreateActivityMutationVariables = Exact<{ + activityId: Scalars['String']; body?: InputMaybe; title?: InputMaybe; type: ActivityType; authorId: Scalars['String']; createdAt: Scalars['DateTime']; - commentThreadTargetArray: Array | CommentThreadTargetCreateManyCommentThreadInput; + activityTargetArray: Array | ActivityTargetCreateManyActivityInput; }>; -export type CreateCommentThreadMutation = { __typename?: 'Mutation', createOneCommentThread: { __typename?: 'CommentThread', id: string, createdAt: string, updatedAt: string, authorId: string, type: ActivityType, commentThreadTargets?: Array<{ __typename?: 'CommentThreadTarget', id: string, createdAt: string, updatedAt: string, commentThreadId: string, commentableType: CommentableType, commentableId: string }> | null, comments?: Array<{ __typename?: 'Comment', id: string, createdAt: string, updatedAt: string, body: string, author: { __typename?: 'User', id: string } }> | null } }; +export type CreateActivityMutation = { __typename?: 'Mutation', createOneActivity: { __typename?: 'Activity', id: string, createdAt: string, updatedAt: string, authorId: string, type: ActivityType, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, createdAt: string, updatedAt: string, activityId: string, commentableType?: CommentableType | null, commentableId?: string | null }> | null, comments?: Array<{ __typename?: 'Comment', id: string, createdAt: string, updatedAt: string, body: string, author: { __typename?: 'User', id: string } }> | null } }; -export type GetCommentThreadsByTargetsQueryVariables = Exact<{ - commentThreadTargetIds: Array | Scalars['String']; - orderBy?: InputMaybe | CommentThreadOrderByWithRelationInput>; +export type GetActivitiesByTargetsQueryVariables = Exact<{ + activityTargetIds: Array | Scalars['String']; + orderBy?: InputMaybe | ActivityOrderByWithRelationInput>; }>; -export type GetCommentThreadsByTargetsQuery = { __typename?: 'Query', findManyCommentThreads: Array<{ __typename?: 'CommentThread', id: string, createdAt: string, title?: string | null, body?: string | null, type: ActivityType, completedAt?: string | null, author: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string }, comments?: Array<{ __typename?: 'Comment', id: string, body: string, createdAt: string, updatedAt: string, author: { __typename?: 'User', id: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } }> | null, commentThreadTargets?: Array<{ __typename?: 'CommentThreadTarget', id: string, commentableId: string, commentableType: CommentableType }> | null }> }; +export type GetActivitiesByTargetsQuery = { __typename?: 'Query', findManyActivities: Array<{ __typename?: 'Activity', id: string, createdAt: string, title?: string | null, body?: string | null, type: ActivityType, completedAt?: string | null, dueAt?: string | null, assignee?: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string } | null, author: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string }, comments?: Array<{ __typename?: 'Comment', id: string, body: string, createdAt: string, updatedAt: string, author: { __typename?: 'User', id: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } }> | null, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, commentableType?: CommentableType | null, commentableId?: string | null }> | null }> }; -export type GetCommentThreadQueryVariables = Exact<{ - commentThreadId: Scalars['String']; +export type GetActivitiesQueryVariables = Exact<{ + where: ActivityWhereInput; + orderBy?: InputMaybe | ActivityOrderByWithRelationInput>; }>; -export type GetCommentThreadQuery = { __typename?: 'Query', findManyCommentThreads: Array<{ __typename?: 'CommentThread', id: string, createdAt: string, body?: string | null, title?: string | null, type: ActivityType, completedAt?: string | null, author: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string }, comments?: Array<{ __typename?: 'Comment', id: string, body: string, createdAt: string, updatedAt: string, author: { __typename?: 'User', id: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } }> | null, commentThreadTargets?: Array<{ __typename?: 'CommentThreadTarget', id: string, commentableId: string, commentableType: CommentableType }> | null }> }; +export type GetActivitiesQuery = { __typename?: 'Query', findManyActivities: Array<{ __typename?: 'Activity', id: string, createdAt: string, title?: string | null, body?: string | null, type: ActivityType, completedAt?: string | null, dueAt?: string | null, assignee?: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string, avatarUrl?: string | null } | null, author: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string }, comments?: Array<{ __typename?: 'Comment', id: string }> | null, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, commentableType?: CommentableType | null, commentableId?: string | null }> | null }> }; -export type AddCommentThreadTargetsOnCommentThreadMutationVariables = Exact<{ - commentThreadId: Scalars['String']; - commentThreadTargetInputs: Array | CommentThreadTargetCreateManyCommentThreadInput; +export type GetActivityQueryVariables = Exact<{ + activityId: Scalars['String']; }>; -export type AddCommentThreadTargetsOnCommentThreadMutation = { __typename?: 'Mutation', updateOneCommentThread: { __typename?: 'CommentThread', id: string, createdAt: string, updatedAt: string, commentThreadTargets?: Array<{ __typename?: 'CommentThreadTarget', id: string, createdAt: string, updatedAt: string, commentableType: CommentableType, commentableId: string }> | null } }; +export type GetActivityQuery = { __typename?: 'Query', findManyActivities: Array<{ __typename?: 'Activity', id: string, createdAt: string, body?: string | null, title?: string | null, type: ActivityType, completedAt?: string | null, dueAt?: string | null, assignee?: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string } | null, author: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string }, comments?: Array<{ __typename?: 'Comment', id: string, body: string, createdAt: string, updatedAt: string, author: { __typename?: 'User', id: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } }> | null, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, commentableType?: CommentableType | null, commentableId?: string | null }> | null }> }; -export type RemoveCommentThreadTargetsOnCommentThreadMutationVariables = Exact<{ - commentThreadId: Scalars['String']; - commentThreadTargetIds: Array | Scalars['String']; +export type AddActivityTargetsOnActivityMutationVariables = Exact<{ + activityId: Scalars['String']; + activityTargetInputs: Array | ActivityTargetCreateManyActivityInput; }>; -export type RemoveCommentThreadTargetsOnCommentThreadMutation = { __typename?: 'Mutation', updateOneCommentThread: { __typename?: 'CommentThread', id: string, createdAt: string, updatedAt: string, commentThreadTargets?: Array<{ __typename?: 'CommentThreadTarget', id: string, createdAt: string, updatedAt: string, commentableType: CommentableType, commentableId: string }> | null } }; +export type AddActivityTargetsOnActivityMutation = { __typename?: 'Mutation', updateOneActivity: { __typename?: 'Activity', id: string, createdAt: string, updatedAt: string, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, createdAt: string, updatedAt: string, commentableType?: CommentableType | null, commentableId?: string | null }> | null } }; -export type DeleteCommentThreadMutationVariables = Exact<{ - commentThreadId: Scalars['String']; +export type RemoveActivityTargetsOnActivityMutationVariables = Exact<{ + activityId: Scalars['String']; + activityTargetIds: Array | Scalars['String']; }>; -export type DeleteCommentThreadMutation = { __typename?: 'Mutation', deleteManyCommentThreads: { __typename?: 'AffectedRows', count: number } }; +export type RemoveActivityTargetsOnActivityMutation = { __typename?: 'Mutation', updateOneActivity: { __typename?: 'Activity', id: string, createdAt: string, updatedAt: string, activityTargets?: Array<{ __typename?: 'ActivityTarget', id: string, createdAt: string, updatedAt: string, commentableType?: CommentableType | null, commentableId?: string | null }> | null } }; -export type UpdateCommentThreadMutationVariables = Exact<{ - id: Scalars['String']; - body?: InputMaybe; - title?: InputMaybe; - type?: InputMaybe; - completedAt?: InputMaybe; +export type DeleteActivityMutationVariables = Exact<{ + activityId: Scalars['String']; +}>; + + +export type DeleteActivityMutation = { __typename?: 'Mutation', deleteManyActivities: { __typename?: 'AffectedRows', count: number } }; + +export type UpdateActivityMutationVariables = Exact<{ + where: ActivityWhereUniqueInput; + data: ActivityUpdateInput; }>; -export type UpdateCommentThreadMutation = { __typename?: 'Mutation', updateOneCommentThread: { __typename?: 'CommentThread', id: string, body?: string | null, title?: string | null, type: ActivityType, completedAt?: string | null } }; +export type UpdateActivityMutation = { __typename?: 'Mutation', updateOneActivity: { __typename?: 'Activity', id: string, body?: string | null, title?: string | null, type: ActivityType, completedAt?: string | null, dueAt?: string | null, assignee?: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string } | null } }; export type UploadAttachmentMutationVariables = Exact<{ file: Scalars['Upload']; @@ -2174,7 +2841,7 @@ export type VerifyMutationVariables = Exact<{ }>; -export type VerifyMutation = { __typename?: 'Mutation', verify: { __typename?: 'Verify', user: { __typename?: 'User', id: string, email: string, displayName: string, firstName?: string | null, lastName?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, workspace: { __typename?: 'Workspace', id: string, domainName?: string | null, displayName?: string | null, logo?: string | null, inviteHash?: string | null } } | null, settings: { __typename?: 'UserSettings', id: string, colorScheme: ColorScheme, locale: string } }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } }; +export type VerifyMutation = { __typename?: 'Mutation', verify: { __typename?: 'Verify', user: { __typename?: 'User', id: string, email: string, displayName: string, firstName?: string | null, lastName?: string | null, canImpersonate: boolean, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, allowImpersonation: boolean, workspace: { __typename?: 'Workspace', id: string, domainName?: string | null, displayName?: string | null, logo?: string | null, inviteHash?: string | null } } | null, settings: { __typename?: 'UserSettings', id: string, colorScheme: ColorScheme, locale: string } }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } }; export type RenewTokenMutationVariables = Exact<{ refreshToken: Scalars['String']; @@ -2183,10 +2850,17 @@ export type RenewTokenMutationVariables = Exact<{ export type RenewTokenMutation = { __typename?: 'Mutation', renewToken: { __typename?: 'AuthTokens', tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', expiresAt: string, token: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } }; +export type ImpersonateMutationVariables = Exact<{ + userId: Scalars['String']; +}>; + + +export type ImpersonateMutation = { __typename?: 'Mutation', impersonate: { __typename?: 'Verify', user: { __typename?: 'User', id: string, email: string, displayName: string, firstName?: string | null, lastName?: string | null, canImpersonate: boolean, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, allowImpersonation: boolean, workspace: { __typename?: 'Workspace', id: string, domainName?: string | null, displayName?: string | null, logo?: string | null, inviteHash?: string | null } } | null, settings: { __typename?: 'UserSettings', id: string, colorScheme: ColorScheme, locale: string } }, tokens: { __typename?: 'AuthTokenPair', accessToken: { __typename?: 'AuthToken', token: string, expiresAt: string }, refreshToken: { __typename?: 'AuthToken', token: string, expiresAt: string } } } }; + export type GetClientConfigQueryVariables = Exact<{ [key: string]: never; }>; -export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', demoMode: boolean, debugMode: boolean, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean }, telemetry: { __typename?: 'Telemetry', enabled: boolean, anonymizationEnabled: boolean } } }; +export type GetClientConfigQuery = { __typename?: 'Query', clientConfig: { __typename?: 'ClientConfig', signInPrefilled: boolean, debugMode: boolean, authProviders: { __typename?: 'AuthProviders', google: boolean, password: boolean }, telemetry: { __typename?: 'Telemetry', enabled: boolean, anonymizationEnabled: boolean } } }; export type GetCompaniesQueryVariables = Exact<{ orderBy?: InputMaybe | CompanyOrderByWithRelationInput>; @@ -2194,14 +2868,14 @@ export type GetCompaniesQueryVariables = Exact<{ }>; -export type GetCompaniesQuery = { __typename?: 'Query', companies: Array<{ __typename?: 'Company', id: string, domainName: string, name: string, createdAt: string, address: string, linkedinUrl?: string | null, employees?: number | null, _commentThreadCount: number, accountOwner?: { __typename?: 'User', id: string, email: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } | null }> }; +export type GetCompaniesQuery = { __typename?: 'Query', companies: Array<{ __typename?: 'Company', id: string, domainName: string, name: string, createdAt: string, address: string, linkedinUrl?: string | null, employees?: number | null, _activityCount: number, accountOwner?: { __typename?: 'User', id: string, email: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } | null }> }; export type GetCompanyQueryVariables = Exact<{ - id: Scalars['String']; + where: CompanyWhereUniqueInput; }>; -export type GetCompanyQuery = { __typename?: 'Query', findUniqueCompany: { __typename?: 'Company', id: string, domainName: string, name: string, createdAt: string, address: string, linkedinUrl?: string | null, employees?: number | null, _commentThreadCount: number, accountOwner?: { __typename?: 'User', id: string, email: string, displayName: string, avatarUrl?: string | null } | null } }; +export type GetCompanyQuery = { __typename?: 'Query', findUniqueCompany: { __typename?: 'Company', id: string, domainName: string, name: string, createdAt: string, address: string, linkedinUrl?: string | null, employees?: number | null, _activityCount: number, accountOwner?: { __typename?: 'User', id: string, email: string, displayName: string, avatarUrl?: string | null } | null } }; export type UpdateOneCompanyMutationVariables = Exact<{ where: CompanyWhereUniqueInput; @@ -2244,7 +2918,7 @@ export type GetPeopleQueryVariables = Exact<{ }>; -export type GetPeopleQuery = { __typename?: 'Query', people: Array<{ __typename?: 'Person', id: string, phone?: string | null, email?: string | null, city?: string | null, firstName?: string | null, lastName?: string | null, displayName: string, jobTitle?: string | null, linkedinUrl?: string | null, createdAt: string, _commentThreadCount: number, company?: { __typename?: 'Company', id: string, name: string, domainName: string } | null }> }; +export type GetPeopleQuery = { __typename?: 'Query', people: Array<{ __typename?: 'Person', id: string, phone?: string | null, email?: string | null, city?: string | null, firstName?: string | null, lastName?: string | null, displayName: string, jobTitle?: string | null, linkedinUrl?: string | null, avatarUrl?: string | null, createdAt: string, _activityCount: number, company?: { __typename?: 'Company', id: string, name: string, domainName: string } | null }> }; export type GetPersonPhoneByIdQueryVariables = Exact<{ id: Scalars['String']; @@ -2265,7 +2939,7 @@ export type GetPersonNamesAndCommentCountByIdQueryVariables = Exact<{ }>; -export type GetPersonNamesAndCommentCountByIdQuery = { __typename?: 'Query', person: { __typename?: 'Person', id: string, firstName?: string | null, lastName?: string | null, displayName: string, _commentThreadCount: number } }; +export type GetPersonNamesAndCommentCountByIdQuery = { __typename?: 'Query', person: { __typename?: 'Person', id: string, firstName?: string | null, lastName?: string | null, displayName: string, _activityCount: number } }; export type GetPersonCompanyByIdQueryVariables = Exact<{ id: Scalars['String']; @@ -2279,7 +2953,7 @@ export type GetPersonCommentCountByIdQueryVariables = Exact<{ }>; -export type GetPersonCommentCountByIdQuery = { __typename?: 'Query', person: { __typename?: 'Person', id: string, _commentThreadCount: number } }; +export type GetPersonCommentCountByIdQuery = { __typename?: 'Query', person: { __typename?: 'Person', id: string, _activityCount: number } }; export type GetPersonCreatedAtByIdQueryVariables = Exact<{ id: Scalars['String']; @@ -2300,7 +2974,7 @@ export type GetPersonQueryVariables = Exact<{ }>; -export type GetPersonQuery = { __typename?: 'Query', findUniquePerson: { __typename?: 'Person', id: string, firstName?: string | null, lastName?: string | null, displayName: string, email?: string | null, createdAt: string, city?: string | null, jobTitle?: string | null, linkedinUrl?: string | null, phone?: string | null, _commentThreadCount: number, company?: { __typename?: 'Company', id: string, name: string, domainName: string } | null } }; +export type GetPersonQuery = { __typename?: 'Query', findUniquePerson: { __typename?: 'Person', id: string, firstName?: string | null, lastName?: string | null, displayName: string, email?: string | null, createdAt: string, city?: string | null, jobTitle?: string | null, linkedinUrl?: string | null, avatarUrl?: string | null, phone?: string | null, _activityCount: number, company?: { __typename?: 'Company', id: string, name: string, domainName: string } | null } }; export type UpdateOnePersonMutationVariables = Exact<{ where: PersonWhereUniqueInput; @@ -2337,7 +3011,22 @@ export type GetPipelineProgressQueryVariables = Exact<{ }>; -export type GetPipelineProgressQuery = { __typename?: 'Query', findManyPipelineProgress: Array<{ __typename?: 'PipelineProgress', id: string, pipelineStageId: string, progressableType: PipelineProgressableType, progressableId: string, amount?: number | null, closeDate?: string | null, pointOfContactId?: string | null, probability?: number | null, pointOfContact?: { __typename?: 'Person', id: string, firstName?: string | null, lastName?: string | null, displayName: string } | null }> }; +export type GetPipelineProgressQuery = { __typename?: 'Query', findManyPipelineProgress: Array<{ __typename?: 'PipelineProgress', id: string, pipelineStageId: string, companyId?: string | null, personId?: string | null, amount?: number | null, closeDate?: string | null, pointOfContactId?: string | null, probability?: number | null, pointOfContact?: { __typename?: 'Person', id: string, firstName?: string | null, lastName?: string | null, displayName: string, avatarUrl?: string | null } | null }> }; + +export type DeleteManyPipelineProgressMutationVariables = Exact<{ + ids?: InputMaybe | Scalars['String']>; +}>; + + +export type DeleteManyPipelineProgressMutation = { __typename?: 'Mutation', deleteManyPipelineProgress: { __typename?: 'AffectedRows', count: number } }; + +export type UpdatePipelineStageMutationVariables = Exact<{ + id?: InputMaybe; + data: PipelineStageUpdateInput; +}>; + + +export type UpdatePipelineStageMutation = { __typename?: 'Mutation', updateOnePipelineStage?: { __typename?: 'PipelineStage', id: string, name: string, color: string } | null }; export type UpdateOnePipelineProgressMutationVariables = Exact<{ id?: InputMaybe; @@ -2358,31 +3047,15 @@ export type UpdateOnePipelineProgressStageMutationVariables = Exact<{ export type UpdateOnePipelineProgressStageMutation = { __typename?: 'Mutation', updateOnePipelineProgress?: { __typename?: 'PipelineProgress', id: string } | null }; -export type CreateOnePipelineProgressMutationVariables = Exact<{ +export type CreateOneCompanyPipelineProgressMutationVariables = Exact<{ uuid: Scalars['String']; - entityType: PipelineProgressableType; - entityId: Scalars['String']; + companyId: Scalars['String']; pipelineId: Scalars['String']; pipelineStageId: Scalars['String']; }>; -export type CreateOnePipelineProgressMutation = { __typename?: 'Mutation', createOnePipelineProgress: { __typename?: 'PipelineProgress', id: string } }; - -export type DeleteManyPipelineProgressMutationVariables = Exact<{ - ids?: InputMaybe | Scalars['String']>; -}>; - - -export type DeleteManyPipelineProgressMutation = { __typename?: 'Mutation', deleteManyPipelineProgress: { __typename?: 'AffectedRows', count: number } }; - -export type UpdatePipelineStageMutationVariables = Exact<{ - id?: InputMaybe; - data: PipelineStageUpdateInput; -}>; - - -export type UpdatePipelineStageMutation = { __typename?: 'Mutation', updateOnePipelineStage?: { __typename?: 'PipelineStage', id: string, name: string, color: string } | null }; +export type CreateOneCompanyPipelineProgressMutation = { __typename?: 'Mutation', createOnePipelineProgress: { __typename?: 'PipelineProgress', id: string } }; export type SearchPeopleQueryVariables = Exact<{ where?: InputMaybe; @@ -2391,7 +3064,7 @@ export type SearchPeopleQueryVariables = Exact<{ }>; -export type SearchPeopleQuery = { __typename?: 'Query', searchResults: Array<{ __typename?: 'Person', id: string, phone?: string | null, email?: string | null, city?: string | null, firstName?: string | null, lastName?: string | null, createdAt: string }> }; +export type SearchPeopleQuery = { __typename?: 'Query', searchResults: Array<{ __typename?: 'Person', id: string, phone?: string | null, email?: string | null, city?: string | null, firstName?: string | null, lastName?: string | null, displayName: string, avatarUrl?: string | null, createdAt: string }> }; export type SearchUserQueryVariables = Exact<{ where?: InputMaybe; @@ -2416,10 +3089,19 @@ export type SearchCompanyQueryVariables = Exact<{ export type SearchCompanyQuery = { __typename?: 'Query', searchResults: Array<{ __typename?: 'Company', id: string, name: string, domainName: string }> }; +export type SearchActivityQueryVariables = Exact<{ + where?: InputMaybe; + limit?: InputMaybe; + orderBy?: InputMaybe | ActivityOrderByWithRelationInput>; +}>; + + +export type SearchActivityQuery = { __typename?: 'Query', searchResults: Array<{ __typename?: 'Activity', id: string, title?: string | null, body?: string | null }> }; + export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>; -export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, email: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, workspace: { __typename?: 'Workspace', id: string, domainName?: string | null, displayName?: string | null, logo?: string | null, inviteHash?: string | null } } | null, settings: { __typename?: 'UserSettings', id: string, locale: string, colorScheme: ColorScheme } } }; +export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: string, email: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null, canImpersonate: boolean, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, allowImpersonation: boolean, workspace: { __typename?: 'Workspace', id: string, domainName?: string | null, displayName?: string | null, logo?: string | null, inviteHash?: string | null } } | null, settings: { __typename?: 'UserSettings', id: string, locale: string, colorScheme: ColorScheme } } }; export type GetUsersQueryVariables = Exact<{ [key: string]: never; }>; @@ -2434,6 +3116,13 @@ export type UpdateUserMutationVariables = Exact<{ export type UpdateUserMutation = { __typename?: 'Mutation', updateUser: { __typename?: 'User', id: string, email: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null, workspaceMember?: { __typename?: 'WorkspaceMember', id: string, workspace: { __typename?: 'Workspace', id: string, domainName?: string | null, displayName?: string | null, logo?: string | null, inviteHash?: string | null } } | null, settings: { __typename?: 'UserSettings', id: string, locale: string, colorScheme: ColorScheme } } }; +export type UpdateAllowImpersonationMutationVariables = Exact<{ + allowImpersonation: Scalars['Boolean']; +}>; + + +export type UpdateAllowImpersonationMutation = { __typename?: 'Mutation', allowImpersonation: { __typename?: 'WorkspaceMember', id: string, allowImpersonation: boolean } }; + export type UploadProfilePictureMutationVariables = Exact<{ file: Scalars['Upload']; }>; @@ -2448,6 +3137,34 @@ export type RemoveProfilePictureMutationVariables = Exact<{ export type RemoveProfilePictureMutation = { __typename?: 'Mutation', updateUser: { __typename?: 'User', id: string, avatarUrl?: string | null } }; +export type DeleteUserAccountMutationVariables = Exact<{ [key: string]: never; }>; + + +export type DeleteUserAccountMutation = { __typename?: 'Mutation', deleteUserAccount: { __typename?: 'User', id: string } }; + +export type CreateViewFieldsMutationVariables = Exact<{ + data: Array | ViewFieldCreateManyInput; +}>; + + +export type CreateViewFieldsMutation = { __typename?: 'Mutation', createManyViewField: { __typename?: 'AffectedRows', count: number } }; + +export type GetViewFieldsQueryVariables = Exact<{ + where?: InputMaybe; + orderBy?: InputMaybe | ViewFieldOrderByWithRelationInput>; +}>; + + +export type GetViewFieldsQuery = { __typename?: 'Query', viewFields: Array<{ __typename?: 'ViewField', id: string, fieldName: string, isVisible: boolean, sizeInPx: number, index: number }> }; + +export type UpdateViewFieldMutationVariables = Exact<{ + data: ViewFieldUpdateInput; + where: ViewFieldWhereUniqueInput; +}>; + + +export type UpdateViewFieldMutation = { __typename?: 'Mutation', updateOneViewField: { __typename?: 'ViewField', id: string, fieldName: string, isVisible: boolean, sizeInPx: number, index: number } }; + export type GetWorkspaceMembersQueryVariables = Exact<{ [key: string]: never; }>; @@ -2479,11 +3196,16 @@ export type RemoveWorkspaceMemberMutationVariables = Exact<{ export type RemoveWorkspaceMemberMutation = { __typename?: 'Mutation', deleteWorkspaceMember: { __typename?: 'WorkspaceMember', id: string } }; +export type DeleteCurrentWorkspaceMutationVariables = Exact<{ [key: string]: never; }>; + + +export type DeleteCurrentWorkspaceMutation = { __typename?: 'Mutation', deleteCurrentWorkspace: { __typename?: 'Workspace', id: string } }; + export const CreateCommentDocument = gql` - mutation CreateComment($commentId: String!, $commentText: String!, $authorId: String!, $commentThreadId: String!, $createdAt: DateTime!) { + mutation CreateComment($commentId: String!, $commentText: String!, $authorId: String!, $activityId: String!, $createdAt: DateTime!) { createOneComment( - data: {id: $commentId, createdAt: $createdAt, body: $commentText, author: {connect: {id: $authorId}}, commentThread: {connect: {id: $commentThreadId}}} + data: {id: $commentId, createdAt: $createdAt, body: $commentText, author: {connect: {id: $authorId}}, activity: {connect: {id: $activityId}}} ) { id createdAt @@ -2495,7 +3217,7 @@ export const CreateCommentDocument = gql` lastName avatarUrl } - commentThreadId + activityId } } `; @@ -2517,7 +3239,7 @@ export type CreateCommentMutationFn = Apollo.MutationFunction; export type CreateCommentMutationResult = Apollo.MutationResult; export type CreateCommentMutationOptions = Apollo.BaseMutationOptions; -export const CreateCommentThreadDocument = gql` - mutation CreateCommentThread($commentThreadId: String!, $body: String, $title: String, $type: ActivityType!, $authorId: String!, $createdAt: DateTime!, $commentThreadTargetArray: [CommentThreadTargetCreateManyCommentThreadInput!]!) { - createOneCommentThread( - data: {id: $commentThreadId, createdAt: $createdAt, updatedAt: $createdAt, author: {connect: {id: $authorId}}, body: $body, title: $title, type: $type, commentThreadTargets: {createMany: {data: $commentThreadTargetArray, skipDuplicates: true}}} +export const CreateActivityDocument = gql` + mutation CreateActivity($activityId: String!, $body: String, $title: String, $type: ActivityType!, $authorId: String!, $createdAt: DateTime!, $activityTargetArray: [ActivityTargetCreateManyActivityInput!]!) { + createOneActivity( + data: {id: $activityId, createdAt: $createdAt, updatedAt: $createdAt, author: {connect: {id: $authorId}}, body: $body, title: $title, type: $type, activityTargets: {createMany: {data: $activityTargetArray, skipDuplicates: true}}} ) { id createdAt updatedAt authorId type - commentThreadTargets { + activityTargets { id createdAt updatedAt - commentThreadId + activityId commentableType commentableId } @@ -2559,43 +3281,43 @@ export const CreateCommentThreadDocument = gql` } } `; -export type CreateCommentThreadMutationFn = Apollo.MutationFunction; +export type CreateActivityMutationFn = Apollo.MutationFunction; /** - * __useCreateCommentThreadMutation__ + * __useCreateActivityMutation__ * - * To run a mutation, you first call `useCreateCommentThreadMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateCommentThreadMutation` returns a tuple that includes: + * To run a mutation, you first call `useCreateActivityMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useCreateActivityMutation` returns a tuple that includes: * - A mutate function that you can call at any time to execute the mutation * - An object with fields that represent the current status of the mutation's execution * * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * * @example - * const [createCommentThreadMutation, { data, loading, error }] = useCreateCommentThreadMutation({ + * const [createActivityMutation, { data, loading, error }] = useCreateActivityMutation({ * variables: { - * commentThreadId: // value for 'commentThreadId' + * activityId: // value for 'activityId' * body: // value for 'body' * title: // value for 'title' * type: // value for 'type' * authorId: // value for 'authorId' * createdAt: // value for 'createdAt' - * commentThreadTargetArray: // value for 'commentThreadTargetArray' + * activityTargetArray: // value for 'activityTargetArray' * }, * }); */ -export function useCreateCommentThreadMutation(baseOptions?: Apollo.MutationHookOptions) { +export function useCreateActivityMutation(baseOptions?: Apollo.MutationHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(CreateCommentThreadDocument, options); + return Apollo.useMutation(CreateActivityDocument, options); } -export type CreateCommentThreadMutationHookResult = ReturnType; -export type CreateCommentThreadMutationResult = Apollo.MutationResult; -export type CreateCommentThreadMutationOptions = Apollo.BaseMutationOptions; -export const GetCommentThreadsByTargetsDocument = gql` - query GetCommentThreadsByTargets($commentThreadTargetIds: [String!]!, $orderBy: [CommentThreadOrderByWithRelationInput!]) { - findManyCommentThreads( +export type CreateActivityMutationHookResult = ReturnType; +export type CreateActivityMutationResult = Apollo.MutationResult; +export type CreateActivityMutationOptions = Apollo.BaseMutationOptions; +export const GetActivitiesByTargetsDocument = gql` + query GetActivitiesByTargets($activityTargetIds: [String!]!, $orderBy: [ActivityOrderByWithRelationInput!]) { + findManyActivities( orderBy: $orderBy - where: {commentThreadTargets: {some: {commentableId: {in: $commentThreadTargetIds}}}} + where: {activityTargets: {some: {commentableId: {in: $activityTargetIds}}}} ) { id createdAt @@ -2603,6 +3325,13 @@ export const GetCommentThreadsByTargetsDocument = gql` body type completedAt + dueAt + assignee { + id + firstName + lastName + displayName + } author { id firstName @@ -2622,52 +3351,60 @@ export const GetCommentThreadsByTargetsDocument = gql` avatarUrl } } - commentThreadTargets { + activityTargets { id - commentableId commentableType + commentableId } } } `; /** - * __useGetCommentThreadsByTargetsQuery__ + * __useGetActivitiesByTargetsQuery__ * - * To run a query within a React component, call `useGetCommentThreadsByTargetsQuery` and pass it any options that fit your needs. - * When your component renders, `useGetCommentThreadsByTargetsQuery` returns an object from Apollo Client that contains loading, error, and data properties + * To run a query within a React component, call `useGetActivitiesByTargetsQuery` and pass it any options that fit your needs. + * When your component renders, `useGetActivitiesByTargetsQuery` returns an object from Apollo Client that contains loading, error, and data properties * you can use to render your UI. * * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; * * @example - * const { data, loading, error } = useGetCommentThreadsByTargetsQuery({ + * const { data, loading, error } = useGetActivitiesByTargetsQuery({ * variables: { - * commentThreadTargetIds: // value for 'commentThreadTargetIds' + * activityTargetIds: // value for 'activityTargetIds' * orderBy: // value for 'orderBy' * }, * }); */ -export function useGetCommentThreadsByTargetsQuery(baseOptions: Apollo.QueryHookOptions) { +export function useGetActivitiesByTargetsQuery(baseOptions: Apollo.QueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useQuery(GetCommentThreadsByTargetsDocument, options); + return Apollo.useQuery(GetActivitiesByTargetsDocument, options); } -export function useGetCommentThreadsByTargetsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { +export function useGetActivitiesByTargetsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useLazyQuery(GetCommentThreadsByTargetsDocument, options); + return Apollo.useLazyQuery(GetActivitiesByTargetsDocument, options); } -export type GetCommentThreadsByTargetsQueryHookResult = ReturnType; -export type GetCommentThreadsByTargetsLazyQueryHookResult = ReturnType; -export type GetCommentThreadsByTargetsQueryResult = Apollo.QueryResult; -export const GetCommentThreadDocument = gql` - query GetCommentThread($commentThreadId: String!) { - findManyCommentThreads(where: {id: {equals: $commentThreadId}}) { +export type GetActivitiesByTargetsQueryHookResult = ReturnType; +export type GetActivitiesByTargetsLazyQueryHookResult = ReturnType; +export type GetActivitiesByTargetsQueryResult = Apollo.QueryResult; +export const GetActivitiesDocument = gql` + query GetActivities($where: ActivityWhereInput!, $orderBy: [ActivityOrderByWithRelationInput!]) { + findManyActivities(orderBy: $orderBy, where: $where) { id createdAt - body title + body type completedAt + dueAt + assignee { + id + firstName + lastName + displayName + avatarUrl + } author { id firstName @@ -2676,109 +3413,171 @@ export const GetCommentThreadDocument = gql` } comments { id - body - createdAt - updatedAt - author { - id - displayName - firstName - lastName - avatarUrl - } } - commentThreadTargets { + activityTargets { id - commentableId commentableType + commentableId } } } `; /** - * __useGetCommentThreadQuery__ + * __useGetActivitiesQuery__ * - * To run a query within a React component, call `useGetCommentThreadQuery` and pass it any options that fit your needs. - * When your component renders, `useGetCommentThreadQuery` returns an object from Apollo Client that contains loading, error, and data properties + * To run a query within a React component, call `useGetActivitiesQuery` and pass it any options that fit your needs. + * When your component renders, `useGetActivitiesQuery` returns an object from Apollo Client that contains loading, error, and data properties * you can use to render your UI. * * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; * * @example - * const { data, loading, error } = useGetCommentThreadQuery({ + * const { data, loading, error } = useGetActivitiesQuery({ * variables: { - * commentThreadId: // value for 'commentThreadId' + * where: // value for 'where' + * orderBy: // value for 'orderBy' * }, * }); */ -export function useGetCommentThreadQuery(baseOptions: Apollo.QueryHookOptions) { +export function useGetActivitiesQuery(baseOptions: Apollo.QueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useQuery(GetCommentThreadDocument, options); + return Apollo.useQuery(GetActivitiesDocument, options); } -export function useGetCommentThreadLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { +export function useGetActivitiesLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useLazyQuery(GetCommentThreadDocument, options); + return Apollo.useLazyQuery(GetActivitiesDocument, options); } -export type GetCommentThreadQueryHookResult = ReturnType; -export type GetCommentThreadLazyQueryHookResult = ReturnType; -export type GetCommentThreadQueryResult = Apollo.QueryResult; -export const AddCommentThreadTargetsOnCommentThreadDocument = gql` - mutation AddCommentThreadTargetsOnCommentThread($commentThreadId: String!, $commentThreadTargetInputs: [CommentThreadTargetCreateManyCommentThreadInput!]!) { - updateOneCommentThread( - where: {id: $commentThreadId} - data: {commentThreadTargets: {createMany: {data: $commentThreadTargetInputs}}} - ) { +export type GetActivitiesQueryHookResult = ReturnType; +export type GetActivitiesLazyQueryHookResult = ReturnType; +export type GetActivitiesQueryResult = Apollo.QueryResult; +export const GetActivityDocument = gql` + query GetActivity($activityId: String!) { + findManyActivities(where: {id: {equals: $activityId}}) { id createdAt - updatedAt - commentThreadTargets { + body + title + type + completedAt + dueAt + assignee { id - createdAt - updatedAt - commentableType - commentableId + firstName + lastName + displayName } - } -} - `; -export type AddCommentThreadTargetsOnCommentThreadMutationFn = Apollo.MutationFunction; - + author { + id + firstName + lastName + displayName + } + comments { + id + body + createdAt + updatedAt + author { + id + displayName + firstName + lastName + avatarUrl + } + } + activityTargets { + id + commentableType + commentableId + } + } +} + `; + +/** + * __useGetActivityQuery__ + * + * To run a query within a React component, call `useGetActivityQuery` and pass it any options that fit your needs. + * When your component renders, `useGetActivityQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetActivityQuery({ + * variables: { + * activityId: // value for 'activityId' + * }, + * }); + */ +export function useGetActivityQuery(baseOptions: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(GetActivityDocument, options); + } +export function useGetActivityLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(GetActivityDocument, options); + } +export type GetActivityQueryHookResult = ReturnType; +export type GetActivityLazyQueryHookResult = ReturnType; +export type GetActivityQueryResult = Apollo.QueryResult; +export const AddActivityTargetsOnActivityDocument = gql` + mutation AddActivityTargetsOnActivity($activityId: String!, $activityTargetInputs: [ActivityTargetCreateManyActivityInput!]!) { + updateOneActivity( + where: {id: $activityId} + data: {activityTargets: {createMany: {data: $activityTargetInputs}}} + ) { + id + createdAt + updatedAt + activityTargets { + id + createdAt + updatedAt + commentableType + commentableId + } + } +} + `; +export type AddActivityTargetsOnActivityMutationFn = Apollo.MutationFunction; + /** - * __useAddCommentThreadTargetsOnCommentThreadMutation__ + * __useAddActivityTargetsOnActivityMutation__ * - * To run a mutation, you first call `useAddCommentThreadTargetsOnCommentThreadMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useAddCommentThreadTargetsOnCommentThreadMutation` returns a tuple that includes: + * To run a mutation, you first call `useAddActivityTargetsOnActivityMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useAddActivityTargetsOnActivityMutation` returns a tuple that includes: * - A mutate function that you can call at any time to execute the mutation * - An object with fields that represent the current status of the mutation's execution * * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * * @example - * const [addCommentThreadTargetsOnCommentThreadMutation, { data, loading, error }] = useAddCommentThreadTargetsOnCommentThreadMutation({ + * const [addActivityTargetsOnActivityMutation, { data, loading, error }] = useAddActivityTargetsOnActivityMutation({ * variables: { - * commentThreadId: // value for 'commentThreadId' - * commentThreadTargetInputs: // value for 'commentThreadTargetInputs' + * activityId: // value for 'activityId' + * activityTargetInputs: // value for 'activityTargetInputs' * }, * }); */ -export function useAddCommentThreadTargetsOnCommentThreadMutation(baseOptions?: Apollo.MutationHookOptions) { +export function useAddActivityTargetsOnActivityMutation(baseOptions?: Apollo.MutationHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(AddCommentThreadTargetsOnCommentThreadDocument, options); + return Apollo.useMutation(AddActivityTargetsOnActivityDocument, options); } -export type AddCommentThreadTargetsOnCommentThreadMutationHookResult = ReturnType; -export type AddCommentThreadTargetsOnCommentThreadMutationResult = Apollo.MutationResult; -export type AddCommentThreadTargetsOnCommentThreadMutationOptions = Apollo.BaseMutationOptions; -export const RemoveCommentThreadTargetsOnCommentThreadDocument = gql` - mutation RemoveCommentThreadTargetsOnCommentThread($commentThreadId: String!, $commentThreadTargetIds: [String!]!) { - updateOneCommentThread( - where: {id: $commentThreadId} - data: {commentThreadTargets: {deleteMany: {id: {in: $commentThreadTargetIds}}}} +export type AddActivityTargetsOnActivityMutationHookResult = ReturnType; +export type AddActivityTargetsOnActivityMutationResult = Apollo.MutationResult; +export type AddActivityTargetsOnActivityMutationOptions = Apollo.BaseMutationOptions; +export const RemoveActivityTargetsOnActivityDocument = gql` + mutation RemoveActivityTargetsOnActivity($activityId: String!, $activityTargetIds: [String!]!) { + updateOneActivity( + where: {id: $activityId} + data: {activityTargets: {deleteMany: {id: {in: $activityTargetIds}}}} ) { id createdAt updatedAt - commentThreadTargets { + activityTargets { id createdAt updatedAt @@ -2788,110 +3587,111 @@ export const RemoveCommentThreadTargetsOnCommentThreadDocument = gql` } } `; -export type RemoveCommentThreadTargetsOnCommentThreadMutationFn = Apollo.MutationFunction; +export type RemoveActivityTargetsOnActivityMutationFn = Apollo.MutationFunction; /** - * __useRemoveCommentThreadTargetsOnCommentThreadMutation__ + * __useRemoveActivityTargetsOnActivityMutation__ * - * To run a mutation, you first call `useRemoveCommentThreadTargetsOnCommentThreadMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useRemoveCommentThreadTargetsOnCommentThreadMutation` returns a tuple that includes: + * To run a mutation, you first call `useRemoveActivityTargetsOnActivityMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useRemoveActivityTargetsOnActivityMutation` returns a tuple that includes: * - A mutate function that you can call at any time to execute the mutation * - An object with fields that represent the current status of the mutation's execution * * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * * @example - * const [removeCommentThreadTargetsOnCommentThreadMutation, { data, loading, error }] = useRemoveCommentThreadTargetsOnCommentThreadMutation({ + * const [removeActivityTargetsOnActivityMutation, { data, loading, error }] = useRemoveActivityTargetsOnActivityMutation({ * variables: { - * commentThreadId: // value for 'commentThreadId' - * commentThreadTargetIds: // value for 'commentThreadTargetIds' + * activityId: // value for 'activityId' + * activityTargetIds: // value for 'activityTargetIds' * }, * }); */ -export function useRemoveCommentThreadTargetsOnCommentThreadMutation(baseOptions?: Apollo.MutationHookOptions) { +export function useRemoveActivityTargetsOnActivityMutation(baseOptions?: Apollo.MutationHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(RemoveCommentThreadTargetsOnCommentThreadDocument, options); + return Apollo.useMutation(RemoveActivityTargetsOnActivityDocument, options); } -export type RemoveCommentThreadTargetsOnCommentThreadMutationHookResult = ReturnType; -export type RemoveCommentThreadTargetsOnCommentThreadMutationResult = Apollo.MutationResult; -export type RemoveCommentThreadTargetsOnCommentThreadMutationOptions = Apollo.BaseMutationOptions; -export const DeleteCommentThreadDocument = gql` - mutation DeleteCommentThread($commentThreadId: String!) { - deleteManyCommentThreads(where: {id: {equals: $commentThreadId}}) { +export type RemoveActivityTargetsOnActivityMutationHookResult = ReturnType; +export type RemoveActivityTargetsOnActivityMutationResult = Apollo.MutationResult; +export type RemoveActivityTargetsOnActivityMutationOptions = Apollo.BaseMutationOptions; +export const DeleteActivityDocument = gql` + mutation DeleteActivity($activityId: String!) { + deleteManyActivities(where: {id: {equals: $activityId}}) { count } } `; -export type DeleteCommentThreadMutationFn = Apollo.MutationFunction; +export type DeleteActivityMutationFn = Apollo.MutationFunction; /** - * __useDeleteCommentThreadMutation__ + * __useDeleteActivityMutation__ * - * To run a mutation, you first call `useDeleteCommentThreadMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useDeleteCommentThreadMutation` returns a tuple that includes: + * To run a mutation, you first call `useDeleteActivityMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useDeleteActivityMutation` returns a tuple that includes: * - A mutate function that you can call at any time to execute the mutation * - An object with fields that represent the current status of the mutation's execution * * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * * @example - * const [deleteCommentThreadMutation, { data, loading, error }] = useDeleteCommentThreadMutation({ + * const [deleteActivityMutation, { data, loading, error }] = useDeleteActivityMutation({ * variables: { - * commentThreadId: // value for 'commentThreadId' + * activityId: // value for 'activityId' * }, * }); */ -export function useDeleteCommentThreadMutation(baseOptions?: Apollo.MutationHookOptions) { +export function useDeleteActivityMutation(baseOptions?: Apollo.MutationHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(DeleteCommentThreadDocument, options); + return Apollo.useMutation(DeleteActivityDocument, options); } -export type DeleteCommentThreadMutationHookResult = ReturnType; -export type DeleteCommentThreadMutationResult = Apollo.MutationResult; -export type DeleteCommentThreadMutationOptions = Apollo.BaseMutationOptions; -export const UpdateCommentThreadDocument = gql` - mutation UpdateCommentThread($id: String!, $body: String, $title: String, $type: ActivityType, $completedAt: DateTime) { - updateOneCommentThread( - where: {id: $id} - data: {body: $body, title: $title, type: $type, completedAt: $completedAt} - ) { +export type DeleteActivityMutationHookResult = ReturnType; +export type DeleteActivityMutationResult = Apollo.MutationResult; +export type DeleteActivityMutationOptions = Apollo.BaseMutationOptions; +export const UpdateActivityDocument = gql` + mutation UpdateActivity($where: ActivityWhereUniqueInput!, $data: ActivityUpdateInput!) { + updateOneActivity(where: $where, data: $data) { id body title type completedAt + dueAt + assignee { + id + firstName + lastName + displayName + } } } `; -export type UpdateCommentThreadMutationFn = Apollo.MutationFunction; +export type UpdateActivityMutationFn = Apollo.MutationFunction; /** - * __useUpdateCommentThreadMutation__ + * __useUpdateActivityMutation__ * - * To run a mutation, you first call `useUpdateCommentThreadMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useUpdateCommentThreadMutation` returns a tuple that includes: + * To run a mutation, you first call `useUpdateActivityMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdateActivityMutation` returns a tuple that includes: * - A mutate function that you can call at any time to execute the mutation * - An object with fields that represent the current status of the mutation's execution * * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * * @example - * const [updateCommentThreadMutation, { data, loading, error }] = useUpdateCommentThreadMutation({ + * const [updateActivityMutation, { data, loading, error }] = useUpdateActivityMutation({ * variables: { - * id: // value for 'id' - * body: // value for 'body' - * title: // value for 'title' - * type: // value for 'type' - * completedAt: // value for 'completedAt' + * where: // value for 'where' + * data: // value for 'data' * }, * }); */ -export function useUpdateCommentThreadMutation(baseOptions?: Apollo.MutationHookOptions) { +export function useUpdateActivityMutation(baseOptions?: Apollo.MutationHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(UpdateCommentThreadDocument, options); + return Apollo.useMutation(UpdateActivityDocument, options); } -export type UpdateCommentThreadMutationHookResult = ReturnType; -export type UpdateCommentThreadMutationResult = Apollo.MutationResult; -export type UpdateCommentThreadMutationOptions = Apollo.BaseMutationOptions; +export type UpdateActivityMutationHookResult = ReturnType; +export type UpdateActivityMutationResult = Apollo.MutationResult; +export type UpdateActivityMutationOptions = Apollo.BaseMutationOptions; export const UploadAttachmentDocument = gql` mutation UploadAttachment($file: Upload!, $activityId: String!) { uploadAttachment(file: $file, activityId: $activityId) @@ -3081,8 +3881,10 @@ export const VerifyDocument = gql` displayName firstName lastName + canImpersonate workspaceMember { id + allowImpersonation workspace { id domainName @@ -3178,6 +3980,72 @@ export function useRenewTokenMutation(baseOptions?: Apollo.MutationHookOptions; export type RenewTokenMutationResult = Apollo.MutationResult; export type RenewTokenMutationOptions = Apollo.BaseMutationOptions; +export const ImpersonateDocument = gql` + mutation Impersonate($userId: String!) { + impersonate(userId: $userId) { + user { + id + email + displayName + firstName + lastName + canImpersonate + workspaceMember { + id + allowImpersonation + workspace { + id + domainName + displayName + logo + inviteHash + } + } + settings { + id + colorScheme + locale + } + } + tokens { + accessToken { + token + expiresAt + } + refreshToken { + token + expiresAt + } + } + } +} + `; +export type ImpersonateMutationFn = Apollo.MutationFunction; + +/** + * __useImpersonateMutation__ + * + * To run a mutation, you first call `useImpersonateMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useImpersonateMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [impersonateMutation, { data, loading, error }] = useImpersonateMutation({ + * variables: { + * userId: // value for 'userId' + * }, + * }); + */ +export function useImpersonateMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(ImpersonateDocument, options); + } +export type ImpersonateMutationHookResult = ReturnType; +export type ImpersonateMutationResult = Apollo.MutationResult; +export type ImpersonateMutationOptions = Apollo.BaseMutationOptions; export const GetClientConfigDocument = gql` query GetClientConfig { clientConfig { @@ -3185,7 +4053,7 @@ export const GetClientConfigDocument = gql` google password } - demoMode + signInPrefilled debugMode telemetry { enabled @@ -3231,7 +4099,7 @@ export const GetCompaniesDocument = gql` address linkedinUrl employees - _commentThreadCount + _activityCount accountOwner { id email @@ -3273,8 +4141,8 @@ export type GetCompaniesQueryHookResult = ReturnType; export type GetCompaniesQueryResult = Apollo.QueryResult; export const GetCompanyDocument = gql` - query GetCompany($id: String!) { - findUniqueCompany(id: $id) { + query GetCompany($where: CompanyWhereUniqueInput!) { + findUniqueCompany(where: $where) { id domainName name @@ -3282,7 +4150,7 @@ export const GetCompanyDocument = gql` address linkedinUrl employees - _commentThreadCount + _activityCount accountOwner { id email @@ -3305,7 +4173,7 @@ export const GetCompanyDocument = gql` * @example * const { data, loading, error } = useGetCompanyQuery({ * variables: { - * id: // value for 'id' + * where: // value for 'where' * }, * }); */ @@ -3544,8 +4412,9 @@ export const GetPeopleDocument = gql` displayName jobTitle linkedinUrl + avatarUrl createdAt - _commentThreadCount + _activityCount company { id name @@ -3663,7 +4532,7 @@ export const GetPersonNamesAndCommentCountByIdDocument = gql` firstName lastName displayName - _commentThreadCount + _activityCount } } `; @@ -3739,7 +4608,7 @@ export const GetPersonCommentCountByIdDocument = gql` query GetPersonCommentCountById($id: String!) { person: findUniquePerson(id: $id) { id - _commentThreadCount + _activityCount } } `; @@ -3855,8 +4724,9 @@ export const GetPersonDocument = gql` city jobTitle linkedinUrl + avatarUrl phone - _commentThreadCount + _activityCount company { id name @@ -4069,8 +4939,8 @@ export const GetPipelineProgressDocument = gql` findManyPipelineProgress(where: $where, orderBy: $orderBy) { id pipelineStageId - progressableType - progressableId + companyId + personId amount closeDate pointOfContactId @@ -4079,6 +4949,7 @@ export const GetPipelineProgressDocument = gql` firstName lastName displayName + avatarUrl } probability } @@ -4113,6 +4984,75 @@ export function useGetPipelineProgressLazyQuery(baseOptions?: Apollo.LazyQueryHo export type GetPipelineProgressQueryHookResult = ReturnType; export type GetPipelineProgressLazyQueryHookResult = ReturnType; export type GetPipelineProgressQueryResult = Apollo.QueryResult; +export const DeleteManyPipelineProgressDocument = gql` + mutation DeleteManyPipelineProgress($ids: [String!]) { + deleteManyPipelineProgress(where: {id: {in: $ids}}) { + count + } +} + `; +export type DeleteManyPipelineProgressMutationFn = Apollo.MutationFunction; + +/** + * __useDeleteManyPipelineProgressMutation__ + * + * To run a mutation, you first call `useDeleteManyPipelineProgressMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useDeleteManyPipelineProgressMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [deleteManyPipelineProgressMutation, { data, loading, error }] = useDeleteManyPipelineProgressMutation({ + * variables: { + * ids: // value for 'ids' + * }, + * }); + */ +export function useDeleteManyPipelineProgressMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(DeleteManyPipelineProgressDocument, options); + } +export type DeleteManyPipelineProgressMutationHookResult = ReturnType; +export type DeleteManyPipelineProgressMutationResult = Apollo.MutationResult; +export type DeleteManyPipelineProgressMutationOptions = Apollo.BaseMutationOptions; +export const UpdatePipelineStageDocument = gql` + mutation UpdatePipelineStage($id: String, $data: PipelineStageUpdateInput!) { + updateOnePipelineStage(where: {id: $id}, data: $data) { + id + name + color + } +} + `; +export type UpdatePipelineStageMutationFn = Apollo.MutationFunction; + +/** + * __useUpdatePipelineStageMutation__ + * + * To run a mutation, you first call `useUpdatePipelineStageMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdatePipelineStageMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [updatePipelineStageMutation, { data, loading, error }] = useUpdatePipelineStageMutation({ + * variables: { + * id: // value for 'id' + * data: // value for 'data' + * }, + * }); + */ +export function useUpdatePipelineStageMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(UpdatePipelineStageDocument, options); + } +export type UpdatePipelineStageMutationHookResult = ReturnType; +export type UpdatePipelineStageMutationResult = Apollo.MutationResult; +export type UpdatePipelineStageMutationOptions = Apollo.BaseMutationOptions; export const UpdateOnePipelineProgressDocument = gql` mutation UpdateOnePipelineProgress($id: String, $amount: Int, $closeDate: DateTime, $probability: Int, $pointOfContactId: String) { updateOnePipelineProgress( @@ -4192,114 +5132,44 @@ export function useUpdateOnePipelineProgressStageMutation(baseOptions?: Apollo.M export type UpdateOnePipelineProgressStageMutationHookResult = ReturnType; export type UpdateOnePipelineProgressStageMutationResult = Apollo.MutationResult; export type UpdateOnePipelineProgressStageMutationOptions = Apollo.BaseMutationOptions; -export const CreateOnePipelineProgressDocument = gql` - mutation CreateOnePipelineProgress($uuid: String!, $entityType: PipelineProgressableType!, $entityId: String!, $pipelineId: String!, $pipelineStageId: String!) { +export const CreateOneCompanyPipelineProgressDocument = gql` + mutation CreateOneCompanyPipelineProgress($uuid: String!, $companyId: String!, $pipelineId: String!, $pipelineStageId: String!) { createOnePipelineProgress( - data: {id: $uuid, progressableType: $entityType, progressableId: $entityId, pipeline: {connect: {id: $pipelineId}}, pipelineStage: {connect: {id: $pipelineStageId}}} + data: {id: $uuid, company: {connect: {id: $companyId}}, pipeline: {connect: {id: $pipelineId}}, pipelineStage: {connect: {id: $pipelineStageId}}} ) { id } } `; -export type CreateOnePipelineProgressMutationFn = Apollo.MutationFunction; +export type CreateOneCompanyPipelineProgressMutationFn = Apollo.MutationFunction; /** - * __useCreateOnePipelineProgressMutation__ + * __useCreateOneCompanyPipelineProgressMutation__ * - * To run a mutation, you first call `useCreateOnePipelineProgressMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useCreateOnePipelineProgressMutation` returns a tuple that includes: + * To run a mutation, you first call `useCreateOneCompanyPipelineProgressMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useCreateOneCompanyPipelineProgressMutation` returns a tuple that includes: * - A mutate function that you can call at any time to execute the mutation * - An object with fields that represent the current status of the mutation's execution * * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * * @example - * const [createOnePipelineProgressMutation, { data, loading, error }] = useCreateOnePipelineProgressMutation({ + * const [createOneCompanyPipelineProgressMutation, { data, loading, error }] = useCreateOneCompanyPipelineProgressMutation({ * variables: { * uuid: // value for 'uuid' - * entityType: // value for 'entityType' - * entityId: // value for 'entityId' + * companyId: // value for 'companyId' * pipelineId: // value for 'pipelineId' * pipelineStageId: // value for 'pipelineStageId' * }, * }); */ -export function useCreateOnePipelineProgressMutation(baseOptions?: Apollo.MutationHookOptions) { +export function useCreateOneCompanyPipelineProgressMutation(baseOptions?: Apollo.MutationHookOptions) { const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(CreateOnePipelineProgressDocument, options); + return Apollo.useMutation(CreateOneCompanyPipelineProgressDocument, options); } -export type CreateOnePipelineProgressMutationHookResult = ReturnType; -export type CreateOnePipelineProgressMutationResult = Apollo.MutationResult; -export type CreateOnePipelineProgressMutationOptions = Apollo.BaseMutationOptions; -export const DeleteManyPipelineProgressDocument = gql` - mutation DeleteManyPipelineProgress($ids: [String!]) { - deleteManyPipelineProgress(where: {id: {in: $ids}}) { - count - } -} - `; -export type DeleteManyPipelineProgressMutationFn = Apollo.MutationFunction; - -/** - * __useDeleteManyPipelineProgressMutation__ - * - * To run a mutation, you first call `useDeleteManyPipelineProgressMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useDeleteManyPipelineProgressMutation` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [deleteManyPipelineProgressMutation, { data, loading, error }] = useDeleteManyPipelineProgressMutation({ - * variables: { - * ids: // value for 'ids' - * }, - * }); - */ -export function useDeleteManyPipelineProgressMutation(baseOptions?: Apollo.MutationHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(DeleteManyPipelineProgressDocument, options); - } -export type DeleteManyPipelineProgressMutationHookResult = ReturnType; -export type DeleteManyPipelineProgressMutationResult = Apollo.MutationResult; -export type DeleteManyPipelineProgressMutationOptions = Apollo.BaseMutationOptions; -export const UpdatePipelineStageDocument = gql` - mutation UpdatePipelineStage($id: String, $data: PipelineStageUpdateInput!) { - updateOnePipelineStage(where: {id: $id}, data: $data) { - id - name - color - } -} - `; -export type UpdatePipelineStageMutationFn = Apollo.MutationFunction; - -/** - * __useUpdatePipelineStageMutation__ - * - * To run a mutation, you first call `useUpdatePipelineStageMutation` within a React component and pass it any options that fit your needs. - * When your component renders, `useUpdatePipelineStageMutation` returns a tuple that includes: - * - A mutate function that you can call at any time to execute the mutation - * - An object with fields that represent the current status of the mutation's execution - * - * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; - * - * @example - * const [updatePipelineStageMutation, { data, loading, error }] = useUpdatePipelineStageMutation({ - * variables: { - * id: // value for 'id' - * data: // value for 'data' - * }, - * }); - */ -export function useUpdatePipelineStageMutation(baseOptions?: Apollo.MutationHookOptions) { - const options = {...defaultOptions, ...baseOptions} - return Apollo.useMutation(UpdatePipelineStageDocument, options); - } -export type UpdatePipelineStageMutationHookResult = ReturnType; -export type UpdatePipelineStageMutationResult = Apollo.MutationResult; -export type UpdatePipelineStageMutationOptions = Apollo.BaseMutationOptions; +export type CreateOneCompanyPipelineProgressMutationHookResult = ReturnType; +export type CreateOneCompanyPipelineProgressMutationResult = Apollo.MutationResult; +export type CreateOneCompanyPipelineProgressMutationOptions = Apollo.BaseMutationOptions; export const SearchPeopleDocument = gql` query SearchPeople($where: PersonWhereInput, $limit: Int, $orderBy: [PersonOrderByWithRelationInput!]) { searchResults: findManyPerson(where: $where, take: $limit, orderBy: $orderBy) { @@ -4309,6 +5179,8 @@ export const SearchPeopleDocument = gql` city firstName lastName + displayName + avatarUrl createdAt } } @@ -4458,6 +5330,49 @@ export function useSearchCompanyLazyQuery(baseOptions?: Apollo.LazyQueryHookOpti export type SearchCompanyQueryHookResult = ReturnType; export type SearchCompanyLazyQueryHookResult = ReturnType; export type SearchCompanyQueryResult = Apollo.QueryResult; +export const SearchActivityDocument = gql` + query SearchActivity($where: ActivityWhereInput, $limit: Int, $orderBy: [ActivityOrderByWithRelationInput!]) { + searchResults: findManyActivities( + where: $where + take: $limit + orderBy: $orderBy + ) { + id + title + body + } +} + `; + +/** + * __useSearchActivityQuery__ + * + * To run a query within a React component, call `useSearchActivityQuery` and pass it any options that fit your needs. + * When your component renders, `useSearchActivityQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useSearchActivityQuery({ + * variables: { + * where: // value for 'where' + * limit: // value for 'limit' + * orderBy: // value for 'orderBy' + * }, + * }); + */ +export function useSearchActivityQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(SearchActivityDocument, options); + } +export function useSearchActivityLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(SearchActivityDocument, options); + } +export type SearchActivityQueryHookResult = ReturnType; +export type SearchActivityLazyQueryHookResult = ReturnType; +export type SearchActivityQueryResult = Apollo.QueryResult; export const GetCurrentUserDocument = gql` query GetCurrentUser { currentUser { @@ -4467,8 +5382,10 @@ export const GetCurrentUserDocument = gql` firstName lastName avatarUrl + canImpersonate workspaceMember { id + allowImpersonation workspace { id domainName @@ -4604,6 +5521,40 @@ export function useUpdateUserMutation(baseOptions?: Apollo.MutationHookOptions; export type UpdateUserMutationResult = Apollo.MutationResult; export type UpdateUserMutationOptions = Apollo.BaseMutationOptions; +export const UpdateAllowImpersonationDocument = gql` + mutation UpdateAllowImpersonation($allowImpersonation: Boolean!) { + allowImpersonation(allowImpersonation: $allowImpersonation) { + id + allowImpersonation + } +} + `; +export type UpdateAllowImpersonationMutationFn = Apollo.MutationFunction; + +/** + * __useUpdateAllowImpersonationMutation__ + * + * To run a mutation, you first call `useUpdateAllowImpersonationMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdateAllowImpersonationMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [updateAllowImpersonationMutation, { data, loading, error }] = useUpdateAllowImpersonationMutation({ + * variables: { + * allowImpersonation: // value for 'allowImpersonation' + * }, + * }); + */ +export function useUpdateAllowImpersonationMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(UpdateAllowImpersonationDocument, options); + } +export type UpdateAllowImpersonationMutationHookResult = ReturnType; +export type UpdateAllowImpersonationMutationResult = Apollo.MutationResult; +export type UpdateAllowImpersonationMutationOptions = Apollo.BaseMutationOptions; export const UploadProfilePictureDocument = gql` mutation UploadProfilePicture($file: Upload!) { uploadProfilePicture(file: $file) @@ -4669,6 +5620,149 @@ export function useRemoveProfilePictureMutation(baseOptions?: Apollo.MutationHoo export type RemoveProfilePictureMutationHookResult = ReturnType; export type RemoveProfilePictureMutationResult = Apollo.MutationResult; export type RemoveProfilePictureMutationOptions = Apollo.BaseMutationOptions; +export const DeleteUserAccountDocument = gql` + mutation DeleteUserAccount { + deleteUserAccount { + id + } +} + `; +export type DeleteUserAccountMutationFn = Apollo.MutationFunction; + +/** + * __useDeleteUserAccountMutation__ + * + * To run a mutation, you first call `useDeleteUserAccountMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useDeleteUserAccountMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [deleteUserAccountMutation, { data, loading, error }] = useDeleteUserAccountMutation({ + * variables: { + * }, + * }); + */ +export function useDeleteUserAccountMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(DeleteUserAccountDocument, options); + } +export type DeleteUserAccountMutationHookResult = ReturnType; +export type DeleteUserAccountMutationResult = Apollo.MutationResult; +export type DeleteUserAccountMutationOptions = Apollo.BaseMutationOptions; +export const CreateViewFieldsDocument = gql` + mutation CreateViewFields($data: [ViewFieldCreateManyInput!]!) { + createManyViewField(data: $data) { + count + } +} + `; +export type CreateViewFieldsMutationFn = Apollo.MutationFunction; + +/** + * __useCreateViewFieldsMutation__ + * + * To run a mutation, you first call `useCreateViewFieldsMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useCreateViewFieldsMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [createViewFieldsMutation, { data, loading, error }] = useCreateViewFieldsMutation({ + * variables: { + * data: // value for 'data' + * }, + * }); + */ +export function useCreateViewFieldsMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(CreateViewFieldsDocument, options); + } +export type CreateViewFieldsMutationHookResult = ReturnType; +export type CreateViewFieldsMutationResult = Apollo.MutationResult; +export type CreateViewFieldsMutationOptions = Apollo.BaseMutationOptions; +export const GetViewFieldsDocument = gql` + query GetViewFields($where: ViewFieldWhereInput, $orderBy: [ViewFieldOrderByWithRelationInput!]) { + viewFields: findManyViewField(where: $where, orderBy: $orderBy) { + id + fieldName + isVisible + sizeInPx + index + } +} + `; + +/** + * __useGetViewFieldsQuery__ + * + * To run a query within a React component, call `useGetViewFieldsQuery` and pass it any options that fit your needs. + * When your component renders, `useGetViewFieldsQuery` returns an object from Apollo Client that contains loading, error, and data properties + * you can use to render your UI. + * + * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options; + * + * @example + * const { data, loading, error } = useGetViewFieldsQuery({ + * variables: { + * where: // value for 'where' + * orderBy: // value for 'orderBy' + * }, + * }); + */ +export function useGetViewFieldsQuery(baseOptions?: Apollo.QueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useQuery(GetViewFieldsDocument, options); + } +export function useGetViewFieldsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useLazyQuery(GetViewFieldsDocument, options); + } +export type GetViewFieldsQueryHookResult = ReturnType; +export type GetViewFieldsLazyQueryHookResult = ReturnType; +export type GetViewFieldsQueryResult = Apollo.QueryResult; +export const UpdateViewFieldDocument = gql` + mutation UpdateViewField($data: ViewFieldUpdateInput!, $where: ViewFieldWhereUniqueInput!) { + updateOneViewField(data: $data, where: $where) { + id + fieldName + isVisible + sizeInPx + index + } +} + `; +export type UpdateViewFieldMutationFn = Apollo.MutationFunction; + +/** + * __useUpdateViewFieldMutation__ + * + * To run a mutation, you first call `useUpdateViewFieldMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useUpdateViewFieldMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [updateViewFieldMutation, { data, loading, error }] = useUpdateViewFieldMutation({ + * variables: { + * data: // value for 'data' + * where: // value for 'where' + * }, + * }); + */ +export function useUpdateViewFieldMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(UpdateViewFieldDocument, options); + } +export type UpdateViewFieldMutationHookResult = ReturnType; +export type UpdateViewFieldMutationResult = Apollo.MutationResult; +export type UpdateViewFieldMutationOptions = Apollo.BaseMutationOptions; export const GetWorkspaceMembersDocument = gql` query GetWorkspaceMembers { workspaceMembers: findManyWorkspaceMember { @@ -4842,4 +5936,36 @@ export function useRemoveWorkspaceMemberMutation(baseOptions?: Apollo.MutationHo } export type RemoveWorkspaceMemberMutationHookResult = ReturnType; export type RemoveWorkspaceMemberMutationResult = Apollo.MutationResult; -export type RemoveWorkspaceMemberMutationOptions = Apollo.BaseMutationOptions; \ No newline at end of file +export type RemoveWorkspaceMemberMutationOptions = Apollo.BaseMutationOptions; +export const DeleteCurrentWorkspaceDocument = gql` + mutation DeleteCurrentWorkspace { + deleteCurrentWorkspace { + id + } +} + `; +export type DeleteCurrentWorkspaceMutationFn = Apollo.MutationFunction; + +/** + * __useDeleteCurrentWorkspaceMutation__ + * + * To run a mutation, you first call `useDeleteCurrentWorkspaceMutation` within a React component and pass it any options that fit your needs. + * When your component renders, `useDeleteCurrentWorkspaceMutation` returns a tuple that includes: + * - A mutate function that you can call at any time to execute the mutation + * - An object with fields that represent the current status of the mutation's execution + * + * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; + * + * @example + * const [deleteCurrentWorkspaceMutation, { data, loading, error }] = useDeleteCurrentWorkspaceMutation({ + * variables: { + * }, + * }); + */ +export function useDeleteCurrentWorkspaceMutation(baseOptions?: Apollo.MutationHookOptions) { + const options = {...defaultOptions, ...baseOptions} + return Apollo.useMutation(DeleteCurrentWorkspaceDocument, options); + } +export type DeleteCurrentWorkspaceMutationHookResult = ReturnType; +export type DeleteCurrentWorkspaceMutationResult = Apollo.MutationResult; +export type DeleteCurrentWorkspaceMutationOptions = Apollo.BaseMutationOptions; \ No newline at end of file diff --git a/front/src/index.tsx b/front/src/index.tsx index 8bbd593870bc0..665a987105027 100644 --- a/front/src/index.tsx +++ b/front/src/index.tsx @@ -6,8 +6,8 @@ import { RecoilRoot } from 'recoil'; import { ApolloProvider } from '@/apollo/components/ApolloProvider'; import { ClientConfigProvider } from '@/client-config/components/ClientConfigProvider'; import { SnackBarProvider } from '@/ui/snack-bar/components/SnackBarProvider'; -import { AppThemeProvider } from '@/ui/themes/components/AppThemeProvider'; -import { ThemeType } from '@/ui/themes/themes'; +import { AppThemeProvider } from '@/ui/theme/components/AppThemeProvider'; +import { ThemeType } from '@/ui/theme/constants/theme'; import { UserProvider } from '@/users/components/UserProvider'; import '@emotion/react'; diff --git a/front/src/modules/activities/comment/CommentHeader.tsx b/front/src/modules/activities/comment/CommentHeader.tsx index ec210e7d631e9..b7071ffdb2b31 100644 --- a/front/src/modules/activities/comment/CommentHeader.tsx +++ b/front/src/modules/activities/comment/CommentHeader.tsx @@ -1,10 +1,9 @@ import { Tooltip } from 'react-tooltip'; -import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { Avatar } from '@/users/components/Avatar'; import { - beautifyExactDate, + beautifyExactDateTime, beautifyPastDateRelativeToNow, } from '~/utils/date-utils'; @@ -64,9 +63,8 @@ const StyledTooltip = styled(Tooltip)` `; export function CommentHeader({ comment, actionBar }: OwnProps) { - const theme = useTheme(); const beautifiedCreatedAt = beautifyPastDateRelativeToNow(comment.createdAt); - const exactCreatedAt = beautifyExactDate(comment.createdAt); + const exactCreatedAt = beautifyExactDateTime(comment.createdAt); const showDate = beautifiedCreatedAt !== ''; const author = comment.author; @@ -79,7 +77,7 @@ export function CommentHeader({ comment, actionBar }: OwnProps) { diff --git a/front/src/modules/activities/comment/__stories__/Comment.stories.tsx b/front/src/modules/activities/comment/__stories__/Comment.stories.tsx index aaf31f461dcc2..265a19a88ed67 100644 --- a/front/src/modules/activities/comment/__stories__/Comment.stories.tsx +++ b/front/src/modules/activities/comment/__stories__/Comment.stories.tsx @@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; -import { CommentThreadActionBar } from '../../right-drawer/components/CommentThreadActionBar'; +import { ActivityActionBar } from '../../right-drawer/components/ActivityActionBar'; import { Comment } from '../Comment'; import { mockComment, mockCommentWithLongValues } from './mock-comment'; @@ -15,7 +15,7 @@ const meta: Meta = { actionBar: { type: 'boolean', mapping: { - true: , + true: , false: undefined, }, }, diff --git a/front/src/modules/activities/comment/__stories__/CommentHeader.stories.tsx b/front/src/modules/activities/comment/__stories__/CommentHeader.stories.tsx index 3e5a53eb3773d..00def6aba7440 100644 --- a/front/src/modules/activities/comment/__stories__/CommentHeader.stories.tsx +++ b/front/src/modules/activities/comment/__stories__/CommentHeader.stories.tsx @@ -1,7 +1,7 @@ import type { Meta, StoryObj } from '@storybook/react'; import { DateTime } from 'luxon'; -import { CommentThreadActionBar } from '@/activities/right-drawer/components/CommentThreadActionBar'; +import { ActivityActionBar } from '@/activities/right-drawer/components/ActivityActionBar'; import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; import { avatarUrl } from '~/testing/mock-data/users'; @@ -17,7 +17,7 @@ const meta: Meta = { actionBar: { type: 'boolean', mapping: { - true: , + true: , false: undefined, }, }, diff --git a/front/src/modules/activities/components/ActivityAssigneePicker.tsx b/front/src/modules/activities/components/ActivityAssigneePicker.tsx new file mode 100644 index 0000000000000..17772b26ee7d1 --- /dev/null +++ b/front/src/modules/activities/components/ActivityAssigneePicker.tsx @@ -0,0 +1,79 @@ +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 { + Activity, + User, + useSearchUserQuery, + useUpdateActivityMutation, +} from '~/generated/graphql'; + +export type OwnProps = { + activity: Pick & { + accountOwner?: Pick | null; + }; + onSubmit?: () => void; + onCancel?: () => void; +}; + +type UserForSelect = EntityForSelect & { + entityType: Entity.User; +}; + +export function ActivityAssigneePicker({ + activity, + onSubmit, + onCancel, +}: OwnProps) { + const [searchFilter] = useRecoilScopedState( + relationPickerSearchFilterScopedState, + ); + const [updateActivity] = useUpdateActivityMutation(); + + const users = useFilteredSearchEntityQuery({ + queryHook: useSearchUserQuery, + selectedIds: activity?.accountOwner?.id ? [activity?.accountOwner?.id] : [], + searchFilter: searchFilter, + mappingFunction: (user) => ({ + entityType: Entity.User, + id: user.id, + name: user.displayName, + avatarType: 'rounded', + avatarUrl: user.avatarUrl ?? '', + }), + orderByField: 'firstName', + searchOnFields: ['firstName', 'lastName'], + }); + + async function handleEntitySelected( + selectedUser: UserForSelect | null | undefined, + ) { + if (selectedUser) { + await updateActivity({ + variables: { + where: { id: activity.id }, + data: { + assignee: { connect: { id: selectedUser.id } }, + }, + }, + }); + } + + onSubmit?.(); + } + + return ( + + ); +} diff --git a/front/src/modules/activities/components/CommentThreadBodyEditor.tsx b/front/src/modules/activities/components/ActivityBodyEditor.tsx similarity index 55% rename from front/src/modules/activities/components/CommentThreadBodyEditor.tsx rename to front/src/modules/activities/components/ActivityBodyEditor.tsx index ddf4bad5cf8ce..61f7ee0a0c606 100644 --- a/front/src/modules/activities/components/CommentThreadBodyEditor.tsx +++ b/front/src/modules/activities/components/ActivityBodyEditor.tsx @@ -6,24 +6,21 @@ import styled from '@emotion/styled'; import debounce from 'lodash.debounce'; import { BlockEditor } from '@/ui/editor/components/BlockEditor'; -import { - CommentThread, - useUpdateCommentThreadMutation, -} from '~/generated/graphql'; +import { Activity, useUpdateActivityMutation } from '~/generated/graphql'; -import { GET_COMMENT_THREADS_BY_TARGETS } from '../queries/select'; +import { GET_ACTIVITIES_BY_TARGETS } from '../queries/select'; const BlockNoteStyledContainer = styled.div` width: 100%; `; type OwnProps = { - commentThread: Pick; - onChange?: (commentThreadBody: string) => void; + activity: Pick; + onChange?: (activityBody: string) => void; }; -export function CommentThreadBodyEditor({ commentThread, onChange }: OwnProps) { - const [updateCommentThreadMutation] = useUpdateCommentThreadMutation(); +export function ActivityBodyEditor({ activity, onChange }: OwnProps) { + const [updateActivityMutation] = useUpdateActivityMutation(); const [body, setBody] = useState(null); @@ -34,26 +31,26 @@ export function CommentThreadBodyEditor({ commentThread, onChange }: OwnProps) { }, [body, onChange]); const debounceOnChange = useMemo(() => { - function onInternalChange(commentThreadBody: string) { - setBody(commentThreadBody); - updateCommentThreadMutation({ + function onInternalChange(activityBody: string) { + setBody(activityBody); + updateActivityMutation({ variables: { - id: commentThread.id, - body: commentThreadBody, + where: { + id: activity.id, + }, + data: { + body: activityBody, + }, }, - refetchQueries: [ - getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '', - ], + refetchQueries: [getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? ''], }); } return debounce(onInternalChange, 200); - }, [commentThread, updateCommentThreadMutation, setBody]); + }, [activity, updateActivityMutation, setBody]); const editor: BlockNoteEditor | null = useBlockNote({ - initialContent: commentThread.body - ? JSON.parse(commentThread.body) - : undefined, + initialContent: activity.body ? JSON.parse(activity.body) : undefined, editorDOMAttributes: { class: 'editor' }, onEditorContentChange: (editor) => { debounceOnChange(JSON.stringify(editor.topLevelBlocks) ?? ''); diff --git a/front/src/modules/activities/components/CommentThreadComments.tsx b/front/src/modules/activities/components/ActivityComments.tsx similarity index 79% rename from front/src/modules/activities/components/CommentThreadComments.tsx rename to front/src/modules/activities/components/ActivityComments.tsx index 363391b451689..059df97816fd7 100644 --- a/front/src/modules/activities/components/CommentThreadComments.tsx +++ b/front/src/modules/activities/components/ActivityComments.tsx @@ -4,17 +4,17 @@ import { useRecoilValue } from 'recoil'; import { v4 } from 'uuid'; import { currentUserState } from '@/auth/states/currentUserState'; -import { useIsMobile } from '@/ui/hooks/useIsMobile'; -import { AutosizeTextInput } from '@/ui/input/components/AutosizeTextInput'; -import { CommentThread, useCreateCommentMutation } from '~/generated/graphql'; +import { AutosizeTextInput } from '@/ui/input/autosize-text/components/AutosizeTextInput'; +import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; +import { Activity, useCreateCommentMutation } from '~/generated/graphql'; import { isNonEmptyString } from '~/utils/isNonEmptyString'; import { Comment } from '../comment/Comment'; -import { GET_COMMENT_THREAD } from '../queries'; +import { GET_ACTIVITY } from '../queries'; import { CommentForDrawer } from '../types/CommentForDrawer'; type OwnProps = { - commentThread: Pick & { + activity: Pick & { comments: Array; }; }; @@ -52,7 +52,7 @@ const StyledThreadCommentTitle = styled.div` text-transform: uppercase; `; -export function CommentThreadComments({ commentThread }: OwnProps) { +export function ActivityComments({ activity }: OwnProps) { const [createCommentMutation] = useCreateCommentMutation(); const currentUser = useRecoilValue(currentUserState); @@ -69,21 +69,21 @@ export function CommentThreadComments({ commentThread }: OwnProps) { variables: { commentId: v4(), authorId: currentUser?.id ?? '', - commentThreadId: commentThread?.id ?? '', + activityId: activity?.id ?? '', commentText: commentText, createdAt: new Date().toISOString(), }, - refetchQueries: [getOperationName(GET_COMMENT_THREAD) ?? ''], + refetchQueries: [getOperationName(GET_ACTIVITY) ?? ''], }); } return ( <> - {commentThread?.comments.length > 0 && ( + {activity?.comments.length > 0 && ( <> Comments - {commentThread?.comments?.map((comment) => ( + {activity?.comments?.map((comment) => ( ))} diff --git a/front/src/modules/activities/components/CommentThreadCreateButton.tsx b/front/src/modules/activities/components/ActivityCreateButton.tsx similarity index 88% rename from front/src/modules/activities/components/CommentThreadCreateButton.tsx rename to front/src/modules/activities/components/ActivityCreateButton.tsx index fb63159364b76..767d4be1dde9e 100644 --- a/front/src/modules/activities/components/CommentThreadCreateButton.tsx +++ b/front/src/modules/activities/components/ActivityCreateButton.tsx @@ -4,17 +4,17 @@ import { Button, ButtonVariant } from '@/ui/button/components/Button'; import { ButtonGroup } from '@/ui/button/components/ButtonGroup'; import { IconCheckbox, IconNotes, IconTimelineEvent } from '@/ui/icon/index'; -type CommentThreadCreateButtonProps = { +type ActivityCreateButtonProps = { onNoteClick?: () => void; onTaskClick?: () => void; onActivityClick?: () => void; }; -export function CommentThreadCreateButton({ +export function ActivityCreateButton({ onNoteClick, onTaskClick, onActivityClick, -}: CommentThreadCreateButtonProps) { +}: ActivityCreateButtonProps) { const theme = useTheme(); return ( diff --git a/front/src/modules/activities/components/ActivityEditor.tsx b/front/src/modules/activities/components/ActivityEditor.tsx new file mode 100644 index 0000000000000..fe3bb29e90a21 --- /dev/null +++ b/front/src/modules/activities/components/ActivityEditor.tsx @@ -0,0 +1,202 @@ +import React, { useCallback, useState } from 'react'; +import { getOperationName } from '@apollo/client/utilities'; +import styled from '@emotion/styled'; + +import { ActivityBodyEditor } from '@/activities/components/ActivityBodyEditor'; +import { ActivityComments } from '@/activities/components/ActivityComments'; +import { ActivityTypeDropdown } from '@/activities/components/ActivityTypeDropdown'; +import { GET_ACTIVITIES_BY_TARGETS } from '@/activities/queries'; +import { PropertyBox } from '@/ui/editable-field/property-box/components/PropertyBox'; +import { DateEditableField } from '@/ui/editable-field/variants/components/DateEditableField'; +import { IconCalendar } from '@/ui/icon/index'; +import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; +import { + Activity, + ActivityTarget, + ActivityType, + User, + useUpdateActivityMutation, +} from '~/generated/graphql'; +import { debounce } from '~/utils/debounce'; + +import { ActivityAssigneeEditableField } from '../editable-fields/components/ActivityAssigneeEditableField'; +import { ActivityRelationEditableField } from '../editable-fields/components/ActivityRelationEditableField'; +import { CommentForDrawer } from '../types/CommentForDrawer'; + +import { ActivityTitle } from './ActivityTitle'; + +import '@blocknote/core/style.css'; + +const StyledContainer = styled.div` + box-sizing: border-box; + display: flex; + flex-direction: column; + height: 100%; + justify-content: space-between; + overflow-y: auto; +`; + +const StyledUpperPartContainer = styled.div` + align-items: flex-start; + box-sizing: border-box; + display: flex; + flex-direction: column; + + gap: ${({ theme }) => theme.spacing(4)}; + justify-content: flex-start; +`; + +const StyledTopContainer = styled.div` + align-items: flex-start; + align-self: stretch; + background: ${({ theme }) => theme.background.secondary}; + border-bottom: ${({ theme }) => + useIsMobile() ? 'none' : `1px solid ${theme.border.color.medium}`}; + display: flex; + flex-direction: column; + gap: 24px; + padding: 24px 24px 24px 48px; +`; + +type OwnProps = { + activity: Pick< + Activity, + 'id' | 'title' | 'body' | 'type' | 'completedAt' | 'dueAt' + > & { + comments?: Array | null; + } & { + assignee?: Pick< + User, + 'id' | 'firstName' | 'lastName' | 'displayName' + > | null; + } & { + activityTargets?: Array< + Pick + > | null; + }; + showComment?: boolean; + autoFillTitle?: boolean; +}; + +export function ActivityEditor({ + activity, + showComment = true, + autoFillTitle = false, +}: OwnProps) { + const [hasUserManuallySetTitle, setHasUserManuallySetTitle] = + useState(false); + + const [title, setTitle] = useState(activity.title ?? ''); + const [completedAt, setCompletedAt] = useState( + activity.completedAt ?? '', + ); + + const [updateActivityMutation] = useUpdateActivityMutation(); + + const updateTitle = useCallback( + (newTitle: string) => { + updateActivityMutation({ + variables: { + where: { + id: activity.id, + }, + data: { + title: newTitle ?? '', + }, + }, + refetchQueries: [getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? ''], + }); + }, + [activity, updateActivityMutation], + ); + + const handleActivityCompletionChange = useCallback( + (value: boolean) => { + updateActivityMutation({ + variables: { + where: { + id: activity.id, + }, + data: { + completedAt: value ? new Date().toISOString() : null, + }, + }, + refetchQueries: [getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? ''], + }); + setCompletedAt(value ? new Date().toISOString() : null); + }, + [activity, updateActivityMutation], + ); + + const debouncedUpdateTitle = debounce(updateTitle, 200); + + function updateTitleFromBody(body: string) { + const parsedTitle = JSON.parse(body)[0]?.content[0]?.text; + if (!hasUserManuallySetTitle && autoFillTitle) { + setTitle(parsedTitle); + debouncedUpdateTitle(parsedTitle); + } + } + + if (!activity) { + return <>; + } + + return ( + + + + + { + setTitle(newTitle); + setHasUserManuallySetTitle(true); + debouncedUpdateTitle(newTitle); + }} + onCompletionChange={handleActivityCompletionChange} + /> + + {activity.type === ActivityType.Task && ( + <> + } + label="Due date" + onSubmit={(newDate) => { + updateActivityMutation({ + variables: { + where: { + id: activity.id, + }, + data: { + dueAt: newDate, + }, + }, + }); + }} + /> + + + )} + + + + + + {showComment && ( + + )} + + ); +} diff --git a/front/src/modules/activities/components/CommentThreadRelationPicker.tsx b/front/src/modules/activities/components/ActivityRelationPicker.tsx similarity index 78% rename from front/src/modules/activities/components/CommentThreadRelationPicker.tsx rename to front/src/modules/activities/components/ActivityRelationPicker.tsx index dff9c41c5ab53..2a9a6d4071bf2 100644 --- a/front/src/modules/activities/components/CommentThreadRelationPicker.tsx +++ b/front/src/modules/activities/components/ActivityRelationPicker.tsx @@ -12,25 +12,22 @@ import { CompanyChip } from '@/companies/components/CompanyChip'; import { useFilteredSearchCompanyQuery } from '@/companies/queries'; import { PersonChip } from '@/people/components/PersonChip'; import { useFilteredSearchPeopleQuery } from '@/people/queries'; -import { useListenClickOutside } from '@/ui/hooks/useListenClickOutside'; -import { usePreviousHotkeyScope } from '@/ui/hotkey/hooks/usePreviousHotkeyScope'; -import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys'; -import { RecoilScope } from '@/ui/recoil-scope/components/RecoilScope'; -import { MultipleEntitySelect } from '@/ui/relation-picker/components/MultipleEntitySelect'; -import { RelationPickerHotkeyScope } from '@/ui/relation-picker/types/RelationPickerHotkeyScope'; -import { - CommentableType, - CommentThread, - CommentThreadTarget, -} from '~/generated/graphql'; - -import { useHandleCheckableCommentThreadTargetChange } from '../hooks/useHandleCheckableCommentThreadTargetChange'; +import { MultipleEntitySelect } from '@/ui/input/relation-picker/components/MultipleEntitySelect'; +import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope'; +import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope'; +import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys'; +import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; +import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope'; +import { Activity, ActivityTarget, CommentableType } from '~/generated/graphql'; +import { assertNotNull } from '~/utils/assert'; + +import { useHandleCheckableActivityTargetChange } from '../hooks/useHandleCheckableActivityTargetChange'; import { flatMapAndSortEntityForSelectArrayOfArrayByName } from '../utils/flatMapAndSortEntityForSelectArrayByName'; type OwnProps = { - commentThread?: Pick & { - commentThreadTargets: Array< - Pick + activity?: Pick & { + activityTargets: Array< + Pick >; }; }; @@ -75,7 +72,7 @@ const StyledMenuWrapper = styled.div` z-index: ${({ theme }) => theme.lastLayerZIndex}; `; -export function CommentThreadRelationPicker({ commentThread }: OwnProps) { +export function ActivityRelationPicker({ activity }: OwnProps) { const [isMenuOpen, setIsMenuOpen] = useState(false); const [searchFilter, setSearchFilter] = useState(''); const [selectedEntityIds, setSelectedEntityIds] = useState< @@ -88,17 +85,20 @@ export function CommentThreadRelationPicker({ commentThread }: OwnProps) { const initialPeopleIds = useMemo( () => - commentThread?.commentThreadTargets + activity?.activityTargets ?.filter((relation) => relation.commentableType === 'Person') - .map((relation) => relation.commentableId) ?? [], - [commentThread?.commentThreadTargets], + .map((relation) => relation.commentableId) + .filter(assertNotNull) ?? [], + [activity?.activityTargets], ); + const initialCompanyIds = useMemo( () => - commentThread?.commentThreadTargets + activity?.activityTargets ?.filter((relation) => relation.commentableType === 'Company') - .map((relation) => relation.commentableId) ?? [], - [commentThread?.commentThreadTargets], + .map((relation) => relation.commentableId) + .filter(assertNotNull) ?? [], + [activity?.activityTargets], ); const initialSelectedEntityIds = useMemo( @@ -135,8 +135,8 @@ export function CommentThreadRelationPicker({ commentThread }: OwnProps) { companiesForMultiSelect.entitiesToSelect, ]); - const handleCheckItemsChange = useHandleCheckableCommentThreadTargetChange({ - commentThread, + const handleCheckItemsChange = useHandleCheckableActivityTargetChange({ + activity, }); const exitEditMode = useCallback(() => { @@ -216,7 +216,12 @@ export function CommentThreadRelationPicker({ commentThread }: OwnProps) { pictureUrl={entity.avatarUrl} /> ) : ( - + ), )} diff --git a/front/src/modules/activities/components/ActivityTargetChips.tsx b/front/src/modules/activities/components/ActivityTargetChips.tsx new file mode 100644 index 0000000000000..5fd3b4ce0c31f --- /dev/null +++ b/front/src/modules/activities/components/ActivityTargetChips.tsx @@ -0,0 +1,43 @@ +import styled from '@emotion/styled'; + +import { CompanyChip } from '@/companies/components/CompanyChip'; +import { PersonChip } from '@/people/components/PersonChip'; +import { GetCompaniesQuery, GetPeopleQuery } from '~/generated/graphql'; +import { getLogoUrlFromDomainName } from '~/utils'; + +const StyledContainer = styled.div` + display: flex; + flex-wrap: wrap; + gap: ${({ theme }) => theme.spacing(1)}; +`; + +export function ActivityTargetChips({ + targetCompanies, + targetPeople, +}: { + targetCompanies?: GetCompaniesQuery; + targetPeople?: GetPeopleQuery; +}) { + return ( + + {targetCompanies?.companies && + targetCompanies.companies.map((company) => ( + + ))} + {targetPeople?.people && + targetPeople.people.map((person) => ( + + ))} + + ); +} diff --git a/front/src/modules/activities/components/CommentThreadTitle.tsx b/front/src/modules/activities/components/ActivityTitle.tsx similarity index 95% rename from front/src/modules/activities/components/CommentThreadTitle.tsx rename to front/src/modules/activities/components/ActivityTitle.tsx index f6c707a4bb7cb..0faeeb27dd8b0 100644 --- a/front/src/modules/activities/components/CommentThreadTitle.tsx +++ b/front/src/modules/activities/components/ActivityTitle.tsx @@ -4,7 +4,7 @@ import { Checkbox, CheckboxShape, CheckboxSize, -} from '@/ui/input/components/Checkbox'; +} from '@/ui/input/checkbox/components/Checkbox'; import { ActivityType } from '~/generated/graphql'; const StyledEditableTitleInput = styled.input<{ @@ -35,6 +35,7 @@ const StyledContainer = styled.div` display: flex; flex-direction: row; gap: ${({ theme }) => theme.spacing(2)}; + width: 100%; `; const StyledCheckboxContainer = styled.div` @@ -51,7 +52,7 @@ type OwnProps = { onCompletionChange: (value: boolean) => void; }; -export function CommentThreadTitle({ +export function ActivityTitle({ title, completed, type, diff --git a/front/src/modules/activities/components/ActivityTypeDropdown.tsx b/front/src/modules/activities/components/ActivityTypeDropdown.tsx new file mode 100644 index 0000000000000..fb3a6ef690183 --- /dev/null +++ b/front/src/modules/activities/components/ActivityTypeDropdown.tsx @@ -0,0 +1,33 @@ +import { useTheme } from '@emotion/react'; + +import { + Chip, + ChipAccent, + ChipSize, + ChipVariant, +} from '@/ui/chip/components/Chip'; +import { IconCheckbox, IconNotes } from '@/ui/icon'; +import { Activity, ActivityType } from '~/generated/graphql'; + +type OwnProps = { + activity: Pick; +}; + +export function ActivityTypeDropdown({ activity }: OwnProps) { + const theme = useTheme(); + return ( + + ) : ( + + ) + } + size={ChipSize.Large} + accent={ChipAccent.TextSecondary} + variant={ChipVariant.Highlighted} + /> + ); +} diff --git a/front/src/modules/activities/components/CommentThreadEditor.tsx b/front/src/modules/activities/components/CommentThreadEditor.tsx deleted file mode 100644 index 92e6c7099c60e..0000000000000 --- a/front/src/modules/activities/components/CommentThreadEditor.tsx +++ /dev/null @@ -1,192 +0,0 @@ -import React, { useCallback, useState } from 'react'; -import { getOperationName } from '@apollo/client/utilities'; -import styled from '@emotion/styled'; - -import { CommentThreadBodyEditor } from '@/activities/components/CommentThreadBodyEditor'; -import { CommentThreadComments } from '@/activities/components/CommentThreadComments'; -import { CommentThreadRelationPicker } from '@/activities/components/CommentThreadRelationPicker'; -import { CommentThreadTypeDropdown } from '@/activities/components/CommentThreadTypeDropdown'; -import { GET_COMMENT_THREADS_BY_TARGETS } from '@/activities/queries'; -import { PropertyBox } from '@/ui/editable-field/property-box/components/PropertyBox'; -import { PropertyBoxItem } from '@/ui/editable-field/property-box/components/PropertyBoxItem'; -import { useIsMobile } from '@/ui/hooks/useIsMobile'; -import { IconArrowUpRight } from '@/ui/icon/index'; -import { - CommentThread, - CommentThreadTarget, - useUpdateCommentThreadMutation, -} from '~/generated/graphql'; -import { debounce } from '~/utils/debounce'; - -import { CommentThreadActionBar } from '../right-drawer/components/CommentThreadActionBar'; -import { CommentForDrawer } from '../types/CommentForDrawer'; - -import { CommentThreadTitle } from './CommentThreadTitle'; - -import '@blocknote/core/style.css'; - -const StyledContainer = styled.div` - box-sizing: border-box; - display: flex; - flex-direction: column; - height: 100%; - justify-content: space-between; - overflow-y: auto; -`; - -const StyledUpperPartContainer = styled.div` - align-items: flex-start; - box-sizing: border-box; - display: flex; - flex-direction: column; - - gap: ${({ theme }) => theme.spacing(4)}; - justify-content: flex-start; -`; - -const StyledTopContainer = styled.div` - align-items: flex-start; - align-self: stretch; - background: ${({ theme }) => theme.background.secondary}; - border-bottom: ${({ theme }) => - useIsMobile() ? 'none' : `1px solid ${theme.border.color.medium}`}; - display: flex; - flex-direction: column; - gap: 24px; - padding: 24px 24px 24px 48px; -`; - -const StyledTopActionsContainer = styled.div` - align-items: center; - display: flex; - flex-direction: row; - justify-content: space-between; - width: 100%; -`; - -type OwnProps = { - commentThread: Pick< - CommentThread, - 'id' | 'title' | 'body' | 'type' | 'completedAt' - > & { - comments?: Array | null; - } & { - commentThreadTargets?: Array< - Pick - > | null; - }; - showComment?: boolean; - autoFillTitle?: boolean; -}; - -export function CommentThreadEditor({ - commentThread, - showComment = true, - autoFillTitle = false, -}: OwnProps) { - const [hasUserManuallySetTitle, setHasUserManuallySetTitle] = - useState(false); - - const [title, setTitle] = useState(commentThread.title ?? ''); - const [completedAt, setCompletedAt] = useState( - commentThread.completedAt ?? '', - ); - - const [updateCommentThreadMutation] = useUpdateCommentThreadMutation(); - - const updateTitle = useCallback( - (newTitle: string) => { - updateCommentThreadMutation({ - variables: { - id: commentThread.id, - title: newTitle ?? '', - }, - refetchQueries: [ - getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '', - ], - }); - }, - [commentThread, updateCommentThreadMutation], - ); - - const handleActivityCompletionChange = useCallback( - (value: boolean) => { - updateCommentThreadMutation({ - variables: { - id: commentThread.id, - completedAt: value ? new Date().toISOString() : null, - }, - refetchQueries: [ - getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '', - ], - }); - setCompletedAt(value ? new Date().toISOString() : null); - }, - [commentThread, updateCommentThreadMutation], - ); - - const debouncedUpdateTitle = debounce(updateTitle, 200); - - function updateTitleFromBody(body: string) { - const parsedTitle = JSON.parse(body)[0]?.content[0]?.text; - if (!hasUserManuallySetTitle && autoFillTitle) { - setTitle(parsedTitle); - debouncedUpdateTitle(parsedTitle); - } - } - - if (!commentThread) { - return <>; - } - - return ( - - - - - - - - { - setTitle(newTitle); - setHasUserManuallySetTitle(true); - debouncedUpdateTitle(newTitle); - }} - onCompletionChange={handleActivityCompletionChange} - /> - - } - value={ - - } - label="Relations" - /> - - - - - {showComment && ( - - )} - - ); -} diff --git a/front/src/modules/activities/components/CommentThreadTypeDropdown.tsx b/front/src/modules/activities/components/CommentThreadTypeDropdown.tsx deleted file mode 100644 index eef0771b74b83..0000000000000 --- a/front/src/modules/activities/components/CommentThreadTypeDropdown.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { useTheme } from '@emotion/react'; - -import { - Chip, - ChipAccent, - ChipSize, - ChipVariant, -} from '@/ui/chip/components/Chip'; -import { IconPhone } from '@/ui/icon'; -import { CommentThread } from '~/generated/graphql'; - -type OwnProps = { - commentThread: Pick; -}; - -export function CommentThreadTypeDropdown({ commentThread }: OwnProps) { - const theme = useTheme(); - return ( - } - size={ChipSize.Large} - accent={ChipAccent.TextSecondary} - variant={ChipVariant.Highlighted} - /> - ); -} diff --git a/front/src/modules/activities/components/TaskGroups.tsx b/front/src/modules/activities/components/TaskGroups.tsx new file mode 100644 index 0000000000000..33330c827c2e0 --- /dev/null +++ b/front/src/modules/activities/components/TaskGroups.tsx @@ -0,0 +1,13 @@ +import { useTasks } from '../hooks/useTasks'; + +import { TaskList } from './TaskList'; + +export function TaskGroups() { + const { todayOrPreviousTasks, upcomingTasks } = useTasks(); + return ( + <> + + + + ); +} diff --git a/front/src/modules/activities/components/TaskList.tsx b/front/src/modules/activities/components/TaskList.tsx new file mode 100644 index 0000000000000..966527fa319f1 --- /dev/null +++ b/front/src/modules/activities/components/TaskList.tsx @@ -0,0 +1,61 @@ +import styled from '@emotion/styled'; + +import { TaskForList } from '../types/TaskForList'; + +import { TaskRow } from './TaskRow'; + +type OwnProps = { + title: string; + tasks: TaskForList[]; +}; + +const StyledContainer = styled.div` + align-items: flex-start; + align-self: stretch; + display: flex; + flex-direction: column; + justify-content: center; + padding: 8px 24px; +`; + +const StyledTitle = styled.h3` + color: ${({ theme }) => theme.font.color.primary}; + margin-bottom: ${({ theme }) => theme.spacing(4)}; + margin-top: ${({ theme }) => theme.spacing(4)}; +`; + +const StyledCount = styled.span` + color: ${({ theme }) => theme.font.color.light}; + margin-left: ${({ theme }) => theme.spacing(2)}; +`; + +const StyledTaskRows = styled.div` + background-color: ${({ theme }) => theme.background.secondary}; + border: 1px solid ${({ theme }) => theme.border.color.light}; + border-radius: ${({ theme }) => theme.border.radius.md}; + width: 100%; +`; + +const StyledEmptyListMessage = styled.div` + color: ${({ theme }) => theme.font.color.secondary}; + padding: ${({ theme }) => theme.spacing(4)}; +`; + +export function TaskList({ title, tasks }: OwnProps) { + return ( + + + {title} {tasks ? tasks.length : 0} + + {tasks && tasks.length > 0 ? ( + + {tasks.map((task) => ( + + ))} + + ) : ( + No task in this section + )} + + ); +} diff --git a/front/src/modules/activities/components/TaskRow.tsx b/front/src/modules/activities/components/TaskRow.tsx new file mode 100644 index 0000000000000..d3f0c450e7920 --- /dev/null +++ b/front/src/modules/activities/components/TaskRow.tsx @@ -0,0 +1,132 @@ +import { useTheme } from '@emotion/react'; +import styled from '@emotion/styled'; + +import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips'; +import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer'; +import { IconCalendar, IconComment } from '@/ui/icon'; +import { + Checkbox, + CheckboxShape, +} from '@/ui/input/checkbox/components/Checkbox'; +import { OverflowingTextWithTooltip } from '@/ui/tooltip/OverflowingTextWithTooltip'; +import { useGetCompaniesQuery, useGetPeopleQuery } from '~/generated/graphql'; +import { beautifyExactDate } from '~/utils/date-utils'; + +import { useCompleteTask } from '../hooks/useCompleteTask'; +import { TaskForList } from '../types/TaskForList'; + +const StyledContainer = styled.div` + align-items: center; + align-self: stretch; + border-bottom: 1px solid ${({ theme }) => theme.border.color.light}; + cursor: pointer; + display: inline-flex; + height: ${({ theme }) => theme.spacing(12)}; + min-width: calc(100% - ${({ theme }) => theme.spacing(8)}); + padding: 0 ${({ theme }) => theme.spacing(4)}; +`; + +const StyledTaskBody = styled.div` + color: ${({ theme }) => theme.font.color.tertiary}; + display: flex; + flex-direction: row; + flex-grow: 1; + width: 1px; +`; + +const StyledTaskTitle = styled.div` + font-weight: ${({ theme }) => theme.font.weight.medium}; + padding: 0 ${({ theme }) => theme.spacing(2)}; +`; + +const StyledCommentIcon = styled.div` + align-items: center; + color: ${({ theme }) => theme.font.color.light}; + display: flex; + margin-left: ${({ theme }) => theme.spacing(2)}; +`; + +const StyledDueDate = styled.div` + align-items: center; + color: ${({ theme }) => theme.font.color.secondary}; + display: flex; + gap: ${({ theme }) => theme.spacing(1)}; + padding-left: ${({ theme }) => theme.spacing(2)}; +`; + +const StyledFieldsContainer = styled.div` + display: flex; +`; + +export function TaskRow({ task }: { task: TaskForList }) { + const theme = useTheme(); + const openActivityRightDrawer = useOpenActivityRightDrawer(); + const { data: targetPeople } = useGetPeopleQuery({ + variables: { + where: { + id: { + in: task?.activityTargets + ? task?.activityTargets + .filter((target) => target.commentableType === 'Person') + .map((target) => target.commentableId ?? '') + : [], + }, + }, + }, + }); + + const { data: targetCompanies } = useGetCompaniesQuery({ + variables: { + where: { + id: { + in: task?.activityTargets + ? task?.activityTargets + .filter((target) => target.commentableType === 'Company') + .map((target) => target.commentableId ?? '') + : [], + }, + }, + }, + }); + const body = JSON.parse(task.body ?? '{}')[0]?.content[0]?.text; + const { completeTask } = useCompleteTask(task); + + return ( + { + openActivityRightDrawer(task.id); + }} + > +
{ + e.stopPropagation(); + }} + > + +
+ {task.title ?? '(No title)'} + + + {task.comments && task.comments.length > 0 && ( + + + + )} + + + + + + {task.dueAt && beautifyExactDate(task.dueAt)} + + +
+ ); +} diff --git a/front/src/modules/activities/components/__stories__/CommentThreadRelationPicker.stories.tsx b/front/src/modules/activities/components/__stories__/ActivityRelationPicker.stories.tsx similarity index 59% rename from front/src/modules/activities/components/__stories__/CommentThreadRelationPicker.stories.tsx rename to front/src/modules/activities/components/__stories__/ActivityRelationPicker.stories.tsx index e3c57cb15a6cd..e8ca2dcd00ebc 100644 --- a/front/src/modules/activities/components/__stories__/CommentThreadRelationPicker.stories.tsx +++ b/front/src/modules/activities/components/__stories__/ActivityRelationPicker.stories.tsx @@ -4,17 +4,17 @@ import type { Meta, StoryObj } from '@storybook/react'; import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; import { graphqlMocks } from '~/testing/graphqlMocks'; -import { mockedCommentThreads } from '~/testing/mock-data/comment-threads'; +import { mockedActivities } from '~/testing/mock-data/activities'; -import { CommentThreadRelationPicker } from '../CommentThreadRelationPicker'; +import { ActivityRelationPicker } from '../ActivityRelationPicker'; const StyledContainer = styled.div` width: 400px; `; -const meta: Meta = { - title: 'Modules/Comments/CommentThreadRelationPicker', - component: CommentThreadRelationPicker, +const meta: Meta = { + title: 'Modules/Comments/ActivityRelationPicker', + component: ActivityRelationPicker, decorators: [ (Story) => ( @@ -25,13 +25,13 @@ const meta: Meta = { ), ComponentDecorator, ], - args: { commentThread: mockedCommentThreads[0] }, + args: { activity: mockedActivities[0] }, parameters: { msw: graphqlMocks, }, }; export default meta; -type Story = StoryObj; +type Story = StoryObj; export const Default: Story = {}; diff --git a/front/src/modules/activities/components/__stories__/TaskList.stories.tsx b/front/src/modules/activities/components/__stories__/TaskList.stories.tsx new file mode 100644 index 0000000000000..b9e8c6f59f0d8 --- /dev/null +++ b/front/src/modules/activities/components/__stories__/TaskList.stories.tsx @@ -0,0 +1,45 @@ +import { MemoryRouter } from 'react-router-dom'; +import type { Meta, StoryObj } from '@storybook/react'; + +import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator'; +import { graphqlMocks } from '~/testing/graphqlMocks'; +import { mockedActivities } from '~/testing/mock-data/activities'; + +import { TaskList } from '../TaskList'; + +const meta: Meta = { + title: 'Modules/Activity/TaskList', + component: TaskList, + decorators: [ + (Story) => ( + + + + ), + ComponentDecorator, + ], + args: { + title: 'Tasks', + tasks: mockedActivities, + }, + parameters: { + msw: graphqlMocks, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + title: 'Tasks', + tasks: mockedActivities, + }, +}; + +export const Empty: Story = { + args: { + title: 'No tasks', + tasks: [], + }, +}; diff --git a/front/src/modules/activities/editable-fields/components/ActivityAssigneeEditableField.tsx b/front/src/modules/activities/editable-fields/components/ActivityAssigneeEditableField.tsx new file mode 100644 index 0000000000000..9623c84930187 --- /dev/null +++ b/front/src/modules/activities/editable-fields/components/ActivityAssigneeEditableField.tsx @@ -0,0 +1,47 @@ +import { EditableField } from '@/ui/editable-field/components/EditableField'; +import { FieldContext } from '@/ui/editable-field/states/FieldContext'; +import { IconUserCircle } from '@/ui/icon'; +import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope'; +import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope'; +import { UserChip } from '@/users/components/UserChip'; +import { Company, User } from '~/generated/graphql'; + +import { ActivityAssigneeEditableFieldEditMode } from './ActivityAssigneeEditableFieldEditMode'; + +type OwnProps = { + activity: Pick & { + assignee?: Pick | null; + }; +}; + +export function ActivityAssigneeEditableField({ activity }: OwnProps) { + return ( + + + } + editModeContent={ + + } + displayModeContent={ + activity.assignee?.displayName ? ( + + ) : ( + <> + ) + } + isDisplayModeContentEmpty={!activity.assignee} + isDisplayModeFixHeight={true} + /> + + + ); +} diff --git a/front/src/modules/activities/editable-fields/components/ActivityAssigneeEditableFieldEditMode.tsx b/front/src/modules/activities/editable-fields/components/ActivityAssigneeEditableFieldEditMode.tsx new file mode 100644 index 0000000000000..5f16bd120c208 --- /dev/null +++ b/front/src/modules/activities/editable-fields/components/ActivityAssigneeEditableFieldEditMode.tsx @@ -0,0 +1,47 @@ +import styled from '@emotion/styled'; + +import { ActivityAssigneePicker } from '@/activities/components/ActivityAssigneePicker'; +import { useEditableField } from '@/ui/editable-field/hooks/useEditableField'; +import { Activity, User } from '~/generated/graphql'; + +const StyledContainer = styled.div` + left: 0px; + position: absolute; + top: -8px; +`; + +export type OwnProps = { + activity: Pick & { + assignee?: Pick | null; + }; + onSubmit?: () => void; + onCancel?: () => void; +}; + +export function ActivityAssigneeEditableFieldEditMode({ + activity, + onSubmit, + onCancel, +}: OwnProps) { + const { closeEditableField } = useEditableField(); + + function handleSubmit() { + closeEditableField(); + onSubmit?.(); + } + + function handleCancel() { + closeEditableField(); + onCancel?.(); + } + + return ( + + + + ); +} diff --git a/front/src/modules/activities/editable-fields/components/ActivityRelationEditableField.tsx b/front/src/modules/activities/editable-fields/components/ActivityRelationEditableField.tsx new file mode 100644 index 0000000000000..7c6c805de38a8 --- /dev/null +++ b/front/src/modules/activities/editable-fields/components/ActivityRelationEditableField.tsx @@ -0,0 +1,76 @@ +import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips'; +import { EditableField } from '@/ui/editable-field/components/EditableField'; +import { FieldContext } from '@/ui/editable-field/states/FieldContext'; +import { IconArrowUpRight } from '@/ui/icon'; +import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope'; +import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope'; +import { + Activity, + ActivityTarget, + useGetCompaniesQuery, + useGetPeopleQuery, +} from '~/generated/graphql'; + +import { ActivityRelationEditableFieldEditMode } from './ActivityRelationEditableFieldEditMode'; + +type OwnProps = { + activity?: Pick & { + activityTargets?: Array< + Pick + > | null; + }; +}; + +export function ActivityRelationEditableField({ activity }: OwnProps) { + const { data: targetPeople } = useGetPeopleQuery({ + variables: { + where: { + id: { + in: activity?.activityTargets + ? activity?.activityTargets + .filter((target) => target.commentableType === 'Person') + .map((target) => target.commentableId ?? '') + : [], + }, + }, + }, + }); + + const { data: targetCompanies } = useGetCompaniesQuery({ + variables: { + where: { + id: { + in: activity?.activityTargets + ? activity?.activityTargets + .filter((target) => target.commentableType === 'Company') + .map((target) => target.commentableId ?? '') + : [], + }, + }, + }, + }); + + return ( + + + } + editModeContent={ + + } + label="Relations" + displayModeContent={ + + } + /> + + + ); +} diff --git a/front/src/modules/activities/editable-fields/components/ActivityRelationEditableFieldEditMode.tsx b/front/src/modules/activities/editable-fields/components/ActivityRelationEditableFieldEditMode.tsx new file mode 100644 index 0000000000000..5539f812a6f27 --- /dev/null +++ b/front/src/modules/activities/editable-fields/components/ActivityRelationEditableFieldEditMode.tsx @@ -0,0 +1,123 @@ +import { useCallback, useMemo, useState } from 'react'; +import styled from '@emotion/styled'; + +import { useHandleCheckableActivityTargetChange } from '@/activities/hooks/useHandleCheckableActivityTargetChange'; +import { flatMapAndSortEntityForSelectArrayOfArrayByName } from '@/activities/utils/flatMapAndSortEntityForSelectArrayByName'; +import { useFilteredSearchCompanyQuery } from '@/companies/queries'; +import { useFilteredSearchPeopleQuery } from '@/people/queries'; +import { useEditableField } from '@/ui/editable-field/hooks/useEditableField'; +import { MultipleEntitySelect } from '@/ui/input/relation-picker/components/MultipleEntitySelect'; +import { Activity, ActivityTarget } from '~/generated/graphql'; +import { assertNotNull } from '~/utils/assert'; + +type OwnProps = { + activity?: Pick & { + activityTargets?: Array< + Pick + > | null; + }; +}; + +const StyledSelectContainer = styled.div` + left: 0px; + position: absolute; + top: -8px; +`; + +export function ActivityRelationEditableFieldEditMode({ activity }: OwnProps) { + const [searchFilter, setSearchFilter] = useState(''); + + const initialPeopleIds = useMemo( + () => + activity?.activityTargets + ?.filter((relation) => relation.commentableType === 'Person') + .map((relation) => relation.commentableId) + .filter(assertNotNull) ?? [], + [activity?.activityTargets], + ); + + const initialCompanyIds = useMemo( + () => + activity?.activityTargets + ?.filter((relation) => relation.commentableType === 'Company') + .map((relation) => relation.commentableId) + .filter(assertNotNull) ?? [], + [activity?.activityTargets], + ); + + const initialSelectedEntityIds = useMemo( + () => + [...initialPeopleIds, ...initialCompanyIds].reduce< + Record + >((result, entityId) => ({ ...result, [entityId]: true }), {}), + [initialPeopleIds, initialCompanyIds], + ); + + const [selectedEntityIds, setSelectedEntityIds] = useState< + Record + >(initialSelectedEntityIds); + + const personsForMultiSelect = useFilteredSearchPeopleQuery({ + searchFilter, + selectedIds: initialPeopleIds, + }); + + const companiesForMultiSelect = useFilteredSearchCompanyQuery({ + searchFilter, + selectedIds: initialCompanyIds, + }); + + const selectedEntities = flatMapAndSortEntityForSelectArrayOfArrayByName([ + personsForMultiSelect.selectedEntities, + companiesForMultiSelect.selectedEntities, + ]); + + const filteredSelectedEntities = + flatMapAndSortEntityForSelectArrayOfArrayByName([ + personsForMultiSelect.filteredSelectedEntities, + companiesForMultiSelect.filteredSelectedEntities, + ]); + + const entitiesToSelect = flatMapAndSortEntityForSelectArrayOfArrayByName([ + personsForMultiSelect.entitiesToSelect, + companiesForMultiSelect.entitiesToSelect, + ]); + + const handleCheckItemsChange = useHandleCheckableActivityTargetChange({ + activity, + }); + const { closeEditableField } = useEditableField(); + + const handleSubmit = useCallback(() => { + handleCheckItemsChange(selectedEntityIds, entitiesToSelect); + closeEditableField(); + }, [ + handleCheckItemsChange, + selectedEntityIds, + entitiesToSelect, + closeEditableField, + ]); + + function handleCancel() { + closeEditableField(); + } + + return ( + + + + ); +} diff --git a/front/src/modules/activities/hooks/useCompleteTask.ts b/front/src/modules/activities/hooks/useCompleteTask.ts new file mode 100644 index 0000000000000..8ca77eae0d48d --- /dev/null +++ b/front/src/modules/activities/hooks/useCompleteTask.ts @@ -0,0 +1,35 @@ +import { useCallback } from 'react'; +import { getOperationName } from '@apollo/client/utilities'; + +import { + GET_ACTIVITIES, + GET_ACTIVITIES_BY_TARGETS, +} from '@/activities/queries'; +import { Activity, useUpdateActivityMutation } from '~/generated/graphql'; + +type Task = Pick; + +export function useCompleteTask(task: Task) { + const [updateActivityMutation] = useUpdateActivityMutation(); + const completeTask = useCallback( + (value: boolean) => { + updateActivityMutation({ + variables: { + where: { id: task.id }, + data: { + completedAt: value ? new Date().toISOString() : null, + }, + }, + refetchQueries: [ + getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? '', + getOperationName(GET_ACTIVITIES) ?? '', + ], + }); + }, + [task, updateActivityMutation], + ); + + return { + completeTask, + }; +} diff --git a/front/src/modules/activities/hooks/useHandleCheckableActivityTargetChange.ts b/front/src/modules/activities/hooks/useHandleCheckableActivityTargetChange.ts new file mode 100644 index 0000000000000..5814ee2a491fd --- /dev/null +++ b/front/src/modules/activities/hooks/useHandleCheckableActivityTargetChange.ts @@ -0,0 +1,89 @@ +import { getOperationName } from '@apollo/client/utilities'; +import { v4 } from 'uuid'; + +import { GET_COMPANIES } from '@/companies/queries'; +import { GET_PEOPLE } from '@/people/queries'; +import { + Activity, + ActivityTarget, + useAddActivityTargetsOnActivityMutation, + useRemoveActivityTargetsOnActivityMutation, +} from '~/generated/graphql'; + +import { GET_ACTIVITY } from '../queries'; +import { CommentableEntityForSelect } from '../types/CommentableEntityForSelect'; + +export function useHandleCheckableActivityTargetChange({ + activity, +}: { + activity?: Pick & { + activityTargets?: Array< + Pick + > | null; + }; +}) { + const [addActivityTargetsOnActivity] = + useAddActivityTargetsOnActivityMutation({ + refetchQueries: [ + getOperationName(GET_COMPANIES) ?? '', + getOperationName(GET_PEOPLE) ?? '', + getOperationName(GET_ACTIVITY) ?? '', + ], + }); + + const [removeActivityTargetsOnActivity] = + useRemoveActivityTargetsOnActivityMutation({ + refetchQueries: [ + getOperationName(GET_COMPANIES) ?? '', + getOperationName(GET_PEOPLE) ?? '', + getOperationName(GET_ACTIVITY) ?? '', + ], + }); + + return async function handleCheckItemsChange( + entityValues: Record, + entities: CommentableEntityForSelect[], + ) { + if (!activity) { + return; + } + + const currentEntityIds = activity.activityTargets + ? activity.activityTargets.map(({ commentableId }) => commentableId) + : []; + + const entitiesToAdd = entities.filter( + ({ id }) => entityValues[id] && !currentEntityIds.includes(id), + ); + + if (entitiesToAdd.length) + await addActivityTargetsOnActivity({ + variables: { + activityId: activity.id, + activityTargetInputs: entitiesToAdd.map((entity) => ({ + id: v4(), + createdAt: new Date().toISOString(), + commentableType: entity.entityType, + commentableId: entity.id, + })), + }, + }); + + const activityTargetIdsToDelete = activity.activityTargets + ? activity.activityTargets + .filter( + ({ commentableId }) => + commentableId && !entityValues[commentableId], + ) + .map(({ id }) => id) + : []; + + if (activityTargetIdsToDelete.length) + await removeActivityTargetsOnActivity({ + variables: { + activityId: activity.id, + activityTargetIds: activityTargetIdsToDelete, + }, + }); + }; +} diff --git a/front/src/modules/activities/hooks/useHandleCheckableCommentThreadTargetChange.ts b/front/src/modules/activities/hooks/useHandleCheckableCommentThreadTargetChange.ts deleted file mode 100644 index 388477da4a3b1..0000000000000 --- a/front/src/modules/activities/hooks/useHandleCheckableCommentThreadTargetChange.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { getOperationName } from '@apollo/client/utilities'; -import { v4 } from 'uuid'; - -import { GET_COMPANIES } from '@/companies/queries'; -import { GET_PEOPLE } from '@/people/queries'; -import { - CommentThread, - CommentThreadTarget, - useAddCommentThreadTargetsOnCommentThreadMutation, - useRemoveCommentThreadTargetsOnCommentThreadMutation, -} from '~/generated/graphql'; - -import { GET_COMMENT_THREADS_BY_TARGETS } from '../queries'; -import { CommentableEntityForSelect } from '../types/CommentableEntityForSelect'; - -export function useHandleCheckableCommentThreadTargetChange({ - commentThread, -}: { - commentThread?: Pick & { - commentThreadTargets: Array< - Pick - >; - }; -}) { - const [addCommentThreadTargetsOnCommentThread] = - useAddCommentThreadTargetsOnCommentThreadMutation({ - refetchQueries: [ - getOperationName(GET_COMPANIES) ?? '', - getOperationName(GET_PEOPLE) ?? '', - getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '', - ], - }); - - const [removeCommentThreadTargetsOnCommentThread] = - useRemoveCommentThreadTargetsOnCommentThreadMutation({ - refetchQueries: [ - getOperationName(GET_COMPANIES) ?? '', - getOperationName(GET_PEOPLE) ?? '', - getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '', - ], - }); - - return async function handleCheckItemsChange( - entityValues: Record, - entities: CommentableEntityForSelect[], - ) { - if (!commentThread) { - return; - } - - const currentEntityIds = commentThread.commentThreadTargets.map( - ({ commentableId }) => commentableId, - ); - - const entitiesToAdd = entities.filter( - ({ id }) => entityValues[id] && !currentEntityIds.includes(id), - ); - - if (entitiesToAdd.length) - await addCommentThreadTargetsOnCommentThread({ - variables: { - commentThreadId: commentThread.id, - commentThreadTargetInputs: entitiesToAdd.map((entity) => ({ - id: v4(), - createdAt: new Date().toISOString(), - commentableType: entity.entityType, - commentableId: entity.id, - })), - }, - }); - - const commentThreadTargetIdsToDelete = commentThread.commentThreadTargets - .filter(({ commentableId }) => !entityValues[commentableId]) - .map(({ id }) => id); - - if (commentThreadTargetIdsToDelete.length) - await removeCommentThreadTargetsOnCommentThread({ - variables: { - commentThreadId: commentThread.id, - commentThreadTargetIds: commentThreadTargetIdsToDelete, - }, - }); - }; -} diff --git a/front/src/modules/activities/hooks/useInitializeTasksFilters.ts b/front/src/modules/activities/hooks/useInitializeTasksFilters.ts new file mode 100644 index 0000000000000..cc810d63ba435 --- /dev/null +++ b/front/src/modules/activities/hooks/useInitializeTasksFilters.ts @@ -0,0 +1,22 @@ +import { useEffect } from 'react'; + +import { availableFiltersScopedState } from '@/ui/filter-n-sort/states/availableFiltersScopedState'; +import { FilterDefinition } from '@/ui/filter-n-sort/types/FilterDefinition'; +import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState'; + +import { TasksContext } from '../states/TasksContext'; + +export function useInitializeTasksFilters({ + availableFilters, +}: { + availableFilters: FilterDefinition[]; +}) { + const [, setAvailableFilters] = useRecoilScopedState( + availableFiltersScopedState, + TasksContext, + ); + + useEffect(() => { + setAvailableFilters(availableFilters); + }, [setAvailableFilters, availableFilters]); +} diff --git a/front/src/modules/activities/hooks/useOpenActivityRightDrawer.ts b/front/src/modules/activities/hooks/useOpenActivityRightDrawer.ts new file mode 100644 index 0000000000000..f5ac2e6651ebb --- /dev/null +++ b/front/src/modules/activities/hooks/useOpenActivityRightDrawer.ts @@ -0,0 +1,20 @@ +import { useRecoilState } from 'recoil'; + +import { useRightDrawer } from '@/ui/right-drawer/hooks/useRightDrawer'; +import { RightDrawerHotkeyScope } from '@/ui/right-drawer/types/RightDrawerHotkeyScope'; +import { RightDrawerPages } from '@/ui/right-drawer/types/RightDrawerPages'; +import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; + +import { viewableActivityIdState } from '../states/viewableActivityIdState'; + +export function useOpenActivityRightDrawer() { + const { openRightDrawer } = useRightDrawer(); + const [, setViewableActivityId] = useRecoilState(viewableActivityIdState); + const setHotkeyScope = useSetHotkeyScope(); + + return function openActivityRightDrawer(activityId: string) { + setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false }); + setViewableActivityId(activityId); + openRightDrawer(RightDrawerPages.EditActivity); + }; +} diff --git a/front/src/modules/activities/hooks/useOpenCommentThreadRightDrawer.ts b/front/src/modules/activities/hooks/useOpenCommentThreadRightDrawer.ts deleted file mode 100644 index e678e9cc6ff60..0000000000000 --- a/front/src/modules/activities/hooks/useOpenCommentThreadRightDrawer.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { useRecoilState } from 'recoil'; - -import { useSetHotkeyScope } from '@/ui/hotkey/hooks/useSetHotkeyScope'; -import { useRightDrawer } from '@/ui/right-drawer/hooks/useRightDrawer'; -import { RightDrawerHotkeyScope } from '@/ui/right-drawer/types/RightDrawerHotkeyScope'; -import { RightDrawerPages } from '@/ui/right-drawer/types/RightDrawerPages'; - -import { viewableCommentThreadIdState } from '../states/viewableCommentThreadIdState'; - -export function useOpenCommentThreadRightDrawer() { - const { openRightDrawer } = useRightDrawer(); - const [, setViewableCommentThreadId] = useRecoilState( - viewableCommentThreadIdState, - ); - const setHotkeyScope = useSetHotkeyScope(); - - return function openCommentThreadRightDrawer(commentThreadId: string) { - setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false }); - setViewableCommentThreadId(commentThreadId); - openRightDrawer(RightDrawerPages.EditCommentThread); - }; -} diff --git a/front/src/modules/activities/hooks/useOpenCreateCommentThreadDrawer.ts b/front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts similarity index 63% rename from front/src/modules/activities/hooks/useOpenCreateCommentThreadDrawer.ts rename to front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts index 45885bcb1d18e..fd342a7d07cdc 100644 --- a/front/src/modules/activities/hooks/useOpenCreateCommentThreadDrawer.ts +++ b/front/src/modules/activities/hooks/useOpenCreateActivityDrawer.ts @@ -5,44 +5,39 @@ import { v4 } from 'uuid'; import { currentUserState } from '@/auth/states/currentUserState'; import { GET_COMPANIES } from '@/companies/queries'; import { GET_PEOPLE } from '@/people/queries'; -import { useSetHotkeyScope } from '@/ui/hotkey/hooks/useSetHotkeyScope'; import { useRightDrawer } from '@/ui/right-drawer/hooks/useRightDrawer'; import { RightDrawerHotkeyScope } from '@/ui/right-drawer/types/RightDrawerHotkeyScope'; import { RightDrawerPages } from '@/ui/right-drawer/types/RightDrawerPages'; -import { - ActivityType, - useCreateCommentThreadMutation, -} from '~/generated/graphql'; +import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; +import { ActivityType, useCreateActivityMutation } from '~/generated/graphql'; -import { GET_COMMENT_THREAD, GET_COMMENT_THREADS_BY_TARGETS } from '../queries'; +import { GET_ACTIVITIES_BY_TARGETS, GET_ACTIVITY } from '../queries'; import { commentableEntityArrayState } from '../states/commentableEntityArrayState'; -import { viewableCommentThreadIdState } from '../states/viewableCommentThreadIdState'; +import { viewableActivityIdState } from '../states/viewableActivityIdState'; import { CommentableEntity } from '../types/CommentableEntity'; -export function useOpenCreateCommentThreadDrawer() { +export function useOpenCreateActivityDrawer() { const { openRightDrawer } = useRightDrawer(); - const [createCommentThreadMutation] = useCreateCommentThreadMutation(); + const [createActivityMutation] = useCreateActivityMutation(); const currentUser = useRecoilValue(currentUserState); const setHotkeyScope = useSetHotkeyScope(); const [, setCommentableEntityArray] = useRecoilState( commentableEntityArrayState, ); - const [, setViewableCommentThreadId] = useRecoilState( - viewableCommentThreadIdState, - ); + const [, setViewableActivityId] = useRecoilState(viewableActivityIdState); - return function openCreateCommentThreadDrawer( + return function openCreateActivityDrawer( entity: CommentableEntity, type: ActivityType, ) { - createCommentThreadMutation({ + createActivityMutation({ variables: { authorId: currentUser?.id ?? '', - commentThreadId: v4(), + activityId: v4(), createdAt: new Date().toISOString(), type: type, - commentThreadTargetArray: [ + activityTargetArray: [ { commentableId: entity.id, commentableType: entity.type, @@ -54,14 +49,14 @@ export function useOpenCreateCommentThreadDrawer() { refetchQueries: [ getOperationName(GET_COMPANIES) ?? '', getOperationName(GET_PEOPLE) ?? '', - getOperationName(GET_COMMENT_THREAD) ?? '', - getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '', + getOperationName(GET_ACTIVITY) ?? '', + getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? '', ], onCompleted(data) { setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false }); - setViewableCommentThreadId(data.createOneCommentThread.id); + setViewableActivityId(data.createOneActivity.id); setCommentableEntityArray([entity]); - openRightDrawer(RightDrawerPages.CreateCommentThread); + openRightDrawer(RightDrawerPages.CreateActivity); }, }); }; diff --git a/front/src/modules/activities/hooks/useOpenCreateCommentDrawerForSelectedRowIds.ts b/front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts similarity index 69% rename from front/src/modules/activities/hooks/useOpenCreateCommentDrawerForSelectedRowIds.ts rename to front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts index a81c504934402..2efd68ea34e2e 100644 --- a/front/src/modules/activities/hooks/useOpenCreateCommentDrawerForSelectedRowIds.ts +++ b/front/src/modules/activities/hooks/useOpenCreateActivityDrawerForSelectedRowIds.ts @@ -5,29 +5,27 @@ import { v4 } from 'uuid'; import { currentUserState } from '@/auth/states/currentUserState'; import { GET_COMPANIES } from '@/companies/queries'; import { GET_PEOPLE } from '@/people/queries'; -import { useSetHotkeyScope } from '@/ui/hotkey/hooks/useSetHotkeyScope'; import { useRightDrawer } from '@/ui/right-drawer/hooks/useRightDrawer'; import { RightDrawerHotkeyScope } from '@/ui/right-drawer/types/RightDrawerHotkeyScope'; import { RightDrawerPages } from '@/ui/right-drawer/types/RightDrawerPages'; import { selectedRowIdsSelector } from '@/ui/table/states/selectedRowIdsSelector'; +import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; import { ActivityType, CommentableType, - useCreateCommentThreadMutation, + useCreateActivityMutation, } from '~/generated/graphql'; -import { GET_COMMENT_THREAD, GET_COMMENT_THREADS_BY_TARGETS } from '../queries'; +import { GET_ACTIVITIES_BY_TARGETS, GET_ACTIVITY } from '../queries'; import { commentableEntityArrayState } from '../states/commentableEntityArrayState'; -import { viewableCommentThreadIdState } from '../states/viewableCommentThreadIdState'; +import { viewableActivityIdState } from '../states/viewableActivityIdState'; import { CommentableEntity } from '../types/CommentableEntity'; -export function useOpenCreateCommentThreadDrawerForSelectedRowIds() { +export function useOpenCreateActivityDrawerForSelectedRowIds() { const { openRightDrawer } = useRightDrawer(); - const [createCommentThreadMutation] = useCreateCommentThreadMutation(); + const [createActivityMutation] = useCreateActivityMutation(); const currentUser = useRecoilValue(currentUserState); - const [, setViewableCommentThreadId] = useRecoilState( - viewableCommentThreadIdState, - ); + const [, setViewableActivityId] = useRecoilState(viewableActivityIdState); const setHotkeyScope = useSetHotkeyScope(); @@ -47,13 +45,13 @@ export function useOpenCreateCommentThreadDrawerForSelectedRowIds() { }), ); - createCommentThreadMutation({ + createActivityMutation({ variables: { authorId: currentUser?.id ?? '', - commentThreadId: v4(), + activityId: v4(), createdAt: new Date().toISOString(), type: ActivityType.Note, - commentThreadTargetArray: commentableEntityArray.map((entity) => ({ + activityTargetArray: commentableEntityArray.map((entity) => ({ commentableId: entity.id, commentableType: entity.type, id: v4(), @@ -63,14 +61,14 @@ export function useOpenCreateCommentThreadDrawerForSelectedRowIds() { refetchQueries: [ getOperationName(GET_COMPANIES) ?? '', getOperationName(GET_PEOPLE) ?? '', - getOperationName(GET_COMMENT_THREAD) ?? '', - getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '', + getOperationName(GET_ACTIVITY) ?? '', + getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? '', ], onCompleted(data) { setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false }); - setViewableCommentThreadId(data.createOneCommentThread.id); + setViewableActivityId(data.createOneActivity.id); setCommentableEntityArray(commentableEntityArray); - openRightDrawer(RightDrawerPages.CreateCommentThread); + openRightDrawer(RightDrawerPages.CreateActivity); }, }); }; diff --git a/front/src/modules/activities/hooks/useOpenTimelineRightDrawer.ts b/front/src/modules/activities/hooks/useOpenTimelineRightDrawer.ts index 796a64298588c..f36e5ef865af8 100644 --- a/front/src/modules/activities/hooks/useOpenTimelineRightDrawer.ts +++ b/front/src/modules/activities/hooks/useOpenTimelineRightDrawer.ts @@ -1,9 +1,9 @@ import { useRecoilState } from 'recoil'; -import { useSetHotkeyScope } from '@/ui/hotkey/hooks/useSetHotkeyScope'; import { useRightDrawer } from '@/ui/right-drawer/hooks/useRightDrawer'; import { RightDrawerHotkeyScope } from '@/ui/right-drawer/types/RightDrawerHotkeyScope'; import { RightDrawerPages } from '@/ui/right-drawer/types/RightDrawerPages'; +import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope'; import { commentableEntityArrayState } from '../states/commentableEntityArrayState'; import { CommentableEntity } from '../types/CommentableEntity'; diff --git a/front/src/modules/activities/hooks/useTasks.ts b/front/src/modules/activities/hooks/useTasks.ts new file mode 100644 index 0000000000000..3b5f60371d9c2 --- /dev/null +++ b/front/src/modules/activities/hooks/useTasks.ts @@ -0,0 +1,103 @@ +import { useEffect } from 'react'; +import { DateTime } from 'luxon'; +import { useRecoilState } from 'recoil'; + +import { currentUserState } from '@/auth/states/currentUserState'; +import { filtersScopedState } from '@/ui/filter-n-sort/states/filtersScopedState'; +import { turnFilterIntoWhereClause } from '@/ui/filter-n-sort/utils/turnFilterIntoWhereClause'; +import { activeTabIdScopedState } from '@/ui/tab/states/activeTabIdScopedState'; +import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState'; +import { ActivityType, useGetActivitiesQuery } from '~/generated/graphql'; +import { tasksFilters } from '~/pages/tasks/tasks-filters'; +import { parseDate } from '~/utils/date-utils'; + +import { TasksContext } from '../states/TasksContext'; + +import { useInitializeTasksFilters } from './useInitializeTasksFilters'; + +export function useTasks() { + useInitializeTasksFilters({ + availableFilters: tasksFilters, + }); + + const [activeTabId] = useRecoilScopedState( + activeTabIdScopedState, + TasksContext, + ); + + const [filters, setFilters] = useRecoilScopedState( + filtersScopedState, + TasksContext, + ); + + // If there is no filter, we set the default filter to the current user + const [currentUser] = useRecoilState(currentUserState); + + useEffect(() => { + if (currentUser && !filters.length) { + setFilters([ + { + field: 'assigneeId', + type: 'entity', + value: currentUser.id, + operand: 'is', + displayValue: currentUser.displayName, + displayAvatarUrl: currentUser.avatarUrl ?? undefined, + }, + ]); + } + }, [currentUser, filters, setFilters]); + + const whereFilters = Object.assign( + {}, + ...filters.map((filter) => { + return turnFilterIntoWhereClause(filter); + }), + ); + + const { data: completeTasksData } = useGetActivitiesQuery({ + variables: { + where: { + type: { equals: ActivityType.Task }, + completedAt: { not: { equals: null } }, + ...whereFilters, + }, + }, + }); + + const { data: incompleteTaskData } = useGetActivitiesQuery({ + variables: { + where: { + type: { equals: ActivityType.Task }, + completedAt: { equals: null }, + ...whereFilters, + }, + }, + }); + + const tasksData = + activeTabId === 'done' ? completeTasksData : incompleteTaskData; + + const todayOrPreviousTasks = tasksData?.findManyActivities.filter((task) => { + if (!task.dueAt) { + return false; + } + const dueDate = parseDate(task.dueAt).toJSDate(); + const today = DateTime.now().endOf('day').toJSDate(); + return dueDate <= today; + }); + + const upcomingTasks = tasksData?.findManyActivities.filter((task) => { + if (!task.dueAt) { + return false; + } + const dueDate = parseDate(task.dueAt).toJSDate(); + const today = DateTime.now().endOf('day').toJSDate(); + return dueDate > today; + }); + + return { + todayOrPreviousTasks, + upcomingTasks, + }; +} diff --git a/front/src/modules/activities/queries/create.ts b/front/src/modules/activities/queries/create.ts index 553eb667ba8f6..f7c3aea375eea 100644 --- a/front/src/modules/activities/queries/create.ts +++ b/front/src/modules/activities/queries/create.ts @@ -5,7 +5,7 @@ export const CREATE_COMMENT = gql` $commentId: String! $commentText: String! $authorId: String! - $commentThreadId: String! + $activityId: String! $createdAt: DateTime! ) { createOneComment( @@ -14,7 +14,7 @@ export const CREATE_COMMENT = gql` createdAt: $createdAt body: $commentText author: { connect: { id: $authorId } } - commentThread: { connect: { id: $commentThreadId } } + activity: { connect: { id: $activityId } } } ) { id @@ -27,32 +27,32 @@ export const CREATE_COMMENT = gql` lastName avatarUrl } - commentThreadId + activityId } } `; -export const CREATE_COMMENT_THREAD_WITH_COMMENT = gql` - mutation CreateCommentThread( - $commentThreadId: String! +export const CREATE_ACTIVITY_WITH_COMMENT = gql` + mutation CreateActivity( + $activityId: String! $body: String $title: String $type: ActivityType! $authorId: String! $createdAt: DateTime! - $commentThreadTargetArray: [CommentThreadTargetCreateManyCommentThreadInput!]! + $activityTargetArray: [ActivityTargetCreateManyActivityInput!]! ) { - createOneCommentThread( + createOneActivity( data: { - id: $commentThreadId + id: $activityId createdAt: $createdAt updatedAt: $createdAt author: { connect: { id: $authorId } } body: $body title: $title type: $type - commentThreadTargets: { - createMany: { data: $commentThreadTargetArray, skipDuplicates: true } + activityTargets: { + createMany: { data: $activityTargetArray, skipDuplicates: true } } } ) { @@ -61,11 +61,11 @@ export const CREATE_COMMENT_THREAD_WITH_COMMENT = gql` updatedAt authorId type - commentThreadTargets { + activityTargets { id createdAt updatedAt - commentThreadId + activityId commentableType commentableId } diff --git a/front/src/modules/activities/queries/select.ts b/front/src/modules/activities/queries/select.ts index 914b81623288a..9d29c5dd9354c 100644 --- a/front/src/modules/activities/queries/select.ts +++ b/front/src/modules/activities/queries/select.ts @@ -1,16 +1,14 @@ import { gql } from '@apollo/client'; -export const GET_COMMENT_THREADS_BY_TARGETS = gql` - query GetCommentThreadsByTargets( - $commentThreadTargetIds: [String!]! - $orderBy: [CommentThreadOrderByWithRelationInput!] +export const GET_ACTIVITIES_BY_TARGETS = gql` + query GetActivitiesByTargets( + $activityTargetIds: [String!]! + $orderBy: [ActivityOrderByWithRelationInput!] ) { - findManyCommentThreads( + findManyActivities( orderBy: $orderBy where: { - commentThreadTargets: { - some: { commentableId: { in: $commentThreadTargetIds } } - } + activityTargets: { some: { commentableId: { in: $activityTargetIds } } } } ) { id @@ -19,6 +17,13 @@ export const GET_COMMENT_THREADS_BY_TARGETS = gql` body type completedAt + dueAt + assignee { + id + firstName + lastName + displayName + } author { id firstName @@ -38,24 +43,69 @@ export const GET_COMMENT_THREADS_BY_TARGETS = gql` avatarUrl } } - commentThreadTargets { + activityTargets { id + commentableType commentableId + } + } + } +`; + +export const GET_ACTIVITIES = gql` + query GetActivities( + $where: ActivityWhereInput! + $orderBy: [ActivityOrderByWithRelationInput!] + ) { + findManyActivities(orderBy: $orderBy, where: $where) { + id + createdAt + title + body + type + completedAt + dueAt + assignee { + id + firstName + lastName + displayName + avatarUrl + } + author { + id + firstName + lastName + displayName + } + comments { + id + } + activityTargets { + id commentableType + commentableId } } } `; -export const GET_COMMENT_THREAD = gql` - query GetCommentThread($commentThreadId: String!) { - findManyCommentThreads(where: { id: { equals: $commentThreadId } }) { +export const GET_ACTIVITY = gql` + query GetActivity($activityId: String!) { + findManyActivities(where: { id: { equals: $activityId } }) { id createdAt body title type completedAt + dueAt + assignee { + id + firstName + lastName + displayName + } author { id firstName @@ -75,10 +125,10 @@ export const GET_COMMENT_THREAD = gql` avatarUrl } } - commentThreadTargets { + activityTargets { id - commentableId commentableType + commentableId } } } diff --git a/front/src/modules/activities/queries/update.ts b/front/src/modules/activities/queries/update.ts index e28a66f6d0b1d..50900d3bd8bc8 100644 --- a/front/src/modules/activities/queries/update.ts +++ b/front/src/modules/activities/queries/update.ts @@ -1,22 +1,18 @@ import { gql } from '@apollo/client'; -export const ADD_COMMENT_THREAD_TARGETS = gql` - mutation AddCommentThreadTargetsOnCommentThread( - $commentThreadId: String! - $commentThreadTargetInputs: [CommentThreadTargetCreateManyCommentThreadInput!]! +export const ADD_ACTIVITY_TARGETS = gql` + mutation AddActivityTargetsOnActivity( + $activityId: String! + $activityTargetInputs: [ActivityTargetCreateManyActivityInput!]! ) { - updateOneCommentThread( - where: { id: $commentThreadId } - data: { - commentThreadTargets: { - createMany: { data: $commentThreadTargetInputs } - } - } + updateOneActivity( + where: { id: $activityId } + data: { activityTargets: { createMany: { data: $activityTargetInputs } } } ) { id createdAt updatedAt - commentThreadTargets { + activityTargets { id createdAt updatedAt @@ -27,23 +23,21 @@ export const ADD_COMMENT_THREAD_TARGETS = gql` } `; -export const REMOVE_COMMENT_THREAD_TARGETS = gql` - mutation RemoveCommentThreadTargetsOnCommentThread( - $commentThreadId: String! - $commentThreadTargetIds: [String!]! +export const REMOVE_ACTIVITY_TARGETS = gql` + mutation RemoveActivityTargetsOnActivity( + $activityId: String! + $activityTargetIds: [String!]! ) { - updateOneCommentThread( - where: { id: $commentThreadId } + updateOneActivity( + where: { id: $activityId } data: { - commentThreadTargets: { - deleteMany: { id: { in: $commentThreadTargetIds } } - } + activityTargets: { deleteMany: { id: { in: $activityTargetIds } } } } ) { id createdAt updatedAt - commentThreadTargets { + activityTargets { id createdAt updatedAt @@ -54,36 +48,32 @@ export const REMOVE_COMMENT_THREAD_TARGETS = gql` } `; -export const DELETE_COMMENT_THREAD = gql` - mutation DeleteCommentThread($commentThreadId: String!) { - deleteManyCommentThreads(where: { id: { equals: $commentThreadId } }) { +export const DELETE_ACTIVITY = gql` + mutation DeleteActivity($activityId: String!) { + deleteManyActivities(where: { id: { equals: $activityId } }) { count } } `; -export const UPDATE_COMMENT_THREAD = gql` - mutation UpdateCommentThread( - $id: String! - $body: String - $title: String - $type: ActivityType - $completedAt: DateTime +export const UPDATE_ACTIVITY = gql` + mutation UpdateActivity( + $where: ActivityWhereUniqueInput! + $data: ActivityUpdateInput! ) { - updateOneCommentThread( - where: { id: $id } - data: { - body: $body - title: $title - type: $type - completedAt: $completedAt - } - ) { + updateOneActivity(where: $where, data: $data) { id body title type completedAt + dueAt + assignee { + id + firstName + lastName + displayName + } } } `; diff --git a/front/src/modules/activities/right-drawer/components/CommentThreadActionBar.tsx b/front/src/modules/activities/right-drawer/components/ActivityActionBar.tsx similarity index 58% rename from front/src/modules/activities/right-drawer/components/CommentThreadActionBar.tsx rename to front/src/modules/activities/right-drawer/components/ActivityActionBar.tsx index b0ec700c46c80..5ba87627167a0 100644 --- a/front/src/modules/activities/right-drawer/components/CommentThreadActionBar.tsx +++ b/front/src/modules/activities/right-drawer/components/ActivityActionBar.tsx @@ -3,35 +3,35 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { useRecoilState } from 'recoil'; -import { GET_COMMENT_THREADS_BY_TARGETS } from '@/activities/queries'; +import { GET_ACTIVITIES_BY_TARGETS } from '@/activities/queries'; import { GET_COMPANIES } from '@/companies/queries'; import { GET_PEOPLE } from '@/people/queries'; -import { Button, ButtonVariant } from '@/ui/button/components/Button'; +import { IconButton } from '@/ui/button/components/IconButton'; import { IconTrash } from '@/ui/icon'; import { isRightDrawerOpenState } from '@/ui/right-drawer/states/isRightDrawerOpenState'; -import { useDeleteCommentThreadMutation } from '~/generated/graphql'; +import { useDeleteActivityMutation } from '~/generated/graphql'; const StyledContainer = styled.div` - color: ${({ theme }) => theme.font.color.tertiary}; - cursor: pointer; + border: 1px solid ${({ theme }) => theme.border.color.medium}; + border-radius: ${({ theme }) => theme.border.radius.sm}; `; type OwnProps = { - commentThreadId: string; + activityId: string; }; -export function CommentThreadActionBar({ commentThreadId }: OwnProps) { +export function ActivityActionBar({ activityId }: OwnProps) { const theme = useTheme(); - const [createCommentMutation] = useDeleteCommentThreadMutation(); + const [createCommentMutation] = useDeleteActivityMutation(); const [, setIsRightDrawerOpen] = useRecoilState(isRightDrawerOpenState); - function deleteCommentThread() { + function deleteActivity() { createCommentMutation({ - variables: { commentThreadId }, + variables: { activityId }, refetchQueries: [ getOperationName(GET_COMPANIES) ?? '', getOperationName(GET_PEOPLE) ?? '', - getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '', + getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? '', ], }); setIsRightDrawerOpen(false); @@ -39,12 +39,11 @@ export function CommentThreadActionBar({ commentThreadId }: OwnProps) { return ( -