Skip to content

Activate/Deactivate workflow and Discard Draft #7022

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
2bff5cb
feat: allow activating workflow version and refetch its data after mu…
Devessier Sep 10, 2024
cfe15a9
feat: add buttons related to workflows in record show header
Devessier Sep 11, 2024
682f3f5
feat: allow deactivating workflow
Devessier Sep 13, 2024
1d166dc
feat: create new workflow version when trying to edit a not draft ver…
Devessier Sep 13, 2024
aba4bdc
feat: allow discard current workflow draft version
Devessier Sep 13, 2024
f352023
refactor: specialize the hook that deletes a workflow version
Devessier Sep 18, 2024
3b8bedf
fix: prevent JSON value from being serialized twice
Devessier Sep 18, 2024
de9f5eb
fix: prevent soft-deleted draft versions to leak
Devessier Sep 18, 2024
6d7e656
feat: allow to discard a draft only if it's not the first workflow ve…
Devessier Sep 18, 2024
58dff55
feat: prevent the deletion of the initial version of a workflow
Devessier Sep 20, 2024
0c1cc04
fix: don't try to deactivate deactivated and archived versions
Devessier Sep 20, 2024
bc9f761
Revert "fix: prevent JSON value from being serialized twice"
Devessier Sep 20, 2024
0c8275a
test: write tests for the RecordShowPageHearderWorkflow component
Devessier Sep 20, 2024
cb64d98
test: update msw service worker script
Devessier Sep 23, 2024
5abfebf
test: found the correct place to put metadata response
Devessier Sep 23, 2024
24da378
test: disable global msw mocks for workflows
Devessier Sep 23, 2024
c2a6067
test: change how we set up msw handlers
Devessier Sep 23, 2024
827d34c
test: find a way to properly override global msw mocks
Devessier Sep 23, 2024
a4237c6
test: associate a different workflow id to each story
Devessier Sep 23, 2024
883e635
feat: don't fetch all versions data when we only need the count of wo…
Devessier Sep 23, 2024
e928b12
refactor: extract common record show page header actions in a separat…
Devessier Sep 23, 2024
eecb639
refactor: use the number of workflow versions to compute the name of …
Devessier Sep 23, 2024
0bf8046
revert: delete the updated mock of the /metadata response
Devessier Sep 24, 2024
2f09924
build: improve seed script by creating custom objects
Devessier Sep 24, 2024
f21a854
feat: update mocked data
Devessier Sep 24, 2024
df71b0e
Deperecate getObjectMetadataItemsMock
charlesBochet Sep 25, 2024
29d0dc4
Fix tests 1
charlesBochet Sep 25, 2024
c59ae77
Fix tests
charlesBochet Sep 25, 2024
fe542ee
test: regenerate metadata mock file
Devessier Sep 25, 2024
631ab78
Fix tests
charlesBochet Sep 25, 2024
b40c560
Fix tests
charlesBochet Sep 25, 2024
73efe7d
Fix tests
charlesBochet Sep 25, 2024
8fb9da0
Fix tests
charlesBochet Sep 25, 2024
5018155
Fix tests
charlesBochet Sep 25, 2024
c51cc86
Fix lint
charlesBochet Sep 25, 2024
52b7f85
Increase test coverage
charlesBochet Sep 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/twenty-front/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ module.exports = {
'mockServiceWorker.js',
'**/generated*/*',
'**/generated/standard-metadata-query-result.ts',
'**/getObjectMetadataItemsMock.ts',
'tsup.config.ts',
'build',
'coverage',
Expand Down
19 changes: 8 additions & 11 deletions packages/twenty-front/public/mockServiceWorker.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
/* tslint:disable */

/**
* Mock Service Worker (2.0.11).
* Mock Service Worker.
* @see https://github.com/mswjs/msw
* - Please do NOT modify this file.
* - Please do NOT serve this file on production.
*/

const INTEGRITY_CHECKSUM = 'c5f7f8e188b673ea4e677df7ea3c5a39'
const PACKAGE_VERSION = '2.3.5'
const INTEGRITY_CHECKSUM = '26357c79639bfa20d64c0efca2a87423'
const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
const activeClientIds = new Set()

Expand Down Expand Up @@ -48,7 +49,10 @@ self.addEventListener('message', async function (event) {
case 'INTEGRITY_CHECK_REQUEST': {
sendToClient(client, {
type: 'INTEGRITY_CHECK_RESPONSE',
payload: INTEGRITY_CHECKSUM,
payload: {
packageVersion: PACKAGE_VERSION,
checksum: INTEGRITY_CHECKSUM,
},
})
break
}
Expand Down Expand Up @@ -202,13 +206,6 @@ async function getResponse(event, client, requestId) {
return passthrough()
}

// Bypass requests with the explicit bypass header.
// Such requests can be issued by "ctx.fetch()".
const mswIntention = request.headers.get('x-msw-intention')
if (['bypass', 'passthrough'].includes(mswIntention)) {
return passthrough()
}

// Notify the client that a request has been intercepted.
const requestBuffer = await request.arrayBuffer()
const clientMessage = await sendToClient(
Expand Down Expand Up @@ -240,7 +237,7 @@ async function getResponse(event, client, requestId) {
return respondWithMock(clientMessage.data)
}

case 'MOCK_NOT_FOUND': {
case 'PASSTHROUGH': {
return passthrough()
}
}
Expand Down
76 changes: 76 additions & 0 deletions packages/twenty-front/src/generated/graphql.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1544,6 +1544,20 @@ export type GetCurrentUserQueryVariables = Exact<{ [key: string]: never; }>;

export type GetCurrentUserQuery = { __typename?: 'Query', currentUser: { __typename?: 'User', id: any, firstName: string, lastName: string, email: string, canImpersonate: boolean, supportUserHash?: string | null, onboardingStatus?: OnboardingStatus | null, userVars: any, workspaceMember?: { __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale?: string | null, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } } | null, workspaceMembers?: Array<{ __typename?: 'WorkspaceMember', id: any, colorScheme: string, avatarUrl?: string | null, locale?: string | null, timeZone?: string | null, dateFormat?: WorkspaceMemberDateFormatEnum | null, timeFormat?: WorkspaceMemberTimeFormatEnum | null, name: { __typename?: 'FullName', firstName: string, lastName: string } }> | null, defaultWorkspace: { __typename?: 'Workspace', id: any, displayName?: string | null, logo?: string | null, domainName?: string | null, inviteHash?: string | null, allowImpersonation: boolean, activationStatus: WorkspaceActivationStatus, metadataVersion: number, workspaceMembersCount?: number | null, featureFlags?: Array<{ __typename?: 'FeatureFlag', id: any, key: string, value: boolean, workspaceId: string }> | null, currentBillingSubscription?: { __typename?: 'BillingSubscription', id: any, status: SubscriptionStatus, interval?: SubscriptionInterval | null } | null }, workspaces: Array<{ __typename?: 'UserWorkspace', workspace?: { __typename?: 'Workspace', id: any, logo?: string | null, displayName?: string | null, domainName?: string | null } | null }> } };

export type ActivateWorkflowVersionMutationVariables = Exact<{
workflowVersionId: Scalars['String'];
}>;


export type ActivateWorkflowVersionMutation = { __typename?: 'Mutation', activateWorkflowVersion: boolean };

export type DeactivateWorkflowVersionMutationVariables = Exact<{
workflowVersionId: Scalars['String'];
}>;


export type DeactivateWorkflowVersionMutation = { __typename?: 'Mutation', deactivateWorkflowVersion: boolean };

export type DeleteWorkspaceInvitationMutationVariables = Exact<{
appTokenId: Scalars['String'];
}>;
Expand Down Expand Up @@ -2886,6 +2900,68 @@ export function useGetCurrentUserLazyQuery(baseOptions?: Apollo.LazyQueryHookOpt
export type GetCurrentUserQueryHookResult = ReturnType<typeof useGetCurrentUserQuery>;
export type GetCurrentUserLazyQueryHookResult = ReturnType<typeof useGetCurrentUserLazyQuery>;
export type GetCurrentUserQueryResult = Apollo.QueryResult<GetCurrentUserQuery, GetCurrentUserQueryVariables>;
export const ActivateWorkflowVersionDocument = gql`
mutation ActivateWorkflowVersion($workflowVersionId: String!) {
activateWorkflowVersion(workflowVersionId: $workflowVersionId)
}
`;
export type ActivateWorkflowVersionMutationFn = Apollo.MutationFunction<ActivateWorkflowVersionMutation, ActivateWorkflowVersionMutationVariables>;

/**
* __useActivateWorkflowVersionMutation__
*
* To run a mutation, you first call `useActivateWorkflowVersionMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useActivateWorkflowVersionMutation` 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 [activateWorkflowVersionMutation, { data, loading, error }] = useActivateWorkflowVersionMutation({
* variables: {
* workflowVersionId: // value for 'workflowVersionId'
* },
* });
*/
export function useActivateWorkflowVersionMutation(baseOptions?: Apollo.MutationHookOptions<ActivateWorkflowVersionMutation, ActivateWorkflowVersionMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<ActivateWorkflowVersionMutation, ActivateWorkflowVersionMutationVariables>(ActivateWorkflowVersionDocument, options);
}
export type ActivateWorkflowVersionMutationHookResult = ReturnType<typeof useActivateWorkflowVersionMutation>;
export type ActivateWorkflowVersionMutationResult = Apollo.MutationResult<ActivateWorkflowVersionMutation>;
export type ActivateWorkflowVersionMutationOptions = Apollo.BaseMutationOptions<ActivateWorkflowVersionMutation, ActivateWorkflowVersionMutationVariables>;
export const DeactivateWorkflowVersionDocument = gql`
mutation DeactivateWorkflowVersion($workflowVersionId: String!) {
deactivateWorkflowVersion(workflowVersionId: $workflowVersionId)
}
`;
export type DeactivateWorkflowVersionMutationFn = Apollo.MutationFunction<DeactivateWorkflowVersionMutation, DeactivateWorkflowVersionMutationVariables>;

/**
* __useDeactivateWorkflowVersionMutation__
*
* To run a mutation, you first call `useDeactivateWorkflowVersionMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useDeactivateWorkflowVersionMutation` 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 [deactivateWorkflowVersionMutation, { data, loading, error }] = useDeactivateWorkflowVersionMutation({
* variables: {
* workflowVersionId: // value for 'workflowVersionId'
* },
* });
*/
export function useDeactivateWorkflowVersionMutation(baseOptions?: Apollo.MutationHookOptions<DeactivateWorkflowVersionMutation, DeactivateWorkflowVersionMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<DeactivateWorkflowVersionMutation, DeactivateWorkflowVersionMutationVariables>(DeactivateWorkflowVersionDocument, options);
}
export type DeactivateWorkflowVersionMutationHookResult = ReturnType<typeof useDeactivateWorkflowVersionMutation>;
export type DeactivateWorkflowVersionMutationResult = Apollo.MutationResult<DeactivateWorkflowVersionMutation>;
export type DeactivateWorkflowVersionMutationOptions = Apollo.BaseMutationOptions<DeactivateWorkflowVersionMutation, DeactivateWorkflowVersionMutationVariables>;
export const DeleteWorkspaceInvitationDocument = gql`
mutation DeleteWorkspaceInvitation($appTokenId: String!) {
deleteWorkspaceInvitation(appTokenId: $appTokenId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ import { RecoilRoot, useSetRecoilState } from 'recoil';
import { useActivityTargetObjectRecords } from '@/activities/hooks/useActivityTargetObjectRecords';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
import { SnackBarProviderScope } from '@/ui/feedback/snack-bar-manager/scopes/SnackBarProviderScope';
import { JestObjectMetadataItemSetter } from '~/testing/jest/JestObjectMetadataItemSetter';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/objectMetadataItems';
import { mockWorkspaceMembers } from '~/testing/mock-data/workspace-members';
const mockObjectMetadataItems = getObjectMetadataItemsMock();

const cache = new InMemoryCache();

Expand Down Expand Up @@ -141,7 +140,7 @@ describe('useActivityTargetObjectRecords', () => {

act(() => {
result.current.setCurrentWorkspaceMember(mockWorkspaceMembers[0]);
result.current.setObjectMetadataItems(mockObjectMetadataItems);
result.current.setObjectMetadataItems(generatedMockObjectMetadataItems);
});

const activityTargetObjectRecords =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ const mocks: MockedResponse[] = [
mutation CreateOneTask($input: TaskCreateInput!) {
createTask(data: $input) {
__typename
status
assigneeId
updatedAt
body
createdAt
dueAt
id
status
body
assigneeId
title
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import { RecoilRoot, useRecoilValue, useSetRecoilState } from 'recoil';
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { getObjectMetadataItemsMock } from '@/object-metadata/utils/getObjectMetadataItemsMock';
import { viewableRecordIdState } from '@/object-record/record-right-drawer/states/viewableRecordIdState';
import gql from 'graphql-tag';
import pick from 'lodash.pick';
import { generatedMockObjectMetadataItems } from '~/testing/mock-data/objectMetadataItems';
import { mockedTasks } from '~/testing/mock-data/tasks';

const mockedDate = '2024-03-15T12:00:00.000Z';
Expand Down Expand Up @@ -69,7 +69,7 @@ const Wrapper = ({ children }: { children: ReactNode }) => (
</RecoilRoot>
);

const mockObjectMetadataItems = getObjectMetadataItemsMock();
const mockObjectMetadataItems = generatedMockObjectMetadataItems;

describe('useOpenCreateActivityDrawer', () => {
it('works as expected', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,21 @@ const mocks: MockedResponse[] = [
mutation UpdateOneTask($idToUpdate: ID!, $input: TaskUpdateInput!) {
updateTask(id: $idToUpdate, data: $input) {
__typename
status
assigneeId
updatedAt
body
createdAt
deletedAt
dueAt
position
id
title
status
body
createdBy {
source
workspaceMemberId
name
}
assigneeId
position
title
}
}
`,
Expand All @@ -53,7 +54,7 @@ const mocks: MockedResponse[] = [
result: jest.fn(() => ({
data: {
updateTask: {
__typename: 'Activity',
__typename: 'Task',
createdAt: '2024-03-15T07:33:14.212Z',
reminderAt: null,
authorId: '123',
Expand Down
Loading
Loading