Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into feat/use-subdomain-…
Browse files Browse the repository at this point in the history
…by-workspace

# Conflicts:
#	packages/twenty-front/src/modules/auth/sign-in-up/components/SignInUpForm.tsx
#	packages/twenty-front/src/pages/auth/SSOWorkspaceSelection.tsx
  • Loading branch information
AMoreaux committed Nov 14, 2024
2 parents 0f9eb2b + 898006f commit 9d505f0
Show file tree
Hide file tree
Showing 39 changed files with 368 additions and 154 deletions.
17 changes: 16 additions & 1 deletion packages/twenty-front/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
<link rel="icon" href="/icons/android/android-launchericon-48-48.png" />
<link rel="apple-touch-icon" href="/icons/ios/192.png" />

<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="A modern open-source CRM" />
<meta
Expand All @@ -30,6 +29,22 @@

<title>Twenty</title>
<script src="/env-config.js"></script>

<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="module">
const disableInputAutoZoom = () => {
const viewportMetadata = document.querySelector('meta[name=viewport]');

if (viewportMetadata !== null) {
viewportMetadata.setAttribute('content', 'width=device-width, initial-scale=1.0, maximum-scale=1.0');
}
}

const isIOS = /iPad|iPhone/.test(navigator.userAgent);
if (isIOS) {
disableInputAutoZoom();
}
</script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
/* @license Enterprise */

import { HorizontalSeparator } from '@/auth/sign-in-up/components/HorizontalSeparator';
import { parseSAMLMetadataFromXMLFile } from '@/settings/security/utils/parseSAMLMetadataFromXMLFile';
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { TextInput } from '@/ui/input/components/TextInput';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { ChangeEvent, useRef } from 'react';
import { useFormContext } from 'react-hook-form';
import {
HorizontalSeparator,
Button,
H2Title,
IconCheck,
Expand All @@ -18,6 +10,14 @@ import {
IconUpload,
Section,
} from 'twenty-ui';
import { parseSAMLMetadataFromXMLFile } from '@/settings/security/utils/parseSAMLMetadataFromXMLFile';
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { TextInput } from '@/ui/input/components/TextInput';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { ChangeEvent, useRef } from 'react';
import { useFormContext } from 'react-hook-form';
import { REACT_APP_SERVER_BASE_URL } from '~/config';
import { isDefined } from '~/utils/isDefined';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { ReactNode } from 'react';
import styled from '@emotion/styled';

import { useGetManyServerlessFunctions } from '@/settings/serverless-functions/hooks/useGetManyServerlessFunctions';
import { setNestedValue } from '@/workflow/utils/setNestedValue';
import { Select, SelectOption } from '@/ui/input/components/Select';
import { WorkflowEditGenericFormBase } from '@/workflow/components/WorkflowEditGenericFormBase';
import VariableTagInput from '@/workflow/search-variables/components/VariableTagInput';
import { WorkflowCodeStep } from '@/workflow/types/Workflow';
import { useTheme } from '@emotion/react';
import { IconCode, isDefined } from 'twenty-ui';
import { IconCode, isDefined, HorizontalSeparator } from 'twenty-ui';
import { useDebouncedCallback } from 'use-debounce';
import { getDefaultFunctionInputFromInputSchema } from '@/workflow/utils/getDefaultFunctionInputFromInputSchema';
import { FunctionInput } from '@/workflow/types/FunctionInput';
Expand All @@ -23,16 +22,19 @@ const StyledLabel = styled.div`
color: ${({ theme }) => theme.font.color.light};
font-size: ${({ theme }) => theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.semiBold};
margin-top: ${({ theme }) => theme.spacing(3)};
margin-top: ${({ theme }) => theme.spacing(2)};
margin-bottom: ${({ theme }) => theme.spacing(2)};
`;

const StyledInputContainer = styled.div`
background: ${({ theme }) => theme.background.secondary};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.md};
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(2)};
padding: ${({ theme }) => theme.spacing(2)};
position: relative;
gap: ${({ theme }) => theme.spacing(4)};
padding-left: ${({ theme }) => theme.spacing(4)};
`;

type WorkflowEditActionFormServerlessFunctionProps =
Expand Down Expand Up @@ -139,17 +141,40 @@ export const WorkflowEditActionFormServerlessFunction = (
const renderFields = (
functionInput: FunctionInput,
path: string[] = [],
): ReactNode | undefined => {
isRoot = true,
): ReactNode[] => {
const displaySeparator = (functionInput: FunctionInput) => {
const keys = Object.keys(functionInput);
if (keys.length > 1) {
return true;
}
if (keys.length === 1) {
const subKeys = Object.keys(functionInput[keys[0]]);
return subKeys.length > 0;
}
return false;
};

return Object.entries(functionInput).map(([inputKey, inputValue]) => {
const currentPath = [...path, inputKey];
const pathKey = currentPath.join('.');

if (inputValue !== null && typeof inputValue === 'object') {
if (isRoot) {
return (
<>
{displaySeparator(functionInput) && (
<HorizontalSeparator noMargin />
)}
{renderFields(inputValue, currentPath, false)}
</>
);
}
return (
<StyledContainer key={pathKey}>
<StyledLabel>{inputKey}</StyledLabel>
<StyledInputContainer>
{renderFields(inputValue, currentPath)}
{renderFields(inputValue, currentPath, false)}
</StyledInputContainer>
</StyledContainer>
);
Expand Down Expand Up @@ -184,7 +209,7 @@ export const WorkflowEditActionFormServerlessFunction = (
disabled={props.readonly}
onChange={handleFunctionChange}
/>
{functionInput && renderFields(functionInput)}
{renderFields(functionInput)}
</WorkflowEditGenericFormBase>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const StyledContainer = styled.div`

const StyledLabel = styled.div`
color: ${({ theme }) => theme.font.color.light};
font-size: ${({ theme }) => theme.font.size.xs};
font-size: ${({ theme }) => theme.font.size.md};
font-weight: ${({ theme }) => theme.font.weight.semiBold};
margin-bottom: ${({ theme }) => theme.spacing(1)};
`;
Expand Down
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import { Field, InputType } from '@nestjs/graphql';

import graphqlTypeJson from 'graphql-type-json';

import { WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
import { WorkflowTrigger } from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type';
import { WorkflowStep } from 'src/modules/workflow/workflow-executor/types/workflow-action.type';

@InputType()
export class ComputeStepOutputSchemaInput {
@Field(() => graphqlTypeJson, {
description: 'Step JSON format',
nullable: false,
})
step: WorkflowTrigger | WorkflowStep;
step: WorkflowTrigger | WorkflowAction;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorat
import { UserAuthGuard } from 'src/engine/guards/user-auth.guard';
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
import { WorkflowBuilderWorkspaceService } from 'src/modules/workflow/workflow-builder/workflow-builder.workspace-service';
import { OutputSchema } from 'src/modules/workflow/workflow-executor/types/workflow-step-settings.type';
import { OutputSchema } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-settings.type';

@Resolver()
@UseGuards(WorkspaceAuthGuard, UserAuthGuard)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/f
import { TimelineActivityWorkspaceEntity } from 'src/modules/timeline/standard-objects/timeline-activity.workspace-entity';
import { WorkflowRunWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity';
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
import { WorkflowStep } from 'src/modules/workflow/workflow-executor/types/workflow-action.type';
import { WorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
import { WorkflowTrigger } from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type';

export enum WorkflowVersionStatus {
Expand Down Expand Up @@ -98,7 +98,7 @@ export class WorkflowVersionWorkspaceEntity extends BaseWorkspaceEntity {
icon: 'IconSettingsAutomation',
})
@WorkspaceIsNullable()
steps: WorkflowStep[] | null;
steps: WorkflowAction[] | null;

@WorkspaceField({
standardId: WORKFLOW_VERSION_STANDARD_FIELD_IDS.status,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,24 @@ import { join } from 'path';

import { Repository } from 'typeorm';

import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';
import { checkStringIsDatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/utils/check-string-is-database-event-action';
import { INDEX_FILE_NAME } from 'src/engine/core-modules/serverless/drivers/constants/index-file-name';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
import { CodeIntrospectionService } from 'src/modules/code-introspection/code-introspection.service';
import { generateFakeObjectRecord } from 'src/modules/workflow/workflow-builder/utils/generate-fake-object-record';
import { generateFakeObjectRecordEvent } from 'src/modules/workflow/workflow-builder/utils/generate-fake-object-record-event';
import { WorkflowSendEmailStepOutputSchema } from 'src/modules/workflow/workflow-executor/workflow-actions/mail-sender/send-email.workflow-action';
import {
WorkflowAction,
WorkflowActionType,
WorkflowStep,
} from 'src/modules/workflow/workflow-executor/types/workflow-action.type';
import { WorkflowSendEmailStepOutputSchema } from 'src/modules/workflow/workflow-executor/types/workflow-step-settings.type';
} from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
import {
WorkflowTrigger,
WorkflowTriggerType,
} from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type';
import { isDefined } from 'src/utils/is-defined';
import { checkStringIsDatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/utils/check-string-is-database-event-action';
import { generateFakeObjectRecordEvent } from 'src/modules/workflow/workflow-builder/utils/generate-fake-object-record-event';
import { DatabaseEventAction } from 'src/engine/api/graphql/graphql-query-runner/enums/database-event-action';

@Injectable()
export class WorkflowBuilderWorkspaceService {
Expand All @@ -37,7 +37,7 @@ export class WorkflowBuilderWorkspaceService {
step,
workspaceId,
}: {
step: WorkflowTrigger | WorkflowStep;
step: WorkflowTrigger | WorkflowAction;
workspaceId: string;
}): Promise<object> {
const stepType = step.type;
Expand All @@ -57,7 +57,7 @@ export class WorkflowBuilderWorkspaceService {
return {};
}

return await this.computeManualTriggerOutputSchema({
return await this.computeRecordOutputSchema({
objectType,
workspaceId,
objectMetadataRepository: this.objectMetadataRepository,
Expand All @@ -78,6 +78,12 @@ export class WorkflowBuilderWorkspaceService {
codeIntrospectionService: this.codeIntrospectionService,
});
}
case WorkflowActionType.RECORD_CRUD:
return await this.computeRecordOutputSchema({
objectType: step.settings.input.objectName,
workspaceId,
objectMetadataRepository: this.objectMetadataRepository,
});
default:
return {};
}
Expand Down Expand Up @@ -116,7 +122,7 @@ export class WorkflowBuilderWorkspaceService {
);
}

private async computeManualTriggerOutputSchema<Entity>({
private async computeRecordOutputSchema<Entity>({
objectType,
workspaceId,
objectMetadataRepository,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@ import { Injectable } from '@nestjs/common';

import { WorkflowAction } from 'src/modules/workflow/workflow-executor/interfaces/workflow-action.interface';

import { WorkflowActionType } from 'src/modules/workflow/workflow-executor/types/workflow-action.type';
import {
WorkflowStepExecutorException,
WorkflowStepExecutorExceptionCode,
} from 'src/modules/workflow/workflow-executor/exceptions/workflow-step-executor.exception';
import { CodeWorkflowAction } from 'src/modules/serverless/workflow-actions/code.workflow-action';
import { SendEmailWorkflowAction } from 'src/modules/mail-sender/workflow-actions/send-email.workflow-action';
import { CodeWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/code/code.workflow-action';
import { SendEmailWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/mail-sender/send-email.workflow-action';
import { RecordCRUDWorkflowAction } from 'src/modules/workflow/workflow-executor/workflow-actions/record-crud/record-crud.workflow-action';
import { WorkflowActionType } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';

@Injectable()
export class WorkflowActionFactory {
constructor(
private readonly codeWorkflowAction: CodeWorkflowAction,
private readonly sendEmailWorkflowAction: SendEmailWorkflowAction,
private readonly recordCRUDWorkflowAction: RecordCRUDWorkflowAction,
) {}

get(stepType: WorkflowActionType): WorkflowAction {
Expand All @@ -23,6 +25,8 @@ export class WorkflowActionFactory {
return this.codeWorkflowAction;
case WorkflowActionType.SEND_EMAIL:
return this.sendEmailWorkflowAction;
case WorkflowActionType.RECORD_CRUD:
return this.recordCRUDWorkflowAction;
default:
throw new WorkflowStepExecutorException(
`Workflow step executor not found for step type '${stepType}'`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { WorkflowActionResult } from 'src/modules/workflow/workflow-executor/types/workflow-action-result.type';
import { WorkflowActionResult } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action-result.type';

export interface WorkflowAction {
execute(workflowStepInput: unknown): Promise<WorkflowActionResult>;
Expand Down

This file was deleted.

This file was deleted.

Loading

0 comments on commit 9d505f0

Please sign in to comment.