Fixed issue #13901 https://github.com/user-attachments/assets/4aa7d0f3-88b8-474f-85e5-b2989ed8afdd --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@@ -5,13 +5,14 @@ import { ApolloError } from '@apollo/client';
|
||||
|
||||
import { verifyEmailRedirectPathState } from '@/app/states/verifyEmailRedirectPathState';
|
||||
import { useVerifyLogin } from '@/auth/hooks/useVerifyLogin';
|
||||
import { clientConfigApiStatusState } from '@/client-config/states/clientConfigApiStatusState';
|
||||
import { useIsCurrentLocationOnAWorkspace } from '@/domain-manager/hooks/useIsCurrentLocationOnAWorkspace';
|
||||
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl';
|
||||
@@ -40,6 +41,7 @@ export const VerifyEmailEffect = () => {
|
||||
const { redirectToWorkspaceDomain } = useRedirectToWorkspaceDomain();
|
||||
const { verifyLoginToken } = useVerifyLogin();
|
||||
const { isOnAWorkspace } = useIsCurrentLocationOnAWorkspace();
|
||||
const clientConfigApiStatus = useRecoilValue(clientConfigApiStatusState);
|
||||
|
||||
const { t } = useLingui();
|
||||
useEffect(() => {
|
||||
@@ -112,10 +114,15 @@ export const VerifyEmailEffect = () => {
|
||||
}
|
||||
};
|
||||
|
||||
if (!clientConfigApiStatus.isLoadedOnce) {
|
||||
return;
|
||||
}
|
||||
|
||||
verifyEmailToken();
|
||||
|
||||
// Verify email only needs to run once at mount
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
}, [clientConfigApiStatus.isLoadedOnce]);
|
||||
|
||||
if (isError) {
|
||||
return (
|
||||
|
||||
+2
-184
@@ -1,105 +1,14 @@
|
||||
import { useClientConfig } from '@/client-config/hooks/useClientConfig';
|
||||
import { aiModelsState } from '@/client-config/states/aiModelsState';
|
||||
import { apiConfigState } from '@/client-config/states/apiConfigState';
|
||||
import { appVersionState } from '@/client-config/states/appVersionState';
|
||||
import { authProvidersState } from '@/client-config/states/authProvidersState';
|
||||
import { billingState } from '@/client-config/states/billingState';
|
||||
import { calendarBookingPageIdState } from '@/client-config/states/calendarBookingPageIdState';
|
||||
import { canManageFeatureFlagsState } from '@/client-config/states/canManageFeatureFlagsState';
|
||||
import { captchaState } from '@/client-config/states/captchaState';
|
||||
import { chromeExtensionIdState } from '@/client-config/states/chromeExtensionIdState';
|
||||
import { clientConfigApiStatusState } from '@/client-config/states/clientConfigApiStatusState';
|
||||
import { isAnalyticsEnabledState } from '@/client-config/states/isAnalyticsEnabledState';
|
||||
import { isAttachmentPreviewEnabledState } from '@/client-config/states/isAttachmentPreviewEnabledState';
|
||||
import { isConfigVariablesInDbEnabledState } from '@/client-config/states/isConfigVariablesInDbEnabledState';
|
||||
import { isDeveloperDefaultSignInPrefilledState } from '@/client-config/states/isDeveloperDefaultSignInPrefilledState';
|
||||
import { isEmailVerificationRequiredState } from '@/client-config/states/isEmailVerificationRequiredState';
|
||||
import { isGoogleCalendarEnabledState } from '@/client-config/states/isGoogleCalendarEnabledState';
|
||||
import { isGoogleMessagingEnabledState } from '@/client-config/states/isGoogleMessagingEnabledState';
|
||||
import { isImapSmtpCaldavEnabledState } from '@/client-config/states/isImapSmtpCaldavEnabledState';
|
||||
import { isMicrosoftCalendarEnabledState } from '@/client-config/states/isMicrosoftCalendarEnabledState';
|
||||
import { isMicrosoftMessagingEnabledState } from '@/client-config/states/isMicrosoftMessagingEnabledState';
|
||||
import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState';
|
||||
import { labPublicFeatureFlagsState } from '@/client-config/states/labPublicFeatureFlagsState';
|
||||
import { sentryConfigState } from '@/client-config/states/sentryConfigState';
|
||||
import { supportChatState } from '@/client-config/states/supportChatState';
|
||||
import { domainConfigurationState } from '@/domain-manager/states/domainConfigurationState';
|
||||
import { useEffect } from 'react';
|
||||
import { useRecoilState, useSetRecoilState } from 'recoil';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const ClientConfigProviderEffect = () => {
|
||||
const setIsAnalyticsEnabled = useSetRecoilState(isAnalyticsEnabledState);
|
||||
const setDomainConfiguration = useSetRecoilState(domainConfigurationState);
|
||||
const setAuthProviders = useSetRecoilState(authProvidersState);
|
||||
const setAiModels = useSetRecoilState(aiModelsState);
|
||||
|
||||
const setIsDeveloperDefaultSignInPrefilled = useSetRecoilState(
|
||||
isDeveloperDefaultSignInPrefilledState,
|
||||
);
|
||||
const setIsMultiWorkspaceEnabled = useSetRecoilState(
|
||||
isMultiWorkspaceEnabledState,
|
||||
);
|
||||
const setIsEmailVerificationRequired = useSetRecoilState(
|
||||
isEmailVerificationRequiredState,
|
||||
);
|
||||
|
||||
const setBilling = useSetRecoilState(billingState);
|
||||
const setSupportChat = useSetRecoilState(supportChatState);
|
||||
|
||||
const setSentryConfig = useSetRecoilState(sentryConfigState);
|
||||
const [clientConfigApiStatus, setClientConfigApiStatus] = useRecoilState(
|
||||
clientConfigApiStatusState,
|
||||
);
|
||||
|
||||
const setCaptcha = useSetRecoilState(captchaState);
|
||||
|
||||
const setChromeExtensionId = useSetRecoilState(chromeExtensionIdState);
|
||||
|
||||
const setApiConfig = useSetRecoilState(apiConfigState);
|
||||
|
||||
const setCanManageFeatureFlags = useSetRecoilState(
|
||||
canManageFeatureFlagsState,
|
||||
);
|
||||
|
||||
const setLabPublicFeatureFlags = useSetRecoilState(
|
||||
labPublicFeatureFlagsState,
|
||||
);
|
||||
|
||||
const setMicrosoftMessagingEnabled = useSetRecoilState(
|
||||
isMicrosoftMessagingEnabledState,
|
||||
);
|
||||
|
||||
const setMicrosoftCalendarEnabled = useSetRecoilState(
|
||||
isMicrosoftCalendarEnabledState,
|
||||
);
|
||||
|
||||
const setGoogleMessagingEnabled = useSetRecoilState(
|
||||
isGoogleMessagingEnabledState,
|
||||
);
|
||||
|
||||
const setGoogleCalendarEnabled = useSetRecoilState(
|
||||
isGoogleCalendarEnabledState,
|
||||
);
|
||||
|
||||
const setIsAttachmentPreviewEnabled = useSetRecoilState(
|
||||
isAttachmentPreviewEnabledState,
|
||||
);
|
||||
|
||||
const setIsConfigVariablesInDbEnabled = useSetRecoilState(
|
||||
isConfigVariablesInDbEnabledState,
|
||||
);
|
||||
|
||||
const setCalendarBookingPageId = useSetRecoilState(
|
||||
calendarBookingPageIdState,
|
||||
);
|
||||
|
||||
const setIsImapSmtpCaldavEnabled = useSetRecoilState(
|
||||
isImapSmtpCaldavEnabledState,
|
||||
);
|
||||
|
||||
const setAppVersion = useSetRecoilState(appVersionState);
|
||||
|
||||
const { data, loading, error, fetchClientConfig } = useClientConfig();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -130,98 +39,7 @@ export const ClientConfigProviderEffect = () => {
|
||||
if (!isDefined(data?.clientConfig)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setClientConfigApiStatus((currentStatus) => ({
|
||||
...currentStatus,
|
||||
isErrored: false,
|
||||
error: undefined,
|
||||
}));
|
||||
setAppVersion(data.clientConfig.appVersion);
|
||||
setAuthProviders({
|
||||
google: data?.clientConfig.authProviders.google,
|
||||
microsoft: data?.clientConfig.authProviders.microsoft,
|
||||
password: data?.clientConfig.authProviders.password,
|
||||
magicLink: false,
|
||||
sso: data?.clientConfig.authProviders.sso,
|
||||
});
|
||||
setAiModels(data?.clientConfig.aiModels || []);
|
||||
setIsAnalyticsEnabled(data?.clientConfig.analyticsEnabled);
|
||||
setIsDeveloperDefaultSignInPrefilled(data?.clientConfig.signInPrefilled);
|
||||
setIsMultiWorkspaceEnabled(data?.clientConfig.isMultiWorkspaceEnabled);
|
||||
setIsEmailVerificationRequired(
|
||||
data?.clientConfig.isEmailVerificationRequired,
|
||||
);
|
||||
setBilling(data?.clientConfig.billing);
|
||||
setSupportChat(data?.clientConfig.support);
|
||||
|
||||
setSentryConfig({
|
||||
dsn: data?.clientConfig?.sentry?.dsn,
|
||||
release: data?.clientConfig?.sentry?.release,
|
||||
environment: data?.clientConfig?.sentry?.environment,
|
||||
});
|
||||
|
||||
setCaptcha({
|
||||
provider: data?.clientConfig?.captcha?.provider,
|
||||
siteKey: data?.clientConfig?.captcha?.siteKey,
|
||||
});
|
||||
|
||||
setChromeExtensionId(data?.clientConfig?.chromeExtensionId);
|
||||
setApiConfig(data?.clientConfig?.api);
|
||||
setDomainConfiguration({
|
||||
defaultSubdomain: data?.clientConfig?.defaultSubdomain,
|
||||
frontDomain: data?.clientConfig?.frontDomain,
|
||||
});
|
||||
setCanManageFeatureFlags(data?.clientConfig?.canManageFeatureFlags);
|
||||
setLabPublicFeatureFlags(data?.clientConfig?.publicFeatureFlags);
|
||||
setMicrosoftMessagingEnabled(
|
||||
data?.clientConfig?.isMicrosoftMessagingEnabled,
|
||||
);
|
||||
setMicrosoftCalendarEnabled(data?.clientConfig?.isMicrosoftCalendarEnabled);
|
||||
setGoogleMessagingEnabled(data?.clientConfig?.isGoogleMessagingEnabled);
|
||||
setGoogleCalendarEnabled(data?.clientConfig?.isGoogleCalendarEnabled);
|
||||
setIsAttachmentPreviewEnabled(
|
||||
data?.clientConfig?.isAttachmentPreviewEnabled,
|
||||
);
|
||||
setIsConfigVariablesInDbEnabled(
|
||||
data?.clientConfig?.isConfigVariablesInDbEnabled,
|
||||
);
|
||||
setClientConfigApiStatus((currentStatus) => ({
|
||||
...currentStatus,
|
||||
isSaved: true,
|
||||
}));
|
||||
|
||||
setCalendarBookingPageId(data?.clientConfig?.calendarBookingPageId ?? null);
|
||||
setIsImapSmtpCaldavEnabled(data?.clientConfig?.isImapSmtpCaldavEnabled);
|
||||
}, [
|
||||
data,
|
||||
loading,
|
||||
error,
|
||||
setIsDeveloperDefaultSignInPrefilled,
|
||||
setIsMultiWorkspaceEnabled,
|
||||
setIsEmailVerificationRequired,
|
||||
setSupportChat,
|
||||
setBilling,
|
||||
setSentryConfig,
|
||||
setClientConfigApiStatus,
|
||||
setCaptcha,
|
||||
setChromeExtensionId,
|
||||
setApiConfig,
|
||||
setIsAnalyticsEnabled,
|
||||
setDomainConfiguration,
|
||||
setAuthProviders,
|
||||
setAiModels,
|
||||
setCanManageFeatureFlags,
|
||||
setLabPublicFeatureFlags,
|
||||
setMicrosoftMessagingEnabled,
|
||||
setMicrosoftCalendarEnabled,
|
||||
setGoogleMessagingEnabled,
|
||||
setGoogleCalendarEnabled,
|
||||
setIsAttachmentPreviewEnabled,
|
||||
setIsConfigVariablesInDbEnabled,
|
||||
setCalendarBookingPageId,
|
||||
setIsImapSmtpCaldavEnabled,
|
||||
setAppVersion,
|
||||
]);
|
||||
}, [data?.clientConfig, error, loading, setClientConfigApiStatus]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,30 @@
|
||||
import { aiModelsState } from '@/client-config/states/aiModelsState';
|
||||
import { apiConfigState } from '@/client-config/states/apiConfigState';
|
||||
import { appVersionState } from '@/client-config/states/appVersionState';
|
||||
import { authProvidersState } from '@/client-config/states/authProvidersState';
|
||||
import { billingState } from '@/client-config/states/billingState';
|
||||
import { calendarBookingPageIdState } from '@/client-config/states/calendarBookingPageIdState';
|
||||
import { canManageFeatureFlagsState } from '@/client-config/states/canManageFeatureFlagsState';
|
||||
import { captchaState } from '@/client-config/states/captchaState';
|
||||
import { chromeExtensionIdState } from '@/client-config/states/chromeExtensionIdState';
|
||||
import { isAnalyticsEnabledState } from '@/client-config/states/isAnalyticsEnabledState';
|
||||
import { isAttachmentPreviewEnabledState } from '@/client-config/states/isAttachmentPreviewEnabledState';
|
||||
import { isConfigVariablesInDbEnabledState } from '@/client-config/states/isConfigVariablesInDbEnabledState';
|
||||
import { isDeveloperDefaultSignInPrefilledState } from '@/client-config/states/isDeveloperDefaultSignInPrefilledState';
|
||||
import { isEmailVerificationRequiredState } from '@/client-config/states/isEmailVerificationRequiredState';
|
||||
import { isGoogleCalendarEnabledState } from '@/client-config/states/isGoogleCalendarEnabledState';
|
||||
import { isGoogleMessagingEnabledState } from '@/client-config/states/isGoogleMessagingEnabledState';
|
||||
import { isImapSmtpCaldavEnabledState } from '@/client-config/states/isImapSmtpCaldavEnabledState';
|
||||
import { isMicrosoftCalendarEnabledState } from '@/client-config/states/isMicrosoftCalendarEnabledState';
|
||||
import { isMicrosoftMessagingEnabledState } from '@/client-config/states/isMicrosoftMessagingEnabledState';
|
||||
import { isMultiWorkspaceEnabledState } from '@/client-config/states/isMultiWorkspaceEnabledState';
|
||||
import { labPublicFeatureFlagsState } from '@/client-config/states/labPublicFeatureFlagsState';
|
||||
import { sentryConfigState } from '@/client-config/states/sentryConfigState';
|
||||
import { supportChatState } from '@/client-config/states/supportChatState';
|
||||
import { type ClientConfig } from '@/client-config/types/ClientConfig';
|
||||
import { domainConfigurationState } from '@/domain-manager/states/domainConfigurationState';
|
||||
import { useCallback } from 'react';
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import { useRecoilState, useSetRecoilState } from 'recoil';
|
||||
import { clientConfigApiStatusState } from '../states/clientConfigApiStatusState';
|
||||
import { getClientConfig } from '../utils/getClientConfig';
|
||||
|
||||
@@ -13,11 +37,77 @@ type UseClientConfigResult = {
|
||||
};
|
||||
|
||||
export const useClientConfig = (): UseClientConfigResult => {
|
||||
const clientConfigApiStatus = useRecoilValue(clientConfigApiStatusState);
|
||||
const setClientConfigApiStatus = useSetRecoilState(
|
||||
const setIsAnalyticsEnabled = useSetRecoilState(isAnalyticsEnabledState);
|
||||
const setDomainConfiguration = useSetRecoilState(domainConfigurationState);
|
||||
const setAuthProviders = useSetRecoilState(authProvidersState);
|
||||
const setAiModels = useSetRecoilState(aiModelsState);
|
||||
|
||||
const setIsDeveloperDefaultSignInPrefilled = useSetRecoilState(
|
||||
isDeveloperDefaultSignInPrefilledState,
|
||||
);
|
||||
const setIsMultiWorkspaceEnabled = useSetRecoilState(
|
||||
isMultiWorkspaceEnabledState,
|
||||
);
|
||||
const setIsEmailVerificationRequired = useSetRecoilState(
|
||||
isEmailVerificationRequiredState,
|
||||
);
|
||||
|
||||
const setBilling = useSetRecoilState(billingState);
|
||||
const setSupportChat = useSetRecoilState(supportChatState);
|
||||
|
||||
const setSentryConfig = useSetRecoilState(sentryConfigState);
|
||||
const [clientConfigApiStatus, setClientConfigApiStatus] = useRecoilState(
|
||||
clientConfigApiStatusState,
|
||||
);
|
||||
|
||||
const setCaptcha = useSetRecoilState(captchaState);
|
||||
|
||||
const setChromeExtensionId = useSetRecoilState(chromeExtensionIdState);
|
||||
|
||||
const setApiConfig = useSetRecoilState(apiConfigState);
|
||||
|
||||
const setCanManageFeatureFlags = useSetRecoilState(
|
||||
canManageFeatureFlagsState,
|
||||
);
|
||||
|
||||
const setLabPublicFeatureFlags = useSetRecoilState(
|
||||
labPublicFeatureFlagsState,
|
||||
);
|
||||
|
||||
const setMicrosoftMessagingEnabled = useSetRecoilState(
|
||||
isMicrosoftMessagingEnabledState,
|
||||
);
|
||||
|
||||
const setMicrosoftCalendarEnabled = useSetRecoilState(
|
||||
isMicrosoftCalendarEnabledState,
|
||||
);
|
||||
|
||||
const setGoogleMessagingEnabled = useSetRecoilState(
|
||||
isGoogleMessagingEnabledState,
|
||||
);
|
||||
|
||||
const setGoogleCalendarEnabled = useSetRecoilState(
|
||||
isGoogleCalendarEnabledState,
|
||||
);
|
||||
|
||||
const setIsAttachmentPreviewEnabled = useSetRecoilState(
|
||||
isAttachmentPreviewEnabledState,
|
||||
);
|
||||
|
||||
const setIsConfigVariablesInDbEnabled = useSetRecoilState(
|
||||
isConfigVariablesInDbEnabledState,
|
||||
);
|
||||
|
||||
const setCalendarBookingPageId = useSetRecoilState(
|
||||
calendarBookingPageIdState,
|
||||
);
|
||||
|
||||
const setIsImapSmtpCaldavEnabled = useSetRecoilState(
|
||||
isImapSmtpCaldavEnabledState,
|
||||
);
|
||||
|
||||
const setAppVersion = useSetRecoilState(appVersionState);
|
||||
|
||||
const fetchClientConfig = useCallback(async () => {
|
||||
setClientConfigApiStatus((prev) => ({
|
||||
...prev,
|
||||
@@ -34,6 +124,61 @@ export const useClientConfig = (): UseClientConfigResult => {
|
||||
error: undefined,
|
||||
data: { clientConfig },
|
||||
}));
|
||||
setClientConfigApiStatus((currentStatus) => ({
|
||||
...currentStatus,
|
||||
isErrored: false,
|
||||
error: undefined,
|
||||
}));
|
||||
setAppVersion(clientConfig.appVersion);
|
||||
setAuthProviders({
|
||||
google: clientConfig.authProviders.google,
|
||||
microsoft: clientConfig.authProviders.microsoft,
|
||||
password: clientConfig.authProviders.password,
|
||||
magicLink: false,
|
||||
sso: clientConfig.authProviders.sso,
|
||||
});
|
||||
setAiModels(clientConfig.aiModels || []);
|
||||
setIsAnalyticsEnabled(clientConfig.analyticsEnabled);
|
||||
setIsDeveloperDefaultSignInPrefilled(clientConfig.signInPrefilled);
|
||||
setIsMultiWorkspaceEnabled(clientConfig.isMultiWorkspaceEnabled);
|
||||
setIsEmailVerificationRequired(clientConfig.isEmailVerificationRequired);
|
||||
setBilling(clientConfig.billing);
|
||||
setSupportChat(clientConfig.support);
|
||||
|
||||
setSentryConfig({
|
||||
dsn: clientConfig?.sentry?.dsn,
|
||||
release: clientConfig?.sentry?.release,
|
||||
environment: clientConfig?.sentry?.environment,
|
||||
});
|
||||
|
||||
setCaptcha({
|
||||
provider: clientConfig?.captcha?.provider,
|
||||
siteKey: clientConfig?.captcha?.siteKey,
|
||||
});
|
||||
|
||||
setChromeExtensionId(clientConfig?.chromeExtensionId);
|
||||
setApiConfig(clientConfig?.api);
|
||||
setDomainConfiguration({
|
||||
defaultSubdomain: clientConfig?.defaultSubdomain,
|
||||
frontDomain: clientConfig?.frontDomain,
|
||||
});
|
||||
setCanManageFeatureFlags(clientConfig?.canManageFeatureFlags);
|
||||
setLabPublicFeatureFlags(clientConfig?.publicFeatureFlags);
|
||||
setMicrosoftMessagingEnabled(clientConfig?.isMicrosoftMessagingEnabled);
|
||||
setMicrosoftCalendarEnabled(clientConfig?.isMicrosoftCalendarEnabled);
|
||||
setGoogleMessagingEnabled(clientConfig?.isGoogleMessagingEnabled);
|
||||
setGoogleCalendarEnabled(clientConfig?.isGoogleCalendarEnabled);
|
||||
setIsAttachmentPreviewEnabled(clientConfig?.isAttachmentPreviewEnabled);
|
||||
setIsConfigVariablesInDbEnabled(
|
||||
clientConfig?.isConfigVariablesInDbEnabled,
|
||||
);
|
||||
setClientConfigApiStatus((currentStatus) => ({
|
||||
...currentStatus,
|
||||
isSaved: true,
|
||||
}));
|
||||
|
||||
setCalendarBookingPageId(clientConfig?.calendarBookingPageId ?? null);
|
||||
setIsImapSmtpCaldavEnabled(clientConfig?.isImapSmtpCaldavEnabled);
|
||||
} catch (err) {
|
||||
const error =
|
||||
err instanceof Error ? err : new Error('Failed to fetch client config');
|
||||
@@ -45,7 +190,33 @@ export const useClientConfig = (): UseClientConfigResult => {
|
||||
error,
|
||||
}));
|
||||
}
|
||||
}, [setClientConfigApiStatus]);
|
||||
}, [
|
||||
setAiModels,
|
||||
setApiConfig,
|
||||
setAppVersion,
|
||||
setAuthProviders,
|
||||
setBilling,
|
||||
setCalendarBookingPageId,
|
||||
setCanManageFeatureFlags,
|
||||
setCaptcha,
|
||||
setChromeExtensionId,
|
||||
setClientConfigApiStatus,
|
||||
setDomainConfiguration,
|
||||
setGoogleCalendarEnabled,
|
||||
setGoogleMessagingEnabled,
|
||||
setIsAnalyticsEnabled,
|
||||
setIsAttachmentPreviewEnabled,
|
||||
setIsConfigVariablesInDbEnabled,
|
||||
setIsDeveloperDefaultSignInPrefilled,
|
||||
setIsEmailVerificationRequired,
|
||||
setIsImapSmtpCaldavEnabled,
|
||||
setIsMultiWorkspaceEnabled,
|
||||
setLabPublicFeatureFlags,
|
||||
setMicrosoftCalendarEnabled,
|
||||
setMicrosoftMessagingEnabled,
|
||||
setSentryConfig,
|
||||
setSupportChat,
|
||||
]);
|
||||
|
||||
return {
|
||||
data: clientConfigApiStatus.data,
|
||||
|
||||
+44
-28
@@ -2,7 +2,7 @@ import { SelectControl } from '@/ui/input/components/SelectControl';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { useWorkflowVersionIdOrThrow } from '@/workflow/hooks/useWorkflowVersionIdOrThrow';
|
||||
import { stepsOutputSchemaFamilySelector } from '@/workflow/states/selectors/stepsOutputSchemaFamilySelector';
|
||||
import { useGetFilterFieldMetadataItem } from '@/workflow/workflow-steps/workflow-actions/filter-action/hooks/useGetFilterFieldMetadataItem';
|
||||
import { useFilterFieldMetadataItem } from '@/workflow/workflow-steps/workflow-actions/filter-action/hooks/useFilterFieldMetadataItem';
|
||||
import { useUpsertStepFilterSettings } from '@/workflow/workflow-steps/workflow-actions/filter-action/hooks/useUpsertStepFilterSettings';
|
||||
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/workflow-actions/filter-action/states/context/WorkflowStepFilterContext';
|
||||
import { getViewFilterOperands } from '@/workflow/workflow-steps/workflow-actions/filter-action/utils/getStepFilterOperands';
|
||||
@@ -15,6 +15,7 @@ import { useContext } from 'react';
|
||||
import { useRecoilCallback, useRecoilValue } from 'recoil';
|
||||
import { type StepFilter } from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
type WorkflowStepFilterFieldSelectProps = {
|
||||
@@ -50,7 +51,12 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
}),
|
||||
);
|
||||
|
||||
const { getFilterFieldMetadataItem } = useGetFilterFieldMetadataItem();
|
||||
const { getIcon } = useIcons();
|
||||
|
||||
const {
|
||||
fieldMetadataItem: filterFieldMetadataItem,
|
||||
objectMetadataItem: filterObjectMetadataItem,
|
||||
} = useFilterFieldMetadataItem(stepFilter.fieldMetadataId ?? '');
|
||||
|
||||
const availableVariablesInWorkflowStep = useAvailableVariablesInWorkflowStep({
|
||||
shouldDisplayRecordFields,
|
||||
@@ -66,7 +72,7 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
rawVariableName: variableName,
|
||||
part: 'stepId',
|
||||
});
|
||||
const currentStepOutputSchema = snapshot
|
||||
const [currentStepOutputSchema] = snapshot
|
||||
.getLoadable(
|
||||
stepsOutputSchemaFamilySelector({
|
||||
workflowVersionId,
|
||||
@@ -81,35 +87,25 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
fieldMetadataId,
|
||||
compositeFieldSubFieldName,
|
||||
} = searchVariableThroughOutputSchema({
|
||||
stepOutputSchema: currentStepOutputSchema?.[0],
|
||||
stepOutputSchema: currentStepOutputSchema,
|
||||
rawVariableName: variableName,
|
||||
isFullRecord: false,
|
||||
});
|
||||
|
||||
const {
|
||||
fieldMetadataItem: selectedFieldMetadataItem,
|
||||
objectMetadataItem,
|
||||
} = isDefined(fieldMetadataId)
|
||||
? getFilterFieldMetadataItem(fieldMetadataId)
|
||||
: {
|
||||
fieldMetadataItem: undefined,
|
||||
objectMetadataItem: undefined,
|
||||
};
|
||||
|
||||
const filterType = isDefined(fieldMetadataId)
|
||||
? (selectedFieldMetadataItem?.type ?? 'unknown')
|
||||
? (filterFieldMetadataItem?.type ?? 'unknown')
|
||||
: variableType;
|
||||
|
||||
const isFullRecord =
|
||||
selectedFieldMetadataItem?.name === 'id' &&
|
||||
isDefined(objectMetadataItem?.labelSingular);
|
||||
filterFieldMetadataItem?.name === 'id' &&
|
||||
isDefined(filterObjectMetadataItem?.labelSingular);
|
||||
|
||||
upsertStepFilterSettings({
|
||||
stepFilterToUpsert: {
|
||||
...stepFilter,
|
||||
stepOutputKey: variableName,
|
||||
displayValue: isFullRecord
|
||||
? objectMetadataItem.labelSingular
|
||||
? filterObjectMetadataItem.labelSingular
|
||||
: (variableLabel ?? ''),
|
||||
type: filterType ?? 'unknown',
|
||||
value: '',
|
||||
@@ -126,7 +122,8 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
upsertStepFilterSettings,
|
||||
stepFilter,
|
||||
workflowVersionId,
|
||||
getFilterFieldMetadataItem,
|
||||
filterFieldMetadataItem,
|
||||
filterObjectMetadataItem,
|
||||
],
|
||||
);
|
||||
|
||||
@@ -144,13 +141,11 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
const label =
|
||||
isSelectedFieldNotFound || !isDefined(stepFilter.displayValue)
|
||||
? t`Select a field from a previous step`
|
||||
: stepFilter.displayValue;
|
||||
: variableLabel;
|
||||
|
||||
const dropdownId = `step-filter-field-${stepFilter.id}`;
|
||||
|
||||
const isReadonly = readonly ?? false;
|
||||
|
||||
if (isReadonly || noAvailableVariables) {
|
||||
if (noAvailableVariables) {
|
||||
return (
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
@@ -158,9 +153,28 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
<SelectControl
|
||||
selectedOption={{
|
||||
value: stepFilter.stepOutputKey,
|
||||
label: isReadonly
|
||||
? (label ?? '')
|
||||
: t`No available fields to select`,
|
||||
label: t`No available fields to select`,
|
||||
}}
|
||||
isDisabled={true}
|
||||
/>
|
||||
}
|
||||
dropdownComponents={[]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
if (readonly === true) {
|
||||
return (
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
clickableComponent={
|
||||
<SelectControl
|
||||
selectedOption={{
|
||||
value: stepFilter.stepOutputKey,
|
||||
label,
|
||||
Icon: filterFieldMetadataItem?.icon
|
||||
? getIcon(filterFieldMetadataItem.icon)
|
||||
: undefined,
|
||||
}}
|
||||
isDisabled={true}
|
||||
/>
|
||||
@@ -174,12 +188,14 @@ export const WorkflowStepFilterFieldSelect = ({
|
||||
<WorkflowVariablesDropdown
|
||||
instanceId={dropdownId}
|
||||
onVariableSelect={handleChange}
|
||||
disabled={readonly}
|
||||
clickableComponent={
|
||||
<SelectControl
|
||||
selectedOption={{
|
||||
value: stepFilter.stepOutputKey,
|
||||
label,
|
||||
label: label,
|
||||
Icon: filterFieldMetadataItem?.icon
|
||||
? getIcon(filterFieldMetadataItem.icon)
|
||||
: undefined,
|
||||
}}
|
||||
textAccent={isSelectedFieldNotFound ? 'placeholder' : 'default'}
|
||||
/>
|
||||
|
||||
+6
-12
@@ -7,7 +7,7 @@ import { FormTextFieldInput } from '@/object-record/record-field/ui/form-types/c
|
||||
import { type FieldMetadata } from '@/object-record/record-field/ui/types/FieldMetadata';
|
||||
|
||||
import { WorkflowStepFilterValueCompositeInput } from '@/workflow/workflow-steps/workflow-actions/filter-action/components/WorkflowStepFilterValueCompositeInput';
|
||||
import { useGetFilterFieldMetadataItem } from '@/workflow/workflow-steps/workflow-actions/filter-action/hooks/useGetFilterFieldMetadataItem';
|
||||
import { useFilterFieldMetadataItem } from '@/workflow/workflow-steps/workflow-actions/filter-action/hooks/useFilterFieldMetadataItem';
|
||||
import { useUpsertStepFilterSettings } from '@/workflow/workflow-steps/workflow-actions/filter-action/hooks/useUpsertStepFilterSettings';
|
||||
import { WorkflowStepFilterContext } from '@/workflow/workflow-steps/workflow-actions/filter-action/states/context/WorkflowStepFilterContext';
|
||||
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
|
||||
@@ -62,7 +62,6 @@ export const WorkflowStepFilterValueInput = ({
|
||||
const { readonly } = useContext(WorkflowStepFilterContext);
|
||||
|
||||
const { upsertStepFilterSettings } = useUpsertStepFilterSettings();
|
||||
const { getFilterFieldMetadataItem } = useGetFilterFieldMetadataItem();
|
||||
|
||||
const handleValueChange = (value: JsonValue) => {
|
||||
const valueToUpsert = isString(value)
|
||||
@@ -85,10 +84,6 @@ export const WorkflowStepFilterValueInput = ({
|
||||
(stepFilter && !configurableViewFilterOperands.has(stepFilter.operand)) ??
|
||||
true;
|
||||
|
||||
if (isDisabled || operandHasNoInput) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
fieldMetadataId,
|
||||
type: variableType,
|
||||
@@ -96,12 +91,11 @@ export const WorkflowStepFilterValueInput = ({
|
||||
} = stepFilter;
|
||||
|
||||
const { fieldMetadataItem: selectedFieldMetadataItem, objectMetadataItem } =
|
||||
isDefined(fieldMetadataId)
|
||||
? getFilterFieldMetadataItem(fieldMetadataId)
|
||||
: {
|
||||
fieldMetadataItem: undefined,
|
||||
objectMetadataItem: undefined,
|
||||
};
|
||||
useFilterFieldMetadataItem(fieldMetadataId ?? '');
|
||||
|
||||
if (isDisabled || operandHasNoInput) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isFilterableByMultiSelectValue =
|
||||
variableType === FieldMetadataType.MULTI_SELECT ||
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
|
||||
export const useFilterFieldMetadataItem = (fieldMetadataId: string) => {
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
|
||||
const objectMetadataItem = objectMetadataItems.find((objectMetadataItem) =>
|
||||
objectMetadataItem.fields.some((field) => field.id === fieldMetadataId),
|
||||
);
|
||||
|
||||
const fieldMetadataItem = objectMetadataItem?.fields.find(
|
||||
(field) => field.id === fieldMetadataId,
|
||||
);
|
||||
|
||||
return {
|
||||
objectMetadataItem,
|
||||
fieldMetadataItem,
|
||||
};
|
||||
};
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
|
||||
import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const useGetFilterFieldMetadataItem = () => {
|
||||
const { objectMetadataItems } = useObjectMetadataItems();
|
||||
|
||||
const getFilterFieldMetadataItem = (
|
||||
fieldMetadataId: string,
|
||||
): {
|
||||
fieldMetadataItem: FieldMetadataItem | undefined;
|
||||
objectMetadataItem: ObjectMetadataItem | undefined;
|
||||
} => {
|
||||
for (const objectMetadataItem of objectMetadataItems) {
|
||||
const field = objectMetadataItem.fields.find(
|
||||
(field) => field.id === fieldMetadataId,
|
||||
);
|
||||
if (isDefined(field)) {
|
||||
return {
|
||||
fieldMetadataItem: field,
|
||||
objectMetadataItem: objectMetadataItem,
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
fieldMetadataItem: undefined,
|
||||
objectMetadataItem: undefined,
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
getFilterFieldMetadataItem,
|
||||
};
|
||||
};
|
||||
+5
-5
@@ -62,17 +62,17 @@ export const WorkflowVariablesDropdownFieldItems = ({
|
||||
/>
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
{filteredOptions.map(([key, subStep]) => (
|
||||
{filteredOptions.map(([key, option]) => (
|
||||
<MenuItemSelect
|
||||
key={key}
|
||||
selected={false}
|
||||
focused={false}
|
||||
onClick={() => handleSelectField(key)}
|
||||
text={subStep.label || key}
|
||||
hasSubMenu={!subStep.isLeaf}
|
||||
LeftIcon={subStep.icon ? getIcon(subStep.icon) : undefined}
|
||||
text={option.label || key}
|
||||
hasSubMenu={!option.isLeaf}
|
||||
LeftIcon={option.icon ? getIcon(option.icon) : undefined}
|
||||
contextualText={
|
||||
subStep.isLeaf ? subStep?.value?.toString() : undefined
|
||||
option.isLeaf ? option?.value?.toString() : undefined
|
||||
}
|
||||
/>
|
||||
))}
|
||||
|
||||
+1
@@ -33,6 +33,7 @@ type UseVariableDropdownReturn = {
|
||||
setSearchInputValue: (value: string) => void;
|
||||
handleSelectField: (key: string) => void;
|
||||
goBack: () => void;
|
||||
// TODO: fix typing here
|
||||
filteredOptions: [string, any][];
|
||||
};
|
||||
|
||||
|
||||
+5
-1
@@ -31,6 +31,10 @@ type Link = {
|
||||
|
||||
export type BaseOutputSchema = Record<string, Leaf | Node>;
|
||||
|
||||
export type FieldOutputSchema = (Leaf | Node) & {
|
||||
fieldMetadataId: string;
|
||||
};
|
||||
|
||||
export type RecordOutputSchema = {
|
||||
object: {
|
||||
nameSingular: string;
|
||||
@@ -38,7 +42,7 @@ export type RecordOutputSchema = {
|
||||
objectMetadataId: string;
|
||||
isRelationField?: boolean;
|
||||
} & Leaf;
|
||||
fields: BaseOutputSchema;
|
||||
fields: Record<string, FieldOutputSchema>;
|
||||
_outputSchemaType: 'RECORD';
|
||||
};
|
||||
|
||||
|
||||
+6
-1
@@ -19,7 +19,12 @@ const mockStep = {
|
||||
objectMetadataId: '123',
|
||||
},
|
||||
fields: {
|
||||
name: { label: 'Name', value: 'Twenty', isLeaf: true },
|
||||
name: {
|
||||
label: 'Name',
|
||||
value: 'Twenty',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
},
|
||||
},
|
||||
_outputSchemaType: 'RECORD',
|
||||
},
|
||||
|
||||
+34
-8
@@ -19,16 +19,42 @@ const mockStep = {
|
||||
objectMetadataId: '123',
|
||||
},
|
||||
fields: {
|
||||
name: { label: 'Name', value: 'Twenty', isLeaf: true },
|
||||
name: {
|
||||
label: 'Name',
|
||||
value: 'Twenty',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174001',
|
||||
},
|
||||
address: {
|
||||
label: 'Address',
|
||||
value: {
|
||||
street: { label: 'Street', value: '123 Main St', isLeaf: true },
|
||||
city: { label: 'City', value: 'New York', isLeaf: true },
|
||||
state: { label: 'State', value: 'NY', isLeaf: true },
|
||||
zip: { label: 'Zip', value: '10001', isLeaf: true },
|
||||
},
|
||||
isLeaf: false,
|
||||
label: 'Address',
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
value: {
|
||||
street: {
|
||||
label: 'Street',
|
||||
value: '123 Main St',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
},
|
||||
city: {
|
||||
label: 'City',
|
||||
value: 'New York',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
},
|
||||
state: {
|
||||
label: 'State',
|
||||
value: 'NY',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
},
|
||||
zip: {
|
||||
label: 'Zip',
|
||||
value: '10001',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
_outputSchemaType: 'RECORD',
|
||||
|
||||
+40
-4
@@ -22,8 +22,18 @@ describe('searchVariableThroughOutputSchema', () => {
|
||||
objectMetadataId: '123',
|
||||
},
|
||||
fields: {
|
||||
name: { label: 'Name', value: 'Twenty', isLeaf: true },
|
||||
address: { label: 'Address', value: '123 Main St', isLeaf: true },
|
||||
name: {
|
||||
label: 'Name',
|
||||
value: 'Twenty',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
},
|
||||
address: {
|
||||
label: 'Address',
|
||||
value: '123 Main St',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
},
|
||||
},
|
||||
_outputSchemaType: 'RECORD',
|
||||
},
|
||||
@@ -42,12 +52,23 @@ describe('searchVariableThroughOutputSchema', () => {
|
||||
objectMetadataId: '123',
|
||||
},
|
||||
fields: {
|
||||
firstName: { label: 'First Name', value: 'Jane', isLeaf: true },
|
||||
lastName: { label: 'Last Name', value: 'Doe', isLeaf: true },
|
||||
firstName: {
|
||||
label: 'First Name',
|
||||
value: 'Jane',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
},
|
||||
lastName: {
|
||||
label: 'Last Name',
|
||||
value: 'Doe',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
},
|
||||
email: {
|
||||
label: 'Email',
|
||||
value: 'jane@example.com',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
},
|
||||
},
|
||||
_outputSchemaType: 'RECORD',
|
||||
@@ -90,6 +111,8 @@ describe('searchVariableThroughOutputSchema', () => {
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
compositeFieldSubFieldName: undefined,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
variableLabel: 'Name',
|
||||
variablePathLabel: 'Step 1 > Company > Name',
|
||||
variableType: 'unknown',
|
||||
@@ -104,6 +127,8 @@ describe('searchVariableThroughOutputSchema', () => {
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
compositeFieldSubFieldName: undefined,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
variableLabel: 'Email',
|
||||
variablePathLabel: 'Step 1 > Person > Email',
|
||||
variableType: 'unknown',
|
||||
@@ -237,6 +262,7 @@ describe('searchVariableThroughOutputSchema', () => {
|
||||
label: 'Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
},
|
||||
'properties.after.name': {
|
||||
icon: 'IconBuildingSkyscraper',
|
||||
@@ -244,22 +270,28 @@ describe('searchVariableThroughOutputSchema', () => {
|
||||
label: 'Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
},
|
||||
'properties.after.annualRecurringRevenue': {
|
||||
icon: 'IconMoneybag',
|
||||
label: 'ARR',
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
value: {
|
||||
amountMicros: {
|
||||
type: FieldMetadataType.NUMERIC,
|
||||
label: ' Amount Micros',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isCompositeSubField: true,
|
||||
},
|
||||
currencyCode: {
|
||||
type: FieldMetadataType.TEXT,
|
||||
label: ' Currency Code',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isCompositeSubField: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
@@ -285,6 +317,8 @@ describe('searchVariableThroughOutputSchema', () => {
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
compositeFieldSubFieldName: undefined,
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
variableLabel: 'Name',
|
||||
variablePathLabel: 'Record is Created > Name',
|
||||
variableType: FieldMetadataType.TEXT,
|
||||
@@ -300,6 +334,8 @@ describe('searchVariableThroughOutputSchema', () => {
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
compositeFieldSubFieldName: 'amountMicros',
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
variableLabel: ' Amount Micros',
|
||||
variablePathLabel: 'Record is Created > ARR > Amount Micros',
|
||||
variableType: FieldMetadataType.NUMERIC,
|
||||
|
||||
+4
-3
@@ -1,6 +1,7 @@
|
||||
import { type InputSchemaPropertyType } from '@/workflow/types/InputSchema';
|
||||
import {
|
||||
type BaseOutputSchema,
|
||||
type FieldOutputSchema,
|
||||
type OutputSchema,
|
||||
type RecordOutputSchema,
|
||||
} from '@/workflow/workflow-variables/types/StepOutputSchema';
|
||||
@@ -35,7 +36,7 @@ const filterRecordOutputSchema = ({
|
||||
shouldDisplayRecordFields: boolean;
|
||||
shouldDisplayRecordObjects: boolean;
|
||||
}): RecordOutputSchema | undefined => {
|
||||
const filteredFields: BaseOutputSchema = {};
|
||||
const filteredFields: Record<string, FieldOutputSchema> = {};
|
||||
let hasValidFields = false;
|
||||
|
||||
for (const key in outputSchema.fields) {
|
||||
@@ -135,8 +136,8 @@ const filterRecordOutputSchemaFieldsByType = ({
|
||||
}: {
|
||||
outputSchema: RecordOutputSchema;
|
||||
fieldTypesToExclude: InputSchemaPropertyType[];
|
||||
}) => {
|
||||
const filteredFields: BaseOutputSchema = {};
|
||||
}): RecordOutputSchema => {
|
||||
const filteredFields: Record<string, FieldOutputSchema> = {};
|
||||
|
||||
for (const key in outputSchema.fields) {
|
||||
const field = outputSchema.fields[key];
|
||||
|
||||
-991
@@ -1,991 +0,0 @@
|
||||
import { WorkflowStatus } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||
import { WorkflowVersionStatus } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
import { WORKSPACE_MEMBER_DATA_SEED_IDS } from 'src/engine/workspace-manager/dev-seeder/data/constants/workspace-member-data-seeds.constant';
|
||||
|
||||
type WorkflowDataSeed = {
|
||||
id: string;
|
||||
name: string;
|
||||
lastPublishedVersionId: string;
|
||||
statuses: WorkflowStatus[];
|
||||
position: number;
|
||||
createdBySource: string;
|
||||
createdByWorkspaceMemberId: string;
|
||||
createdByName: string;
|
||||
createdByContext: object;
|
||||
};
|
||||
|
||||
type WorkflowVersionDataSeed = {
|
||||
id: string;
|
||||
name: string;
|
||||
trigger: string;
|
||||
steps: string;
|
||||
status: WorkflowVersionStatus;
|
||||
position: number;
|
||||
workflowId: string;
|
||||
};
|
||||
|
||||
export const WORKFLOW_DATA_SEED_COLUMNS: (keyof WorkflowDataSeed)[] = [
|
||||
'id',
|
||||
'name',
|
||||
'lastPublishedVersionId',
|
||||
'statuses',
|
||||
'position',
|
||||
'createdBySource',
|
||||
'createdByWorkspaceMemberId',
|
||||
'createdByName',
|
||||
'createdByContext',
|
||||
];
|
||||
|
||||
export const WORKFLOW_VERSION_DATA_SEED_COLUMNS: (keyof WorkflowVersionDataSeed)[] =
|
||||
['id', 'name', 'trigger', 'steps', 'status', 'position', 'workflowId'];
|
||||
|
||||
export const WORKFLOW_DATA_SEED_IDS = {
|
||||
ID_1: '20202020-8532-47bd-a4fe-2c1e5c4aeed3',
|
||||
};
|
||||
|
||||
export const WORKFLOW_VERSION_DATA_SEED_IDS = {
|
||||
ID_1: '20202020-9cd5-44a8-8b2f-1160b01f06dd',
|
||||
};
|
||||
|
||||
export const WORKFLOW_DATA_SEEDS: WorkflowDataSeed[] = [
|
||||
{
|
||||
id: WORKFLOW_DATA_SEED_IDS.ID_1,
|
||||
name: 'Quick Lead',
|
||||
lastPublishedVersionId: WORKFLOW_VERSION_DATA_SEED_IDS.ID_1,
|
||||
statuses: [WorkflowStatus.ACTIVE],
|
||||
position: 1,
|
||||
createdBySource: 'MANUAL',
|
||||
createdByWorkspaceMemberId: WORKSPACE_MEMBER_DATA_SEED_IDS.TIM,
|
||||
createdByName: 'Tim A',
|
||||
createdByContext: {},
|
||||
},
|
||||
];
|
||||
|
||||
export const WORKFLOW_VERSION_DATA_SEEDS: WorkflowVersionDataSeed[] = [
|
||||
{
|
||||
id: WORKFLOW_VERSION_DATA_SEED_IDS.ID_1,
|
||||
name: 'v1',
|
||||
trigger: JSON.stringify({
|
||||
name: 'Launch manually',
|
||||
type: 'MANUAL',
|
||||
position: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
settings: { outputSchema: {} },
|
||||
nextStepIds: ['6e089bc9-aabd-435f-865f-f31c01c8f4a7'],
|
||||
}),
|
||||
steps: JSON.stringify([
|
||||
{
|
||||
id: '6e089bc9-aabd-435f-865f-f31c01c8f4a7',
|
||||
name: 'Quick Lead Form',
|
||||
type: 'FORM',
|
||||
valid: false,
|
||||
position: {
|
||||
x: 0,
|
||||
y: 141,
|
||||
},
|
||||
settings: {
|
||||
input: [
|
||||
{
|
||||
id: '14d669f0-5249-4fa4-b0bb-f8bd408328d5',
|
||||
name: 'firstName',
|
||||
type: 'TEXT',
|
||||
label: 'First name',
|
||||
placeholder: 'Tim',
|
||||
},
|
||||
{
|
||||
id: '4eb6ce85-d231-4aef-9837-744490c026d0',
|
||||
name: 'lastName',
|
||||
type: 'TEXT',
|
||||
label: 'Last Name',
|
||||
placeholder: 'Apple',
|
||||
},
|
||||
{
|
||||
id: 'adbf0e9f-1427-49be-b4fb-092b34d97350',
|
||||
name: 'email',
|
||||
type: 'TEXT',
|
||||
label: 'Email',
|
||||
placeholder: 'timapple@apple.com',
|
||||
},
|
||||
{
|
||||
id: '4ffc7992-9e65-4a4d-9baf-b52e62f2c273',
|
||||
name: 'jobTitle',
|
||||
type: 'TEXT',
|
||||
label: 'Job title',
|
||||
placeholder: 'CEO',
|
||||
},
|
||||
{
|
||||
id: '42f11926-04ea-4924-94a4-2293cc748362',
|
||||
name: 'companyName',
|
||||
type: 'TEXT',
|
||||
label: 'Company name',
|
||||
placeholder: 'Apple',
|
||||
},
|
||||
{
|
||||
id: 'd6ca80ee-26cd-466d-91bf-984d7205451c',
|
||||
name: 'companyDomain',
|
||||
type: 'TEXT',
|
||||
label: 'Company domain',
|
||||
placeholder: 'https://www.apple.com',
|
||||
},
|
||||
],
|
||||
outputSchema: {
|
||||
email: {
|
||||
type: 'TEXT',
|
||||
label: 'Email',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
jobTitle: {
|
||||
type: 'TEXT',
|
||||
label: 'Job title',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
lastName: {
|
||||
type: 'TEXT',
|
||||
label: 'Last Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
firstName: {
|
||||
type: 'TEXT',
|
||||
label: 'First name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
companyName: {
|
||||
type: 'TEXT',
|
||||
label: 'Company name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
companyDomain: {
|
||||
type: 'TEXT',
|
||||
label: 'Company domain',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
errorHandlingOptions: {
|
||||
retryOnFailure: { value: false },
|
||||
continueOnFailure: { value: false },
|
||||
},
|
||||
},
|
||||
__typename: 'WorkflowAction',
|
||||
nextStepIds: ['0715b6cd-7cc1-4b98-971b-00f54dfe643b'],
|
||||
},
|
||||
{
|
||||
id: '0715b6cd-7cc1-4b98-971b-00f54dfe643b',
|
||||
name: 'Create Company',
|
||||
type: 'CREATE_RECORD',
|
||||
valid: false,
|
||||
position: {
|
||||
x: 0.5,
|
||||
y: 282,
|
||||
},
|
||||
settings: {
|
||||
input: {
|
||||
objectName: 'company',
|
||||
objectRecord: {
|
||||
name: '{{6e089bc9-aabd-435f-865f-f31c01c8f4a7.companyName}}',
|
||||
domainName: {
|
||||
primaryLinkUrl:
|
||||
'{{6e089bc9-aabd-435f-865f-f31c01c8f4a7.companyDomain}}',
|
||||
primaryLinkLabel: '',
|
||||
},
|
||||
},
|
||||
},
|
||||
outputSchema: {
|
||||
fields: {
|
||||
id: {
|
||||
icon: 'Icon123',
|
||||
type: 'UUID',
|
||||
label: 'Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
},
|
||||
name: {
|
||||
icon: 'IconBuildingSkyscraper',
|
||||
type: 'TEXT',
|
||||
label: 'Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
xLink: {
|
||||
icon: 'IconBrandX',
|
||||
label: 'X',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
address: {
|
||||
icon: 'IconMap',
|
||||
label: 'Address',
|
||||
value: {
|
||||
addressLat: {
|
||||
type: 'NUMERIC',
|
||||
label: ' Address Lat',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
addressLng: {
|
||||
type: 'NUMERIC',
|
||||
label: ' Address Lng',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
addressCity: {
|
||||
type: 'TEXT',
|
||||
label: ' Address City',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressState: {
|
||||
type: 'TEXT',
|
||||
label: ' Address State',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressCountry: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Country',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressStreet1: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Street1',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressStreet2: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Street2',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressPostcode: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Postcode',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
createdAt: {
|
||||
icon: 'IconCalendar',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Creation date',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
createdBy: {
|
||||
icon: 'IconCreativeCommonsSa',
|
||||
label: 'Created by',
|
||||
value: {
|
||||
name: {
|
||||
type: 'TEXT',
|
||||
label: ' Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
source: {
|
||||
type: 'SELECT',
|
||||
label: ' Source',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
context: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Context',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
workspaceMemberId: {
|
||||
type: 'UUID',
|
||||
label: ' Workspace Member Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
deletedAt: {
|
||||
icon: 'IconCalendarMinus',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Deleted at',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
employees: {
|
||||
icon: 'IconUsers',
|
||||
type: 'NUMBER',
|
||||
label: 'Employees',
|
||||
value: 20,
|
||||
isLeaf: true,
|
||||
},
|
||||
updatedAt: {
|
||||
icon: 'IconCalendarClock',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Last update',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
domainName: {
|
||||
icon: 'IconLink',
|
||||
label: 'Domain Name',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
accountOwner: {
|
||||
icon: 'IconUserCircle',
|
||||
label: 'Account Owner',
|
||||
value: {
|
||||
id: {
|
||||
icon: 'Icon123',
|
||||
type: 'UUID',
|
||||
label: 'Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
},
|
||||
name: {
|
||||
icon: 'IconCircleUser',
|
||||
label: 'Name',
|
||||
value: {
|
||||
lastName: {
|
||||
type: 'TEXT',
|
||||
label: ' Last Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
firstName: {
|
||||
type: 'TEXT',
|
||||
label: ' First Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
createdAt: {
|
||||
icon: 'IconCalendar',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Creation date',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
deletedAt: {
|
||||
icon: 'IconCalendarMinus',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Deleted at',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
updatedAt: {
|
||||
icon: 'IconCalendarClock',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Last update',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
userEmail: {
|
||||
icon: 'IconMail',
|
||||
type: 'TEXT',
|
||||
label: 'User Email',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
linkedinLink: {
|
||||
icon: 'IconBrandLinkedin',
|
||||
label: 'Linkedin',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
idealCustomerProfile: {
|
||||
icon: 'IconTarget',
|
||||
type: 'BOOLEAN',
|
||||
label: 'ICP',
|
||||
value: true,
|
||||
isLeaf: true,
|
||||
},
|
||||
annualRecurringRevenue: {
|
||||
icon: 'IconMoneybag',
|
||||
label: 'ARR',
|
||||
value: {
|
||||
amountMicros: {
|
||||
type: 'NUMERIC',
|
||||
label: ' Amount Micros',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
currencyCode: {
|
||||
type: 'TEXT',
|
||||
label: ' Currency Code',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
},
|
||||
object: {
|
||||
icon: 'IconBuildingSkyscraper',
|
||||
label: 'Company',
|
||||
value: 'A company',
|
||||
isLeaf: true,
|
||||
fieldIdName: 'id',
|
||||
nameSingular: 'company',
|
||||
},
|
||||
_outputSchemaType: 'RECORD',
|
||||
},
|
||||
errorHandlingOptions: {
|
||||
retryOnFailure: { value: false },
|
||||
continueOnFailure: { value: false },
|
||||
},
|
||||
},
|
||||
__typename: 'WorkflowAction',
|
||||
nextStepIds: ['6f553ea7-b00e-4371-9d88-d8298568a246'],
|
||||
},
|
||||
{
|
||||
id: '6f553ea7-b00e-4371-9d88-d8298568a246',
|
||||
name: 'Create Person',
|
||||
type: 'CREATE_RECORD',
|
||||
valid: false,
|
||||
position: {
|
||||
x: 8.5,
|
||||
y: 423,
|
||||
},
|
||||
settings: {
|
||||
input: {
|
||||
objectName: 'person',
|
||||
objectRecord: {
|
||||
name: {
|
||||
lastName: '{{6e089bc9-aabd-435f-865f-f31c01c8f4a7.lastName}}',
|
||||
firstName: '{{6e089bc9-aabd-435f-865f-f31c01c8f4a7.firstName}}',
|
||||
},
|
||||
emails: {
|
||||
primaryEmail: '{{6e089bc9-aabd-435f-865f-f31c01c8f4a7.email}}',
|
||||
additionalEmails: [],
|
||||
},
|
||||
company: {
|
||||
id: '{{0715b6cd-7cc1-4b98-971b-00f54dfe643b.id}}',
|
||||
},
|
||||
},
|
||||
},
|
||||
outputSchema: {
|
||||
fields: {
|
||||
id: {
|
||||
icon: 'Icon123',
|
||||
type: 'UUID',
|
||||
label: 'Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
},
|
||||
city: {
|
||||
icon: 'IconMap',
|
||||
type: 'TEXT',
|
||||
label: 'City',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
name: {
|
||||
icon: 'IconUser',
|
||||
label: 'Name',
|
||||
value: {
|
||||
lastName: {
|
||||
type: 'TEXT',
|
||||
label: ' Last Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
firstName: {
|
||||
type: 'TEXT',
|
||||
label: ' First Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
xLink: {
|
||||
icon: 'IconBrandX',
|
||||
label: 'X',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
emails: {
|
||||
icon: 'IconMail',
|
||||
label: 'Emails',
|
||||
value: {
|
||||
primaryEmail: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Email',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
additionalEmails: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Additional Emails',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
phones: {
|
||||
icon: 'IconPhone',
|
||||
label: 'Phones',
|
||||
value: {
|
||||
additionalPhones: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Additional Phones',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryPhoneNumber: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Phone Number',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryPhoneCallingCode: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Phone Calling Code',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryPhoneCountryCode: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Phone Country Code',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
company: {
|
||||
icon: 'IconBuildingSkyscraper',
|
||||
label: 'Company',
|
||||
value: {
|
||||
id: {
|
||||
icon: 'Icon123',
|
||||
type: 'UUID',
|
||||
label: 'Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
},
|
||||
name: {
|
||||
icon: 'IconBuildingSkyscraper',
|
||||
type: 'TEXT',
|
||||
label: 'Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
xLink: {
|
||||
icon: 'IconBrandX',
|
||||
label: 'X',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
address: {
|
||||
icon: 'IconMap',
|
||||
label: 'Address',
|
||||
value: {
|
||||
addressLat: {
|
||||
type: 'NUMERIC',
|
||||
label: ' Address Lat',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
addressLng: {
|
||||
type: 'NUMERIC',
|
||||
label: ' Address Lng',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
addressCity: {
|
||||
type: 'TEXT',
|
||||
label: ' Address City',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressState: {
|
||||
type: 'TEXT',
|
||||
label: ' Address State',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressCountry: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Country',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressStreet1: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Street1',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressStreet2: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Street2',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressPostcode: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Postcode',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
createdAt: {
|
||||
icon: 'IconCalendar',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Creation date',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
createdBy: {
|
||||
icon: 'IconCreativeCommonsSa',
|
||||
label: 'Created by',
|
||||
value: {
|
||||
name: {
|
||||
type: 'TEXT',
|
||||
label: ' Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
source: {
|
||||
type: 'SELECT',
|
||||
label: ' Source',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
context: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Context',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
workspaceMemberId: {
|
||||
type: 'UUID',
|
||||
label: ' Workspace Member Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
deletedAt: {
|
||||
icon: 'IconCalendarMinus',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Deleted at',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
employees: {
|
||||
icon: 'IconUsers',
|
||||
type: 'NUMBER',
|
||||
label: 'Employees',
|
||||
value: 20,
|
||||
isLeaf: true,
|
||||
},
|
||||
updatedAt: {
|
||||
icon: 'IconCalendarClock',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Last update',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
domainName: {
|
||||
icon: 'IconLink',
|
||||
label: 'Domain Name',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
linkedinLink: {
|
||||
icon: 'IconBrandLinkedin',
|
||||
label: 'Linkedin',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
idealCustomerProfile: {
|
||||
icon: 'IconTarget',
|
||||
type: 'BOOLEAN',
|
||||
label: 'ICP',
|
||||
value: true,
|
||||
isLeaf: true,
|
||||
},
|
||||
annualRecurringRevenue: {
|
||||
icon: 'IconMoneybag',
|
||||
label: 'ARR',
|
||||
value: {
|
||||
amountMicros: {
|
||||
type: 'NUMERIC',
|
||||
label: ' Amount Micros',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
currencyCode: {
|
||||
type: 'TEXT',
|
||||
label: ' Currency Code',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
jobTitle: {
|
||||
icon: 'IconBriefcase',
|
||||
type: 'TEXT',
|
||||
label: 'Job Title',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
createdAt: {
|
||||
icon: 'IconCalendar',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Creation date',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
createdBy: {
|
||||
icon: 'IconCreativeCommonsSa',
|
||||
label: 'Created by',
|
||||
value: {
|
||||
name: {
|
||||
type: 'TEXT',
|
||||
label: ' Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
source: {
|
||||
type: 'SELECT',
|
||||
label: ' Source',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
context: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Context',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
workspaceMemberId: {
|
||||
type: 'UUID',
|
||||
label: ' Workspace Member Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
deletedAt: {
|
||||
icon: 'IconCalendarMinus',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Deleted at',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
updatedAt: {
|
||||
icon: 'IconCalendarClock',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Last update',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
linkedinLink: {
|
||||
icon: 'IconBrandLinkedin',
|
||||
label: 'Linkedin',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
},
|
||||
object: {
|
||||
icon: 'IconUser',
|
||||
label: 'Person',
|
||||
value: 'A person',
|
||||
isLeaf: true,
|
||||
fieldIdName: 'id',
|
||||
nameSingular: 'person',
|
||||
},
|
||||
_outputSchemaType: 'RECORD',
|
||||
},
|
||||
errorHandlingOptions: {
|
||||
retryOnFailure: { value: false },
|
||||
continueOnFailure: { value: false },
|
||||
},
|
||||
},
|
||||
__typename: 'WorkflowAction',
|
||||
nextStepIds: null,
|
||||
},
|
||||
]),
|
||||
status: WorkflowVersionStatus.ACTIVE,
|
||||
position: 1,
|
||||
workflowId: WORKFLOW_DATA_SEED_IDS.ID_1,
|
||||
},
|
||||
];
|
||||
+3
-20
@@ -81,18 +81,13 @@ import {
|
||||
TASK_TARGET_DATA_SEED_COLUMNS,
|
||||
TASK_TARGET_DATA_SEEDS,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/task-target-data-seeds.constant';
|
||||
import {
|
||||
WORKFLOW_DATA_SEED_COLUMNS,
|
||||
WORKFLOW_DATA_SEEDS,
|
||||
WORKFLOW_VERSION_DATA_SEED_COLUMNS,
|
||||
WORKFLOW_VERSION_DATA_SEEDS,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/workflow-data-seeds.constants';
|
||||
import {
|
||||
WORKSPACE_MEMBER_DATA_SEED_COLUMNS,
|
||||
WORKSPACE_MEMBER_DATA_SEEDS,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/workspace-member-data-seeds.constant';
|
||||
import { TimelineActivitySeederService } from 'src/engine/workspace-manager/dev-seeder/data/services/timeline-activity-seeder.service';
|
||||
import { prefillViews } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-views';
|
||||
import { prefillWorkflows } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-workflows';
|
||||
import { prefillWorkspaceFavorites } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-workspace-favorites';
|
||||
|
||||
const RECORD_SEEDS_CONFIGS = [
|
||||
@@ -176,16 +171,6 @@ const RECORD_SEEDS_CONFIGS = [
|
||||
pgColumns: MESSAGE_PARTICIPANT_DATA_SEED_COLUMNS,
|
||||
recordSeeds: MESSAGE_PARTICIPANT_DATA_SEEDS,
|
||||
},
|
||||
{
|
||||
tableName: 'workflow',
|
||||
pgColumns: WORKFLOW_DATA_SEED_COLUMNS,
|
||||
recordSeeds: WORKFLOW_DATA_SEEDS,
|
||||
},
|
||||
{
|
||||
tableName: 'workflowVersion',
|
||||
pgColumns: WORKFLOW_VERSION_DATA_SEED_COLUMNS,
|
||||
recordSeeds: WORKFLOW_VERSION_DATA_SEEDS,
|
||||
},
|
||||
{
|
||||
tableName: '_pet',
|
||||
pgColumns: PET_DATA_SEED_COLUMNS,
|
||||
@@ -261,16 +246,14 @@ export class DevSeederDataService {
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
// For now views/favorites are auto-created for custom
|
||||
// objects but not for standard objects.
|
||||
// This is probably something we want to fix in the future.
|
||||
|
||||
const viewDefinitionsWithId = await prefillViews(
|
||||
entityManager,
|
||||
schemaName,
|
||||
objectMetadataItems.filter((item) => !item.isCustom),
|
||||
);
|
||||
|
||||
await prefillWorkflows(entityManager, schemaName, objectMetadataItems);
|
||||
|
||||
await prefillWorkspaceFavorites(
|
||||
viewDefinitionsWithId
|
||||
.filter(
|
||||
|
||||
+41
-730
@@ -1,5 +1,10 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { generateObjectMetadataMaps } from 'src/engine/metadata-modules/utils/generate-object-metadata-maps.util';
|
||||
import { type WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { generateObjectRecordFields } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-object-record-fields';
|
||||
|
||||
const QUICK_LEAD_WORKFLOW_ID = '8b213cac-a68b-4ffe-817a-3ec994e9932d';
|
||||
const QUICK_LEAD_WORKFLOW_VERSION_ID = 'ac67974f-c524-4288-9d88-af8515400b68';
|
||||
@@ -7,7 +12,30 @@ const QUICK_LEAD_WORKFLOW_VERSION_ID = 'ac67974f-c524-4288-9d88-af8515400b68';
|
||||
export const prefillWorkflows = async (
|
||||
entityManager: WorkspaceEntityManager,
|
||||
schemaName: string,
|
||||
objectMetadataItems: ObjectMetadataEntity[],
|
||||
) => {
|
||||
const objectMetadataMaps = generateObjectMetadataMaps(objectMetadataItems);
|
||||
const companyObjectMetadataId =
|
||||
objectMetadataMaps.idByNameSingular['company'];
|
||||
|
||||
const personObjectMetadataId = objectMetadataMaps.idByNameSingular['person'];
|
||||
|
||||
if (
|
||||
!isDefined(companyObjectMetadataId) ||
|
||||
!isDefined(personObjectMetadataId)
|
||||
) {
|
||||
throw new Error('Company or person object metadata not found');
|
||||
}
|
||||
|
||||
const companyObjectMetadata =
|
||||
objectMetadataMaps.byId[companyObjectMetadataId];
|
||||
|
||||
const personObjectMetadata = objectMetadataMaps.byId[personObjectMetadataId];
|
||||
|
||||
if (!isDefined(companyObjectMetadata) || !isDefined(personObjectMetadata)) {
|
||||
throw new Error('Company or person object metadata not found');
|
||||
}
|
||||
|
||||
await entityManager
|
||||
.createQueryBuilder(undefined, undefined, undefined, {
|
||||
shouldBypassPermissionChecks: true,
|
||||
@@ -181,298 +209,6 @@ export const prefillWorkflows = async (
|
||||
},
|
||||
},
|
||||
outputSchema: {
|
||||
fields: {
|
||||
id: {
|
||||
icon: 'Icon123',
|
||||
type: 'UUID',
|
||||
label: 'Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
},
|
||||
name: {
|
||||
icon: 'IconBuildingSkyscraper',
|
||||
type: 'TEXT',
|
||||
label: 'Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
xLink: {
|
||||
icon: 'IconBrandX',
|
||||
label: 'X',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
address: {
|
||||
icon: 'IconMap',
|
||||
label: 'Address',
|
||||
value: {
|
||||
addressLat: {
|
||||
type: 'NUMERIC',
|
||||
label: ' Address Lat',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
addressLng: {
|
||||
type: 'NUMERIC',
|
||||
label: ' Address Lng',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
addressCity: {
|
||||
type: 'TEXT',
|
||||
label: ' Address City',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressState: {
|
||||
type: 'TEXT',
|
||||
label: ' Address State',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressCountry: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Country',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressStreet1: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Street1',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressStreet2: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Street2',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressPostcode: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Postcode',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
createdAt: {
|
||||
icon: 'IconCalendar',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Creation date',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
createdBy: {
|
||||
icon: 'IconCreativeCommonsSa',
|
||||
label: 'Created by',
|
||||
value: {
|
||||
name: {
|
||||
type: 'TEXT',
|
||||
label: ' Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
source: {
|
||||
type: 'SELECT',
|
||||
label: ' Source',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
context: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Context',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
workspaceMemberId: {
|
||||
type: 'UUID',
|
||||
label: ' Workspace Member Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
deletedAt: {
|
||||
icon: 'IconCalendarMinus',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Deleted at',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
employees: {
|
||||
icon: 'IconUsers',
|
||||
type: 'NUMBER',
|
||||
label: 'Employees',
|
||||
value: 20,
|
||||
isLeaf: true,
|
||||
},
|
||||
updatedAt: {
|
||||
icon: 'IconCalendarClock',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Last update',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
domainName: {
|
||||
icon: 'IconLink',
|
||||
label: 'Domain Name',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
accountOwner: {
|
||||
icon: 'IconUserCircle',
|
||||
label: 'Account Owner',
|
||||
value: {
|
||||
id: {
|
||||
icon: 'Icon123',
|
||||
type: 'UUID',
|
||||
label: 'Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
},
|
||||
name: {
|
||||
icon: 'IconCircleUser',
|
||||
label: 'Name',
|
||||
value: {
|
||||
lastName: {
|
||||
type: 'TEXT',
|
||||
label: ' Last Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
firstName: {
|
||||
type: 'TEXT',
|
||||
label: ' First Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
createdAt: {
|
||||
icon: 'IconCalendar',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Creation date',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
deletedAt: {
|
||||
icon: 'IconCalendarMinus',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Deleted at',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
updatedAt: {
|
||||
icon: 'IconCalendarClock',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Last update',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
userEmail: {
|
||||
icon: 'IconMail',
|
||||
type: 'TEXT',
|
||||
label: 'User Email',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
linkedinLink: {
|
||||
icon: 'IconBrandLinkedin',
|
||||
label: 'Linkedin',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
idealCustomerProfile: {
|
||||
icon: 'IconTarget',
|
||||
type: 'BOOLEAN',
|
||||
label: 'ICP',
|
||||
value: true,
|
||||
isLeaf: true,
|
||||
},
|
||||
annualRecurringRevenue: {
|
||||
icon: 'IconMoneybag',
|
||||
label: 'ARR',
|
||||
value: {
|
||||
amountMicros: {
|
||||
type: 'NUMERIC',
|
||||
label: ' Amount Micros',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
currencyCode: {
|
||||
type: 'TEXT',
|
||||
label: ' Currency Code',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
},
|
||||
object: {
|
||||
icon: 'IconBuildingSkyscraper',
|
||||
label: 'Company',
|
||||
@@ -482,6 +218,13 @@ export const prefillWorkflows = async (
|
||||
nameSingular: 'company',
|
||||
},
|
||||
_outputSchemaType: 'RECORD',
|
||||
fields: generateObjectRecordFields({
|
||||
objectMetadataInfo: {
|
||||
objectMetadataItemWithFieldsMaps: companyObjectMetadata,
|
||||
objectMetadataMaps,
|
||||
},
|
||||
depth: 0,
|
||||
}),
|
||||
},
|
||||
errorHandlingOptions: {
|
||||
retryOnFailure: { value: false },
|
||||
@@ -517,445 +260,13 @@ export const prefillWorkflows = async (
|
||||
},
|
||||
},
|
||||
outputSchema: {
|
||||
fields: {
|
||||
id: {
|
||||
icon: 'Icon123',
|
||||
type: 'UUID',
|
||||
label: 'Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
fields: generateObjectRecordFields({
|
||||
objectMetadataInfo: {
|
||||
objectMetadataItemWithFieldsMaps: personObjectMetadata,
|
||||
objectMetadataMaps,
|
||||
},
|
||||
city: {
|
||||
icon: 'IconMap',
|
||||
type: 'TEXT',
|
||||
label: 'City',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
name: {
|
||||
icon: 'IconUser',
|
||||
label: 'Name',
|
||||
value: {
|
||||
lastName: {
|
||||
type: 'TEXT',
|
||||
label: ' Last Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
firstName: {
|
||||
type: 'TEXT',
|
||||
label: ' First Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
xLink: {
|
||||
icon: 'IconBrandX',
|
||||
label: 'X',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
emails: {
|
||||
icon: 'IconMail',
|
||||
label: 'Emails',
|
||||
value: {
|
||||
primaryEmail: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Email',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
additionalEmails: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Additional Emails',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
phones: {
|
||||
icon: 'IconPhone',
|
||||
label: 'Phones',
|
||||
value: {
|
||||
additionalPhones: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Additional Phones',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryPhoneNumber: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Phone Number',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryPhoneCallingCode: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Phone Calling Code',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryPhoneCountryCode: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Phone Country Code',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
company: {
|
||||
icon: 'IconBuildingSkyscraper',
|
||||
label: 'Company',
|
||||
value: {
|
||||
id: {
|
||||
icon: 'Icon123',
|
||||
type: 'UUID',
|
||||
label: 'Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
},
|
||||
name: {
|
||||
icon: 'IconBuildingSkyscraper',
|
||||
type: 'TEXT',
|
||||
label: 'Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
xLink: {
|
||||
icon: 'IconBrandX',
|
||||
label: 'X',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
address: {
|
||||
icon: 'IconMap',
|
||||
label: 'Address',
|
||||
value: {
|
||||
addressLat: {
|
||||
type: 'NUMERIC',
|
||||
label: ' Address Lat',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
addressLng: {
|
||||
type: 'NUMERIC',
|
||||
label: ' Address Lng',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
addressCity: {
|
||||
type: 'TEXT',
|
||||
label: ' Address City',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressState: {
|
||||
type: 'TEXT',
|
||||
label: ' Address State',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressCountry: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Country',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressStreet1: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Street1',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressStreet2: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Street2',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
addressPostcode: {
|
||||
type: 'TEXT',
|
||||
label: ' Address Postcode',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
createdAt: {
|
||||
icon: 'IconCalendar',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Creation date',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
createdBy: {
|
||||
icon: 'IconCreativeCommonsSa',
|
||||
label: 'Created by',
|
||||
value: {
|
||||
name: {
|
||||
type: 'TEXT',
|
||||
label: ' Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
source: {
|
||||
type: 'SELECT',
|
||||
label: ' Source',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
context: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Context',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
workspaceMemberId: {
|
||||
type: 'UUID',
|
||||
label: ' Workspace Member Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
deletedAt: {
|
||||
icon: 'IconCalendarMinus',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Deleted at',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
employees: {
|
||||
icon: 'IconUsers',
|
||||
type: 'NUMBER',
|
||||
label: 'Employees',
|
||||
value: 20,
|
||||
isLeaf: true,
|
||||
},
|
||||
updatedAt: {
|
||||
icon: 'IconCalendarClock',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Last update',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
domainName: {
|
||||
icon: 'IconLink',
|
||||
label: 'Domain Name',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
linkedinLink: {
|
||||
icon: 'IconBrandLinkedin',
|
||||
label: 'Linkedin',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
idealCustomerProfile: {
|
||||
icon: 'IconTarget',
|
||||
type: 'BOOLEAN',
|
||||
label: 'ICP',
|
||||
value: true,
|
||||
isLeaf: true,
|
||||
},
|
||||
annualRecurringRevenue: {
|
||||
icon: 'IconMoneybag',
|
||||
label: 'ARR',
|
||||
value: {
|
||||
amountMicros: {
|
||||
type: 'NUMERIC',
|
||||
label: ' Amount Micros',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
currencyCode: {
|
||||
type: 'TEXT',
|
||||
label: ' Currency Code',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
jobTitle: {
|
||||
icon: 'IconBriefcase',
|
||||
type: 'TEXT',
|
||||
label: 'Job Title',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
createdAt: {
|
||||
icon: 'IconCalendar',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Creation date',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
createdBy: {
|
||||
icon: 'IconCreativeCommonsSa',
|
||||
label: 'Created by',
|
||||
value: {
|
||||
name: {
|
||||
type: 'TEXT',
|
||||
label: ' Name',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
source: {
|
||||
type: 'SELECT',
|
||||
label: ' Source',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
context: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Context',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
workspaceMemberId: {
|
||||
type: 'UUID',
|
||||
label: ' Workspace Member Id',
|
||||
value: '123e4567-e89b-12d3-a456-426614174000',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
deletedAt: {
|
||||
icon: 'IconCalendarMinus',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Deleted at',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
updatedAt: {
|
||||
icon: 'IconCalendarClock',
|
||||
type: 'DATE_TIME',
|
||||
label: 'Last update',
|
||||
value: '01/23/2025 15:16',
|
||||
isLeaf: true,
|
||||
},
|
||||
linkedinLink: {
|
||||
icon: 'IconBrandLinkedin',
|
||||
label: 'Linkedin',
|
||||
value: {
|
||||
primaryLinkUrl: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Url',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
secondaryLinks: {
|
||||
type: 'RAW_JSON',
|
||||
label: ' Secondary Links',
|
||||
value: null,
|
||||
isLeaf: true,
|
||||
},
|
||||
primaryLinkLabel: {
|
||||
type: 'TEXT',
|
||||
label: ' Primary Link Label',
|
||||
value: 'My text',
|
||||
isLeaf: true,
|
||||
},
|
||||
},
|
||||
isLeaf: false,
|
||||
},
|
||||
},
|
||||
object: {
|
||||
icon: 'IconUser',
|
||||
label: 'Person',
|
||||
value: 'A person',
|
||||
isLeaf: true,
|
||||
fieldIdName: 'id',
|
||||
nameSingular: 'person',
|
||||
},
|
||||
_outputSchemaType: 'RECORD',
|
||||
depth: 0,
|
||||
}),
|
||||
},
|
||||
errorHandlingOptions: {
|
||||
retryOnFailure: { value: false },
|
||||
|
||||
+2
-2
@@ -6,8 +6,8 @@ import { shouldSeedWorkspaceFavorite } from 'src/engine/utils/should-seed-worksp
|
||||
import { prefillCompanies } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-companies';
|
||||
import { prefillPeople } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-people';
|
||||
import { prefillViews } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-views';
|
||||
import { prefillWorkspaceFavorites } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-workspace-favorites';
|
||||
import { prefillWorkflows } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-workflows';
|
||||
import { prefillWorkspaceFavorites } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-workspace-favorites';
|
||||
|
||||
export const standardObjectsPrefillData = async (
|
||||
mainDataSource: DataSource,
|
||||
@@ -19,7 +19,7 @@ export const standardObjectsPrefillData = async (
|
||||
|
||||
await prefillPeople(entityManager, schemaName);
|
||||
|
||||
await prefillWorkflows(entityManager, schemaName);
|
||||
await prefillWorkflows(entityManager, schemaName, objectMetadataItems);
|
||||
|
||||
const viewDefinitionsWithId = await prefillViews(
|
||||
entityManager,
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ export type BaseOutputSchema = Record<string, Leaf | Node>;
|
||||
|
||||
export type FieldOutputSchema =
|
||||
| ((Leaf | Node) & {
|
||||
fieldMetadataId?: string;
|
||||
fieldMetadataId: string;
|
||||
})
|
||||
| RecordOutputSchema;
|
||||
|
||||
|
||||
+3
-3
@@ -10,7 +10,7 @@ const companyMockObjectMetadataItem = mockObjectMetadataItemsWithFieldMaps.find(
|
||||
|
||||
describe('generateFakeFormResponse', () => {
|
||||
it('should generate fake responses for a form schema', async () => {
|
||||
const schema: FormFieldMetadata[] = [
|
||||
const formFieldMetadataItems: FormFieldMetadata[] = [
|
||||
{
|
||||
id: '96939213-49ac-4dee-949d-56e6c7be98e6',
|
||||
name: 'name',
|
||||
@@ -51,8 +51,8 @@ describe('generateFakeFormResponse', () => {
|
||||
},
|
||||
};
|
||||
|
||||
const result = await generateFakeFormResponse({
|
||||
formMetadata: schema,
|
||||
const result = generateFakeFormResponse({
|
||||
formFieldMetadataItems,
|
||||
objectMetadataMaps: mockObjectMetadataMaps,
|
||||
});
|
||||
|
||||
|
||||
+9
-9
@@ -1,7 +1,7 @@
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import * as generateFakeValueModule from 'src/engine/utils/generate-fake-value';
|
||||
import { generateFakeField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-field';
|
||||
import { generateFakeRecordField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-record-field';
|
||||
import * as camelToTitleCaseModule from 'src/utils/camel-to-title-case';
|
||||
|
||||
jest.mock('src/engine/utils/generate-fake-value');
|
||||
@@ -52,7 +52,7 @@ describe('generateFakeField', () => {
|
||||
it('should generate a leaf node for TEXT type', () => {
|
||||
generateFakeValueSpy.mockReturnValueOnce('Fake Text');
|
||||
|
||||
const result = generateFakeField({
|
||||
const result = generateFakeRecordField({
|
||||
type: FieldMetadataType.TEXT,
|
||||
label: 'Text Field',
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
@@ -74,7 +74,7 @@ describe('generateFakeField', () => {
|
||||
});
|
||||
|
||||
it('should handle custom value', () => {
|
||||
const result = generateFakeField({
|
||||
const result = generateFakeRecordField({
|
||||
type: FieldMetadataType.TEXT,
|
||||
label: 'Text Field',
|
||||
value: 'Test value',
|
||||
@@ -96,7 +96,7 @@ describe('generateFakeField', () => {
|
||||
it('should generate a leaf node for NUMBER type with icon', () => {
|
||||
generateFakeValueSpy.mockReturnValueOnce(42);
|
||||
|
||||
const result = generateFakeField({
|
||||
const result = generateFakeRecordField({
|
||||
type: FieldMetadataType.NUMBER,
|
||||
label: 'Number Field',
|
||||
icon: 'IconNumber',
|
||||
@@ -118,7 +118,7 @@ describe('generateFakeField', () => {
|
||||
|
||||
generateFakeValueSpy.mockReturnValueOnce(fakeDate);
|
||||
|
||||
const result = generateFakeField({
|
||||
const result = generateFakeRecordField({
|
||||
type: FieldMetadataType.DATE,
|
||||
label: 'Date Field',
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
@@ -145,7 +145,7 @@ describe('generateFakeField', () => {
|
||||
.mockReturnValueOnce('Label')
|
||||
.mockReturnValueOnce('Url');
|
||||
|
||||
const result = generateFakeField({
|
||||
const result = generateFakeRecordField({
|
||||
type: FieldMetadataType.LINKS,
|
||||
label: 'Links Field',
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
@@ -189,7 +189,7 @@ describe('generateFakeField', () => {
|
||||
.mockReturnValueOnce('Amount')
|
||||
.mockReturnValueOnce('Currency Code');
|
||||
|
||||
const result = generateFakeField({
|
||||
const result = generateFakeRecordField({
|
||||
type: FieldMetadataType.CURRENCY,
|
||||
label: 'Currency Field',
|
||||
icon: 'IconCurrency',
|
||||
@@ -230,7 +230,7 @@ describe('generateFakeField', () => {
|
||||
|
||||
generateFakeValueSpy.mockReturnValueOnce('Unknown Value');
|
||||
|
||||
const result = generateFakeField({
|
||||
const result = generateFakeRecordField({
|
||||
type: unknownType,
|
||||
label: 'Unknown Field',
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
@@ -249,7 +249,7 @@ describe('generateFakeField', () => {
|
||||
it('should handle empty label', () => {
|
||||
generateFakeValueSpy.mockReturnValueOnce('Fake Boolean');
|
||||
|
||||
const result = generateFakeField({
|
||||
const result = generateFakeRecordField({
|
||||
type: FieldMetadataType.BOOLEAN,
|
||||
label: '',
|
||||
fieldMetadataId: '123e4567-e89b-12d3-a456-426614174000',
|
||||
+6
-6
@@ -1,12 +1,12 @@
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { generateFakeField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-field';
|
||||
import { mockObjectMetadataItemsWithFieldMaps } from 'src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps';
|
||||
import { generateFakeRecordField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-record-field';
|
||||
import { generateObjectRecordFields } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-object-record-fields';
|
||||
import { shouldGenerateFieldFakeValue } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/should-generate-field-fake-value';
|
||||
import { mockObjectMetadataItemsWithFieldMaps } from 'src/engine/core-modules/__mocks__/mockObjectMetadataItemsWithFieldMaps';
|
||||
|
||||
jest.mock(
|
||||
'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-field',
|
||||
'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-record-field',
|
||||
);
|
||||
jest.mock(
|
||||
'src/modules/workflow/workflow-builder/workflow-schema/utils/should-generate-field-fake-value',
|
||||
@@ -42,7 +42,7 @@ describe('generateObjectRecordFields', () => {
|
||||
(field) => field.type !== FieldMetadataType.RELATION,
|
||||
);
|
||||
|
||||
(generateFakeField as jest.Mock).mockImplementation(
|
||||
(generateFakeRecordField as jest.Mock).mockImplementation(
|
||||
({ type, label, icon }) => ({
|
||||
type,
|
||||
label,
|
||||
@@ -69,7 +69,7 @@ describe('generateObjectRecordFields', () => {
|
||||
});
|
||||
|
||||
expect(shouldGenerateFieldFakeValue).toHaveBeenCalledTimes(2);
|
||||
expect(generateFakeField).toHaveBeenCalledTimes(2);
|
||||
expect(generateFakeRecordField).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('should return empty object when no valid fields', () => {
|
||||
@@ -79,6 +79,6 @@ describe('generateObjectRecordFields', () => {
|
||||
|
||||
expect(result).toEqual({});
|
||||
expect(shouldGenerateFieldFakeValue).toHaveBeenCalledTimes(2);
|
||||
expect(generateFakeField).not.toHaveBeenCalled();
|
||||
expect(generateFakeRecordField).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import { type FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { generateFakeValue } from 'src/engine/utils/generate-fake-value';
|
||||
import {
|
||||
type Leaf,
|
||||
type Node,
|
||||
} from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
|
||||
|
||||
type GenerateFakeFormFieldArgs = {
|
||||
type: FieldMetadataType;
|
||||
label: string;
|
||||
value?: string;
|
||||
};
|
||||
|
||||
export const generateFakeFormField = ({
|
||||
type,
|
||||
label,
|
||||
value,
|
||||
}: GenerateFakeFormFieldArgs): Leaf | Node => {
|
||||
return {
|
||||
isLeaf: true,
|
||||
type: type,
|
||||
label: label,
|
||||
value: value ?? generateFakeValue(type, 'FieldMetadataType'),
|
||||
};
|
||||
};
|
||||
+47
-47
@@ -6,59 +6,59 @@ import {
|
||||
type Leaf,
|
||||
type Node,
|
||||
} from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
|
||||
import { generateFakeField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-field';
|
||||
import { generateFakeFormField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-form-field';
|
||||
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record';
|
||||
import { type FormFieldMetadata } from 'src/modules/workflow/workflow-executor/workflow-actions/form/types/workflow-form-action-settings.type';
|
||||
|
||||
export const generateFakeFormResponse = async ({
|
||||
formMetadata,
|
||||
objectMetadataMaps,
|
||||
}: {
|
||||
formMetadata: FormFieldMetadata[];
|
||||
type GenerateFakeFormResponseArgs = {
|
||||
formFieldMetadataItems: FormFieldMetadata[];
|
||||
objectMetadataMaps: ObjectMetadataMaps;
|
||||
}): Promise<Record<string, Leaf | Node>> => {
|
||||
const result = await Promise.all(
|
||||
formMetadata.map(async (formFieldMetadata) => {
|
||||
if (formFieldMetadata.type === 'RECORD') {
|
||||
if (!formFieldMetadata?.settings?.objectName) {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const objectMetadataItemWithFieldsMaps =
|
||||
getObjectMetadataMapItemByNameSingular(
|
||||
objectMetadataMaps,
|
||||
formFieldMetadata?.settings?.objectName,
|
||||
);
|
||||
|
||||
if (!isDefined(objectMetadataItemWithFieldsMaps)) {
|
||||
throw new Error(
|
||||
`Object metadata not found for object name ${formFieldMetadata?.settings?.objectName}`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
[formFieldMetadata.name]: {
|
||||
isLeaf: false,
|
||||
label: formFieldMetadata.label,
|
||||
value: generateFakeObjectRecord({
|
||||
objectMetadataInfo: {
|
||||
objectMetadataItemWithFieldsMaps,
|
||||
objectMetadataMaps,
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
[formFieldMetadata.name]: generateFakeField({
|
||||
type: formFieldMetadata.type,
|
||||
label: formFieldMetadata.label,
|
||||
value: formFieldMetadata.placeholder,
|
||||
}),
|
||||
};
|
||||
export const generateFakeFormResponse = ({
|
||||
formFieldMetadataItems,
|
||||
objectMetadataMaps,
|
||||
}: GenerateFakeFormResponseArgs): Record<string, Leaf | Node> => {
|
||||
const result = formFieldMetadataItems.map((formFieldMetadata) => {
|
||||
if (formFieldMetadata.type === 'RECORD') {
|
||||
if (!formFieldMetadata?.settings?.objectName) {
|
||||
return undefined;
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
const objectMetadataItemWithFieldsMaps =
|
||||
getObjectMetadataMapItemByNameSingular(
|
||||
objectMetadataMaps,
|
||||
formFieldMetadata?.settings?.objectName,
|
||||
);
|
||||
|
||||
if (!isDefined(objectMetadataItemWithFieldsMaps)) {
|
||||
throw new Error(
|
||||
`Object metadata not found for object name ${formFieldMetadata?.settings?.objectName}`,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
[formFieldMetadata.name]: {
|
||||
isLeaf: false,
|
||||
label: formFieldMetadata.label,
|
||||
value: generateFakeObjectRecord({
|
||||
objectMetadataInfo: {
|
||||
objectMetadataItemWithFieldsMaps,
|
||||
objectMetadataMaps,
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
[formFieldMetadata.name]: generateFakeFormField({
|
||||
type: formFieldMetadata.type,
|
||||
label: formFieldMetadata.label,
|
||||
value: formFieldMetadata.placeholder,
|
||||
}),
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return result.filter(isDefined).reduce(
|
||||
(acc, curr) => {
|
||||
|
||||
+12
-8
@@ -8,19 +8,23 @@ import {
|
||||
} from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
|
||||
import { camelToTitleCase } from 'src/utils/camel-to-title-case';
|
||||
|
||||
export const generateFakeField = ({
|
||||
type GenerateFakeRecordFieldArgs = {
|
||||
type: FieldMetadataType;
|
||||
label: string;
|
||||
fieldMetadataId: string;
|
||||
icon?: string;
|
||||
value?: string;
|
||||
};
|
||||
|
||||
export const generateFakeRecordField = ({
|
||||
type,
|
||||
label,
|
||||
icon,
|
||||
value,
|
||||
fieldMetadataId,
|
||||
}: {
|
||||
type: FieldMetadataType;
|
||||
label: string;
|
||||
fieldMetadataId?: string;
|
||||
icon?: string;
|
||||
value?: string;
|
||||
}): (Leaf | Node) & { fieldMetadataId?: string } => {
|
||||
}: GenerateFakeRecordFieldArgs): (Leaf | Node) & {
|
||||
fieldMetadataId: string;
|
||||
} => {
|
||||
const compositeType = compositeTypeDefinitions.get(type);
|
||||
|
||||
if (compositeType) {
|
||||
+2
-2
@@ -3,8 +3,8 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ObjectMetadataInfo } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
|
||||
import { type FieldOutputSchema } from 'src/modules/workflow/workflow-builder/workflow-schema/types/output-schema.type';
|
||||
import { generateFakeField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-field';
|
||||
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-object-record';
|
||||
import { generateFakeRecordField } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/generate-fake-record-field';
|
||||
import { shouldGenerateFieldFakeValue } from 'src/modules/workflow/workflow-builder/workflow-schema/utils/should-generate-field-fake-value';
|
||||
|
||||
const MAXIMUM_DEPTH = 1;
|
||||
@@ -25,7 +25,7 @@ export const generateObjectRecordFields = ({
|
||||
}
|
||||
|
||||
if (field.type !== FieldMetadataType.RELATION) {
|
||||
acc[field.name] = generateFakeField({
|
||||
acc[field.name] = generateFakeRecordField({
|
||||
type: field.type,
|
||||
label: field.label,
|
||||
icon: field.icon ?? undefined,
|
||||
|
||||
+4
-4
@@ -73,7 +73,7 @@ export class WorkflowSchemaWorkspaceService {
|
||||
});
|
||||
case WorkflowActionType.FORM:
|
||||
return this.computeFormActionOutputSchema({
|
||||
formMetadata: step.settings.input,
|
||||
formFieldMetadataItems: step.settings.input,
|
||||
workspaceId,
|
||||
});
|
||||
case WorkflowActionType.CODE: // StepOutput schema is computed on serverlessFunction draft execution
|
||||
@@ -156,10 +156,10 @@ export class WorkflowSchemaWorkspaceService {
|
||||
}
|
||||
|
||||
private async computeFormActionOutputSchema({
|
||||
formMetadata,
|
||||
formFieldMetadataItems,
|
||||
workspaceId,
|
||||
}: {
|
||||
formMetadata: FormFieldMetadata[];
|
||||
formFieldMetadataItems: FormFieldMetadata[];
|
||||
workspaceId: string;
|
||||
}): Promise<OutputSchema> {
|
||||
const objectMetadataMaps =
|
||||
@@ -168,7 +168,7 @@ export class WorkflowSchemaWorkspaceService {
|
||||
);
|
||||
|
||||
return generateFakeFormResponse({
|
||||
formMetadata,
|
||||
formFieldMetadataItems,
|
||||
objectMetadataMaps,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user