Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8f2dc7817f | |||
| 80d0721e68 | |||
| 43e92f7257 | |||
| 5b80432b9b | |||
| 153942c1c6 | |||
| 3a8a048342 | |||
| 4ce2d6827c |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-e2e-testing",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-emails",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-front",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
|
||||
import { useVerifyLogin } from '@/auth/hooks/useVerifyLogin';
|
||||
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';
|
||||
@@ -70,7 +71,11 @@ export const VerifyEmailEffect = () => {
|
||||
}, []);
|
||||
|
||||
if (isError) {
|
||||
return <EmailVerificationSent email={email} isError={true} />;
|
||||
return (
|
||||
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||
<EmailVerificationSent email={email} isError={true} />
|
||||
</Modal.Content>
|
||||
);
|
||||
}
|
||||
|
||||
return <></>;
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { MemoryRouter, Route, Routes } from 'react-router-dom';
|
||||
import { RecoilRoot } from 'recoil';
|
||||
import { VerifyEmailEffect } from '../VerifyEmailEffect';
|
||||
|
||||
// Mock component that just renders the error state of VerifyEmailEffect directly
|
||||
// (since normal VerifyEmailEffect has async logic that's hard to test in Storybook)
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
import { EmailVerificationSent } from '../../sign-in-up/components/EmailVerificationSent';
|
||||
|
||||
const VerifyEmailEffectErrorState = ({ email = 'user@example.com' }) => {
|
||||
return (
|
||||
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||
<EmailVerificationSent email={email} isError={true} />
|
||||
</Modal.Content>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta<typeof VerifyEmailEffectErrorState> = {
|
||||
title: 'Pages/Auth/VerifyEmailEffect',
|
||||
component: VerifyEmailEffectErrorState,
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<div style={{ padding: '24px' }}>
|
||||
<RecoilRoot>
|
||||
<Story />
|
||||
</RecoilRoot>
|
||||
</div>
|
||||
),
|
||||
SnackBarDecorator,
|
||||
],
|
||||
parameters: {
|
||||
codeSection: {
|
||||
docs: 'IMPORTANT: When rendering EmailVerificationSent from VerifyEmailEffect, always wrap it with Modal.Content to maintain consistent styling.',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof VerifyEmailEffect>;
|
||||
|
||||
export const ErrorState: Story = {
|
||||
args: {
|
||||
email: 'user@example.com',
|
||||
},
|
||||
};
|
||||
|
||||
export const IntegratedExample: StoryObj<typeof VerifyEmailEffect> = {
|
||||
render: () => (
|
||||
<RecoilRoot>
|
||||
<MemoryRouter
|
||||
initialEntries={[
|
||||
'/verify-email?email=user@example.com&emailVerificationToken=invalid-token',
|
||||
]}
|
||||
>
|
||||
<Routes>
|
||||
<Route
|
||||
path="/verify-email"
|
||||
element={<VerifyEmailEffectErrorState email="user@example.com" />}
|
||||
/>
|
||||
</Routes>
|
||||
</MemoryRouter>
|
||||
</RecoilRoot>
|
||||
),
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
story:
|
||||
'This demonstrates how the component should look when rendered in the app with proper Modal.Content wrapping.',
|
||||
},
|
||||
},
|
||||
},
|
||||
decorators: [SnackBarDecorator],
|
||||
};
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { Modal } from '@/ui/layout/modal/components/Modal';
|
||||
import { ComponentDecorator } from 'twenty-ui/testing';
|
||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
import { EmailVerificationSent } from '../EmailVerificationSent';
|
||||
|
||||
// Wrap the component in Modal.Content to reflect how it's used in the app
|
||||
const RenderWithModal = (
|
||||
args: React.ComponentProps<typeof EmailVerificationSent>,
|
||||
) => {
|
||||
return (
|
||||
<Modal padding="none" modalVariant="primary">
|
||||
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||
<EmailVerificationSent email={args.email} isError={args.isError} />
|
||||
</Modal.Content>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
const meta: Meta<typeof EmailVerificationSent> = {
|
||||
title: 'Pages/Auth/EmailVerificationSent',
|
||||
component: EmailVerificationSent,
|
||||
decorators: [ComponentDecorator, SnackBarDecorator],
|
||||
parameters: {
|
||||
codeSection: {
|
||||
docs: 'This component should always be wrapped with Modal.Content in the app.\n\nCorrect usage:\n```tsx\n<Modal.Content isVerticalCentered isHorizontalCentered>\n <EmailVerificationSent email={email} />\n</Modal.Content>\n```\n',
|
||||
},
|
||||
},
|
||||
render: RenderWithModal,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof EmailVerificationSent>;
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
email: 'user@example.com',
|
||||
isError: false,
|
||||
},
|
||||
};
|
||||
|
||||
export const Error: Story = {
|
||||
args: {
|
||||
email: 'user@example.com',
|
||||
isError: true,
|
||||
},
|
||||
};
|
||||
@@ -2,7 +2,6 @@ import { useFieldMetadataItemById } from '@/object-metadata/hooks/useFieldMetada
|
||||
import { getOperandLabelShort } from '@/object-record/object-filter-dropdown/utils/getOperandLabel';
|
||||
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
|
||||
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
|
||||
import { isNonEmptyString } from '@sniptt/guards';
|
||||
import { useIcons } from 'twenty-ui/display';
|
||||
|
||||
type EditableFilterChipProps = {
|
||||
@@ -24,13 +23,11 @@ export const EditableFilterChip = ({
|
||||
|
||||
const operandLabelShort = getOperandLabelShort(viewFilter.operand);
|
||||
|
||||
const labelKey = `${viewFilter.label}${isNonEmptyString(viewFilter.value) ? operandLabelShort : ''}`;
|
||||
|
||||
return (
|
||||
<SortOrFilterChip
|
||||
key={viewFilter.id}
|
||||
testId={viewFilter.id}
|
||||
labelKey={labelKey}
|
||||
labelKey={`${viewFilter.label}${getOperandLabelShort(viewFilter.operand)}`}
|
||||
labelValue={viewFilter.displayValue}
|
||||
Icon={FieldMetadataItemIcon}
|
||||
onRemove={onRemove}
|
||||
|
||||
@@ -120,7 +120,11 @@ export const SignInUp = () => {
|
||||
]);
|
||||
|
||||
if (signInUpStep === SignInUpStep.EmailVerification) {
|
||||
return <EmailVerificationSent email={searchParams.get('email')} />;
|
||||
return (
|
||||
<Modal.Content isVerticalCentered isHorizontalCentered>
|
||||
<EmailVerificationSent email={searchParams.get('email')} />
|
||||
</Modal.Content>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-server",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"description": "",
|
||||
"author": "",
|
||||
"private": true,
|
||||
|
||||
+2
-2
@@ -4,9 +4,9 @@ import { BillingPlanKey } from 'src/engine/core-modules/billing/enums/billing-pl
|
||||
export const getPlanKeyFromSubscription = (
|
||||
subscription: BillingSubscription,
|
||||
): BillingPlanKey => {
|
||||
const planKey = subscription.metadata?.planKey;
|
||||
const plan = subscription.metadata?.plan; //To do : #867 Naming issue decide if we should rename stripe product metadata planKey to plan (+ productKey to product) OR at session checkout creating subscription with metadata planKey (and not plan)
|
||||
|
||||
switch (planKey) {
|
||||
switch (plan) {
|
||||
case 'PRO':
|
||||
return BillingPlanKey.PRO;
|
||||
case 'ENTERPRISE':
|
||||
|
||||
+4
-1
@@ -55,7 +55,10 @@ export class WorkspaceMetadataCacheService {
|
||||
}
|
||||
|
||||
if (currentCacheVersion !== undefined) {
|
||||
this.workspaceCacheStorageService.flush(workspaceId, currentCacheVersion);
|
||||
this.workspaceCacheStorageService.flushVersionedMetadata(
|
||||
workspaceId,
|
||||
currentCacheVersion,
|
||||
);
|
||||
}
|
||||
|
||||
await this.workspaceCacheStorageService.addObjectMetadataCollectionOngoingCachingLock(
|
||||
|
||||
+8
-1
@@ -253,7 +253,10 @@ export class WorkspaceCacheStorageService {
|
||||
);
|
||||
}
|
||||
|
||||
async flush(workspaceId: string, metadataVersion: number): Promise<void> {
|
||||
async flushVersionedMetadata(
|
||||
workspaceId: string,
|
||||
metadataVersion: number,
|
||||
): Promise<void> {
|
||||
await this.cacheStorageService.del(
|
||||
`${WorkspaceCacheKeys.MetadataObjectMetadataMaps}:${workspaceId}:${metadataVersion}`,
|
||||
);
|
||||
@@ -272,6 +275,10 @@ export class WorkspaceCacheStorageService {
|
||||
await this.cacheStorageService.del(
|
||||
`${WorkspaceCacheKeys.MetadataObjectMetadataOngoingCachingLock}:${workspaceId}:${metadataVersion}`,
|
||||
);
|
||||
}
|
||||
|
||||
async flush(workspaceId: string, metadataVersion: number): Promise<void> {
|
||||
await this.flushVersionedMetadata(workspaceId, metadataVersion);
|
||||
|
||||
await this.cacheStorageService.del(
|
||||
`${WorkspaceCacheKeys.MetadataPermissionsRolesPermissions}:${workspaceId}`,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-shared",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"main": "dist/twenty-shared.cjs.js",
|
||||
"module": "dist/twenty-shared.esm.js",
|
||||
"license": "AGPL-3.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-ui",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"main": "dist/index.cjs",
|
||||
"module": "dist/index.mjs",
|
||||
"style": "./dist/style.css",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "twenty-website",
|
||||
"version": "0.52.0-canary",
|
||||
"version": "0.51.5",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"nx": "NX_DEFAULT_PROJECT=twenty-website node ../../node_modules/nx/bin/nx.js",
|
||||
|
||||
Reference in New Issue
Block a user