Add dueDate and assignee on notes (#988)
* Add dueDate and assignee on notes * Fix tests * Fix tests
This commit is contained in:
@ -0,0 +1,79 @@
|
||||
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
||||
import { useRecoilScopedState } from '@/ui/recoil-scope/hooks/useRecoilScopedState';
|
||||
import { SingleEntitySelect } from '@/ui/relation-picker/components/SingleEntitySelect';
|
||||
import { relationPickerSearchFilterScopedState } from '@/ui/relation-picker/states/relationPickerSearchFilterScopedState';
|
||||
import { EntityForSelect } from '@/ui/relation-picker/types/EntityForSelect';
|
||||
import { Entity } from '@/ui/relation-picker/types/EntityTypeForSelect';
|
||||
import {
|
||||
Activity,
|
||||
User,
|
||||
useSearchUserQuery,
|
||||
useUpdateActivityMutation,
|
||||
} from '~/generated/graphql';
|
||||
|
||||
export type OwnProps = {
|
||||
activity: Pick<Activity, 'id'> & {
|
||||
accountOwner?: Pick<User, 'id' | 'displayName'> | null;
|
||||
};
|
||||
onSubmit?: () => void;
|
||||
onCancel?: () => void;
|
||||
};
|
||||
|
||||
type UserForSelect = EntityForSelect & {
|
||||
entityType: Entity.User;
|
||||
};
|
||||
|
||||
export function ActivityAssigneePicker({
|
||||
activity,
|
||||
onSubmit,
|
||||
onCancel,
|
||||
}: OwnProps) {
|
||||
const [searchFilter] = useRecoilScopedState(
|
||||
relationPickerSearchFilterScopedState,
|
||||
);
|
||||
const [updateActivity] = useUpdateActivityMutation();
|
||||
|
||||
const companies = useFilteredSearchEntityQuery({
|
||||
queryHook: useSearchUserQuery,
|
||||
selectedIds: activity?.accountOwner?.id ? [activity?.accountOwner?.id] : [],
|
||||
searchFilter: searchFilter,
|
||||
mappingFunction: (user) => ({
|
||||
entityType: Entity.User,
|
||||
id: user.id,
|
||||
name: user.displayName,
|
||||
avatarType: 'rounded',
|
||||
avatarUrl: user.avatarUrl ?? '',
|
||||
}),
|
||||
orderByField: 'firstName',
|
||||
searchOnFields: ['firstName', 'lastName'],
|
||||
});
|
||||
|
||||
async function handleEntitySelected(
|
||||
selectedUser: UserForSelect | null | undefined,
|
||||
) {
|
||||
if (selectedUser) {
|
||||
await updateActivity({
|
||||
variables: {
|
||||
where: { id: activity.id },
|
||||
data: {
|
||||
assignee: { connect: { id: selectedUser.id } },
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onSubmit?.();
|
||||
}
|
||||
|
||||
return (
|
||||
<SingleEntitySelect
|
||||
onEntitySelected={handleEntitySelected}
|
||||
onCancel={onCancel}
|
||||
entities={{
|
||||
loading: companies.loading,
|
||||
entitiesToSelect: companies.entitiesToSelect,
|
||||
selectedEntity: companies.selectedEntities[0],
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -35,8 +35,12 @@ export function ActivityBodyEditor({ activity, onChange }: OwnProps) {
|
||||
setBody(activityBody);
|
||||
updateActivityMutation({
|
||||
variables: {
|
||||
id: activity.id,
|
||||
body: activityBody,
|
||||
where: {
|
||||
id: activity.id,
|
||||
},
|
||||
data: {
|
||||
body: activityBody,
|
||||
},
|
||||
},
|
||||
refetchQueries: [getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? ''],
|
||||
});
|
||||
|
||||
@ -4,20 +4,23 @@ import styled from '@emotion/styled';
|
||||
|
||||
import { ActivityBodyEditor } from '@/activities/components/ActivityBodyEditor';
|
||||
import { ActivityComments } from '@/activities/components/ActivityComments';
|
||||
import { ActivityRelationPicker } from '@/activities/components/ActivityRelationPicker';
|
||||
import { ActivityTypeDropdown } from '@/activities/components/ActivityTypeDropdown';
|
||||
import { GET_ACTIVITIES_BY_TARGETS } from '@/activities/queries';
|
||||
import { PropertyBox } from '@/ui/editable-field/property-box/components/PropertyBox';
|
||||
import { PropertyBoxItem } from '@/ui/editable-field/property-box/components/PropertyBoxItem';
|
||||
import { DateEditableField } from '@/ui/editable-field/variants/components/DateEditableField';
|
||||
import { useIsMobile } from '@/ui/hooks/useIsMobile';
|
||||
import { IconArrowUpRight } from '@/ui/icon/index';
|
||||
import { IconCalendar } from '@/ui/icon/index';
|
||||
import {
|
||||
Activity,
|
||||
ActivityTarget,
|
||||
ActivityType,
|
||||
User,
|
||||
useUpdateActivityMutation,
|
||||
} from '~/generated/graphql';
|
||||
import { debounce } from '~/utils/debounce';
|
||||
|
||||
import { ActivityAssigneeEditableField } from '../editable-fields/components/ActivityAssigneeEditableField';
|
||||
import { ActivityRelationEditableField } from '../editable-fields/components/ActivityRelationEditableField';
|
||||
import { ActivityActionBar } from '../right-drawer/components/ActivityActionBar';
|
||||
import { CommentForDrawer } from '../types/CommentForDrawer';
|
||||
|
||||
@ -65,8 +68,16 @@ const StyledTopActionsContainer = styled.div`
|
||||
`;
|
||||
|
||||
type OwnProps = {
|
||||
activity: Pick<Activity, 'id' | 'title' | 'body' | 'type' | 'completedAt'> & {
|
||||
activity: Pick<
|
||||
Activity,
|
||||
'id' | 'title' | 'body' | 'type' | 'completedAt' | 'dueAt'
|
||||
> & {
|
||||
comments?: Array<CommentForDrawer> | null;
|
||||
} & {
|
||||
assignee?: Pick<
|
||||
User,
|
||||
'id' | 'firstName' | 'lastName' | 'displayName'
|
||||
> | null;
|
||||
} & {
|
||||
activityTargets?: Array<
|
||||
Pick<ActivityTarget, 'id' | 'commentableId' | 'commentableType'>
|
||||
@ -95,8 +106,12 @@ export function ActivityEditor({
|
||||
(newTitle: string) => {
|
||||
updateActivityMutation({
|
||||
variables: {
|
||||
id: activity.id,
|
||||
title: newTitle ?? '',
|
||||
where: {
|
||||
id: activity.id,
|
||||
},
|
||||
data: {
|
||||
title: newTitle ?? '',
|
||||
},
|
||||
},
|
||||
refetchQueries: [getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? ''],
|
||||
});
|
||||
@ -108,8 +123,12 @@ export function ActivityEditor({
|
||||
(value: boolean) => {
|
||||
updateActivityMutation({
|
||||
variables: {
|
||||
id: activity.id,
|
||||
completedAt: value ? new Date().toISOString() : null,
|
||||
where: {
|
||||
id: activity.id,
|
||||
},
|
||||
data: {
|
||||
completedAt: value ? new Date().toISOString() : null,
|
||||
},
|
||||
},
|
||||
refetchQueries: [getOperationName(GET_ACTIVITIES_BY_TARGETS) ?? ''],
|
||||
});
|
||||
@ -152,18 +171,29 @@ export function ActivityEditor({
|
||||
onCompletionChange={handleActivityCompletionChange}
|
||||
/>
|
||||
<PropertyBox>
|
||||
<PropertyBoxItem
|
||||
icon={<IconArrowUpRight />}
|
||||
value={
|
||||
<ActivityRelationPicker
|
||||
activity={{
|
||||
id: activity.id,
|
||||
activityTargets: activity.activityTargets ?? [],
|
||||
{activity.type === ActivityType.Task && (
|
||||
<>
|
||||
<DateEditableField
|
||||
value={activity.dueAt}
|
||||
icon={<IconCalendar />}
|
||||
label="Due date"
|
||||
onSubmit={(newDate) => {
|
||||
updateActivityMutation({
|
||||
variables: {
|
||||
where: {
|
||||
id: activity.id,
|
||||
},
|
||||
data: {
|
||||
dueAt: newDate,
|
||||
},
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
}
|
||||
label="Relations"
|
||||
/>
|
||||
<ActivityAssigneeEditableField activity={activity} />
|
||||
</>
|
||||
)}
|
||||
<ActivityRelationEditableField activity={activity} />
|
||||
</PropertyBox>
|
||||
</StyledTopContainer>
|
||||
<ActivityBodyEditor
|
||||
|
||||
Reference in New Issue
Block a user