Skip to content

Commit

Permalink
Merge branch 'twentyhq:main' into fixed-issue-6630
Browse files Browse the repository at this point in the history
  • Loading branch information
ehconitin authored Aug 20, 2024
2 parents 9867240 + 091c0f8 commit 3f4591d
Show file tree
Hide file tree
Showing 265 changed files with 3,411 additions and 1,760 deletions.
2 changes: 1 addition & 1 deletion nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
},
"start": {
"cache": true,
"dependsOn": ["^build"]
"dependsOn": ["^typecheck","^build"]
},
"lint": {
"executor": "@nx/eslint:lint",
Expand Down
2 changes: 1 addition & 1 deletion packages/twenty-chrome-extension/src/generated/graphql.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7455,7 +7455,7 @@ export type Workspace = {
billingSubscriptions?: Maybe<Array<BillingSubscription>>;
createdAt: Scalars['DateTime'];
currentBillingSubscription?: Maybe<BillingSubscription>;
currentCacheVersion?: Maybe<Scalars['String']>;
metadataVersion?: Maybe<Scalars['String']>;
deletedAt?: Maybe<Scalars['DateTime']>;
displayName?: Maybe<Scalars['String']>;
domainName?: Maybe<Scalars['String']>;
Expand Down
11 changes: 11 additions & 0 deletions packages/twenty-front/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,16 @@ const config: StorybookConfig = {
name: '@storybook/react-vite',
options: {},
},
viteFinal: async (config) => {
// Merge custom configuration into the default config
const { mergeConfig } = await import('vite');

return mergeConfig(config, {
// Add dependencies to pre-optimization
optimizeDeps: {
exclude: ['@tabler/icons-react'],
},
});
},
};
export default config;
6 changes: 6 additions & 0 deletions packages/twenty-front/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
"outputPath": "{projectRoot}/build"
}
},
"serve": {
"executor": "nx:run-commands",
"options": {
"command": "npx serve -s {projectRoot}/build"
}
},
"start": {
"executor": "@nx/vite:dev-server",
"options": {
Expand Down
27 changes: 19 additions & 8 deletions packages/twenty-front/src/generated-metadata/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,9 @@ export type FieldConnection = {

/** Type of the field */
export enum FieldMetadataType {
Actor = 'ACTOR',
Address = 'ADDRESS',
Boolean = 'BOOLEAN',
Actor = 'ACTOR',
Currency = 'CURRENCY',
Date = 'DATE',
DateTime = 'DATE_TIME',
Expand Down Expand Up @@ -452,13 +452,13 @@ export type Mutation = {
generateTransientToken: TransientToken;
impersonate: Verify;
renewToken: AuthTokens;
runWorkflowVersion: WorkflowTriggerResult;
sendInviteLink: SendInviteLink;
signUp: LoginToken;
skipSyncEmailOnboardingStep: OnboardingStepSuccess;
syncRemoteTable: RemoteTable;
syncRemoteTableSchemaChanges: RemoteTable;
track: Analytics;
triggerWorkflow: WorkflowTriggerResult;
unsyncRemoteTable: RemoteTable;
updateBillingSubscription: UpdateBillingEntity;
updateOneField: Field;
Expand Down Expand Up @@ -610,6 +610,11 @@ export type MutationRenewTokenArgs = {
};


export type MutationRunWorkflowVersionArgs = {
input: RunWorkflowVersionInput;
};


export type MutationSendInviteLinkArgs = {
emails: Array<Scalars['String']['input']>;
};
Expand Down Expand Up @@ -639,11 +644,6 @@ export type MutationTrackArgs = {
};


export type MutationTriggerWorkflowArgs = {
workflowVersionId: Scalars['String']['input'];
};


export type MutationUnsyncRemoteTableArgs = {
input: RemoteTableInput;
};
Expand Down Expand Up @@ -1001,6 +1001,13 @@ export enum RemoteTableStatus {
Synced = 'SYNCED'
}

export type RunWorkflowVersionInput = {
/** Execution result in JSON format */
payload?: InputMaybe<Scalars['JSON']['input']>;
/** Workflow version ID */
workflowVersionId: Scalars['String']['input'];
};

export type SendInviteLink = {
__typename?: 'SendInviteLink';
/** Boolean that confirms query was dispatched */
Expand Down Expand Up @@ -1373,14 +1380,17 @@ export type Workspace = {
billingSubscriptions?: Maybe<Array<BillingSubscription>>;
createdAt: Scalars['DateTime']['output'];
currentBillingSubscription?: Maybe<BillingSubscription>;
currentCacheVersion?: Maybe<Scalars['String']['output']>;
currentMetadataVersion: Scalars['Float']['output'];
databaseSchema: Scalars['String']['output'];
databaseUrl: Scalars['String']['output'];
deletedAt?: Maybe<Scalars['DateTime']['output']>;
displayName?: Maybe<Scalars['String']['output']>;
domainName?: Maybe<Scalars['String']['output']>;
featureFlags?: Maybe<Array<FeatureFlag>>;
id: Scalars['UUID']['output'];
inviteHash?: Maybe<Scalars['String']['output']>;
logo?: Maybe<Scalars['String']['output']>;
metadataVersion: Scalars['Float']['output'];
updatedAt: Scalars['DateTime']['output'];
workspaceMembersCount?: Maybe<Scalars['Float']['output']>;
};
Expand All @@ -1400,6 +1410,7 @@ export type WorkspaceFeatureFlagsArgs = {
export enum WorkspaceActivationStatus {
Active = 'ACTIVE',
Inactive = 'INACTIVE',
OngoingCreation = 'ONGOING_CREATION',
PendingCreation = 'PENDING_CREATION'
}

Expand Down
38 changes: 24 additions & 14 deletions packages/twenty-front/src/generated/graphql.tsx

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/twenty-front/src/hooks/useIsMatchingLocation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const useIsMatchingLocation = () => {
return useCallback(
(path: string, basePath?: AppBasePath) => {
const constructedPath = basePath
? new URL(basePath + path, document.location.origin).pathname ?? ''
? (new URL(basePath + path, document.location.origin).pathname ?? '')
: path;

return !!matchPath(constructedPath, location.pathname);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const StyledItemsContainer = styled.div`
align-items: center;
display: flex;
flex-direction: column;
gap: 12px;
gap: 14px;
height: calc(100dvh - 32px);
margin-bottom: auto;
max-width: 204px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const MessageThreadSubscribersChip = ({
? `+${numberOfMessageThreadSubscribers - MAX_NUMBER_OF_AVATARS}`
: null;

const label = isPrivateThread ? privateLabel : moreAvatarsLabel ?? '';
const label = isPrivateThread ? privateLabel : (moreAvatarsLabel ?? '');

return (
<Chip
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IconCirclePlus, IconEditCircle, useIcons } from 'twenty-ui';
import { IconCirclePlus, IconEditCircle, IconTrash, useIcons } from 'twenty-ui';

import { TimelineActivity } from '@/activities/timelineActivities/types/TimelineActivity';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
Expand All @@ -19,6 +19,9 @@ export const EventIconDynamicComponent = ({
if (eventAction === 'updated') {
return <IconEditCircle />;
}
if (eventAction === 'deleted') {
return <IconTrash />;
}

const IconComponent = getIcon(linkedObjectMetadataItem?.icon);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,17 @@ export const EventRowMainObject = ({
/>
);
}
case 'deleted': {
return (
<StyledMainContainer>
<StyledEventRowItemColumn>
{labelIdentifierValue}
</StyledEventRowItemColumn>
<StyledEventRowItemAction>was deleted by</StyledEventRowItemAction>
<StyledEventRowItemColumn>{authorFullName}</StyledEventRowItemColumn>
</StyledMainContainer>
);
}
default:
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { InMemoryCache, NormalizedCacheObject } from '@apollo/client';
import { useMemo, useRef } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { InMemoryCache, NormalizedCacheObject } from '@apollo/client';
import { useRecoilState, useSetRecoilState } from 'recoil';

import { currentUserState } from '@/auth/states/currentUserState';
Expand Down Expand Up @@ -49,8 +49,8 @@ export const useApolloFactory = (options: Partial<Options<any>> = {}) => {
},
}),
headers: {
...(currentWorkspace?.currentCacheVersion && {
'X-Schema-Version': currentWorkspace.currentCacheVersion,
...(currentWorkspace?.metadataVersion && {
'X-Schema-Version': `${currentWorkspace.metadataVersion}`,
}),
},
defaultOptions: {
Expand Down Expand Up @@ -95,7 +95,7 @@ export const useApolloFactory = (options: Partial<Options<any>> = {}) => {
setCurrentWorkspace,
setWorkspaces,
isDebugMode,
currentWorkspace?.currentCacheVersion,
currentWorkspace?.metadataVersion,
setPreviousUrl,
]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type CurrentWorkspace = Pick<
| 'activationStatus'
| 'currentBillingSubscription'
| 'workspaceMembersCount'
| 'currentCacheVersion'
| 'metadataVersion'
>;

export const currentWorkspaceState = createState<CurrentWorkspace | null>({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Button } from '@/ui/input/button/components/Button';
import styled from '@emotion/styled';
import { Banner, IconComponent } from 'twenty-ui';
import { Banner, BannerVariant, IconComponent } from 'twenty-ui';

const StyledBanner = styled(Banner)`
position: absolute;
Expand All @@ -14,26 +14,30 @@ const StyledText = styled.div`

export const InformationBanner = ({
message,
variant = 'default',
buttonTitle,
buttonIcon,
buttonOnClick,
}: {
message: string;
buttonTitle: string;
variant?: BannerVariant;
buttonTitle?: string;
buttonIcon?: IconComponent;
buttonOnClick: () => void;
buttonOnClick?: () => void;
}) => {
return (
<StyledBanner>
<StyledBanner variant={variant}>
<StyledText>{message}</StyledText>
<Button
variant="secondary"
title={buttonTitle}
Icon={buttonIcon}
size="small"
inverted
onClick={buttonOnClick}
/>
{buttonTitle && buttonOnClick && (
<Button
variant="secondary"
title={buttonTitle}
Icon={buttonIcon}
size="small"
inverted
onClick={buttonOnClick}
/>
)}
</StyledBanner>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { InformationBanner } from '@/information-banner/components/InformationBanner';
import { useRestoreManyRecords } from '@/object-record/hooks/useRestoreManyRecords';
import styled from '@emotion/styled';
import { IconRefresh } from 'twenty-ui';

const StyledInformationBannerDeletedRecord = styled.div`
height: 40px;
position: relative;
&:empty {
height: 0;
}
`;

export const InformationBannerDeletedRecord = ({
recordId,
objectNameSingular,
}: {
recordId: string;
objectNameSingular: string;
}) => {
const { restoreManyRecords } = useRestoreManyRecords({
objectNameSingular,
});

return (
<StyledInformationBannerDeletedRecord>
<InformationBanner
variant="danger"
message={`This record has been deleted`}
buttonTitle="Restore"
buttonIcon={IconRefresh}
buttonOnClick={() => restoreManyRecords([recordId])}
/>
</StyledInformationBannerDeletedRecord>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const INFORMATION_BANNER_HEIGHT = '40px';
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord';
export const generateDefaultRecordChipData = (record: ObjectRecord) => {
const name = isFieldFullNameValue(record.name)
? record.name.firstName + ' ' + record.name.lastName
: record.name ?? '';
: (record.name ?? '');

return {
name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { isDefined } from '~/utils/isDefined';
import { sleep } from '~/utils/sleep';
import { capitalize } from '~/utils/string/capitalize';

type useDeleteOneRecordProps = {
type useDeleteManyRecordProps = {
objectNameSingular: string;
refetchFindManyQuery?: boolean;
};
Expand All @@ -25,7 +25,7 @@ type DeleteManyRecordsOptions = {

export const useDeleteManyRecords = ({
objectNameSingular,
}: useDeleteOneRecordProps) => {
}: useDeleteManyRecordProps) => {
const apiConfig = useRecoilValue(apiConfigState);

const mutationPageSize =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import gql from 'graphql-tag';

import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
import { EMPTY_MUTATION } from '@/object-record/constants/EmptyMutation';
import { getDestroyManyRecordsMutationResponseField } from '@/object-record/utils/getDestroyManyRecordsMutationResponseField';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
import { capitalize } from '~/utils/string/capitalize';

export const useDestroyManyRecordsMutation = ({
objectNameSingular,
}: {
objectNameSingular: string;
}) => {
const { objectMetadataItem } = useObjectMetadataItem({
objectNameSingular,
});

if (isUndefinedOrNull(objectMetadataItem)) {
return { destroyManyRecordsMutation: EMPTY_MUTATION };
}

const capitalizedObjectName = capitalize(objectMetadataItem.namePlural);

const mutationResponseField = getDestroyManyRecordsMutationResponseField(
objectMetadataItem.namePlural,
);

const destroyManyRecordsMutation = gql`
mutation DestroyMany${capitalizedObjectName}($filter: ${capitalize(
objectMetadataItem.nameSingular,
)}FilterInput!) {
${mutationResponseField}(filter: $filter) {
id
}
}
`;

return {
destroyManyRecordsMutation,
};
};
Loading

0 comments on commit 3f4591d

Please sign in to comment.