Fix workflow activation optimistic rendering in Cmd+K (#10109)
Close https://discord.com/channels/1130383047699738754/1334441759484149793 Using refetch queries was not working for certain use cases. To find manual active workflows in cmd+k, we use a query with specific filters that was complicated to refetch. Finally I will update the cache manually. It was not properly updated before because the json value of the version trigger was stringified without spaces. So the entity was not found in apollo cache.
This commit is contained in:
@ -162,7 +162,6 @@ describe('useDeactivateWorkflowSingleRecordAction', () => {
|
|||||||
|
|
||||||
expect(deactivateWorkflowVersionMock).toHaveBeenCalledWith({
|
expect(deactivateWorkflowVersionMock).toHaveBeenCalledWith({
|
||||||
workflowVersionId: activeWorkflowMock.currentVersion.id,
|
workflowVersionId: activeWorkflowMock.currentVersion.id,
|
||||||
workflowId: activeWorkflowMock.id,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -23,7 +23,6 @@ export const useDeactivateWorkflowSingleRecordAction: ActionHookWithoutObjectMet
|
|||||||
|
|
||||||
deactivateWorkflowVersion({
|
deactivateWorkflowVersion({
|
||||||
workflowVersionId: workflowWithCurrentVersion.currentVersion.id,
|
workflowVersionId: workflowWithCurrentVersion.currentVersion.id,
|
||||||
workflowId: workflowWithCurrentVersion.id,
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { contextStoreTargetedRecordsRuleComponentState } from '@/context-store/s
|
|||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
|
||||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||||
import { useAllActiveWorkflowVersions } from '@/workflow/hooks/useAllActiveWorkflowVersions';
|
import { useActiveWorkflowVersionsWithManualTrigger } from '@/workflow/hooks/useActiveWorkflowVersionsWithManualTrigger';
|
||||||
import { useRunWorkflowVersion } from '@/workflow/hooks/useRunWorkflowVersion';
|
import { useRunWorkflowVersion } from '@/workflow/hooks/useRunWorkflowVersion';
|
||||||
import { msg } from '@lingui/core/macro';
|
import { msg } from '@lingui/core/macro';
|
||||||
|
|
||||||
@ -38,10 +38,10 @@ export const useWorkflowRunRecordActions = ({
|
|||||||
recordStoreFamilyState(selectedRecordId),
|
recordStoreFamilyState(selectedRecordId),
|
||||||
);
|
);
|
||||||
|
|
||||||
const { records: activeWorkflowVersions } = useAllActiveWorkflowVersions({
|
const { records: activeWorkflowVersions } =
|
||||||
objectMetadataItem,
|
useActiveWorkflowVersionsWithManualTrigger({
|
||||||
triggerType: 'MANUAL',
|
objectMetadataItem,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { runWorkflowVersion } = useRunWorkflowVersion();
|
const { runWorkflowVersion } = useRunWorkflowVersion();
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import {
|
|||||||
ActionMenuEntryScope,
|
ActionMenuEntryScope,
|
||||||
ActionMenuEntryType,
|
ActionMenuEntryType,
|
||||||
} from '@/action-menu/types/ActionMenuEntry';
|
} from '@/action-menu/types/ActionMenuEntry';
|
||||||
import { useAllActiveWorkflowVersions } from '@/workflow/hooks/useAllActiveWorkflowVersions';
|
import { useActiveWorkflowVersionsWithManualTrigger } from '@/workflow/hooks/useActiveWorkflowVersionsWithManualTrigger';
|
||||||
import { useRunWorkflowVersion } from '@/workflow/hooks/useRunWorkflowVersion';
|
import { useRunWorkflowVersion } from '@/workflow/hooks/useRunWorkflowVersion';
|
||||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||||
import { msg } from '@lingui/core/macro';
|
import { msg } from '@lingui/core/macro';
|
||||||
@ -16,9 +16,8 @@ export const useRunWorkflowActions = () => {
|
|||||||
FeatureFlagKey.IsWorkflowEnabled,
|
FeatureFlagKey.IsWorkflowEnabled,
|
||||||
);
|
);
|
||||||
|
|
||||||
const { records: activeWorkflowVersions } = useAllActiveWorkflowVersions({
|
const { records: activeWorkflowVersions } =
|
||||||
triggerType: 'MANUAL',
|
useActiveWorkflowVersionsWithManualTrigger({});
|
||||||
});
|
|
||||||
|
|
||||||
const { runWorkflowVersion } = useRunWorkflowVersion();
|
const { runWorkflowVersion } = useRunWorkflowVersion();
|
||||||
|
|
||||||
|
|||||||
@ -10,9 +10,9 @@ export const isMatchingRawJsonFilter = ({
|
|||||||
switch (true) {
|
switch (true) {
|
||||||
case rawJsonFilter.like !== undefined: {
|
case rawJsonFilter.like !== undefined: {
|
||||||
const regexPattern = rawJsonFilter.like.replace(/%/g, '.*');
|
const regexPattern = rawJsonFilter.like.replace(/%/g, '.*');
|
||||||
const regexCaseInsensitive = new RegExp(`^${regexPattern}$`, 'i');
|
const regexCaseInsensitive = new RegExp(`^${regexPattern}$`, 'is');
|
||||||
|
|
||||||
const stringValue = JSON.stringify(value);
|
const stringValue = JSON.stringify(value, null, 1);
|
||||||
|
|
||||||
return regexCaseInsensitive.test(stringValue);
|
return regexCaseInsensitive.test(stringValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -124,7 +124,6 @@ export const RecordShowPageWorkflowHeader = ({
|
|||||||
|
|
||||||
return deactivateWorkflowVersion({
|
return deactivateWorkflowVersion({
|
||||||
workflowVersionId: workflowWithCurrentVersion.currentVersion.id,
|
workflowVersionId: workflowWithCurrentVersion.currentVersion.id,
|
||||||
workflowId: workflowWithCurrentVersion.id,
|
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -128,7 +128,6 @@ export const RecordShowPageWorkflowVersionHeader = ({
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
return deactivateWorkflowVersion({
|
return deactivateWorkflowVersion({
|
||||||
workflowVersionId: workflowVersion.id,
|
workflowVersionId: workflowVersion.id,
|
||||||
workflowId: workflowVersion.workflowId,
|
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -1,8 +1,12 @@
|
|||||||
import { useApolloClient, useMutation } from '@apollo/client';
|
import { useApolloClient, useMutation } from '@apollo/client';
|
||||||
|
|
||||||
|
import { triggerUpdateRecordOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffect';
|
||||||
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { useFindManyRecordsQuery } from '@/object-record/hooks/useFindManyRecordsQuery';
|
import { modifyRecordFromCache } from '@/object-record/cache/utils/modifyRecordFromCache';
|
||||||
import { ACTIVATE_WORKFLOW_VERSION } from '@/workflow/graphql/mutations/activateWorkflowVersion';
|
import { ACTIVATE_WORKFLOW_VERSION } from '@/workflow/graphql/mutations/activateWorkflowVersion';
|
||||||
|
import { WorkflowVersion } from '@/workflow/types/Workflow';
|
||||||
|
import { isDefined } from 'twenty-shared';
|
||||||
import {
|
import {
|
||||||
ActivateWorkflowVersionMutation,
|
ActivateWorkflowVersionMutation,
|
||||||
ActivateWorkflowVersionMutationVariables,
|
ActivateWorkflowVersionMutationVariables,
|
||||||
@ -17,8 +21,8 @@ export const useActivateWorkflowVersion = () => {
|
|||||||
client: apolloClient,
|
client: apolloClient,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { findManyRecordsQuery: findManyWorkflowVersionsQuery } =
|
const { objectMetadataItem: objectMetadataItemWorkflowVersion } =
|
||||||
useFindManyRecordsQuery({
|
useObjectMetadataItem({
|
||||||
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -33,14 +37,72 @@ export const useActivateWorkflowVersion = () => {
|
|||||||
variables: {
|
variables: {
|
||||||
workflowVersionId,
|
workflowVersionId,
|
||||||
},
|
},
|
||||||
refetchQueries: [
|
update: () => {
|
||||||
{
|
modifyRecordFromCache({
|
||||||
query: findManyWorkflowVersionsQuery,
|
cache: apolloClient.cache,
|
||||||
variables: {
|
recordId: workflowVersionId,
|
||||||
workflowId,
|
objectMetadataItem: objectMetadataItemWorkflowVersion,
|
||||||
|
fieldModifiers: {
|
||||||
|
status: () => 'ACTIVE',
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
],
|
|
||||||
|
const cacheSnapshot = apolloClient.cache.extract();
|
||||||
|
const allWorkflowVersions: Array<WorkflowVersion> = Object.values(
|
||||||
|
cacheSnapshot,
|
||||||
|
).filter(
|
||||||
|
(item) =>
|
||||||
|
item.__typename === 'WorkflowVersion' &&
|
||||||
|
item.workflowId === workflowId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const previousActiveWorkflowVersions = allWorkflowVersions.filter(
|
||||||
|
(version) =>
|
||||||
|
version.status === 'ACTIVE' && version.id !== workflowVersionId,
|
||||||
|
);
|
||||||
|
|
||||||
|
const newlyActiveWorkflowVersion = allWorkflowVersions.find(
|
||||||
|
(version) => version.id === workflowVersionId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDefined(newlyActiveWorkflowVersion)) {
|
||||||
|
triggerUpdateRecordOptimisticEffect({
|
||||||
|
cache: apolloClient.cache,
|
||||||
|
objectMetadataItem: objectMetadataItemWorkflowVersion,
|
||||||
|
currentRecord: newlyActiveWorkflowVersion,
|
||||||
|
updatedRecord: {
|
||||||
|
...newlyActiveWorkflowVersion,
|
||||||
|
status: 'ACTIVE',
|
||||||
|
},
|
||||||
|
objectMetadataItems: [objectMetadataItemWorkflowVersion],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const workflowVersion of previousActiveWorkflowVersions) {
|
||||||
|
apolloClient.cache.modify({
|
||||||
|
id: apolloClient.cache.identify(workflowVersion),
|
||||||
|
fields: {
|
||||||
|
status: () => {
|
||||||
|
return workflowVersion.id !== workflowVersionId &&
|
||||||
|
workflowVersion.status === 'ACTIVE'
|
||||||
|
? 'ARCHIVED'
|
||||||
|
: workflowVersion.status;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
triggerUpdateRecordOptimisticEffect({
|
||||||
|
cache: apolloClient.cache,
|
||||||
|
objectMetadataItem: objectMetadataItemWorkflowVersion,
|
||||||
|
currentRecord: workflowVersion,
|
||||||
|
updatedRecord: {
|
||||||
|
...workflowVersion,
|
||||||
|
status: 'ARCHIVED',
|
||||||
|
},
|
||||||
|
objectMetadataItems: [objectMetadataItemWorkflowVersion],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -3,19 +3,13 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi
|
|||||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||||
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
|
import { generateDepthOneRecordGqlFields } from '@/object-record/graphql/utils/generateDepthOneRecordGqlFields';
|
||||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||||
import {
|
import { Workflow, WorkflowVersion } from '@/workflow/types/Workflow';
|
||||||
Workflow,
|
|
||||||
WorkflowTriggerType,
|
|
||||||
WorkflowVersion,
|
|
||||||
} from '@/workflow/types/Workflow';
|
|
||||||
import { isDefined } from 'twenty-shared';
|
import { isDefined } from 'twenty-shared';
|
||||||
|
|
||||||
export const useAllActiveWorkflowVersions = ({
|
export const useActiveWorkflowVersionsWithManualTrigger = ({
|
||||||
objectMetadataItem,
|
objectMetadataItem,
|
||||||
triggerType,
|
|
||||||
}: {
|
}: {
|
||||||
objectMetadataItem?: ObjectMetadataItem;
|
objectMetadataItem?: ObjectMetadataItem;
|
||||||
triggerType: WorkflowTriggerType;
|
|
||||||
}) => {
|
}) => {
|
||||||
const filters = [
|
const filters = [
|
||||||
{
|
{
|
||||||
@ -25,7 +19,7 @@ export const useAllActiveWorkflowVersions = ({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
trigger: {
|
trigger: {
|
||||||
like: `%"type": "${triggerType}"%`,
|
like: `%"type": "MANUAL"%`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -63,7 +57,8 @@ export const useAllActiveWorkflowVersions = ({
|
|||||||
return {
|
return {
|
||||||
records: records.filter(
|
records: records.filter(
|
||||||
(record) =>
|
(record) =>
|
||||||
record.trigger?.type !== 'CRON' &&
|
record.status === 'ACTIVE' &&
|
||||||
|
record.trigger?.type === 'MANUAL' &&
|
||||||
!isDefined(record.trigger?.settings.objectType),
|
!isDefined(record.trigger?.settings.objectType),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@ -1,8 +1,12 @@
|
|||||||
import { useApolloClient, useMutation } from '@apollo/client';
|
import { useApolloClient, useMutation } from '@apollo/client';
|
||||||
|
|
||||||
|
import { triggerUpdateRecordOptimisticEffect } from '@/apollo/optimistic-effect/utils/triggerUpdateRecordOptimisticEffect';
|
||||||
|
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||||
import { useFindManyRecordsQuery } from '@/object-record/hooks/useFindManyRecordsQuery';
|
import { modifyRecordFromCache } from '@/object-record/cache/utils/modifyRecordFromCache';
|
||||||
import { DEACTIVATE_WORKFLOW_VERSION } from '@/workflow/graphql/mutations/deactivateWorkflowVersion';
|
import { DEACTIVATE_WORKFLOW_VERSION } from '@/workflow/graphql/mutations/deactivateWorkflowVersion';
|
||||||
|
import { WorkflowVersion } from '@/workflow/types/Workflow';
|
||||||
|
import { isDefined } from 'twenty-shared';
|
||||||
import {
|
import {
|
||||||
DeactivateWorkflowVersionMutation,
|
DeactivateWorkflowVersionMutation,
|
||||||
DeactivateWorkflowVersionMutationVariables,
|
DeactivateWorkflowVersionMutationVariables,
|
||||||
@ -17,30 +21,54 @@ export const useDeactivateWorkflowVersion = () => {
|
|||||||
client: apolloClient,
|
client: apolloClient,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { findManyRecordsQuery: findManyWorkflowVersionsQuery } =
|
const { objectMetadataItem: objectMetadataItemWorkflowVersion } =
|
||||||
useFindManyRecordsQuery({
|
useObjectMetadataItem({
|
||||||
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
objectNameSingular: CoreObjectNameSingular.WorkflowVersion,
|
||||||
});
|
});
|
||||||
|
|
||||||
const deactivateWorkflowVersion = async ({
|
const deactivateWorkflowVersion = async ({
|
||||||
workflowVersionId,
|
workflowVersionId,
|
||||||
workflowId,
|
|
||||||
}: {
|
}: {
|
||||||
workflowVersionId: string;
|
workflowVersionId: string;
|
||||||
workflowId: string;
|
|
||||||
}) => {
|
}) => {
|
||||||
await mutate({
|
await mutate({
|
||||||
variables: {
|
variables: {
|
||||||
workflowVersionId,
|
workflowVersionId,
|
||||||
},
|
},
|
||||||
refetchQueries: [
|
update: () => {
|
||||||
{
|
modifyRecordFromCache({
|
||||||
query: findManyWorkflowVersionsQuery,
|
cache: apolloClient.cache,
|
||||||
variables: {
|
recordId: workflowVersionId,
|
||||||
workflowId,
|
objectMetadataItem: objectMetadataItemWorkflowVersion,
|
||||||
|
fieldModifiers: {
|
||||||
|
status: () => 'DEACTIVATED',
|
||||||
},
|
},
|
||||||
},
|
});
|
||||||
],
|
|
||||||
|
const cacheSnapshot = apolloClient.cache.extract();
|
||||||
|
const workflowVersion: WorkflowVersion | undefined = Object.values(
|
||||||
|
cacheSnapshot,
|
||||||
|
).find(
|
||||||
|
(item) =>
|
||||||
|
item.__typename === 'WorkflowVersion' &&
|
||||||
|
item.id === workflowVersionId,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!isDefined(workflowVersion)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
triggerUpdateRecordOptimisticEffect({
|
||||||
|
cache: apolloClient.cache,
|
||||||
|
objectMetadataItem: objectMetadataItemWorkflowVersion,
|
||||||
|
currentRecord: workflowVersion,
|
||||||
|
updatedRecord: {
|
||||||
|
...workflowVersion,
|
||||||
|
status: 'DEACTIVATED',
|
||||||
|
},
|
||||||
|
objectMetadataItems: [objectMetadataItemWorkflowVersion],
|
||||||
|
});
|
||||||
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user