feat: disallow removing all comment thread targets (#779)

* feat: disallow removing all comment thread targets

Closes #431

* Rename variables

* Fix console error

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Thaïs
2023-07-21 01:17:43 +02:00
committed by GitHub
parent 872ec9e6bb
commit a2087da624
6 changed files with 174 additions and 155 deletions

View File

@ -1915,24 +1915,21 @@ export type GetCommentThreadQueryVariables = Exact<{
export type GetCommentThreadQuery = { __typename?: 'Query', findManyCommentThreads: Array<{ __typename?: 'CommentThread', id: string, createdAt: string, body?: string | null, title?: string | null, type: ActivityType, author: { __typename?: 'User', id: string, firstName?: string | null, lastName?: string | null, displayName: string }, comments?: Array<{ __typename?: 'Comment', id: string, body: string, createdAt: string, updatedAt: string, author: { __typename?: 'User', id: string, displayName: string, firstName?: string | null, lastName?: string | null, avatarUrl?: string | null } }> | null, commentThreadTargets?: Array<{ __typename?: 'CommentThreadTarget', id: string, commentableId: string, commentableType: CommentableType }> | null }> };
export type AddCommentThreadTargetOnCommentThreadMutationVariables = Exact<{
export type AddCommentThreadTargetsOnCommentThreadMutationVariables = Exact<{
commentThreadId: Scalars['String'];
commentThreadTargetCreationDate: Scalars['DateTime'];
commentThreadTargetId: Scalars['String'];
commentableEntityId: Scalars['String'];
commentableEntityType: CommentableType;
commentThreadTargetInputs: Array<CommentThreadTargetCreateManyCommentThreadInput> | CommentThreadTargetCreateManyCommentThreadInput;
}>;
export type AddCommentThreadTargetOnCommentThreadMutation = { __typename?: 'Mutation', updateOneCommentThread: { __typename?: 'CommentThread', id: string, createdAt: string, updatedAt: string, commentThreadTargets?: Array<{ __typename?: 'CommentThreadTarget', id: string, createdAt: string, updatedAt: string, commentableType: CommentableType, commentableId: string }> | null } };
export type AddCommentThreadTargetsOnCommentThreadMutation = { __typename?: 'Mutation', updateOneCommentThread: { __typename?: 'CommentThread', id: string, createdAt: string, updatedAt: string, commentThreadTargets?: Array<{ __typename?: 'CommentThreadTarget', id: string, createdAt: string, updatedAt: string, commentableType: CommentableType, commentableId: string }> | null } };
export type RemoveCommentThreadTargetOnCommentThreadMutationVariables = Exact<{
export type RemoveCommentThreadTargetsOnCommentThreadMutationVariables = Exact<{
commentThreadId: Scalars['String'];
commentThreadTargetId: Scalars['String'];
commentThreadTargetIds: Array<Scalars['String']> | Scalars['String'];
}>;
export type RemoveCommentThreadTargetOnCommentThreadMutation = { __typename?: 'Mutation', updateOneCommentThread: { __typename?: 'CommentThread', id: string, createdAt: string, updatedAt: string, commentThreadTargets?: Array<{ __typename?: 'CommentThreadTarget', id: string, createdAt: string, updatedAt: string, commentableType: CommentableType, commentableId: string }> | null } };
export type RemoveCommentThreadTargetsOnCommentThreadMutation = { __typename?: 'Mutation', updateOneCommentThread: { __typename?: 'CommentThread', id: string, createdAt: string, updatedAt: string, commentThreadTargets?: Array<{ __typename?: 'CommentThreadTarget', id: string, createdAt: string, updatedAt: string, commentableType: CommentableType, commentableId: string }> | null } };
export type DeleteCommentThreadMutationVariables = Exact<{
commentThreadId: Scalars['String'];
@ -2531,11 +2528,11 @@ export function useGetCommentThreadLazyQuery(baseOptions?: Apollo.LazyQueryHookO
export type GetCommentThreadQueryHookResult = ReturnType<typeof useGetCommentThreadQuery>;
export type GetCommentThreadLazyQueryHookResult = ReturnType<typeof useGetCommentThreadLazyQuery>;
export type GetCommentThreadQueryResult = Apollo.QueryResult<GetCommentThreadQuery, GetCommentThreadQueryVariables>;
export const AddCommentThreadTargetOnCommentThreadDocument = gql`
mutation AddCommentThreadTargetOnCommentThread($commentThreadId: String!, $commentThreadTargetCreationDate: DateTime!, $commentThreadTargetId: String!, $commentableEntityId: String!, $commentableEntityType: CommentableType!) {
export const AddCommentThreadTargetsOnCommentThreadDocument = gql`
mutation AddCommentThreadTargetsOnCommentThread($commentThreadId: String!, $commentThreadTargetInputs: [CommentThreadTargetCreateManyCommentThreadInput!]!) {
updateOneCommentThread(
where: {id: $commentThreadId}
data: {commentThreadTargets: {connectOrCreate: {create: {id: $commentThreadTargetId, createdAt: $commentThreadTargetCreationDate, commentableType: $commentableEntityType, commentableId: $commentableEntityId}, where: {id: $commentThreadTargetId}}}}
data: {commentThreadTargets: {createMany: {data: $commentThreadTargetInputs}}}
) {
id
createdAt
@ -2550,41 +2547,38 @@ export const AddCommentThreadTargetOnCommentThreadDocument = gql`
}
}
`;
export type AddCommentThreadTargetOnCommentThreadMutationFn = Apollo.MutationFunction<AddCommentThreadTargetOnCommentThreadMutation, AddCommentThreadTargetOnCommentThreadMutationVariables>;
export type AddCommentThreadTargetsOnCommentThreadMutationFn = Apollo.MutationFunction<AddCommentThreadTargetsOnCommentThreadMutation, AddCommentThreadTargetsOnCommentThreadMutationVariables>;
/**
* __useAddCommentThreadTargetOnCommentThreadMutation__
* __useAddCommentThreadTargetsOnCommentThreadMutation__
*
* To run a mutation, you first call `useAddCommentThreadTargetOnCommentThreadMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useAddCommentThreadTargetOnCommentThreadMutation` returns a tuple that includes:
* To run a mutation, you first call `useAddCommentThreadTargetsOnCommentThreadMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useAddCommentThreadTargetsOnCommentThreadMutation` 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 [addCommentThreadTargetOnCommentThreadMutation, { data, loading, error }] = useAddCommentThreadTargetOnCommentThreadMutation({
* const [addCommentThreadTargetsOnCommentThreadMutation, { data, loading, error }] = useAddCommentThreadTargetsOnCommentThreadMutation({
* variables: {
* commentThreadId: // value for 'commentThreadId'
* commentThreadTargetCreationDate: // value for 'commentThreadTargetCreationDate'
* commentThreadTargetId: // value for 'commentThreadTargetId'
* commentableEntityId: // value for 'commentableEntityId'
* commentableEntityType: // value for 'commentableEntityType'
* commentThreadTargetInputs: // value for 'commentThreadTargetInputs'
* },
* });
*/
export function useAddCommentThreadTargetOnCommentThreadMutation(baseOptions?: Apollo.MutationHookOptions<AddCommentThreadTargetOnCommentThreadMutation, AddCommentThreadTargetOnCommentThreadMutationVariables>) {
export function useAddCommentThreadTargetsOnCommentThreadMutation(baseOptions?: Apollo.MutationHookOptions<AddCommentThreadTargetsOnCommentThreadMutation, AddCommentThreadTargetsOnCommentThreadMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<AddCommentThreadTargetOnCommentThreadMutation, AddCommentThreadTargetOnCommentThreadMutationVariables>(AddCommentThreadTargetOnCommentThreadDocument, options);
return Apollo.useMutation<AddCommentThreadTargetsOnCommentThreadMutation, AddCommentThreadTargetsOnCommentThreadMutationVariables>(AddCommentThreadTargetsOnCommentThreadDocument, options);
}
export type AddCommentThreadTargetOnCommentThreadMutationHookResult = ReturnType<typeof useAddCommentThreadTargetOnCommentThreadMutation>;
export type AddCommentThreadTargetOnCommentThreadMutationResult = Apollo.MutationResult<AddCommentThreadTargetOnCommentThreadMutation>;
export type AddCommentThreadTargetOnCommentThreadMutationOptions = Apollo.BaseMutationOptions<AddCommentThreadTargetOnCommentThreadMutation, AddCommentThreadTargetOnCommentThreadMutationVariables>;
export const RemoveCommentThreadTargetOnCommentThreadDocument = gql`
mutation RemoveCommentThreadTargetOnCommentThread($commentThreadId: String!, $commentThreadTargetId: String!) {
export type AddCommentThreadTargetsOnCommentThreadMutationHookResult = ReturnType<typeof useAddCommentThreadTargetsOnCommentThreadMutation>;
export type AddCommentThreadTargetsOnCommentThreadMutationResult = Apollo.MutationResult<AddCommentThreadTargetsOnCommentThreadMutation>;
export type AddCommentThreadTargetsOnCommentThreadMutationOptions = Apollo.BaseMutationOptions<AddCommentThreadTargetsOnCommentThreadMutation, AddCommentThreadTargetsOnCommentThreadMutationVariables>;
export const RemoveCommentThreadTargetsOnCommentThreadDocument = gql`
mutation RemoveCommentThreadTargetsOnCommentThread($commentThreadId: String!, $commentThreadTargetIds: [String!]!) {
updateOneCommentThread(
where: {id: $commentThreadId}
data: {commentThreadTargets: {delete: {id: $commentThreadTargetId}}}
data: {commentThreadTargets: {deleteMany: {id: {in: $commentThreadTargetIds}}}}
) {
id
createdAt
@ -2599,33 +2593,33 @@ export const RemoveCommentThreadTargetOnCommentThreadDocument = gql`
}
}
`;
export type RemoveCommentThreadTargetOnCommentThreadMutationFn = Apollo.MutationFunction<RemoveCommentThreadTargetOnCommentThreadMutation, RemoveCommentThreadTargetOnCommentThreadMutationVariables>;
export type RemoveCommentThreadTargetsOnCommentThreadMutationFn = Apollo.MutationFunction<RemoveCommentThreadTargetsOnCommentThreadMutation, RemoveCommentThreadTargetsOnCommentThreadMutationVariables>;
/**
* __useRemoveCommentThreadTargetOnCommentThreadMutation__
* __useRemoveCommentThreadTargetsOnCommentThreadMutation__
*
* To run a mutation, you first call `useRemoveCommentThreadTargetOnCommentThreadMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useRemoveCommentThreadTargetOnCommentThreadMutation` returns a tuple that includes:
* To run a mutation, you first call `useRemoveCommentThreadTargetsOnCommentThreadMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useRemoveCommentThreadTargetsOnCommentThreadMutation` 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 [removeCommentThreadTargetOnCommentThreadMutation, { data, loading, error }] = useRemoveCommentThreadTargetOnCommentThreadMutation({
* const [removeCommentThreadTargetsOnCommentThreadMutation, { data, loading, error }] = useRemoveCommentThreadTargetsOnCommentThreadMutation({
* variables: {
* commentThreadId: // value for 'commentThreadId'
* commentThreadTargetId: // value for 'commentThreadTargetId'
* commentThreadTargetIds: // value for 'commentThreadTargetIds'
* },
* });
*/
export function useRemoveCommentThreadTargetOnCommentThreadMutation(baseOptions?: Apollo.MutationHookOptions<RemoveCommentThreadTargetOnCommentThreadMutation, RemoveCommentThreadTargetOnCommentThreadMutationVariables>) {
export function useRemoveCommentThreadTargetsOnCommentThreadMutation(baseOptions?: Apollo.MutationHookOptions<RemoveCommentThreadTargetsOnCommentThreadMutation, RemoveCommentThreadTargetsOnCommentThreadMutationVariables>) {
const options = {...defaultOptions, ...baseOptions}
return Apollo.useMutation<RemoveCommentThreadTargetOnCommentThreadMutation, RemoveCommentThreadTargetOnCommentThreadMutationVariables>(RemoveCommentThreadTargetOnCommentThreadDocument, options);
return Apollo.useMutation<RemoveCommentThreadTargetsOnCommentThreadMutation, RemoveCommentThreadTargetsOnCommentThreadMutationVariables>(RemoveCommentThreadTargetsOnCommentThreadDocument, options);
}
export type RemoveCommentThreadTargetOnCommentThreadMutationHookResult = ReturnType<typeof useRemoveCommentThreadTargetOnCommentThreadMutation>;
export type RemoveCommentThreadTargetOnCommentThreadMutationResult = Apollo.MutationResult<RemoveCommentThreadTargetOnCommentThreadMutation>;
export type RemoveCommentThreadTargetOnCommentThreadMutationOptions = Apollo.BaseMutationOptions<RemoveCommentThreadTargetOnCommentThreadMutation, RemoveCommentThreadTargetOnCommentThreadMutationVariables>;
export type RemoveCommentThreadTargetsOnCommentThreadMutationHookResult = ReturnType<typeof useRemoveCommentThreadTargetsOnCommentThreadMutation>;
export type RemoveCommentThreadTargetsOnCommentThreadMutationResult = Apollo.MutationResult<RemoveCommentThreadTargetsOnCommentThreadMutation>;
export type RemoveCommentThreadTargetsOnCommentThreadMutationOptions = Apollo.BaseMutationOptions<RemoveCommentThreadTargetsOnCommentThreadMutation, RemoveCommentThreadTargetsOnCommentThreadMutationVariables>;
export const DeleteCommentThreadDocument = gql`
mutation DeleteCommentThread($commentThreadId: String!) {
deleteManyCommentThreads(where: {id: {equals: $commentThreadId}}) {

View File

@ -1,4 +1,4 @@
import { useState } from 'react';
import { useCallback, useMemo, useState } from 'react';
import styled from '@emotion/styled';
import {
autoUpdate,
@ -78,56 +78,98 @@ const StyledMenuWrapper = styled.div`
export function CommentThreadRelationPicker({ commentThread }: OwnProps) {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [searchFilter, setSearchFilter] = useState('');
const peopleIds =
commentThread?.commentThreadTargets
?.filter((relation) => relation.commentableType === 'Person')
.map((relation) => relation.commentableId) ?? [];
const companyIds =
commentThread?.commentThreadTargets
?.filter((relation) => relation.commentableType === 'Company')
.map((relation) => relation.commentableId) ?? [];
const personsForMultiSelect = useFilteredSearchPeopleQuery({
searchFilter,
selectedIds: peopleIds,
});
const companiesForMultiSelect = useFilteredSearchCompanyQuery({
searchFilter,
selectedIds: companyIds,
});
const [selectedEntityIds, setSelectedEntityIds] = useState<
Record<string, boolean>
>({});
const {
setHotkeyScopeAndMemorizePreviousScope,
goBackToPreviousHotkeyScope,
} = usePreviousHotkeyScope();
function handleRelationContainerClick() {
const initialPeopleIds = useMemo(
() =>
commentThread?.commentThreadTargets
?.filter((relation) => relation.commentableType === 'Person')
.map((relation) => relation.commentableId) ?? [],
[commentThread?.commentThreadTargets],
);
const initialCompanyIds = useMemo(
() =>
commentThread?.commentThreadTargets
?.filter((relation) => relation.commentableType === 'Company')
.map((relation) => relation.commentableId) ?? [],
[commentThread?.commentThreadTargets],
);
const initialSelectedEntityIds = useMemo(
() =>
[...initialPeopleIds, ...initialCompanyIds].reduce<
Record<string, boolean>
>((result, entityId) => ({ ...result, [entityId]: true }), {}),
[initialPeopleIds, initialCompanyIds],
);
const personsForMultiSelect = useFilteredSearchPeopleQuery({
searchFilter,
selectedIds: initialPeopleIds,
});
const companiesForMultiSelect = useFilteredSearchCompanyQuery({
searchFilter,
selectedIds: initialCompanyIds,
});
const selectedEntities = flatMapAndSortEntityForSelectArrayOfArrayByName([
personsForMultiSelect.selectedEntities,
companiesForMultiSelect.selectedEntities,
]);
const filteredSelectedEntities =
flatMapAndSortEntityForSelectArrayOfArrayByName([
personsForMultiSelect.filteredSelectedEntities,
companiesForMultiSelect.filteredSelectedEntities,
]);
const entitiesToSelect = flatMapAndSortEntityForSelectArrayOfArrayByName([
personsForMultiSelect.entitiesToSelect,
companiesForMultiSelect.entitiesToSelect,
]);
const handleCheckItemsChange = useHandleCheckableCommentThreadTargetChange({
commentThread,
});
const exitEditMode = useCallback(() => {
goBackToPreviousHotkeyScope();
setIsMenuOpen(false);
setSearchFilter('');
if (Object.values(selectedEntityIds).some((value) => !!value)) {
handleCheckItemsChange(selectedEntityIds, entitiesToSelect);
}
}, [
entitiesToSelect,
selectedEntityIds,
goBackToPreviousHotkeyScope,
handleCheckItemsChange,
]);
const handleRelationContainerClick = useCallback(() => {
if (isMenuOpen) {
exitEditMode();
} else {
setIsMenuOpen(true);
setSelectedEntityIds(initialSelectedEntityIds);
setHotkeyScopeAndMemorizePreviousScope(
RelationPickerHotkeyScope.RelationPicker,
);
}
}
// TODO: Place in a scoped recoil atom family
function handleFilterChange(newSearchFilter: string) {
setSearchFilter(newSearchFilter);
}
const handleCheckItemChange = useHandleCheckableCommentThreadTargetChange({
commentThread,
});
function exitEditMode() {
goBackToPreviousHotkeyScope();
setIsMenuOpen(false);
setSearchFilter('');
}
}, [
initialSelectedEntityIds,
exitEditMode,
isMenuOpen,
setHotkeyScopeAndMemorizePreviousScope,
]);
useScopedHotkeys(
['esc', 'enter'],
@ -159,22 +201,6 @@ export function CommentThreadRelationPicker({ commentThread }: OwnProps) {
},
});
const selectedEntities = flatMapAndSortEntityForSelectArrayOfArrayByName([
personsForMultiSelect.selectedEntities,
companiesForMultiSelect.selectedEntities,
]);
const filteredSelectedEntities =
flatMapAndSortEntityForSelectArrayOfArrayByName([
personsForMultiSelect.filteredSelectedEntities,
companiesForMultiSelect.filteredSelectedEntities,
]);
const entitiesToSelect = flatMapAndSortEntityForSelectArrayOfArrayByName([
personsForMultiSelect.entitiesToSelect,
companiesForMultiSelect.entitiesToSelect,
]);
return (
<StyledContainer>
<StyledRelationContainer
@ -204,9 +230,10 @@ export function CommentThreadRelationPicker({ commentThread }: OwnProps) {
selectedEntities,
loading: false, // TODO implement skeleton loading
}}
onItemCheckChange={handleCheckItemChange}
onSearchFilterChange={handleFilterChange}
onChange={setSelectedEntityIds}
onSearchFilterChange={setSearchFilter}
searchFilter={searchFilter}
value={selectedEntityIds}
/>
</StyledMenuWrapper>
</RecoilScope>

View File

@ -6,8 +6,8 @@ import { GET_PEOPLE } from '@/people/queries';
import {
CommentThread,
CommentThreadTarget,
useAddCommentThreadTargetOnCommentThreadMutation,
useRemoveCommentThreadTargetOnCommentThreadMutation,
useAddCommentThreadTargetsOnCommentThreadMutation,
useRemoveCommentThreadTargetsOnCommentThreadMutation,
} from '~/generated/graphql';
import { GET_COMMENT_THREADS_BY_TARGETS } from '../queries';
@ -22,8 +22,8 @@ export function useHandleCheckableCommentThreadTargetChange({
>;
};
}) {
const [addCommentThreadTargetOnCommentThread] =
useAddCommentThreadTargetOnCommentThreadMutation({
const [addCommentThreadTargetsOnCommentThread] =
useAddCommentThreadTargetsOnCommentThreadMutation({
refetchQueries: [
getOperationName(GET_COMPANIES) ?? '',
getOperationName(GET_PEOPLE) ?? '',
@ -31,8 +31,8 @@ export function useHandleCheckableCommentThreadTargetChange({
],
});
const [removeCommentThreadTargetOnCommentThread] =
useRemoveCommentThreadTargetOnCommentThreadMutation({
const [removeCommentThreadTargetsOnCommentThread] =
useRemoveCommentThreadTargetsOnCommentThreadMutation({
refetchQueries: [
getOperationName(GET_COMPANIES) ?? '',
getOperationName(GET_PEOPLE) ?? '',
@ -40,36 +40,45 @@ export function useHandleCheckableCommentThreadTargetChange({
],
});
return function handleCheckItemChange(
newCheckedValue: boolean,
entity: CommentableEntityForSelect,
return async function handleCheckItemsChange(
entityValues: Record<string, boolean>,
entities: CommentableEntityForSelect[],
) {
if (!commentThread) {
return;
}
if (newCheckedValue) {
addCommentThreadTargetOnCommentThread({
const currentEntityIds = commentThread.commentThreadTargets.map(
({ commentableId }) => commentableId,
);
const entitiesToAdd = entities.filter(
({ id }) => entityValues[id] && !currentEntityIds.includes(id),
);
if (entitiesToAdd.length)
await addCommentThreadTargetsOnCommentThread({
variables: {
commentableEntityId: entity.id,
commentableEntityType: entity.entityType,
commentThreadId: commentThread.id,
commentThreadTargetCreationDate: new Date().toISOString(),
commentThreadTargetId: v4(),
commentThreadTargetInputs: entitiesToAdd.map((entity) => ({
id: v4(),
createdAt: new Date().toISOString(),
commentableType: entity.entityType,
commentableId: entity.id,
})),
},
});
} else {
const foundCorrespondingTarget = commentThread.commentThreadTargets?.find(
(target) => target.commentableId === entity.id,
);
if (foundCorrespondingTarget) {
removeCommentThreadTargetOnCommentThread({
variables: {
commentThreadId: commentThread.id,
commentThreadTargetId: foundCorrespondingTarget.id,
},
});
}
}
const commentThreadTargetIdsToDelete = commentThread.commentThreadTargets
.filter(({ commentableId }) => !entityValues[commentableId])
.map(({ id }) => id);
if (commentThreadTargetIdsToDelete.length)
await removeCommentThreadTargetsOnCommentThread({
variables: {
commentThreadId: commentThread.id,
commentThreadTargetIds: commentThreadTargetIdsToDelete,
},
});
};
}

View File

@ -1,26 +1,15 @@
import { gql } from '@apollo/client';
export const ADD_COMMENT_THREAD_TARGET = gql`
mutation AddCommentThreadTargetOnCommentThread(
export const ADD_COMMENT_THREAD_TARGETS = gql`
mutation AddCommentThreadTargetsOnCommentThread(
$commentThreadId: String!
$commentThreadTargetCreationDate: DateTime!
$commentThreadTargetId: String!
$commentableEntityId: String!
$commentableEntityType: CommentableType!
$commentThreadTargetInputs: [CommentThreadTargetCreateManyCommentThreadInput!]!
) {
updateOneCommentThread(
where: { id: $commentThreadId }
data: {
commentThreadTargets: {
connectOrCreate: {
create: {
id: $commentThreadTargetId
createdAt: $commentThreadTargetCreationDate
commentableType: $commentableEntityType
commentableId: $commentableEntityId
}
where: { id: $commentThreadTargetId }
}
createMany: { data: $commentThreadTargetInputs }
}
}
) {
@ -38,14 +27,18 @@ export const ADD_COMMENT_THREAD_TARGET = gql`
}
`;
export const REMOVE_COMMENT_THREAD_TARGET = gql`
mutation RemoveCommentThreadTargetOnCommentThread(
export const REMOVE_COMMENT_THREAD_TARGETS = gql`
mutation RemoveCommentThreadTargetsOnCommentThread(
$commentThreadId: String!
$commentThreadTargetId: String!
$commentThreadTargetIds: [String!]!
) {
updateOneCommentThread(
where: { id: $commentThreadId }
data: { commentThreadTargets: { delete: { id: $commentThreadTargetId } } }
data: {
commentThreadTargets: {
deleteMany: { id: { in: $commentThreadTargetIds } }
}
}
) {
id
createdAt

View File

@ -79,7 +79,8 @@ export function Checkbox({
indeterminate,
variant = CheckboxVariant.Primary,
}: OwnProps) {
const [isInternalChecked, setIsInternalChecked] = React.useState(false);
const [isInternalChecked, setIsInternalChecked] =
React.useState<boolean>(false);
React.useEffect(() => {
setIsInternalChecked(checked);

View File

@ -23,17 +23,16 @@ export function MultipleEntitySelect<
CustomEntityForSelect extends EntityForSelect,
>({
entities,
onItemCheckChange,
onChange,
onSearchFilterChange,
searchFilter,
value,
}: {
entities: EntitiesForMultipleEntitySelect<CustomEntityForSelect>;
searchFilter: string;
onSearchFilterChange: (newSearchFilter: string) => void;
onItemCheckChange: (
newCheckedValue: boolean,
entity: CustomEntityForSelect,
) => void;
onChange: (value: Record<string, boolean>) => void;
value: Record<string, boolean>;
}) {
const debouncedSetSearchFilter = debounce(onSearchFilterChange, 100, {
leading: true,
@ -61,13 +60,9 @@ export function MultipleEntitySelect<
{entitiesInDropdown?.map((entity) => (
<DropdownMenuCheckableItem
key={entity.id}
checked={
entities.selectedEntities
?.map((selectedEntity) => selectedEntity.id)
?.includes(entity.id) ?? false
}
checked={value[entity.id]}
onChange={(newCheckedValue) =>
onItemCheckChange(newCheckedValue, entity)
onChange({ ...value, [entity.id]: newCheckedValue })
}
>
<Avatar