refactor: create/update/delete one view instead of many (#1384)

Closes #1359
This commit is contained in:
Thaïs
2023-08-30 15:35:18 +02:00
committed by GitHub
parent fa33506b96
commit 6eadd1d132
8 changed files with 223 additions and 137 deletions

View File

@ -1004,6 +1004,7 @@ export type Mutation = {
createOneCompany: Company; createOneCompany: Company;
createOnePerson: Person; createOnePerson: Person;
createOnePipelineProgress: PipelineProgress; createOnePipelineProgress: PipelineProgress;
createOneView: View;
createOneViewField: ViewField; createOneViewField: ViewField;
deleteCurrentWorkspace: Workspace; deleteCurrentWorkspace: Workspace;
deleteFavorite: Favorite; deleteFavorite: Favorite;
@ -1014,6 +1015,7 @@ export type Mutation = {
deleteManyView: AffectedRows; deleteManyView: AffectedRows;
deleteManyViewFilter: AffectedRows; deleteManyViewFilter: AffectedRows;
deleteManyViewSort: AffectedRows; deleteManyViewSort: AffectedRows;
deleteOneView: View;
deleteUserAccount: User; deleteUserAccount: User;
deleteWorkspaceMember: WorkspaceMember; deleteWorkspaceMember: WorkspaceMember;
impersonate: Verify; impersonate: Verify;
@ -1128,6 +1130,11 @@ export type MutationCreateOnePipelineProgressArgs = {
}; };
export type MutationCreateOneViewArgs = {
data: ViewCreateInput;
};
export type MutationCreateOneViewFieldArgs = { export type MutationCreateOneViewFieldArgs = {
data: ViewFieldCreateInput; data: ViewFieldCreateInput;
}; };
@ -1173,6 +1180,11 @@ export type MutationDeleteManyViewSortArgs = {
}; };
export type MutationDeleteOneViewArgs = {
where: ViewWhereUniqueInput;
};
export type MutationDeleteWorkspaceMemberArgs = { export type MutationDeleteWorkspaceMemberArgs = {
where: WorkspaceMemberWhereUniqueInput; where: WorkspaceMemberWhereUniqueInput;
}; };
@ -2423,6 +2435,16 @@ export type View = {
type: ViewType; type: ViewType;
}; };
export type ViewCreateInput = {
fields?: InputMaybe<ViewFieldCreateNestedManyWithoutViewInput>;
filters?: InputMaybe<ViewFilterCreateNestedManyWithoutViewInput>;
id?: InputMaybe<Scalars['String']>;
name: Scalars['String'];
objectId: Scalars['String'];
sorts?: InputMaybe<ViewSortCreateNestedManyWithoutViewInput>;
type: ViewType;
};
export type ViewCreateManyInput = { export type ViewCreateManyInput = {
id?: InputMaybe<Scalars['String']>; id?: InputMaybe<Scalars['String']>;
name: Scalars['String']; name: Scalars['String'];
@ -2466,6 +2488,10 @@ export type ViewFieldCreateManyInput = {
viewId?: InputMaybe<Scalars['String']>; viewId?: InputMaybe<Scalars['String']>;
}; };
export type ViewFieldCreateNestedManyWithoutViewInput = {
connect?: InputMaybe<Array<ViewFieldWhereUniqueInput>>;
};
export type ViewFieldListRelationFilter = { export type ViewFieldListRelationFilter = {
every?: InputMaybe<ViewFieldWhereInput>; every?: InputMaybe<ViewFieldWhereInput>;
none?: InputMaybe<ViewFieldWhereInput>; none?: InputMaybe<ViewFieldWhereInput>;
@ -2565,6 +2591,10 @@ export type ViewFilterCreateManyInput = {
viewId: Scalars['String']; viewId: Scalars['String'];
}; };
export type ViewFilterCreateNestedManyWithoutViewInput = {
connect?: InputMaybe<Array<ViewFilterWhereUniqueInput>>;
};
export type ViewFilterListRelationFilter = { export type ViewFilterListRelationFilter = {
every?: InputMaybe<ViewFilterWhereInput>; every?: InputMaybe<ViewFilterWhereInput>;
none?: InputMaybe<ViewFilterWhereInput>; none?: InputMaybe<ViewFilterWhereInput>;
@ -2686,6 +2716,10 @@ export type ViewSortCreateManyInput = {
viewId: Scalars['String']; viewId: Scalars['String'];
}; };
export type ViewSortCreateNestedManyWithoutViewInput = {
connect?: InputMaybe<Array<ViewSortWhereUniqueInput>>;
};
export enum ViewSortDirection { export enum ViewSortDirection {
Asc = 'asc', Asc = 'asc',
Desc = 'desc' Desc = 'desc'
@ -3380,6 +3414,13 @@ export type GetUsersQueryVariables = Exact<{ [key: string]: never; }>;
export type GetUsersQuery = { __typename?: 'Query', findManyUser: Array<{ __typename?: 'User', id: string, email: string, displayName: string, firstName?: string | null, lastName?: string | null }> }; export type GetUsersQuery = { __typename?: 'Query', findManyUser: Array<{ __typename?: 'User', id: string, email: string, displayName: string, firstName?: string | null, lastName?: string | null }> };
export type CreateViewMutationVariables = Exact<{
data: ViewCreateInput;
}>;
export type CreateViewMutation = { __typename?: 'Mutation', view: { __typename?: 'View', id: string, name: string } };
export type CreateViewFieldsMutationVariables = Exact<{ export type CreateViewFieldsMutationVariables = Exact<{
data: Array<ViewFieldCreateManyInput> | ViewFieldCreateManyInput; data: Array<ViewFieldCreateManyInput> | ViewFieldCreateManyInput;
}>; }>;
@ -3401,12 +3442,12 @@ export type CreateViewSortsMutationVariables = Exact<{
export type CreateViewSortsMutation = { __typename?: 'Mutation', createManyViewSort: { __typename?: 'AffectedRows', count: number } }; export type CreateViewSortsMutation = { __typename?: 'Mutation', createManyViewSort: { __typename?: 'AffectedRows', count: number } };
export type CreateViewsMutationVariables = Exact<{ export type DeleteViewMutationVariables = Exact<{
data: Array<ViewCreateManyInput> | ViewCreateManyInput; where: ViewWhereUniqueInput;
}>; }>;
export type CreateViewsMutation = { __typename?: 'Mutation', createManyView: { __typename?: 'AffectedRows', count: number } }; export type DeleteViewMutation = { __typename?: 'Mutation', view: { __typename?: 'View', id: string, name: string } };
export type DeleteViewFiltersMutationVariables = Exact<{ export type DeleteViewFiltersMutationVariables = Exact<{
where: ViewFilterWhereInput; where: ViewFilterWhereInput;
@ -3422,20 +3463,13 @@ export type DeleteViewSortsMutationVariables = Exact<{
export type DeleteViewSortsMutation = { __typename?: 'Mutation', deleteManyViewSort: { __typename?: 'AffectedRows', count: number } }; export type DeleteViewSortsMutation = { __typename?: 'Mutation', deleteManyViewSort: { __typename?: 'AffectedRows', count: number } };
export type DeleteViewsMutationVariables = Exact<{
where: ViewWhereInput;
}>;
export type DeleteViewsMutation = { __typename?: 'Mutation', deleteManyView: { __typename?: 'AffectedRows', count: number } };
export type UpdateViewMutationVariables = Exact<{ export type UpdateViewMutationVariables = Exact<{
data: ViewUpdateInput; data: ViewUpdateInput;
where: ViewWhereUniqueInput; where: ViewWhereUniqueInput;
}>; }>;
export type UpdateViewMutation = { __typename?: 'Mutation', updateOneView: { __typename?: 'View', id: string, name: string } }; export type UpdateViewMutation = { __typename?: 'Mutation', view: { __typename?: 'View', id: string, name: string } };
export type UpdateViewFieldMutationVariables = Exact<{ export type UpdateViewFieldMutationVariables = Exact<{
data: ViewFieldUpdateInput; data: ViewFieldUpdateInput;
@ -6108,6 +6142,40 @@ export function useGetUsersLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<G
export type GetUsersQueryHookResult = ReturnType<typeof useGetUsersQuery>; export type GetUsersQueryHookResult = ReturnType<typeof useGetUsersQuery>;
export type GetUsersLazyQueryHookResult = ReturnType<typeof useGetUsersLazyQuery>; export type GetUsersLazyQueryHookResult = ReturnType<typeof useGetUsersLazyQuery>;
export type GetUsersQueryResult = Apollo.QueryResult<GetUsersQuery, GetUsersQueryVariables>; export type GetUsersQueryResult = Apollo.QueryResult<GetUsersQuery, GetUsersQueryVariables>;
export const CreateViewDocument = gql`
mutation CreateView($data: ViewCreateInput!) {
view: createOneView(data: $data) {
id
name
}
}
`;
export type CreateViewMutationFn = Apollo.MutationFunction<CreateViewMutation, CreateViewMutationVariables>;
/**
* __useCreateViewMutation__
*
* To run a mutation, you first call `useCreateViewMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useCreateViewMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [createViewMutation, { data, loading, error }] = useCreateViewMutation({
* variables: {
* data: // value for 'data'
* },
* });
*/
export function useCreateViewMutation(baseOptions?: Apollo.MutationHookOptions<CreateViewMutation, CreateViewMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<CreateViewMutation, CreateViewMutationVariables>(CreateViewDocument, options);
}
export type CreateViewMutationHookResult = ReturnType<typeof useCreateViewMutation>;
export type CreateViewMutationResult = Apollo.MutationResult<CreateViewMutation>;
export type CreateViewMutationOptions = Apollo.BaseMutationOptions<CreateViewMutation, CreateViewMutationVariables>;
export const CreateViewFieldsDocument = gql` export const CreateViewFieldsDocument = gql`
mutation CreateViewFields($data: [ViewFieldCreateManyInput!]!) { mutation CreateViewFields($data: [ViewFieldCreateManyInput!]!) {
createManyViewField(data: $data) { createManyViewField(data: $data) {
@ -6207,39 +6275,40 @@ export function useCreateViewSortsMutation(baseOptions?: Apollo.MutationHookOpti
export type CreateViewSortsMutationHookResult = ReturnType<typeof useCreateViewSortsMutation>; export type CreateViewSortsMutationHookResult = ReturnType<typeof useCreateViewSortsMutation>;
export type CreateViewSortsMutationResult = Apollo.MutationResult<CreateViewSortsMutation>; export type CreateViewSortsMutationResult = Apollo.MutationResult<CreateViewSortsMutation>;
export type CreateViewSortsMutationOptions = Apollo.BaseMutationOptions<CreateViewSortsMutation, CreateViewSortsMutationVariables>; export type CreateViewSortsMutationOptions = Apollo.BaseMutationOptions<CreateViewSortsMutation, CreateViewSortsMutationVariables>;
export const CreateViewsDocument = gql` export const DeleteViewDocument = gql`
mutation CreateViews($data: [ViewCreateManyInput!]!) { mutation DeleteView($where: ViewWhereUniqueInput!) {
createManyView(data: $data) { view: deleteOneView(where: $where) {
count id
name
} }
} }
`; `;
export type CreateViewsMutationFn = Apollo.MutationFunction<CreateViewsMutation, CreateViewsMutationVariables>; export type DeleteViewMutationFn = Apollo.MutationFunction<DeleteViewMutation, DeleteViewMutationVariables>;
/** /**
* __useCreateViewsMutation__ * __useDeleteViewMutation__
* *
* To run a mutation, you first call `useCreateViewsMutation` within a React component and pass it any options that fit your needs. * To run a mutation, you first call `useDeleteViewMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useCreateViewsMutation` returns a tuple that includes: * When your component renders, `useDeleteViewMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation * - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution * - An object with fields that represent the current status of the mutation's execution
* *
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2; * @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
* *
* @example * @example
* const [createViewsMutation, { data, loading, error }] = useCreateViewsMutation({ * const [deleteViewMutation, { data, loading, error }] = useDeleteViewMutation({
* variables: { * variables: {
* data: // value for 'data' * where: // value for 'where'
* }, * },
* }); * });
*/ */
export function useCreateViewsMutation(baseOptions?: Apollo.MutationHookOptions<CreateViewsMutation, CreateViewsMutationVariables>) { export function useDeleteViewMutation(baseOptions?: Apollo.MutationHookOptions<DeleteViewMutation, DeleteViewMutationVariables>) {
const options = {...defaultOptions, ...baseOptions} const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<CreateViewsMutation, CreateViewsMutationVariables>(CreateViewsDocument, options); return Apollo.useMutation<DeleteViewMutation, DeleteViewMutationVariables>(DeleteViewDocument, options);
} }
export type CreateViewsMutationHookResult = ReturnType<typeof useCreateViewsMutation>; export type DeleteViewMutationHookResult = ReturnType<typeof useDeleteViewMutation>;
export type CreateViewsMutationResult = Apollo.MutationResult<CreateViewsMutation>; export type DeleteViewMutationResult = Apollo.MutationResult<DeleteViewMutation>;
export type CreateViewsMutationOptions = Apollo.BaseMutationOptions<CreateViewsMutation, CreateViewsMutationVariables>; export type DeleteViewMutationOptions = Apollo.BaseMutationOptions<DeleteViewMutation, DeleteViewMutationVariables>;
export const DeleteViewFiltersDocument = gql` export const DeleteViewFiltersDocument = gql`
mutation DeleteViewFilters($where: ViewFilterWhereInput!) { mutation DeleteViewFilters($where: ViewFilterWhereInput!) {
deleteManyViewFilter(where: $where) { deleteManyViewFilter(where: $where) {
@ -6306,42 +6375,9 @@ export function useDeleteViewSortsMutation(baseOptions?: Apollo.MutationHookOpti
export type DeleteViewSortsMutationHookResult = ReturnType<typeof useDeleteViewSortsMutation>; export type DeleteViewSortsMutationHookResult = ReturnType<typeof useDeleteViewSortsMutation>;
export type DeleteViewSortsMutationResult = Apollo.MutationResult<DeleteViewSortsMutation>; export type DeleteViewSortsMutationResult = Apollo.MutationResult<DeleteViewSortsMutation>;
export type DeleteViewSortsMutationOptions = Apollo.BaseMutationOptions<DeleteViewSortsMutation, DeleteViewSortsMutationVariables>; export type DeleteViewSortsMutationOptions = Apollo.BaseMutationOptions<DeleteViewSortsMutation, DeleteViewSortsMutationVariables>;
export const DeleteViewsDocument = gql`
mutation DeleteViews($where: ViewWhereInput!) {
deleteManyView(where: $where) {
count
}
}
`;
export type DeleteViewsMutationFn = Apollo.MutationFunction<DeleteViewsMutation, DeleteViewsMutationVariables>;
/**
* __useDeleteViewsMutation__
*
* To run a mutation, you first call `useDeleteViewsMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useDeleteViewsMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [deleteViewsMutation, { data, loading, error }] = useDeleteViewsMutation({
* variables: {
* where: // value for 'where'
* },
* });
*/
export function useDeleteViewsMutation(baseOptions?: Apollo.MutationHookOptions<DeleteViewsMutation, DeleteViewsMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<DeleteViewsMutation, DeleteViewsMutationVariables>(DeleteViewsDocument, options);
}
export type DeleteViewsMutationHookResult = ReturnType<typeof useDeleteViewsMutation>;
export type DeleteViewsMutationResult = Apollo.MutationResult<DeleteViewsMutation>;
export type DeleteViewsMutationOptions = Apollo.BaseMutationOptions<DeleteViewsMutation, DeleteViewsMutationVariables>;
export const UpdateViewDocument = gql` export const UpdateViewDocument = gql`
mutation UpdateView($data: ViewUpdateInput!, $where: ViewWhereUniqueInput!) { mutation UpdateView($data: ViewUpdateInput!, $where: ViewWhereUniqueInput!) {
updateOneView(data: $data, where: $where) { view: updateOneView(data: $data, where: $where) {
id id
name name
} }

View File

@ -0,0 +1,10 @@
import { gql } from '@apollo/client';
export const CREATE_VIEW = gql`
mutation CreateView($data: ViewCreateInput!) {
view: createOneView(data: $data) {
id
name
}
}
`;

View File

@ -1,9 +0,0 @@
import { gql } from '@apollo/client';
export const CREATE_VIEWS = gql`
mutation CreateViews($data: [ViewCreateManyInput!]!) {
createManyView(data: $data) {
count
}
}
`;

View File

@ -0,0 +1,10 @@
import { gql } from '@apollo/client';
export const DELETE_VIEW = gql`
mutation DeleteView($where: ViewWhereUniqueInput!) {
view: deleteOneView(where: $where) {
id
name
}
}
`;

View File

@ -1,9 +0,0 @@
import { gql } from '@apollo/client';
export const DELETE_VIEWS = gql`
mutation DeleteViews($where: ViewWhereInput!) {
deleteManyView(where: $where) {
count
}
}
`;

View File

@ -2,7 +2,7 @@ import { gql } from '@apollo/client';
export const UPDATE_VIEW = gql` export const UPDATE_VIEW = gql`
mutation UpdateView($data: ViewUpdateInput!, $where: ViewWhereUniqueInput!) { mutation UpdateView($data: ViewUpdateInput!, $where: ViewWhereUniqueInput!) {
updateOneView(data: $data, where: $where) { view: updateOneView(data: $data, where: $where) {
id id
name name
} }

View File

@ -10,8 +10,8 @@ import {
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState'; import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue'; import { useRecoilScopedValue } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedValue';
import { import {
useCreateViewsMutation, useCreateViewMutation,
useDeleteViewsMutation, useDeleteViewMutation,
useGetViewsQuery, useGetViewsQuery,
useUpdateViewMutation, useUpdateViewMutation,
ViewType, ViewType,
@ -38,60 +38,42 @@ export const useViews = ({
TableRecoilScopeContext, TableRecoilScopeContext,
); );
const [createViewsMutation] = useCreateViewsMutation(); const [createViewMutation] = useCreateViewMutation();
const [updateViewMutation] = useUpdateViewMutation(); const [updateViewMutation] = useUpdateViewMutation();
const [deleteViewsMutation] = useDeleteViewsMutation(); const [deleteViewMutation] = useDeleteViewMutation();
const createViews = useCallback( const createView = useCallback(
async (views: TableView[]) => { async (view: TableView) => {
if (!views.length) return; const { data } = await createViewMutation({
await createViewsMutation({
variables: { variables: {
data: views.map((view) => ({ data: {
...view, ...view,
objectId, objectId,
type: ViewType.Table, type: ViewType.Table,
})),
},
});
await Promise.all(views.map((view) => onViewCreate(view.id)));
},
[createViewsMutation, objectId, onViewCreate],
);
const updateViews = useCallback(
(views: TableView[]) => {
if (!views.length) return;
return Promise.all(
views.map((view) =>
updateViewMutation({
variables: {
data: { name: view.name },
where: { id: view.id },
},
}),
),
);
},
[updateViewMutation],
);
const deleteViews = useCallback(
(viewIds: string[]) => {
if (!viewIds.length) return;
return deleteViewsMutation({
variables: {
where: {
id: { in: viewIds },
}, },
}, },
}); });
if (data?.view) await onViewCreate(data.view.id);
}, },
[deleteViewsMutation], [createViewMutation, objectId, onViewCreate],
);
const updateView = useCallback(
(view: TableView) =>
updateViewMutation({
variables: {
data: { name: view.name },
where: { id: view.id },
},
}),
[updateViewMutation],
);
const deleteView = useCallback(
(viewId: string) =>
deleteViewMutation({ variables: { where: { id: viewId } } }),
[deleteViewMutation],
); );
const { refetch } = useGetViewsQuery({ const { refetch } = useGetViewsQuery({
@ -114,27 +96,33 @@ export const useViews = ({
const handleViewsChange = useCallback( const handleViewsChange = useCallback(
async (nextViews: TableView[]) => { async (nextViews: TableView[]) => {
const viewsToCreate = nextViews.filter( const viewToCreate = nextViews.find(
(nextView) => !viewsById[nextView.id], (nextView) => !viewsById[nextView.id],
); );
await createViews(viewsToCreate); if (viewToCreate) {
await createView(viewToCreate);
return refetch();
}
const viewsToUpdate = nextViews.filter( const viewToUpdate = nextViews.find(
(nextView) => (nextView) =>
viewsById[nextView.id] && viewsById[nextView.id] &&
viewsById[nextView.id].name !== nextView.name, viewsById[nextView.id].name !== nextView.name,
); );
await updateViews(viewsToUpdate); if (viewToUpdate) {
await updateView(viewToUpdate);
return refetch();
}
const nextViewIds = nextViews.map((nextView) => nextView.id); const nextViewIds = nextViews.map((nextView) => nextView.id);
const viewIdsToDelete = Object.keys(viewsById).filter( const viewIdToDelete = Object.keys(viewsById).find(
(previousViewId) => !nextViewIds.includes(previousViewId), (previousViewId) => !nextViewIds.includes(previousViewId),
); );
await deleteViews(viewIdsToDelete); if (viewIdToDelete) await deleteView(viewIdToDelete);
return refetch(); return refetch();
}, },
[createViews, deleteViews, refetch, updateViews, viewsById], [createView, deleteView, refetch, updateView, viewsById],
); );
return { handleViewsChange }; return { handleViewsChange };

View File

@ -1,6 +1,7 @@
import { import {
BadRequestException, BadRequestException,
ForbiddenException, ForbiddenException,
NotFoundException,
UseGuards, UseGuards,
} from '@nestjs/common'; } from '@nestjs/common';
import { Args, Mutation, Query, Resolver } from '@nestjs/graphql'; import { Args, Mutation, Query, Resolver } from '@nestjs/graphql';
@ -15,9 +16,16 @@ import {
ReadViewAbilityHandler, ReadViewAbilityHandler,
UpdateViewAbilityHandler, UpdateViewAbilityHandler,
} from 'src/ability/handlers/view.ability-handler'; } from 'src/ability/handlers/view.ability-handler';
import { AffectedRows } from 'src/core/@generated/prisma/affected-rows.output';
import { CreateManyViewArgs } from 'src/core/@generated/view/create-many-view.args';
import { CreateOneViewArgs } from 'src/core/@generated/view/create-one-view.args';
import { DeleteManyViewArgs } from 'src/core/@generated/view/delete-many-view.args';
import { DeleteOneViewArgs } from 'src/core/@generated/view/delete-one-view.args';
import { FindManyViewArgs } from 'src/core/@generated/view/find-many-view.args'; import { FindManyViewArgs } from 'src/core/@generated/view/find-many-view.args';
import { UpdateOneViewArgs } from 'src/core/@generated/view/update-one-view.args';
import { View } from 'src/core/@generated/view/view.model'; import { View } from 'src/core/@generated/view/view.model';
import { ViewService } from 'src/core/view/services/view.service'; import { ViewService } from 'src/core/view/services/view.service';
import { AuthWorkspace } from 'src/decorators/auth-workspace.decorator';
import { CheckAbilities } from 'src/decorators/check-abilities.decorator'; import { CheckAbilities } from 'src/decorators/check-abilities.decorator';
import { import {
PrismaSelect, PrismaSelect,
@ -26,17 +34,32 @@ import {
import { UserAbility } from 'src/decorators/user-ability.decorator'; import { UserAbility } from 'src/decorators/user-ability.decorator';
import { AbilityGuard } from 'src/guards/ability.guard'; import { AbilityGuard } from 'src/guards/ability.guard';
import { JwtAuthGuard } from 'src/guards/jwt.auth.guard'; import { JwtAuthGuard } from 'src/guards/jwt.auth.guard';
import { UpdateOneViewArgs } from 'src/core/@generated/view/update-one-view.args';
import { AuthWorkspace } from 'src/decorators/auth-workspace.decorator';
import { AffectedRows } from 'src/core/@generated/prisma/affected-rows.output';
import { CreateManyViewArgs } from 'src/core/@generated/view/create-many-view.args';
import { DeleteManyViewArgs } from 'src/core/@generated/view/delete-many-view.args';
@UseGuards(JwtAuthGuard) @UseGuards(JwtAuthGuard)
@Resolver(() => View) @Resolver(() => View)
export class ViewResolver { export class ViewResolver {
constructor(private readonly viewService: ViewService) {} constructor(private readonly viewService: ViewService) {}
@Mutation(() => View, {
nullable: false,
})
@UseGuards(AbilityGuard)
@CheckAbilities(CreateViewAbilityHandler)
async createOneView(
@Args() args: CreateOneViewArgs,
@AuthWorkspace() workspace: Workspace,
@PrismaSelector({ modelName: 'View' })
prismaSelect: PrismaSelect<'View'>,
): Promise<Partial<View>> {
return this.viewService.create({
data: {
...args.data,
workspace: { connect: { id: workspace.id } },
},
select: prismaSelect.value,
} as Prisma.ViewCreateArgs);
}
@Mutation(() => AffectedRows) @Mutation(() => AffectedRows)
@UseGuards(AbilityGuard) @UseGuards(AbilityGuard)
@CheckAbilities(CreateViewAbilityHandler) @CheckAbilities(CreateViewAbilityHandler)
@ -91,6 +114,43 @@ export class ViewResolver {
} as Prisma.ViewUpdateArgs); } as Prisma.ViewUpdateArgs);
} }
@Mutation(() => View, {
nullable: false,
})
@UseGuards(AbilityGuard)
@CheckAbilities(DeleteViewAbilityHandler)
async deleteOneView(
@Args() args: DeleteOneViewArgs,
@AuthWorkspace() workspace: Workspace,
): Promise<View> {
const viewToDelete = await this.viewService.findUnique({
where: args.where,
});
if (!viewToDelete) {
throw new NotFoundException();
}
const { objectId } = viewToDelete;
const viewsNb = await this.viewService.count({
where: {
objectId: { equals: objectId },
workspaceId: { equals: workspace.id },
},
});
if (viewsNb <= 1) {
throw new ForbiddenException(
`Deleting last '${objectId}' view is not allowed`,
);
}
return this.viewService.delete({
where: args.where,
});
}
@Mutation(() => AffectedRows, { @Mutation(() => AffectedRows, {
nullable: false, nullable: false,
}) })