Remove viewGroup v1 implem (#16178)
# Introduction Removing v1 implementation of view groups and both view group and view field relicas front fetchers Related https://github.com/twentyhq/core-team-issues/issues/1911
This commit is contained in:
@@ -4,18 +4,14 @@ import { useMetadataErrorHandler } from '@/metadata-error-handler/hooks/useMetad
|
|||||||
import { type MetadataRequestResult } from '@/object-metadata/types/MetadataRequestResult.type';
|
import { type MetadataRequestResult } from '@/object-metadata/types/MetadataRequestResult.type';
|
||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||||
import { useTriggerViewFieldOptimisticEffect } from '@/views/optimistic-effects/hooks/useTriggerViewFieldOptimisticEffect';
|
import { useTriggerViewFieldOptimisticEffect } from '@/views/optimistic-effects/hooks/useTriggerViewFieldOptimisticEffect';
|
||||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
|
||||||
import { ApolloError } from '@apollo/client';
|
import { ApolloError } from '@apollo/client';
|
||||||
import { t } from '@lingui/core/macro';
|
import { t } from '@lingui/core/macro';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import {
|
import {
|
||||||
type CreateCoreViewFieldMutationVariables,
|
|
||||||
type CreateManyCoreViewFieldsMutationVariables,
|
type CreateManyCoreViewFieldsMutationVariables,
|
||||||
type DeleteCoreViewFieldMutationVariables,
|
type DeleteCoreViewFieldMutationVariables,
|
||||||
type DestroyCoreViewFieldMutationVariables,
|
type DestroyCoreViewFieldMutationVariables,
|
||||||
FeatureFlagKey,
|
|
||||||
type UpdateCoreViewFieldMutationVariables,
|
type UpdateCoreViewFieldMutationVariables,
|
||||||
useCreateCoreViewFieldMutation,
|
|
||||||
useCreateManyCoreViewFieldsMutation,
|
useCreateManyCoreViewFieldsMutation,
|
||||||
useDeleteCoreViewFieldMutation,
|
useDeleteCoreViewFieldMutation,
|
||||||
useDestroyCoreViewFieldMutation,
|
useDestroyCoreViewFieldMutation,
|
||||||
@@ -25,11 +21,6 @@ export const usePersistViewField = () => {
|
|||||||
const { triggerViewFieldOptimisticEffect } =
|
const { triggerViewFieldOptimisticEffect } =
|
||||||
useTriggerViewFieldOptimisticEffect();
|
useTriggerViewFieldOptimisticEffect();
|
||||||
|
|
||||||
const isWorkspaceMigrationV2Enabled = useIsFeatureEnabled(
|
|
||||||
FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
|
||||||
);
|
|
||||||
|
|
||||||
const [createCoreViewFieldMutation] = useCreateCoreViewFieldMutation();
|
|
||||||
const [createManyCoreViewFieldsMutation] =
|
const [createManyCoreViewFieldsMutation] =
|
||||||
useCreateManyCoreViewFieldsMutation();
|
useCreateManyCoreViewFieldsMutation();
|
||||||
const [updateCoreViewFieldMutation] = useUpdateCoreViewFieldMutation();
|
const [updateCoreViewFieldMutation] = useUpdateCoreViewFieldMutation();
|
||||||
@@ -39,77 +30,13 @@ export const usePersistViewField = () => {
|
|||||||
const { handleMetadataError } = useMetadataErrorHandler();
|
const { handleMetadataError } = useMetadataErrorHandler();
|
||||||
const { enqueueErrorSnackBar } = useSnackBar();
|
const { enqueueErrorSnackBar } = useSnackBar();
|
||||||
|
|
||||||
const oldCreateViewFields = useCallback(
|
|
||||||
async (
|
|
||||||
createCoreViewFieldInputs: CreateCoreViewFieldMutationVariables[],
|
|
||||||
): Promise<
|
|
||||||
MetadataRequestResult<
|
|
||||||
Awaited<ReturnType<typeof createCoreViewFieldMutation>>[]
|
|
||||||
>
|
|
||||||
> => {
|
|
||||||
if (createCoreViewFieldInputs.length === 0) {
|
|
||||||
return {
|
|
||||||
status: 'successful',
|
|
||||||
response: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const results = await Promise.all(
|
|
||||||
createCoreViewFieldInputs.map(async (variables) =>
|
|
||||||
createCoreViewFieldMutation({
|
|
||||||
variables,
|
|
||||||
update: (_cache, { data }) => {
|
|
||||||
const createdViewField = data?.createCoreViewField;
|
|
||||||
if (!isDefined(createdViewField)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerViewFieldOptimisticEffect({
|
|
||||||
createdViewFields: [createdViewField],
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
status: 'successful',
|
|
||||||
response: results,
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
if (error instanceof ApolloError) {
|
|
||||||
handleMetadataError(error, {
|
|
||||||
primaryMetadataName: 'viewField',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
enqueueErrorSnackBar({ message: t`An error occurred.` });
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
status: 'failed',
|
|
||||||
error,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[
|
|
||||||
triggerViewFieldOptimisticEffect,
|
|
||||||
createCoreViewFieldMutation,
|
|
||||||
handleMetadataError,
|
|
||||||
enqueueErrorSnackBar,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
const createViewFields = useCallback(
|
const createViewFields = useCallback(
|
||||||
async (
|
async (
|
||||||
createCoreViewFieldInputs: CreateManyCoreViewFieldsMutationVariables,
|
createCoreViewFieldInputs: CreateManyCoreViewFieldsMutationVariables,
|
||||||
): Promise<
|
): Promise<
|
||||||
| MetadataRequestResult<Awaited<
|
MetadataRequestResult<Awaited<
|
||||||
ReturnType<typeof createManyCoreViewFieldsMutation>
|
ReturnType<typeof createManyCoreViewFieldsMutation>
|
||||||
> | null>
|
> | null>
|
||||||
| MetadataRequestResult<
|
|
||||||
Awaited<ReturnType<typeof createCoreViewFieldMutation>>[]
|
|
||||||
>
|
|
||||||
> => {
|
> => {
|
||||||
if (
|
if (
|
||||||
!Array.isArray(createCoreViewFieldInputs.inputs) ||
|
!Array.isArray(createCoreViewFieldInputs.inputs) ||
|
||||||
@@ -121,12 +48,6 @@ export const usePersistViewField = () => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isWorkspaceMigrationV2Enabled) {
|
|
||||||
const oldFormatInputs: CreateCoreViewFieldMutationVariables[] =
|
|
||||||
createCoreViewFieldInputs.inputs.map((input) => ({ input }));
|
|
||||||
return await oldCreateViewFields(oldFormatInputs);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await createManyCoreViewFieldsMutation({
|
const result = await createManyCoreViewFieldsMutation({
|
||||||
variables: createCoreViewFieldInputs,
|
variables: createCoreViewFieldInputs,
|
||||||
@@ -162,8 +83,6 @@ export const usePersistViewField = () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
isWorkspaceMigrationV2Enabled,
|
|
||||||
oldCreateViewFields,
|
|
||||||
triggerViewFieldOptimisticEffect,
|
triggerViewFieldOptimisticEffect,
|
||||||
createManyCoreViewFieldsMutation,
|
createManyCoreViewFieldsMutation,
|
||||||
handleMetadataError,
|
handleMetadataError,
|
||||||
|
|||||||
@@ -4,18 +4,14 @@ import { useMetadataErrorHandler } from '@/metadata-error-handler/hooks/useMetad
|
|||||||
import { type MetadataRequestResult } from '@/object-metadata/types/MetadataRequestResult.type';
|
import { type MetadataRequestResult } from '@/object-metadata/types/MetadataRequestResult.type';
|
||||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||||
import { useTriggerViewGroupOptimisticEffect } from '@/views/optimistic-effects/hooks/useTriggerViewGroupOptimisticEffect';
|
import { useTriggerViewGroupOptimisticEffect } from '@/views/optimistic-effects/hooks/useTriggerViewGroupOptimisticEffect';
|
||||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
|
||||||
import { ApolloError } from '@apollo/client';
|
import { ApolloError } from '@apollo/client';
|
||||||
import { t } from '@lingui/core/macro';
|
import { t } from '@lingui/core/macro';
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import {
|
import {
|
||||||
type CreateCoreViewGroupMutationVariables,
|
|
||||||
type CreateManyCoreViewGroupsMutationVariables,
|
type CreateManyCoreViewGroupsMutationVariables,
|
||||||
type DeleteCoreViewGroupMutationVariables,
|
type DeleteCoreViewGroupMutationVariables,
|
||||||
type DestroyCoreViewGroupMutationVariables,
|
type DestroyCoreViewGroupMutationVariables,
|
||||||
FeatureFlagKey,
|
|
||||||
type UpdateCoreViewGroupMutationVariables,
|
type UpdateCoreViewGroupMutationVariables,
|
||||||
useCreateCoreViewGroupMutation,
|
|
||||||
useCreateManyCoreViewGroupsMutation,
|
useCreateManyCoreViewGroupsMutation,
|
||||||
useDeleteCoreViewGroupMutation,
|
useDeleteCoreViewGroupMutation,
|
||||||
useDestroyCoreViewGroupMutation,
|
useDestroyCoreViewGroupMutation,
|
||||||
@@ -26,11 +22,6 @@ export const usePersistViewGroupRecords = () => {
|
|||||||
const { triggerViewGroupOptimisticEffect } =
|
const { triggerViewGroupOptimisticEffect } =
|
||||||
useTriggerViewGroupOptimisticEffect();
|
useTriggerViewGroupOptimisticEffect();
|
||||||
|
|
||||||
const isWorkspaceMigrationV2Enabled = useIsFeatureEnabled(
|
|
||||||
FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
|
||||||
);
|
|
||||||
|
|
||||||
const [createCoreViewGroupMutation] = useCreateCoreViewGroupMutation();
|
|
||||||
const [createManyCoreViewGroupsMutation] =
|
const [createManyCoreViewGroupsMutation] =
|
||||||
useCreateManyCoreViewGroupsMutation();
|
useCreateManyCoreViewGroupsMutation();
|
||||||
const [updateCoreViewGroupMutation] = useUpdateCoreViewGroupMutation();
|
const [updateCoreViewGroupMutation] = useUpdateCoreViewGroupMutation();
|
||||||
@@ -40,77 +31,13 @@ export const usePersistViewGroupRecords = () => {
|
|||||||
const { handleMetadataError } = useMetadataErrorHandler();
|
const { handleMetadataError } = useMetadataErrorHandler();
|
||||||
const { enqueueErrorSnackBar } = useSnackBar();
|
const { enqueueErrorSnackBar } = useSnackBar();
|
||||||
|
|
||||||
const oldCreateViewGroups = useCallback(
|
|
||||||
async (
|
|
||||||
createCoreViewGroupInputs: CreateCoreViewGroupMutationVariables[],
|
|
||||||
): Promise<
|
|
||||||
MetadataRequestResult<
|
|
||||||
Awaited<ReturnType<typeof createCoreViewGroupMutation>>[]
|
|
||||||
>
|
|
||||||
> => {
|
|
||||||
if (createCoreViewGroupInputs.length === 0) {
|
|
||||||
return {
|
|
||||||
status: 'successful',
|
|
||||||
response: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const results = await Promise.all(
|
|
||||||
createCoreViewGroupInputs.map(async (variables) =>
|
|
||||||
createCoreViewGroupMutation({
|
|
||||||
variables,
|
|
||||||
update: (_cache, { data }) => {
|
|
||||||
const createdViewGroup = data?.createCoreViewGroup;
|
|
||||||
if (!isDefined(createdViewGroup)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
triggerViewGroupOptimisticEffect({
|
|
||||||
createdViewGroups: [createdViewGroup],
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
status: 'successful',
|
|
||||||
response: results,
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
if (error instanceof ApolloError) {
|
|
||||||
handleMetadataError(error, {
|
|
||||||
primaryMetadataName: 'viewGroup',
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
enqueueErrorSnackBar({ message: t`An error occurred.` });
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
status: 'failed',
|
|
||||||
error,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[
|
|
||||||
triggerViewGroupOptimisticEffect,
|
|
||||||
createCoreViewGroupMutation,
|
|
||||||
handleMetadataError,
|
|
||||||
enqueueErrorSnackBar,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
const createViewGroups = useCallback(
|
const createViewGroups = useCallback(
|
||||||
async (
|
async (
|
||||||
createCoreViewGroupInputs: CreateManyCoreViewGroupsMutationVariables,
|
createCoreViewGroupInputs: CreateManyCoreViewGroupsMutationVariables,
|
||||||
): Promise<
|
): Promise<
|
||||||
| MetadataRequestResult<Awaited<
|
MetadataRequestResult<Awaited<
|
||||||
ReturnType<typeof createManyCoreViewGroupsMutation>
|
ReturnType<typeof createManyCoreViewGroupsMutation>
|
||||||
> | null>
|
> | null>
|
||||||
| MetadataRequestResult<
|
|
||||||
Awaited<ReturnType<typeof createCoreViewGroupMutation>>[]
|
|
||||||
>
|
|
||||||
> => {
|
> => {
|
||||||
if (
|
if (
|
||||||
!Array.isArray(createCoreViewGroupInputs.inputs) ||
|
!Array.isArray(createCoreViewGroupInputs.inputs) ||
|
||||||
@@ -122,12 +49,6 @@ export const usePersistViewGroupRecords = () => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isWorkspaceMigrationV2Enabled) {
|
|
||||||
const oldFormatInputs: CreateCoreViewGroupMutationVariables[] =
|
|
||||||
createCoreViewGroupInputs.inputs.map((input) => ({ input }));
|
|
||||||
return await oldCreateViewGroups(oldFormatInputs);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await createManyCoreViewGroupsMutation({
|
const result = await createManyCoreViewGroupsMutation({
|
||||||
variables: createCoreViewGroupInputs,
|
variables: createCoreViewGroupInputs,
|
||||||
@@ -163,8 +84,6 @@ export const usePersistViewGroupRecords = () => {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
isWorkspaceMigrationV2Enabled,
|
|
||||||
oldCreateViewGroups,
|
|
||||||
triggerViewGroupOptimisticEffect,
|
triggerViewGroupOptimisticEffect,
|
||||||
createManyCoreViewGroupsMutation,
|
createManyCoreViewGroupsMutation,
|
||||||
handleMetadataError,
|
handleMetadataError,
|
||||||
|
|||||||
+14
-65
@@ -13,8 +13,6 @@ import {
|
|||||||
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
|
|
||||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
|
||||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
|
||||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||||
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
|
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
|
||||||
@@ -30,7 +28,6 @@ import {
|
|||||||
ViewGroupExceptionMessageKey,
|
ViewGroupExceptionMessageKey,
|
||||||
} from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
} from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
||||||
import { ViewGroupRestApiExceptionFilter } from 'src/engine/metadata-modules/view-group/filters/view-group-rest-api-exception.filter';
|
import { ViewGroupRestApiExceptionFilter } from 'src/engine/metadata-modules/view-group/filters/view-group-rest-api-exception.filter';
|
||||||
import { ViewGroupV2Service } from 'src/engine/metadata-modules/view-group/services/view-group-v2.service';
|
|
||||||
import { ViewGroupService } from 'src/engine/metadata-modules/view-group/services/view-group.service';
|
import { ViewGroupService } from 'src/engine/metadata-modules/view-group/services/view-group.service';
|
||||||
import { CreateViewGroupPermissionGuard } from 'src/engine/metadata-modules/view-permissions/guards/create-view-group-permission.guard';
|
import { CreateViewGroupPermissionGuard } from 'src/engine/metadata-modules/view-permissions/guards/create-view-group-permission.guard';
|
||||||
import { DeleteViewGroupPermissionGuard } from 'src/engine/metadata-modules/view-permissions/guards/delete-view-group-permission.guard';
|
import { DeleteViewGroupPermissionGuard } from 'src/engine/metadata-modules/view-permissions/guards/delete-view-group-permission.guard';
|
||||||
@@ -40,11 +37,7 @@ import { UpdateViewGroupPermissionGuard } from 'src/engine/metadata-modules/view
|
|||||||
@UseGuards(WorkspaceAuthGuard)
|
@UseGuards(WorkspaceAuthGuard)
|
||||||
@UseFilters(ViewGroupRestApiExceptionFilter)
|
@UseFilters(ViewGroupRestApiExceptionFilter)
|
||||||
export class ViewGroupController {
|
export class ViewGroupController {
|
||||||
constructor(
|
constructor(private readonly viewGroupService: ViewGroupService) {}
|
||||||
private readonly viewGroupService: ViewGroupService,
|
|
||||||
private readonly viewGroupV2Service: ViewGroupV2Service,
|
|
||||||
private readonly featureFlagService: FeatureFlagService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
@Get()
|
@Get()
|
||||||
@UseGuards(NoPermissionGuard)
|
@UseGuards(NoPermissionGuard)
|
||||||
@@ -91,21 +84,8 @@ export class ViewGroupController {
|
|||||||
@Body() input: CreateViewGroupInput,
|
@Body() input: CreateViewGroupInput,
|
||||||
@AuthWorkspace() workspace: WorkspaceEntity,
|
@AuthWorkspace() workspace: WorkspaceEntity,
|
||||||
): Promise<ViewGroupDTO> {
|
): Promise<ViewGroupDTO> {
|
||||||
const isWorkspaceMigrationV2Enabled =
|
return await this.viewGroupService.createOne({
|
||||||
await this.featureFlagService.isFeatureEnabled(
|
createViewGroupInput: input,
|
||||||
FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
|
||||||
workspace.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isWorkspaceMigrationV2Enabled) {
|
|
||||||
return await this.viewGroupV2Service.createOne({
|
|
||||||
createViewGroupInput: input,
|
|
||||||
workspaceId: workspace.id,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.viewGroupService.create({
|
|
||||||
...input,
|
|
||||||
workspaceId: workspace.id,
|
workspaceId: workspace.id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -117,31 +97,15 @@ export class ViewGroupController {
|
|||||||
@Body() input: UpdateViewGroupInput,
|
@Body() input: UpdateViewGroupInput,
|
||||||
@AuthWorkspace() workspace: WorkspaceEntity,
|
@AuthWorkspace() workspace: WorkspaceEntity,
|
||||||
): Promise<ViewGroupDTO> {
|
): Promise<ViewGroupDTO> {
|
||||||
const isWorkspaceMigrationV2Enabled =
|
const updateInput = {
|
||||||
await this.featureFlagService.isFeatureEnabled(
|
|
||||||
FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
|
||||||
workspace.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isWorkspaceMigrationV2Enabled) {
|
|
||||||
const updateInput = {
|
|
||||||
id,
|
|
||||||
update: input.update ?? input,
|
|
||||||
};
|
|
||||||
|
|
||||||
return await this.viewGroupV2Service.updateOne({
|
|
||||||
updateViewGroupInput: updateInput,
|
|
||||||
workspaceId: workspace.id,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedViewGroup = await this.viewGroupService.update(
|
|
||||||
id,
|
id,
|
||||||
workspace.id,
|
update: input.update ?? input,
|
||||||
input,
|
};
|
||||||
);
|
|
||||||
|
|
||||||
return updatedViewGroup;
|
return await this.viewGroupService.updateOne({
|
||||||
|
updateViewGroupInput: updateInput,
|
||||||
|
workspaceId: workspace.id,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete(':id')
|
@Delete(':id')
|
||||||
@@ -150,25 +114,10 @@ export class ViewGroupController {
|
|||||||
@Param('id') id: string,
|
@Param('id') id: string,
|
||||||
@AuthWorkspace() workspace: WorkspaceEntity,
|
@AuthWorkspace() workspace: WorkspaceEntity,
|
||||||
): Promise<{ success: boolean }> {
|
): Promise<{ success: boolean }> {
|
||||||
const isWorkspaceMigrationV2Enabled =
|
const deletedViewGroup = await this.viewGroupService.deleteOne({
|
||||||
await this.featureFlagService.isFeatureEnabled(
|
deleteViewGroupInput: { id },
|
||||||
FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
workspaceId: workspace.id,
|
||||||
workspace.id,
|
});
|
||||||
);
|
|
||||||
|
|
||||||
if (isWorkspaceMigrationV2Enabled) {
|
|
||||||
const deletedViewGroup = await this.viewGroupV2Service.deleteOne({
|
|
||||||
deleteViewGroupInput: { id },
|
|
||||||
workspaceId: workspace.id,
|
|
||||||
});
|
|
||||||
|
|
||||||
return { success: isDefined(deletedViewGroup) };
|
|
||||||
}
|
|
||||||
|
|
||||||
const deletedViewGroup = await this.viewGroupService.delete(
|
|
||||||
id,
|
|
||||||
workspace.id,
|
|
||||||
);
|
|
||||||
|
|
||||||
return { success: isDefined(deletedViewGroup) };
|
return { success: isDefined(deletedViewGroup) };
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-86
@@ -1,8 +1,6 @@
|
|||||||
import { UseFilters, UseGuards } from '@nestjs/common';
|
import { UseFilters, UseGuards } from '@nestjs/common';
|
||||||
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
|
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
|
||||||
|
|
||||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
|
||||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
|
||||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||||
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
|
import { NoPermissionGuard } from 'src/engine/guards/no-permission.guard';
|
||||||
@@ -12,11 +10,6 @@ import { DeleteViewGroupInput } from 'src/engine/metadata-modules/view-group/dto
|
|||||||
import { DestroyViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/destroy-view-group.input';
|
import { DestroyViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/destroy-view-group.input';
|
||||||
import { UpdateViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/update-view-group.input';
|
import { UpdateViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/update-view-group.input';
|
||||||
import { ViewGroupDTO } from 'src/engine/metadata-modules/view-group/dtos/view-group.dto';
|
import { ViewGroupDTO } from 'src/engine/metadata-modules/view-group/dtos/view-group.dto';
|
||||||
import {
|
|
||||||
ViewGroupException,
|
|
||||||
ViewGroupExceptionCode,
|
|
||||||
} from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
|
||||||
import { ViewGroupV2Service } from 'src/engine/metadata-modules/view-group/services/view-group-v2.service';
|
|
||||||
import { ViewGroupService } from 'src/engine/metadata-modules/view-group/services/view-group.service';
|
import { ViewGroupService } from 'src/engine/metadata-modules/view-group/services/view-group.service';
|
||||||
import { CreateViewGroupPermissionGuard } from 'src/engine/metadata-modules/view-permissions/guards/create-view-group-permission.guard';
|
import { CreateViewGroupPermissionGuard } from 'src/engine/metadata-modules/view-permissions/guards/create-view-group-permission.guard';
|
||||||
import { DeleteViewGroupPermissionGuard } from 'src/engine/metadata-modules/view-permissions/guards/delete-view-group-permission.guard';
|
import { DeleteViewGroupPermissionGuard } from 'src/engine/metadata-modules/view-permissions/guards/delete-view-group-permission.guard';
|
||||||
@@ -28,11 +21,7 @@ import { ViewGraphqlApiExceptionFilter } from 'src/engine/metadata-modules/view/
|
|||||||
@UseFilters(ViewGraphqlApiExceptionFilter)
|
@UseFilters(ViewGraphqlApiExceptionFilter)
|
||||||
@UseGuards(WorkspaceAuthGuard)
|
@UseGuards(WorkspaceAuthGuard)
|
||||||
export class ViewGroupResolver {
|
export class ViewGroupResolver {
|
||||||
constructor(
|
constructor(private readonly viewGroupService: ViewGroupService) {}
|
||||||
private readonly viewGroupService: ViewGroupService,
|
|
||||||
private readonly featureFlagService: FeatureFlagService,
|
|
||||||
private readonly viewGroupV2Service: ViewGroupV2Service,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
@Query(() => [ViewGroupDTO])
|
@Query(() => [ViewGroupDTO])
|
||||||
@UseGuards(NoPermissionGuard)
|
@UseGuards(NoPermissionGuard)
|
||||||
@@ -63,21 +52,8 @@ export class ViewGroupResolver {
|
|||||||
@Args('input') createViewGroupInput: CreateViewGroupInput,
|
@Args('input') createViewGroupInput: CreateViewGroupInput,
|
||||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||||
): Promise<ViewGroupDTO> {
|
): Promise<ViewGroupDTO> {
|
||||||
const isWorkspaceMigrationV2Enabled =
|
return await this.viewGroupService.createOne({
|
||||||
await this.featureFlagService.isFeatureEnabled(
|
createViewGroupInput,
|
||||||
FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
|
||||||
workspaceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isWorkspaceMigrationV2Enabled) {
|
|
||||||
return await this.viewGroupV2Service.createOne({
|
|
||||||
createViewGroupInput,
|
|
||||||
workspaceId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.viewGroupService.create({
|
|
||||||
...createViewGroupInput,
|
|
||||||
workspaceId,
|
workspaceId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -89,20 +65,7 @@ export class ViewGroupResolver {
|
|||||||
createViewGroupInputs: CreateViewGroupInput[],
|
createViewGroupInputs: CreateViewGroupInput[],
|
||||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||||
): Promise<ViewGroupDTO[]> {
|
): Promise<ViewGroupDTO[]> {
|
||||||
const isWorkspaceMigrationV2Enabled =
|
return await this.viewGroupService.createMany({
|
||||||
await this.featureFlagService.isFeatureEnabled(
|
|
||||||
FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
|
||||||
workspaceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!isWorkspaceMigrationV2Enabled) {
|
|
||||||
throw new ViewGroupException(
|
|
||||||
'Not implemented in v1, please active IS_WORKSPACE_MIGRATION_V2_ENABLED',
|
|
||||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return await this.viewGroupV2Service.createMany({
|
|
||||||
createViewGroupInputs,
|
createViewGroupInputs,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
});
|
});
|
||||||
@@ -114,24 +77,10 @@ export class ViewGroupResolver {
|
|||||||
@Args('input') updateViewGroupInput: UpdateViewGroupInput,
|
@Args('input') updateViewGroupInput: UpdateViewGroupInput,
|
||||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||||
): Promise<ViewGroupDTO> {
|
): Promise<ViewGroupDTO> {
|
||||||
const isWorkspaceMigrationV2Enabled =
|
return await this.viewGroupService.updateOne({
|
||||||
await this.featureFlagService.isFeatureEnabled(
|
updateViewGroupInput,
|
||||||
FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
|
||||||
workspaceId,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isWorkspaceMigrationV2Enabled) {
|
|
||||||
return await this.viewGroupV2Service.updateOne({
|
|
||||||
updateViewGroupInput,
|
|
||||||
workspaceId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.viewGroupService.update(
|
|
||||||
updateViewGroupInput.id,
|
|
||||||
workspaceId,
|
workspaceId,
|
||||||
updateViewGroupInput.update,
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Mutation(() => ViewGroupDTO)
|
@Mutation(() => ViewGroupDTO)
|
||||||
@@ -140,20 +89,10 @@ export class ViewGroupResolver {
|
|||||||
@Args('input') deleteViewGroupInput: DeleteViewGroupInput,
|
@Args('input') deleteViewGroupInput: DeleteViewGroupInput,
|
||||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||||
): Promise<ViewGroupDTO> {
|
): Promise<ViewGroupDTO> {
|
||||||
const isWorkspaceMigrationV2Enabled =
|
return await this.viewGroupService.deleteOne({
|
||||||
await this.featureFlagService.isFeatureEnabled(
|
deleteViewGroupInput,
|
||||||
FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
workspaceId,
|
||||||
workspaceId,
|
});
|
||||||
);
|
|
||||||
|
|
||||||
if (isWorkspaceMigrationV2Enabled) {
|
|
||||||
return await this.viewGroupV2Service.deleteOne({
|
|
||||||
deleteViewGroupInput,
|
|
||||||
workspaceId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.viewGroupService.delete(deleteViewGroupInput.id, workspaceId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Mutation(() => ViewGroupDTO)
|
@Mutation(() => ViewGroupDTO)
|
||||||
@@ -162,19 +101,9 @@ export class ViewGroupResolver {
|
|||||||
@Args('input') destroyViewGroupInput: DestroyViewGroupInput,
|
@Args('input') destroyViewGroupInput: DestroyViewGroupInput,
|
||||||
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
@AuthWorkspace() { id: workspaceId }: WorkspaceEntity,
|
||||||
): Promise<ViewGroupDTO> {
|
): Promise<ViewGroupDTO> {
|
||||||
const isWorkspaceMigrationV2Enabled =
|
return await this.viewGroupService.destroyOne({
|
||||||
await this.featureFlagService.isFeatureEnabled(
|
destroyViewGroupInput,
|
||||||
FeatureFlagKey.IS_WORKSPACE_MIGRATION_V2_ENABLED,
|
workspaceId,
|
||||||
workspaceId,
|
});
|
||||||
);
|
|
||||||
|
|
||||||
if (isWorkspaceMigrationV2Enabled) {
|
|
||||||
return await this.viewGroupV2Service.destroyOne({
|
|
||||||
destroyViewGroupInput,
|
|
||||||
workspaceId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.viewGroupService.destroy(destroyViewGroupInput.id, workspaceId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-327
@@ -1,327 +0,0 @@
|
|||||||
import { Test, type TestingModule } from '@nestjs/testing';
|
|
||||||
import { getRepositoryToken } from '@nestjs/typeorm';
|
|
||||||
|
|
||||||
import { type Repository } from 'typeorm';
|
|
||||||
|
|
||||||
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
|
|
||||||
import {
|
|
||||||
ViewGroupException,
|
|
||||||
ViewGroupExceptionCode,
|
|
||||||
ViewGroupExceptionMessageKey,
|
|
||||||
generateViewGroupExceptionMessage,
|
|
||||||
generateViewGroupUserFriendlyExceptionMessage,
|
|
||||||
} from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
|
||||||
import { ViewGroupService } from 'src/engine/metadata-modules/view-group/services/view-group.service';
|
|
||||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
|
||||||
|
|
||||||
describe('ViewGroupService', () => {
|
|
||||||
let viewGroupService: ViewGroupService;
|
|
||||||
let viewGroupRepository: Repository<ViewGroupEntity>;
|
|
||||||
|
|
||||||
const mockViewGroup = {
|
|
||||||
id: 'view-group-id',
|
|
||||||
fieldMetadataId: 'field-id',
|
|
||||||
viewId: 'view-id',
|
|
||||||
workspaceId: 'workspace-id',
|
|
||||||
fieldValue: 'group-value',
|
|
||||||
isVisible: true,
|
|
||||||
position: 0,
|
|
||||||
createdAt: new Date(),
|
|
||||||
updatedAt: new Date(),
|
|
||||||
deletedAt: null,
|
|
||||||
} as ViewGroupEntity;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
|
||||||
providers: [
|
|
||||||
ViewGroupService,
|
|
||||||
{
|
|
||||||
provide: getRepositoryToken(ViewGroupEntity),
|
|
||||||
useValue: {
|
|
||||||
find: jest.fn(),
|
|
||||||
findOne: jest.fn(),
|
|
||||||
create: jest.fn(),
|
|
||||||
save: jest.fn(),
|
|
||||||
softDelete: jest.fn(),
|
|
||||||
delete: jest.fn(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: WorkspaceCacheStorageService,
|
|
||||||
useValue: {
|
|
||||||
flushGraphQLOperation: jest.fn(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}).compile();
|
|
||||||
|
|
||||||
viewGroupService = module.get<ViewGroupService>(ViewGroupService);
|
|
||||||
viewGroupRepository = module.get<Repository<ViewGroupEntity>>(
|
|
||||||
getRepositoryToken(ViewGroupEntity),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be defined', () => {
|
|
||||||
expect(viewGroupService).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('findByWorkspaceId', () => {
|
|
||||||
it('should return view groups for a workspace', async () => {
|
|
||||||
const workspaceId = 'workspace-id';
|
|
||||||
const expectedViewGroups = [mockViewGroup];
|
|
||||||
|
|
||||||
jest
|
|
||||||
.spyOn(viewGroupRepository, 'find')
|
|
||||||
.mockResolvedValue(expectedViewGroups);
|
|
||||||
|
|
||||||
const result = await viewGroupService.findByWorkspaceId(workspaceId);
|
|
||||||
|
|
||||||
expect(viewGroupRepository.find).toHaveBeenCalledWith({
|
|
||||||
where: {
|
|
||||||
workspaceId,
|
|
||||||
deletedAt: expect.anything(),
|
|
||||||
},
|
|
||||||
order: { position: 'ASC' },
|
|
||||||
relations: ['workspace', 'view'],
|
|
||||||
});
|
|
||||||
expect(result).toEqual(expectedViewGroups);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('findByViewId', () => {
|
|
||||||
it('should return view groups for a view', async () => {
|
|
||||||
const workspaceId = 'workspace-id';
|
|
||||||
const viewId = 'view-id';
|
|
||||||
const expectedViewGroups = [mockViewGroup];
|
|
||||||
|
|
||||||
jest
|
|
||||||
.spyOn(viewGroupRepository, 'find')
|
|
||||||
.mockResolvedValue(expectedViewGroups);
|
|
||||||
|
|
||||||
const result = await viewGroupService.findByViewId(workspaceId, viewId);
|
|
||||||
|
|
||||||
expect(viewGroupRepository.find).toHaveBeenCalledWith({
|
|
||||||
where: {
|
|
||||||
workspaceId,
|
|
||||||
viewId,
|
|
||||||
deletedAt: expect.anything(),
|
|
||||||
},
|
|
||||||
order: { position: 'ASC' },
|
|
||||||
relations: ['workspace', 'view'],
|
|
||||||
});
|
|
||||||
expect(result).toEqual(expectedViewGroups);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('findById', () => {
|
|
||||||
it('should return a view group by id', async () => {
|
|
||||||
const id = 'view-group-id';
|
|
||||||
const workspaceId = 'workspace-id';
|
|
||||||
|
|
||||||
jest
|
|
||||||
.spyOn(viewGroupRepository, 'findOne')
|
|
||||||
.mockResolvedValue(mockViewGroup);
|
|
||||||
|
|
||||||
const result = await viewGroupService.findById(id, workspaceId);
|
|
||||||
|
|
||||||
expect(viewGroupRepository.findOne).toHaveBeenCalledWith({
|
|
||||||
where: {
|
|
||||||
id,
|
|
||||||
workspaceId,
|
|
||||||
deletedAt: expect.anything(),
|
|
||||||
},
|
|
||||||
relations: ['workspace', 'view'],
|
|
||||||
});
|
|
||||||
expect(result).toEqual(mockViewGroup);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return null when view group is not found', async () => {
|
|
||||||
const id = 'non-existent-id';
|
|
||||||
const workspaceId = 'workspace-id';
|
|
||||||
|
|
||||||
jest.spyOn(viewGroupRepository, 'findOne').mockResolvedValue(null);
|
|
||||||
|
|
||||||
const result = await viewGroupService.findById(id, workspaceId);
|
|
||||||
|
|
||||||
expect(result).toBeNull();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('create', () => {
|
|
||||||
const validViewGroupData = {
|
|
||||||
fieldMetadataId: 'field-id',
|
|
||||||
viewId: 'view-id',
|
|
||||||
workspaceId: 'workspace-id',
|
|
||||||
fieldValue: 'group-value',
|
|
||||||
isVisible: true,
|
|
||||||
position: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
it('should create a view group successfully', async () => {
|
|
||||||
jest.spyOn(viewGroupRepository, 'create').mockReturnValue(mockViewGroup);
|
|
||||||
jest.spyOn(viewGroupRepository, 'save').mockResolvedValue(mockViewGroup);
|
|
||||||
|
|
||||||
const result = await viewGroupService.create(validViewGroupData);
|
|
||||||
|
|
||||||
expect(viewGroupRepository.create).toHaveBeenCalledWith(
|
|
||||||
validViewGroupData,
|
|
||||||
);
|
|
||||||
expect(viewGroupRepository.save).toHaveBeenCalledWith(mockViewGroup);
|
|
||||||
expect(result).toEqual(mockViewGroup);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw exception when workspaceId is missing', async () => {
|
|
||||||
const invalidData = { ...validViewGroupData, workspaceId: undefined };
|
|
||||||
|
|
||||||
await expect(viewGroupService.create(invalidData)).rejects.toThrow(
|
|
||||||
new ViewGroupException(
|
|
||||||
generateViewGroupExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.WORKSPACE_ID_REQUIRED,
|
|
||||||
),
|
|
||||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
|
||||||
{
|
|
||||||
userFriendlyMessage: generateViewGroupUserFriendlyExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.WORKSPACE_ID_REQUIRED,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw exception when viewId is missing', async () => {
|
|
||||||
const invalidData = { ...validViewGroupData, viewId: undefined };
|
|
||||||
|
|
||||||
await expect(viewGroupService.create(invalidData)).rejects.toThrow(
|
|
||||||
new ViewGroupException(
|
|
||||||
generateViewGroupExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.VIEW_ID_REQUIRED,
|
|
||||||
),
|
|
||||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
|
||||||
{
|
|
||||||
userFriendlyMessage: generateViewGroupUserFriendlyExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.VIEW_ID_REQUIRED,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw exception when fieldMetadataId is missing', async () => {
|
|
||||||
const invalidData = { ...validViewGroupData, fieldMetadataId: undefined };
|
|
||||||
|
|
||||||
await expect(viewGroupService.create(invalidData)).rejects.toThrow(
|
|
||||||
new ViewGroupException(
|
|
||||||
generateViewGroupExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.FIELD_METADATA_ID_REQUIRED,
|
|
||||||
),
|
|
||||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
|
||||||
{
|
|
||||||
userFriendlyMessage: generateViewGroupUserFriendlyExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.FIELD_METADATA_ID_REQUIRED,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('update', () => {
|
|
||||||
it('should update a view group successfully', async () => {
|
|
||||||
const id = 'view-group-id';
|
|
||||||
const workspaceId = 'workspace-id';
|
|
||||||
const updateData = { isVisible: false };
|
|
||||||
const updatedViewGroup = { ...mockViewGroup, ...updateData };
|
|
||||||
|
|
||||||
jest.spyOn(viewGroupService, 'findById').mockResolvedValue(mockViewGroup);
|
|
||||||
jest
|
|
||||||
.spyOn(viewGroupRepository, 'save')
|
|
||||||
.mockResolvedValue(updatedViewGroup);
|
|
||||||
|
|
||||||
const result = await viewGroupService.update(id, workspaceId, updateData);
|
|
||||||
|
|
||||||
expect(viewGroupService.findById).toHaveBeenCalledWith(id, workspaceId);
|
|
||||||
expect(viewGroupRepository.save).toHaveBeenCalledWith({
|
|
||||||
id,
|
|
||||||
...updateData,
|
|
||||||
});
|
|
||||||
expect(result).toEqual({ ...mockViewGroup, ...updatedViewGroup });
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw exception when view group is not found', async () => {
|
|
||||||
const id = 'non-existent-id';
|
|
||||||
const workspaceId = 'workspace-id';
|
|
||||||
const updateData = { isVisible: false };
|
|
||||||
|
|
||||||
jest.spyOn(viewGroupService, 'findById').mockResolvedValue(null);
|
|
||||||
|
|
||||||
await expect(
|
|
||||||
viewGroupService.update(id, workspaceId, updateData),
|
|
||||||
).rejects.toThrow(
|
|
||||||
new ViewGroupException(
|
|
||||||
generateViewGroupExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.VIEW_GROUP_NOT_FOUND,
|
|
||||||
id,
|
|
||||||
),
|
|
||||||
ViewGroupExceptionCode.VIEW_GROUP_NOT_FOUND,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('delete', () => {
|
|
||||||
it('should delete a view group successfully', async () => {
|
|
||||||
const id = 'view-group-id';
|
|
||||||
const workspaceId = 'workspace-id';
|
|
||||||
|
|
||||||
jest.spyOn(viewGroupService, 'findById').mockResolvedValue(mockViewGroup);
|
|
||||||
jest
|
|
||||||
.spyOn(viewGroupRepository, 'softDelete')
|
|
||||||
.mockResolvedValue({} as any);
|
|
||||||
|
|
||||||
const result = await viewGroupService.delete(id, workspaceId);
|
|
||||||
|
|
||||||
expect(viewGroupService.findById).toHaveBeenCalledWith(id, workspaceId);
|
|
||||||
expect(viewGroupRepository.softDelete).toHaveBeenCalledWith(id);
|
|
||||||
expect(result).toEqual(mockViewGroup);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should throw exception when view group is not found', async () => {
|
|
||||||
const id = 'non-existent-id';
|
|
||||||
const workspaceId = 'workspace-id';
|
|
||||||
|
|
||||||
jest.spyOn(viewGroupService, 'findById').mockResolvedValue(null);
|
|
||||||
|
|
||||||
await expect(viewGroupService.delete(id, workspaceId)).rejects.toThrow(
|
|
||||||
new ViewGroupException(
|
|
||||||
generateViewGroupExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.VIEW_GROUP_NOT_FOUND,
|
|
||||||
id,
|
|
||||||
),
|
|
||||||
ViewGroupExceptionCode.VIEW_GROUP_NOT_FOUND,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('destroy', () => {
|
|
||||||
it('should destroy a view group successfully', async () => {
|
|
||||||
const id = 'view-group-id';
|
|
||||||
const workspaceId = 'workspace-id';
|
|
||||||
|
|
||||||
jest
|
|
||||||
.spyOn(viewGroupRepository, 'findOne')
|
|
||||||
.mockResolvedValue(mockViewGroup);
|
|
||||||
jest.spyOn(viewGroupRepository, 'delete').mockResolvedValue({} as any);
|
|
||||||
|
|
||||||
const result = await viewGroupService.destroy(id, workspaceId);
|
|
||||||
|
|
||||||
expect(viewGroupRepository.findOne).toHaveBeenCalledWith({
|
|
||||||
where: { id, workspaceId },
|
|
||||||
relations: ['workspace', 'view'],
|
|
||||||
withDeleted: true,
|
|
||||||
});
|
|
||||||
expect(viewGroupRepository.delete).toHaveBeenCalledWith(id);
|
|
||||||
expect(result).toEqual(mockViewGroup);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
-347
@@ -1,347 +0,0 @@
|
|||||||
import { Injectable } from '@nestjs/common';
|
|
||||||
|
|
||||||
import { isDefined } from 'twenty-shared/utils';
|
|
||||||
|
|
||||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
|
||||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
|
||||||
import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util';
|
|
||||||
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
|
||||||
import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
|
||||||
import { fromCreateViewGroupInputToFlatViewGroupToCreate } from 'src/engine/metadata-modules/flat-view-group/utils/from-create-view-group-input-to-flat-view-group-to-create.util';
|
|
||||||
import { fromDeleteViewGroupInputToFlatViewGroupOrThrow } from 'src/engine/metadata-modules/flat-view-group/utils/from-delete-view-group-input-to-flat-view-group-or-throw.util';
|
|
||||||
import { fromDestroyViewGroupInputToFlatViewGroupOrThrow } from 'src/engine/metadata-modules/flat-view-group/utils/from-destroy-view-group-input-to-flat-view-group-or-throw.util';
|
|
||||||
import { fromUpdateViewGroupInputToFlatViewGroupToUpdateOrThrow } from 'src/engine/metadata-modules/flat-view-group/utils/from-update-view-group-input-to-flat-view-group-to-update-or-throw.util';
|
|
||||||
import { CreateViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/create-view-group.input';
|
|
||||||
import { DeleteViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/delete-view-group.input';
|
|
||||||
import { DestroyViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/destroy-view-group.input';
|
|
||||||
import { UpdateViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/update-view-group.input';
|
|
||||||
import { ViewGroupDTO } from 'src/engine/metadata-modules/view-group/dtos/view-group.dto';
|
|
||||||
import {
|
|
||||||
ViewGroupException,
|
|
||||||
ViewGroupExceptionCode,
|
|
||||||
} from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
|
||||||
import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
|
||||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class ViewGroupV2Service {
|
|
||||||
constructor(
|
|
||||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
|
||||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
|
||||||
private readonly applicationService: ApplicationService,
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async createOne({
|
|
||||||
createViewGroupInput,
|
|
||||||
workspaceId,
|
|
||||||
}: {
|
|
||||||
createViewGroupInput: CreateViewGroupInput;
|
|
||||||
workspaceId: string;
|
|
||||||
}): Promise<ViewGroupDTO> {
|
|
||||||
const [createdViewGroup] = await this.createMany({
|
|
||||||
workspaceId,
|
|
||||||
createViewGroupInputs: [createViewGroupInput],
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!isDefined(createdViewGroup)) {
|
|
||||||
throw new ViewGroupException(
|
|
||||||
'Failed to create view group',
|
|
||||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return createdViewGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
async createMany({
|
|
||||||
createViewGroupInputs,
|
|
||||||
workspaceId,
|
|
||||||
}: {
|
|
||||||
createViewGroupInputs: CreateViewGroupInput[];
|
|
||||||
workspaceId: string;
|
|
||||||
}): Promise<ViewGroupDTO[]> {
|
|
||||||
if (createViewGroupInputs.length === 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
const { workspaceCustomFlatApplication } =
|
|
||||||
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
|
||||||
{
|
|
||||||
workspaceId,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const {
|
|
||||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
|
||||||
flatViewMaps,
|
|
||||||
flatFieldMetadataMaps,
|
|
||||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
||||||
{
|
|
||||||
workspaceId,
|
|
||||||
flatMapsKeys: [
|
|
||||||
'flatViewGroupMaps',
|
|
||||||
'flatViewMaps',
|
|
||||||
'flatFieldMetadataMaps',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const flatViewGroupsToCreate = createViewGroupInputs.map(
|
|
||||||
(createViewGroupInput) =>
|
|
||||||
fromCreateViewGroupInputToFlatViewGroupToCreate({
|
|
||||||
createViewGroupInput,
|
|
||||||
workspaceId,
|
|
||||||
workspaceCustomApplicationId: workspaceCustomFlatApplication.id,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const validateAndBuildResult =
|
|
||||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
|
||||||
{
|
|
||||||
fromToAllFlatEntityMaps: {
|
|
||||||
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
|
||||||
flatEntityMaps: existingFlatViewGroupMaps,
|
|
||||||
flatEntityToCreate: flatViewGroupsToCreate,
|
|
||||||
flatEntityToDelete: [],
|
|
||||||
flatEntityToUpdate: [],
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
dependencyAllFlatEntityMaps: {
|
|
||||||
flatFieldMetadataMaps,
|
|
||||||
flatViewMaps,
|
|
||||||
},
|
|
||||||
buildOptions: {
|
|
||||||
isSystemBuild: false,
|
|
||||||
},
|
|
||||||
workspaceId,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isDefined(validateAndBuildResult)) {
|
|
||||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
|
||||||
validateAndBuildResult,
|
|
||||||
'Multiple validation errors occurred while creating view groups',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { flatViewGroupMaps: recomputedExistingFlatViewGroupMaps } =
|
|
||||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
||||||
{
|
|
||||||
workspaceId,
|
|
||||||
flatMapsKeys: ['flatViewGroupMaps'],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return findManyFlatEntityByIdInFlatEntityMapsOrThrow({
|
|
||||||
flatEntityIds: flatViewGroupsToCreate.map((el) => el.id),
|
|
||||||
flatEntityMaps: recomputedExistingFlatViewGroupMaps,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateOne({
|
|
||||||
updateViewGroupInput,
|
|
||||||
workspaceId,
|
|
||||||
}: {
|
|
||||||
workspaceId: string;
|
|
||||||
updateViewGroupInput: UpdateViewGroupInput;
|
|
||||||
}): Promise<ViewGroupDTO> {
|
|
||||||
const {
|
|
||||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
|
||||||
flatViewMaps,
|
|
||||||
flatFieldMetadataMaps,
|
|
||||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
||||||
{
|
|
||||||
workspaceId,
|
|
||||||
flatMapsKeys: [
|
|
||||||
'flatViewGroupMaps',
|
|
||||||
'flatViewMaps',
|
|
||||||
'flatFieldMetadataMaps',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const optimisticallyUpdatedFlatViewGroup =
|
|
||||||
fromUpdateViewGroupInputToFlatViewGroupToUpdateOrThrow({
|
|
||||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
|
||||||
updateViewGroupInput,
|
|
||||||
});
|
|
||||||
|
|
||||||
const validateAndBuildResult =
|
|
||||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
|
||||||
{
|
|
||||||
fromToAllFlatEntityMaps: {
|
|
||||||
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
|
||||||
flatEntityMaps: existingFlatViewGroupMaps,
|
|
||||||
flatEntityToCreate: [],
|
|
||||||
flatEntityToDelete: [],
|
|
||||||
flatEntityToUpdate: [optimisticallyUpdatedFlatViewGroup],
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
dependencyAllFlatEntityMaps: {
|
|
||||||
flatViewMaps,
|
|
||||||
flatFieldMetadataMaps,
|
|
||||||
},
|
|
||||||
buildOptions: {
|
|
||||||
isSystemBuild: false,
|
|
||||||
},
|
|
||||||
workspaceId,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isDefined(validateAndBuildResult)) {
|
|
||||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
|
||||||
validateAndBuildResult,
|
|
||||||
'Multiple validation errors occurred while updating view group',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { flatViewGroupMaps: recomputedExistingFlatViewGroupMaps } =
|
|
||||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
||||||
{
|
|
||||||
workspaceId,
|
|
||||||
flatMapsKeys: ['flatViewGroupMaps'],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
|
||||||
flatEntityId: optimisticallyUpdatedFlatViewGroup.id,
|
|
||||||
flatEntityMaps: recomputedExistingFlatViewGroupMaps,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async deleteOne({
|
|
||||||
deleteViewGroupInput,
|
|
||||||
workspaceId,
|
|
||||||
}: {
|
|
||||||
deleteViewGroupInput: DeleteViewGroupInput;
|
|
||||||
workspaceId: string;
|
|
||||||
}): Promise<ViewGroupDTO> {
|
|
||||||
const {
|
|
||||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
|
||||||
flatViewMaps,
|
|
||||||
flatFieldMetadataMaps,
|
|
||||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
||||||
{
|
|
||||||
workspaceId,
|
|
||||||
flatMapsKeys: [
|
|
||||||
'flatViewGroupMaps',
|
|
||||||
'flatViewMaps',
|
|
||||||
'flatFieldMetadataMaps',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const optimisticallyUpdatedFlatViewGroupWithDeletedAt =
|
|
||||||
fromDeleteViewGroupInputToFlatViewGroupOrThrow({
|
|
||||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
|
||||||
deleteViewGroupInput,
|
|
||||||
});
|
|
||||||
|
|
||||||
const validateAndBuildResult =
|
|
||||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
|
||||||
{
|
|
||||||
fromToAllFlatEntityMaps: {
|
|
||||||
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
|
||||||
flatEntityMaps: existingFlatViewGroupMaps,
|
|
||||||
flatEntityToCreate: [],
|
|
||||||
flatEntityToDelete: [],
|
|
||||||
flatEntityToUpdate: [
|
|
||||||
optimisticallyUpdatedFlatViewGroupWithDeletedAt,
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
dependencyAllFlatEntityMaps: {
|
|
||||||
flatFieldMetadataMaps,
|
|
||||||
flatViewMaps,
|
|
||||||
},
|
|
||||||
buildOptions: {
|
|
||||||
isSystemBuild: false,
|
|
||||||
},
|
|
||||||
workspaceId,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isDefined(validateAndBuildResult)) {
|
|
||||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
|
||||||
validateAndBuildResult,
|
|
||||||
'Multiple validation errors occurred while deleting view group',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const { flatViewGroupMaps: recomputedExistingFlatViewGroupMaps } =
|
|
||||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
||||||
{
|
|
||||||
workspaceId,
|
|
||||||
flatMapsKeys: ['flatViewGroupMaps'],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
|
||||||
flatEntityId: optimisticallyUpdatedFlatViewGroupWithDeletedAt.id,
|
|
||||||
flatEntityMaps: recomputedExistingFlatViewGroupMaps,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async destroyOne({
|
|
||||||
destroyViewGroupInput,
|
|
||||||
workspaceId,
|
|
||||||
}: {
|
|
||||||
destroyViewGroupInput: DestroyViewGroupInput;
|
|
||||||
workspaceId: string;
|
|
||||||
}): Promise<ViewGroupDTO> {
|
|
||||||
const {
|
|
||||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
|
||||||
flatViewMaps: existingFlatViewMaps,
|
|
||||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
|
||||||
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
|
||||||
{
|
|
||||||
workspaceId,
|
|
||||||
flatMapsKeys: [
|
|
||||||
'flatViewGroupMaps',
|
|
||||||
'flatViewMaps',
|
|
||||||
'flatFieldMetadataMaps',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const existingViewGroupToDelete =
|
|
||||||
fromDestroyViewGroupInputToFlatViewGroupOrThrow({
|
|
||||||
destroyViewGroupInput,
|
|
||||||
flatViewGroupMaps: existingFlatViewGroupMaps,
|
|
||||||
});
|
|
||||||
|
|
||||||
const validateAndBuildResult =
|
|
||||||
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
|
||||||
{
|
|
||||||
fromToAllFlatEntityMaps: {
|
|
||||||
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
|
||||||
flatEntityMaps: existingFlatViewGroupMaps,
|
|
||||||
flatEntityToCreate: [],
|
|
||||||
flatEntityToDelete: [existingViewGroupToDelete],
|
|
||||||
flatEntityToUpdate: [],
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
dependencyAllFlatEntityMaps: {
|
|
||||||
flatViewMaps: existingFlatViewMaps,
|
|
||||||
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
|
||||||
},
|
|
||||||
buildOptions: {
|
|
||||||
isSystemBuild: false,
|
|
||||||
inferDeletionFromMissingEntities: {
|
|
||||||
viewGroup: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
workspaceId,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isDefined(validateAndBuildResult)) {
|
|
||||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
|
||||||
validateAndBuildResult,
|
|
||||||
'Multiple validation errors occurred while destroying view group',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return existingViewGroupToDelete;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+333
-143
@@ -4,25 +4,352 @@ import { InjectRepository } from '@nestjs/typeorm';
|
|||||||
import { isDefined } from 'twenty-shared/utils';
|
import { isDefined } from 'twenty-shared/utils';
|
||||||
import { IsNull, Repository } from 'typeorm';
|
import { IsNull, Repository } from 'typeorm';
|
||||||
|
|
||||||
|
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||||
|
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||||
|
import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util';
|
||||||
|
import { findFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||||
|
import { findManyFlatEntityByIdInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-many-flat-entity-by-id-in-flat-entity-maps-or-throw.util';
|
||||||
|
import { fromCreateViewGroupInputToFlatViewGroupToCreate } from 'src/engine/metadata-modules/flat-view-group/utils/from-create-view-group-input-to-flat-view-group-to-create.util';
|
||||||
|
import { fromDeleteViewGroupInputToFlatViewGroupOrThrow } from 'src/engine/metadata-modules/flat-view-group/utils/from-delete-view-group-input-to-flat-view-group-or-throw.util';
|
||||||
|
import { fromDestroyViewGroupInputToFlatViewGroupOrThrow } from 'src/engine/metadata-modules/flat-view-group/utils/from-destroy-view-group-input-to-flat-view-group-or-throw.util';
|
||||||
|
import { fromUpdateViewGroupInputToFlatViewGroupToUpdateOrThrow } from 'src/engine/metadata-modules/flat-view-group/utils/from-update-view-group-input-to-flat-view-group-to-update-or-throw.util';
|
||||||
|
import { CreateViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/create-view-group.input';
|
||||||
|
import { DeleteViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/delete-view-group.input';
|
||||||
|
import { DestroyViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/destroy-view-group.input';
|
||||||
|
import { UpdateViewGroupInput } from 'src/engine/metadata-modules/view-group/dtos/inputs/update-view-group.input';
|
||||||
|
import { ViewGroupDTO } from 'src/engine/metadata-modules/view-group/dtos/view-group.dto';
|
||||||
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
|
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
|
||||||
import {
|
import {
|
||||||
ViewGroupException,
|
ViewGroupException,
|
||||||
ViewGroupExceptionCode,
|
ViewGroupExceptionCode,
|
||||||
ViewGroupExceptionMessageKey,
|
|
||||||
generateViewGroupExceptionMessage,
|
|
||||||
generateViewGroupUserFriendlyExceptionMessage,
|
|
||||||
} from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
} from 'src/engine/metadata-modules/view-group/exceptions/view-group.exception';
|
||||||
import { FIND_ALL_CORE_VIEWS_GRAPHQL_OPERATION } from 'src/engine/metadata-modules/view/constants/find-all-core-views-graphql-operation.constant';
|
import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
||||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ViewGroupService {
|
export class ViewGroupService {
|
||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(ViewGroupEntity)
|
@InjectRepository(ViewGroupEntity)
|
||||||
private readonly viewGroupRepository: Repository<ViewGroupEntity>,
|
private readonly viewGroupRepository: Repository<ViewGroupEntity>,
|
||||||
private readonly workspaceCacheStorageService: WorkspaceCacheStorageService,
|
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||||
|
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||||
|
private readonly applicationService: ApplicationService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
async createOne({
|
||||||
|
createViewGroupInput,
|
||||||
|
workspaceId,
|
||||||
|
}: {
|
||||||
|
createViewGroupInput: CreateViewGroupInput;
|
||||||
|
workspaceId: string;
|
||||||
|
}): Promise<ViewGroupDTO> {
|
||||||
|
const [createdViewGroup] = await this.createMany({
|
||||||
|
workspaceId,
|
||||||
|
createViewGroupInputs: [createViewGroupInput],
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!isDefined(createdViewGroup)) {
|
||||||
|
throw new ViewGroupException(
|
||||||
|
'Failed to create view group',
|
||||||
|
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return createdViewGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
async createMany({
|
||||||
|
createViewGroupInputs,
|
||||||
|
workspaceId,
|
||||||
|
}: {
|
||||||
|
createViewGroupInputs: CreateViewGroupInput[];
|
||||||
|
workspaceId: string;
|
||||||
|
}): Promise<ViewGroupDTO[]> {
|
||||||
|
if (createViewGroupInputs.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const { workspaceCustomFlatApplication } =
|
||||||
|
await this.applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
||||||
|
{
|
||||||
|
workspaceId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||||
|
flatViewMaps,
|
||||||
|
flatFieldMetadataMaps,
|
||||||
|
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||||
|
{
|
||||||
|
workspaceId,
|
||||||
|
flatMapsKeys: [
|
||||||
|
'flatViewGroupMaps',
|
||||||
|
'flatViewMaps',
|
||||||
|
'flatFieldMetadataMaps',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const flatViewGroupsToCreate = createViewGroupInputs.map(
|
||||||
|
(createViewGroupInput) =>
|
||||||
|
fromCreateViewGroupInputToFlatViewGroupToCreate({
|
||||||
|
createViewGroupInput,
|
||||||
|
workspaceId,
|
||||||
|
workspaceCustomApplicationId: workspaceCustomFlatApplication.id,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const validateAndBuildResult =
|
||||||
|
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||||
|
{
|
||||||
|
fromToAllFlatEntityMaps: {
|
||||||
|
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
||||||
|
flatEntityMaps: existingFlatViewGroupMaps,
|
||||||
|
flatEntityToCreate: flatViewGroupsToCreate,
|
||||||
|
flatEntityToDelete: [],
|
||||||
|
flatEntityToUpdate: [],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
dependencyAllFlatEntityMaps: {
|
||||||
|
flatFieldMetadataMaps,
|
||||||
|
flatViewMaps,
|
||||||
|
},
|
||||||
|
buildOptions: {
|
||||||
|
isSystemBuild: false,
|
||||||
|
},
|
||||||
|
workspaceId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDefined(validateAndBuildResult)) {
|
||||||
|
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||||
|
validateAndBuildResult,
|
||||||
|
'Multiple validation errors occurred while creating view groups',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { flatViewGroupMaps: recomputedExistingFlatViewGroupMaps } =
|
||||||
|
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||||
|
{
|
||||||
|
workspaceId,
|
||||||
|
flatMapsKeys: ['flatViewGroupMaps'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return findManyFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||||
|
flatEntityIds: flatViewGroupsToCreate.map((el) => el.id),
|
||||||
|
flatEntityMaps: recomputedExistingFlatViewGroupMaps,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateOne({
|
||||||
|
updateViewGroupInput,
|
||||||
|
workspaceId,
|
||||||
|
}: {
|
||||||
|
workspaceId: string;
|
||||||
|
updateViewGroupInput: UpdateViewGroupInput;
|
||||||
|
}): Promise<ViewGroupDTO> {
|
||||||
|
const {
|
||||||
|
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||||
|
flatViewMaps,
|
||||||
|
flatFieldMetadataMaps,
|
||||||
|
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||||
|
{
|
||||||
|
workspaceId,
|
||||||
|
flatMapsKeys: [
|
||||||
|
'flatViewGroupMaps',
|
||||||
|
'flatViewMaps',
|
||||||
|
'flatFieldMetadataMaps',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const optimisticallyUpdatedFlatViewGroup =
|
||||||
|
fromUpdateViewGroupInputToFlatViewGroupToUpdateOrThrow({
|
||||||
|
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||||
|
updateViewGroupInput,
|
||||||
|
});
|
||||||
|
|
||||||
|
const validateAndBuildResult =
|
||||||
|
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||||
|
{
|
||||||
|
fromToAllFlatEntityMaps: {
|
||||||
|
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
||||||
|
flatEntityMaps: existingFlatViewGroupMaps,
|
||||||
|
flatEntityToCreate: [],
|
||||||
|
flatEntityToDelete: [],
|
||||||
|
flatEntityToUpdate: [optimisticallyUpdatedFlatViewGroup],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
dependencyAllFlatEntityMaps: {
|
||||||
|
flatViewMaps,
|
||||||
|
flatFieldMetadataMaps,
|
||||||
|
},
|
||||||
|
buildOptions: {
|
||||||
|
isSystemBuild: false,
|
||||||
|
},
|
||||||
|
workspaceId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDefined(validateAndBuildResult)) {
|
||||||
|
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||||
|
validateAndBuildResult,
|
||||||
|
'Multiple validation errors occurred while updating view group',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { flatViewGroupMaps: recomputedExistingFlatViewGroupMaps } =
|
||||||
|
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||||
|
{
|
||||||
|
workspaceId,
|
||||||
|
flatMapsKeys: ['flatViewGroupMaps'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||||
|
flatEntityId: optimisticallyUpdatedFlatViewGroup.id,
|
||||||
|
flatEntityMaps: recomputedExistingFlatViewGroupMaps,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteOne({
|
||||||
|
deleteViewGroupInput,
|
||||||
|
workspaceId,
|
||||||
|
}: {
|
||||||
|
deleteViewGroupInput: DeleteViewGroupInput;
|
||||||
|
workspaceId: string;
|
||||||
|
}): Promise<ViewGroupDTO> {
|
||||||
|
const {
|
||||||
|
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||||
|
flatViewMaps,
|
||||||
|
flatFieldMetadataMaps,
|
||||||
|
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||||
|
{
|
||||||
|
workspaceId,
|
||||||
|
flatMapsKeys: [
|
||||||
|
'flatViewGroupMaps',
|
||||||
|
'flatViewMaps',
|
||||||
|
'flatFieldMetadataMaps',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const optimisticallyUpdatedFlatViewGroupWithDeletedAt =
|
||||||
|
fromDeleteViewGroupInputToFlatViewGroupOrThrow({
|
||||||
|
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||||
|
deleteViewGroupInput,
|
||||||
|
});
|
||||||
|
|
||||||
|
const validateAndBuildResult =
|
||||||
|
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||||
|
{
|
||||||
|
fromToAllFlatEntityMaps: {
|
||||||
|
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
||||||
|
flatEntityMaps: existingFlatViewGroupMaps,
|
||||||
|
flatEntityToCreate: [],
|
||||||
|
flatEntityToDelete: [],
|
||||||
|
flatEntityToUpdate: [
|
||||||
|
optimisticallyUpdatedFlatViewGroupWithDeletedAt,
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
dependencyAllFlatEntityMaps: {
|
||||||
|
flatFieldMetadataMaps,
|
||||||
|
flatViewMaps,
|
||||||
|
},
|
||||||
|
buildOptions: {
|
||||||
|
isSystemBuild: false,
|
||||||
|
},
|
||||||
|
workspaceId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDefined(validateAndBuildResult)) {
|
||||||
|
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||||
|
validateAndBuildResult,
|
||||||
|
'Multiple validation errors occurred while deleting view group',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const { flatViewGroupMaps: recomputedExistingFlatViewGroupMaps } =
|
||||||
|
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||||
|
{
|
||||||
|
workspaceId,
|
||||||
|
flatMapsKeys: ['flatViewGroupMaps'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return findFlatEntityByIdInFlatEntityMapsOrThrow({
|
||||||
|
flatEntityId: optimisticallyUpdatedFlatViewGroupWithDeletedAt.id,
|
||||||
|
flatEntityMaps: recomputedExistingFlatViewGroupMaps,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async destroyOne({
|
||||||
|
destroyViewGroupInput,
|
||||||
|
workspaceId,
|
||||||
|
}: {
|
||||||
|
destroyViewGroupInput: DestroyViewGroupInput;
|
||||||
|
workspaceId: string;
|
||||||
|
}): Promise<ViewGroupDTO> {
|
||||||
|
const {
|
||||||
|
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||||
|
flatViewMaps: existingFlatViewMaps,
|
||||||
|
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||||
|
} = await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||||
|
{
|
||||||
|
workspaceId,
|
||||||
|
flatMapsKeys: [
|
||||||
|
'flatViewGroupMaps',
|
||||||
|
'flatViewMaps',
|
||||||
|
'flatFieldMetadataMaps',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const existingViewGroupToDelete =
|
||||||
|
fromDestroyViewGroupInputToFlatViewGroupOrThrow({
|
||||||
|
destroyViewGroupInput,
|
||||||
|
flatViewGroupMaps: existingFlatViewGroupMaps,
|
||||||
|
});
|
||||||
|
|
||||||
|
const validateAndBuildResult =
|
||||||
|
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||||
|
{
|
||||||
|
fromToAllFlatEntityMaps: {
|
||||||
|
flatViewGroupMaps: computeFlatEntityMapsFromTo({
|
||||||
|
flatEntityMaps: existingFlatViewGroupMaps,
|
||||||
|
flatEntityToCreate: [],
|
||||||
|
flatEntityToDelete: [existingViewGroupToDelete],
|
||||||
|
flatEntityToUpdate: [],
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
dependencyAllFlatEntityMaps: {
|
||||||
|
flatViewMaps: existingFlatViewMaps,
|
||||||
|
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
|
||||||
|
},
|
||||||
|
buildOptions: {
|
||||||
|
isSystemBuild: false,
|
||||||
|
inferDeletionFromMissingEntities: {
|
||||||
|
viewGroup: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
workspaceId,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDefined(validateAndBuildResult)) {
|
||||||
|
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||||
|
validateAndBuildResult,
|
||||||
|
'Multiple validation errors occurred while destroying view group',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return existingViewGroupToDelete;
|
||||||
|
}
|
||||||
|
|
||||||
async findByWorkspaceId(workspaceId: string): Promise<ViewGroupEntity[]> {
|
async findByWorkspaceId(workspaceId: string): Promise<ViewGroupEntity[]> {
|
||||||
return this.viewGroupRepository.find({
|
return this.viewGroupRepository.find({
|
||||||
where: {
|
where: {
|
||||||
@@ -64,141 +391,4 @@ export class ViewGroupService {
|
|||||||
|
|
||||||
return viewGroup || null;
|
return viewGroup || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(
|
|
||||||
viewGroupData: Partial<ViewGroupEntity>,
|
|
||||||
): Promise<ViewGroupEntity> {
|
|
||||||
if (!isDefined(viewGroupData.workspaceId)) {
|
|
||||||
throw new ViewGroupException(
|
|
||||||
generateViewGroupExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.WORKSPACE_ID_REQUIRED,
|
|
||||||
),
|
|
||||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
|
||||||
{
|
|
||||||
userFriendlyMessage: generateViewGroupUserFriendlyExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.WORKSPACE_ID_REQUIRED,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isDefined(viewGroupData.viewId)) {
|
|
||||||
throw new ViewGroupException(
|
|
||||||
generateViewGroupExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.VIEW_ID_REQUIRED,
|
|
||||||
),
|
|
||||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
|
||||||
{
|
|
||||||
userFriendlyMessage: generateViewGroupUserFriendlyExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.VIEW_ID_REQUIRED,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isDefined(viewGroupData.fieldMetadataId)) {
|
|
||||||
throw new ViewGroupException(
|
|
||||||
generateViewGroupExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.FIELD_METADATA_ID_REQUIRED,
|
|
||||||
),
|
|
||||||
ViewGroupExceptionCode.INVALID_VIEW_GROUP_DATA,
|
|
||||||
{
|
|
||||||
userFriendlyMessage: generateViewGroupUserFriendlyExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.FIELD_METADATA_ID_REQUIRED,
|
|
||||||
),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const viewGroup = this.viewGroupRepository.create(viewGroupData);
|
|
||||||
|
|
||||||
await this.flushGraphQLCache(viewGroupData.workspaceId);
|
|
||||||
|
|
||||||
const savedViewGroup = await this.viewGroupRepository.save(viewGroup);
|
|
||||||
|
|
||||||
await this.flushGraphQLCache(viewGroupData.workspaceId);
|
|
||||||
|
|
||||||
return savedViewGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
async update(
|
|
||||||
id: string,
|
|
||||||
workspaceId: string,
|
|
||||||
updateData: Partial<ViewGroupEntity>,
|
|
||||||
): Promise<ViewGroupEntity> {
|
|
||||||
const existingViewGroup = await this.findById(id, workspaceId);
|
|
||||||
|
|
||||||
if (!isDefined(existingViewGroup)) {
|
|
||||||
throw new ViewGroupException(
|
|
||||||
generateViewGroupExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.VIEW_GROUP_NOT_FOUND,
|
|
||||||
id,
|
|
||||||
),
|
|
||||||
ViewGroupExceptionCode.VIEW_GROUP_NOT_FOUND,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedViewGroup = await this.viewGroupRepository.save({
|
|
||||||
id,
|
|
||||||
...updateData,
|
|
||||||
});
|
|
||||||
|
|
||||||
await this.flushGraphQLCache(workspaceId);
|
|
||||||
|
|
||||||
return { ...existingViewGroup, ...updatedViewGroup };
|
|
||||||
}
|
|
||||||
|
|
||||||
async delete(id: string, workspaceId: string): Promise<ViewGroupEntity> {
|
|
||||||
const viewGroup = await this.findById(id, workspaceId);
|
|
||||||
|
|
||||||
if (!isDefined(viewGroup)) {
|
|
||||||
throw new ViewGroupException(
|
|
||||||
generateViewGroupExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.VIEW_GROUP_NOT_FOUND,
|
|
||||||
id,
|
|
||||||
),
|
|
||||||
ViewGroupExceptionCode.VIEW_GROUP_NOT_FOUND,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.viewGroupRepository.softDelete(id);
|
|
||||||
|
|
||||||
await this.flushGraphQLCache(workspaceId);
|
|
||||||
|
|
||||||
return viewGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
async destroy(id: string, workspaceId: string): Promise<ViewGroupEntity> {
|
|
||||||
const viewGroup = await this.viewGroupRepository.findOne({
|
|
||||||
where: {
|
|
||||||
id,
|
|
||||||
workspaceId,
|
|
||||||
},
|
|
||||||
relations: ['workspace', 'view'],
|
|
||||||
withDeleted: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!isDefined(viewGroup)) {
|
|
||||||
throw new ViewGroupException(
|
|
||||||
generateViewGroupExceptionMessage(
|
|
||||||
ViewGroupExceptionMessageKey.VIEW_GROUP_NOT_FOUND,
|
|
||||||
id,
|
|
||||||
),
|
|
||||||
ViewGroupExceptionCode.VIEW_GROUP_NOT_FOUND,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.viewGroupRepository.delete(id);
|
|
||||||
|
|
||||||
await this.flushGraphQLCache(workspaceId);
|
|
||||||
|
|
||||||
return viewGroup;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async flushGraphQLCache(workspaceId: string): Promise<void> {
|
|
||||||
await this.workspaceCacheStorageService.flushGraphQLOperation({
|
|
||||||
operationName: FIND_ALL_CORE_VIEWS_GRAPHQL_OPERATION,
|
|
||||||
workspaceId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permi
|
|||||||
import { ViewGroupController } from 'src/engine/metadata-modules/view-group/controllers/view-group.controller';
|
import { ViewGroupController } from 'src/engine/metadata-modules/view-group/controllers/view-group.controller';
|
||||||
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
|
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
|
||||||
import { ViewGroupResolver } from 'src/engine/metadata-modules/view-group/resolvers/view-group.resolver';
|
import { ViewGroupResolver } from 'src/engine/metadata-modules/view-group/resolvers/view-group.resolver';
|
||||||
import { ViewGroupV2Service } from 'src/engine/metadata-modules/view-group/services/view-group-v2.service';
|
|
||||||
import { ViewGroupService } from 'src/engine/metadata-modules/view-group/services/view-group.service';
|
import { ViewGroupService } from 'src/engine/metadata-modules/view-group/services/view-group.service';
|
||||||
import { ViewPermissionsModule } from 'src/engine/metadata-modules/view-permissions/view-permissions.module';
|
import { ViewPermissionsModule } from 'src/engine/metadata-modules/view-permissions/view-permissions.module';
|
||||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||||
@@ -27,7 +26,7 @@ import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspa
|
|||||||
ViewPermissionsModule,
|
ViewPermissionsModule,
|
||||||
],
|
],
|
||||||
controllers: [ViewGroupController],
|
controllers: [ViewGroupController],
|
||||||
providers: [ViewGroupService, ViewGroupV2Service, ViewGroupResolver],
|
providers: [ViewGroupService, ViewGroupResolver],
|
||||||
exports: [ViewGroupService],
|
exports: [ViewGroupService],
|
||||||
})
|
})
|
||||||
export class ViewGroupModule {}
|
export class ViewGroupModule {}
|
||||||
|
|||||||
Reference in New Issue
Block a user