Skip to content

Commit

Permalink
Merge branch 'main' into fix/signup-on-existing-workspace-without-inv…
Browse files Browse the repository at this point in the history
…itation
  • Loading branch information
AMoreaux authored Jan 13, 2025
2 parents 9d69df6 + 21e2295 commit b4cb174
Show file tree
Hide file tree
Showing 19 changed files with 96 additions and 54 deletions.
22 changes: 0 additions & 22 deletions packages/twenty-front/src/generated/graphql.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -313,12 +313,6 @@ export type FeatureFlag = {
workspaceId: Scalars['String'];
};

export type FeatureFlagFilter = {
and?: InputMaybe<Array<FeatureFlagFilter>>;
id?: InputMaybe<UuidFilterComparison>;
or?: InputMaybe<Array<FeatureFlagFilter>>;
};

export enum FeatureFlagKey {
IsAdvancedFiltersEnabled = 'IsAdvancedFiltersEnabled',
IsAirtableIntegrationEnabled = 'IsAirtableIntegrationEnabled',
Expand All @@ -338,16 +332,6 @@ export enum FeatureFlagKey {
IsWorkflowEnabled = 'IsWorkflowEnabled'
}

export type FeatureFlagSort = {
direction: SortDirection;
field: FeatureFlagSortFields;
nulls?: InputMaybe<SortNulls>;
};

export enum FeatureFlagSortFields {
Id = 'id'
}

export type FieldConnection = {
__typename?: 'FieldConnection';
/** Array of edges. */
Expand Down Expand Up @@ -1544,12 +1528,6 @@ export type WorkspaceBillingSubscriptionsArgs = {
sorting?: Array<BillingSubscriptionSort>;
};


export type WorkspaceFeatureFlagsArgs = {
filter?: FeatureFlagFilter;
sorting?: Array<FeatureFlagSort>;
};

export enum WorkspaceActivationStatus {
Active = 'ACTIVE',
Inactive = 'INACTIVE',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
import { RelationFilterValue } from '@/views/view-filter-value/types/RelationFilterValue';
import { relationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/relationFilterValueSchema';
import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema';
import { simpleRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/simpleRelationFilterValueSchema';
import { IconUserCircle } from 'twenty-ui';
import { isDefined } from '~/utils/isDefined';

Expand Down Expand Up @@ -63,10 +64,12 @@ export const ObjectFilterDropdownRecordSelect = ({

const [fieldId] = useState(v4());

const { isCurrentWorkspaceMemberSelected } = relationFilterValueSchema
const { isCurrentWorkspaceMemberSelected } = jsonRelationFilterValueSchema
.catch({
isCurrentWorkspaceMemberSelected: false,
selectedRecordIds: [],
selectedRecordIds: simpleRelationFilterValueSchema.parse(
selectedFilter?.value,
),
})
.parse(selectedFilter?.value);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import { useSelectableList } from '@/ui/layout/selectable-list/hooks/useSelectab
import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useId, useState } from 'react';
import { Key } from 'ts-key-enum';
import { isDefined, VisibilityHidden } from 'twenty-ui';
import { IconChevronDown, isDefined, VisibilityHidden } from 'twenty-ui';

type FormSelectFieldInputProps = {
label?: string;
Expand All @@ -37,6 +38,7 @@ const StyledDisplayModeReadonlyContainer = styled.div`
font-family: inherit;
padding-inline: ${({ theme }) => theme.spacing(2)};
width: 100%;
justify-content: space-between;
`;

const StyledDisplayModeContainer = styled(StyledDisplayModeReadonlyContainer)`
Expand All @@ -46,6 +48,7 @@ const StyledDisplayModeContainer = styled(StyledDisplayModeReadonlyContainer)`
&[data-open='true'] {
background-color: ${({ theme }) => theme.background.transparent.lighter};
}
justify-content: space-between;
`;

const StyledSelectInputContainer = styled.div`
Expand All @@ -66,6 +69,7 @@ export const FormSelectFieldInput = ({
const inputId = useId();

const hotkeyScope = InlineCellHotkeyScope.InlineCell;
const theme = useTheme();

const {
setHotkeyScopeAndMemorizePreviousScope,
Expand Down Expand Up @@ -227,6 +231,10 @@ export const FormSelectFieldInput = ({
Icon={selectedOption.icon ?? undefined}
/>
)}
<IconChevronDown
size={theme.icon.size.md}
color={theme.font.color.tertiary}
/>
</StyledDisplayModeReadonlyContainer>
) : (
<StyledDisplayModeContainer
Expand All @@ -242,6 +250,10 @@ export const FormSelectFieldInput = ({
Icon={selectedOption.icon ?? undefined}
/>
)}
<IconChevronDown
size={theme.icon.size.md}
color={theme.font.color.tertiary}
/>
</StyledDisplayModeContainer>
)
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ import { ViewFilterGroup } from '@/views/types/ViewFilterGroup';
import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator';
import { resolveDateViewFilterValue } from '@/views/view-filter-value/utils/resolveDateViewFilterValue';
import { resolveSelectViewFilterValue } from '@/views/view-filter-value/utils/resolveSelectViewFilterValue';
import { relationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/relationFilterValueSchema';
import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema';
import { simpleRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/simpleRelationFilterValueSchema';
import { endOfDay, roundToNearestMinutes, startOfDay } from 'date-fns';
import { z } from 'zod';

Expand Down Expand Up @@ -306,7 +307,14 @@ const computeFilterRecordGqlOperationFilter = (
case 'RELATION': {
if (!isEmptyOperand) {
const { isCurrentWorkspaceMemberSelected, selectedRecordIds } =
relationFilterValueSchema.parse(filter.value);
jsonRelationFilterValueSchema
.catch({
isCurrentWorkspaceMemberSelected: false,
selectedRecordIds: simpleRelationFilterValueSchema.parse(
filter.value,
),
})
.parse(filter.value);

const recordIds = isCurrentWorkspaceMemberSelected
? [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import { onFilterSelectComponentState } from '@/object-record/object-filter-drop
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
import { useUpsertCombinedViewFilters } from '@/views/hooks/useUpsertCombinedViewFilters';
import { availableFilterDefinitionsComponentState } from '@/views/states/availableFilterDefinitionsComponentState';
import { relationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/relationFilterValueSchema';
import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema';
import { simpleRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/simpleRelationFilterValueSchema';
import { isDefined } from '~/utils/isDefined';

type ViewBarFilterEffectProps = {
Expand Down Expand Up @@ -82,10 +83,12 @@ export const ViewBarFilterEffect = ({
filterDefinitionUsedInDropdown?.fieldMetadataId,
);

const { selectedRecordIds } = relationFilterValueSchema
const { selectedRecordIds } = jsonRelationFilterValueSchema
.catch({
isCurrentWorkspaceMemberSelected: false,
selectedRecordIds: [],
selectedRecordIds: simpleRelationFilterValueSchema.parse(
viewFilterUsedInDropdown?.value,
),
})
.parse(viewFilterUsedInDropdown?.value);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { generateFindManyRecordsQuery } from '@/object-record/utils/generateFindManyRecordsQuery';
import { ViewFilter } from '@/views/types/ViewFilter';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { relationFilterValueSchemaObject } from '@/views/view-filter-value/validation-schemas/relationFilterValueSchema';
import { relationFilterValueSchemaObject } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema';
import { isDefined } from '~/utils/isDefined';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { relationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/relationFilterValueSchema';
import { jsonRelationFilterValueSchema } from '@/views/view-filter-value/validation-schemas/jsonRelationFilterValueSchema';
import { z } from 'zod';

export type RelationFilterValue = z.infer<typeof relationFilterValueSchema>;
export type RelationFilterValue = z.infer<typeof jsonRelationFilterValueSchema>;
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const relationFilterValueSchemaObject = z.object({
selectedRecordIds: z.array(z.string()),
});

export const relationFilterValueSchema = z
export const jsonRelationFilterValueSchema = z
.string()
.transform((value, ctx) => {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { z } from 'zod';

export const simpleRelationFilterValueSchema = z
.preprocess((value) => {
try {
return typeof value === 'string' ? JSON.parse(value) : [];
} catch {
return [];
}
}, z.array(z.string().uuid()))
.catch([]);
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { WorkflowCodeAction } from '@/workflow/types/Workflow';
import { WorkflowStepHeader } from '@/workflow/workflow-steps/components/WorkflowStepHeader';
import { setNestedValue } from '@/workflow/workflow-steps/workflow-actions/utils/setNestedValue';

import { Monaco } from '@monaco-editor/react';
import { CmdEnterActionButton } from '@/action-menu/components/CmdEnterActionButton';
import { ServerlessFunctionExecutionResult } from '@/serverless-functions/components/ServerlessFunctionExecutionResult';
import { INDEX_FILE_PATH } from '@/serverless-functions/constants/IndexFilePath';
Expand All @@ -24,16 +23,17 @@ import { serverlessFunctionTestDataFamilyState } from '@/workflow/states/serverl
import { WorkflowStepBody } from '@/workflow/workflow-steps/components/WorkflowStepBody';
import { WorkflowEditActionFormServerlessFunctionFields } from '@/workflow/workflow-steps/workflow-actions/components/WorkflowEditActionFormServerlessFunctionFields';
import { WORKFLOW_SERVERLESS_FUNCTION_TAB_LIST_COMPONENT_ID } from '@/workflow/workflow-steps/workflow-actions/constants/WorkflowServerlessFunctionTabListComponentId';
import { getWrongExportedFunctionMarkers } from '@/workflow/workflow-steps/workflow-actions/utils/getWrongExportedFunctionMarkers';
import { WorkflowVariablePicker } from '@/workflow/workflow-variables/components/WorkflowVariablePicker';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { Monaco } from '@monaco-editor/react';
import { editor } from 'monaco-editor';
import { AutoTypings } from 'monaco-editor-auto-typings';
import { useEffect, useState } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { CodeEditor, IconCode, IconPlayerPlay, isDefined } from 'twenty-ui';
import { useDebouncedCallback } from 'use-debounce';
import { getWrongExportedFunctionMarkers } from '@/workflow/workflow-steps/workflow-actions/utils/getWrongExportedFunctionMarkers';

const StyledContainer = styled.div`
display: flex;
Expand Down Expand Up @@ -178,7 +178,7 @@ export const WorkflowEditActionFormServerlessFunction = ({
isLeaf: true,
icon: 'IconVariable',
tab: 'test',
label: 'Generate Function Input',
label: 'Generate Function Output',
},
_outputSchemaType: 'LINK',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class BillingResolver {
) {
return {
url: await this.billingPortalWorkspaceService.computeBillingPortalSessionURLOrThrow(
workspace.id,
workspace,
returnUrlPath,
),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ export class BillingPortalWorkspaceService {
plan?: BillingPlanKey,
requirePaymentMethod?: boolean,
): Promise<string> {
const frontBaseUrl = this.domainManagerService.getBaseUrl();
const frontBaseUrl = this.domainManagerService.buildWorkspaceURL({
subdomain: workspace.subdomain,
});
const cancelUrl = frontBaseUrl.toString();

if (successUrlPath) {
Expand Down Expand Up @@ -72,13 +74,13 @@ export class BillingPortalWorkspaceService {
}

async computeBillingPortalSessionURLOrThrow(
workspaceId: string,
workspace: Workspace,
returnUrlPath?: string,
) {
const currentSubscription =
await this.billingSubscriptionService.getCurrentBillingSubscriptionOrThrow(
{
workspaceId,
workspaceId: workspace.id,
},
);

Expand All @@ -92,7 +94,9 @@ export class BillingPortalWorkspaceService {
throw new Error('Error: missing stripeCustomerId');
}

const frontBaseUrl = this.domainManagerService.getBaseUrl();
const frontBaseUrl = this.domainManagerService.buildWorkspaceURL({
subdomain: workspace.subdomain,
});

if (returnUrlPath) {
frontBaseUrl.pathname = returnUrlPath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class FeatureFlagEntity {

@Field(() => FeatureFlagKey)
@Column({ nullable: false, type: 'text' })
key: `${FeatureFlagKey}`;
key: FeatureFlagKey;

@Field()
@Column({ nullable: false, type: 'uuid' })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,15 @@ export class FeatureFlagService {

public async getWorkspaceFeatureFlags(
workspaceId: string,
): Promise<FeatureFlagEntity[]> {
return this.featureFlagRepository.find({ where: { workspaceId } });
}

public async getWorkspaceFeatureFlagsMap(
workspaceId: string,
): Promise<FeatureFlagMap> {
const workspaceFeatureFlags = await this.featureFlagRepository.find({
where: { workspaceId },
});
const workspaceFeatureFlags =
await this.getWorkspaceFeatureFlags(workspaceId);

const workspaceFeatureFlagsMap = workspaceFeatureFlags.reduce(
(result, currentFeatureFlag) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ registerEnumType(WorkspaceActivationStatus, {

@Entity({ name: 'workspace', schema: 'core' })
@ObjectType('Workspace')
@UnPagedRelation('featureFlags', () => FeatureFlagEntity, { nullable: true })
@UnPagedRelation('billingSubscriptions', () => BillingSubscription, {
nullable: true,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import { BillingSubscription } from 'src/engine/core-modules/billing/entities/bi
import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/service/domain-manager.service';
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
import { FeatureFlagEntity } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
import { FileUploadService } from 'src/engine/core-modules/file/file-upload/services/file-upload.service';
import { FileService } from 'src/engine/core-modules/file/services/file.service';
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
Expand Down Expand Up @@ -59,6 +62,7 @@ export class WorkspaceResolver {
private readonly fileUploadService: FileUploadService,
private readonly fileService: FileService,
private readonly billingSubscriptionService: BillingSubscriptionService,
private readonly featureFlagService: FeatureFlagService,
) {}

@Query(() => Workspace)
Expand Down Expand Up @@ -134,6 +138,21 @@ export class WorkspaceResolver {
return `${paths[0]}?token=${workspaceLogoToken}`;
}

@ResolveField(() => [FeatureFlagEntity], { nullable: true })
async featureFlags(
@Parent() workspace: Workspace,
): Promise<FeatureFlagEntity[]> {
const featureFlags = await this.featureFlagService.getWorkspaceFeatureFlags(
workspace.id,
);

const filteredFeatureFlags = featureFlags.filter((flag) =>
Object.values(FeatureFlagKey).includes(flag.key),
);

return filteredFeatureFlags;
}

@Mutation(() => Workspace)
@UseGuards(DemoEnvGuard, WorkspaceAuthGuard)
async deleteCurrentWorkspace(@AuthWorkspace() { id }: Workspace) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export class WorkspaceSyncMetadataService {

// Retrieve feature flags
const workspaceFeatureFlagsMap =
await this.featureFlagService.getWorkspaceFeatureFlags(
await this.featureFlagService.getWorkspaceFeatureFlagsMap(
context.workspaceId,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export class WorkflowVersionStepWorkspaceService {
isLeaf: true,
icon: 'IconVariable',
tab: 'test',
label: 'Generate Function Input',
label: 'Generate Function Output',
},
_outputSchemaType: 'LINK',
},
Expand Down
Loading

0 comments on commit b4cb174

Please sign in to comment.