Enable Task creation (#688)

This commit is contained in:
Charles Bochet
2023-07-16 09:39:52 -07:00
committed by GitHub
parent 098cd038bd
commit 037628ab1d
126 changed files with 3032 additions and 253 deletions

View File

@ -9,7 +9,7 @@ import { BlockEditor } from '@/ui/components/editor/BlockEditor';
import { debounce } from '@/utils/debounce';
import {
CommentThread,
useUpdateCommentThreadBodyMutation,
useUpdateCommentThreadMutation,
} from '~/generated/graphql';
const BlockNoteStyledContainer = styled.div`
@ -22,8 +22,7 @@ type OwnProps = {
};
export function CommentThreadBodyEditor({ commentThread, onChange }: OwnProps) {
const [updateCommentThreadBodyMutation] =
useUpdateCommentThreadBodyMutation();
const [updateCommentThreadMutation] = useUpdateCommentThreadMutation();
const [body, setBody] = useState<string | null>(null);
@ -36,10 +35,10 @@ export function CommentThreadBodyEditor({ commentThread, onChange }: OwnProps) {
const debounceOnChange = useMemo(() => {
function onInternalChange(commentThreadBody: string) {
setBody(commentThreadBody);
updateCommentThreadBodyMutation({
updateCommentThreadMutation({
variables: {
commentThreadId: commentThread.id,
commentThreadBody: commentThreadBody,
id: commentThread.id,
body: commentThreadBody,
},
refetchQueries: [
getOperationName(GET_COMMENT_THREADS_BY_TARGETS) ?? '',
@ -48,7 +47,7 @@ export function CommentThreadBodyEditor({ commentThread, onChange }: OwnProps) {
}
return debounce(onInternalChange, 200);
}, [commentThread, updateCommentThreadBodyMutation, setBody]);
}, [commentThread, updateCommentThreadMutation, setBody]);
const editor: BlockNoteEditor | null = useBlockNote({
initialContent: commentThread.body

View File

@ -26,7 +26,6 @@ export function CommentThreadCreateButton({
<Button
icon={<IconCheckbox size={theme.icon.size.sm} />}
title="Task"
soon={true}
onClick={onTaskClick}
/>
<Button

View File

@ -2,17 +2,59 @@ import {
DropdownButton,
DropdownOptionType,
} from '@/ui/components/buttons/DropdownButton';
import { IconNotes } from '@/ui/icons/index';
import { IconCheck, IconNotes } from '@/ui/icons/index';
import {
ActivityType,
CommentThread,
useUpdateCommentThreadMutation,
} from '~/generated/graphql';
export function CommentThreadTypeDropdown() {
type OwnProps = {
commentThread: Pick<CommentThread, 'id' | 'type'>;
};
export function CommentThreadTypeDropdown({ commentThread }: OwnProps) {
const [updateCommentThreadMutation] = useUpdateCommentThreadMutation();
const options: DropdownOptionType[] = [
{ label: 'Note', icon: <IconNotes /> },
// { label: 'Call', icon: <IconPhone /> },
{ label: 'Note', key: 'note', icon: <IconNotes /> },
{ label: 'Task', key: 'task', icon: <IconCheck /> },
];
const handleSelect = (selectedOption: DropdownOptionType) => {
// console.log(`You selected: ${selectedOption.label}`);
function getSelectedOptionKey() {
if (commentThread.type === ActivityType.Note) {
return 'note';
} else if (commentThread.type === ActivityType.Task) {
return 'task';
} else {
return undefined;
}
}
const convertSelectionOptionKeyToActivityType = (key: string) => {
switch (key) {
case 'note':
return ActivityType.Note;
case 'task':
return ActivityType.Task;
default:
return undefined;
}
};
return <DropdownButton options={options} onSelection={handleSelect} />;
const handleSelect = (selectedOption: DropdownOptionType) => {
updateCommentThreadMutation({
variables: {
id: commentThread.id,
type: convertSelectionOptionKeyToActivityType(selectedOption.key),
},
});
};
return (
<DropdownButton
options={options}
onSelection={handleSelect}
selectedOptionKey={getSelectedOptionKey()}
/>
);
}

View File

@ -9,7 +9,7 @@ import { IconArrowUpRight } from '@/ui/icons/index';
import { debounce } from '@/utils/debounce';
import {
useGetCommentThreadQuery,
useUpdateCommentThreadTitleMutation,
useUpdateCommentThreadMutation,
} from '~/generated/graphql';
import { CommentThreadBodyEditor } from '../comment-thread/CommentThreadBodyEditor';
@ -105,21 +105,20 @@ export function CommentThread({
const [hasUserManuallySetTitle, setHasUserManuallySetTitle] =
useState<boolean>(false);
const [updateCommentThreadTitleMutation] =
useUpdateCommentThreadTitleMutation();
const [updateCommentThreadMutation] = useUpdateCommentThreadMutation();
const debounceUpdateTitle = useMemo(() => {
function updateTitle(title: string) {
updateCommentThreadTitleMutation({
updateCommentThreadMutation({
variables: {
commentThreadId: commentThreadId,
commentThreadTitle: title ?? '',
id: commentThreadId,
title: title ?? '',
},
refetchQueries: [getOperationName(GET_COMMENT_THREAD) ?? ''],
});
}
return debounce(updateTitle, 200);
}, [commentThreadId, updateCommentThreadTitleMutation]);
}, [commentThreadId, updateCommentThreadMutation]);
function updateTitleFromBody(body: string) {
const parsedTitle = JSON.parse(body)[0]?.content[0]?.text;
@ -144,11 +143,11 @@ export function CommentThread({
<StyledUpperPartContainer>
<StyledTopContainer>
<StyledTopActionsContainer>
<CommentThreadTypeDropdown />
<CommentThreadTypeDropdown commentThread={commentThread} />
<CommentThreadActionBar commentThreadId={commentThread?.id ?? ''} />
</StyledTopActionsContainer>
<StyledEditableTitleInput
placeholder="Note title (optional)"
placeholder={`${commentThread.type} title (optional)`}
onChange={(event) => {
setHasUserManuallySetTitle(true);
setTitle(event.target.value);

View File

@ -12,7 +12,7 @@ export function RightDrawerCreateCommentThread() {
return (
<RightDrawerPage>
<RightDrawerTopBar title="New note" />
<RightDrawerTopBar />
<RightDrawerBody>
{commentThreadId && (
<CommentThread

View File

@ -12,7 +12,7 @@ export function RightDrawerEditCommentThread() {
return (
<RightDrawerPage>
<RightDrawerTopBar title="" />
<RightDrawerTopBar />
<RightDrawerBody>
{commentThreadId && <CommentThread commentThreadId={commentThreadId} />}
</RightDrawerBody>

View File

@ -12,6 +12,7 @@ import {
beautifyPastDateRelativeToNow,
} from '@/utils/datetime/date-utils';
import {
ActivityType,
SortOrder,
useGetCommentThreadsByTargetsQuery,
} from '~/generated/graphql';
@ -187,7 +188,7 @@ const StyledTopActionBar = styled.div`
`;
export function Timeline({ entity }: { entity: CommentableEntity }) {
const { data: queryResult } = useGetCommentThreadsByTargetsQuery({
const { data: queryResult, loading } = useGetCommentThreadsByTargetsQuery({
variables: {
commentThreadTargetIds: [entity.id],
orderBy: [
@ -205,13 +206,18 @@ export function Timeline({ entity }: { entity: CommentableEntity }) {
const commentThreads: CommentThreadForDrawer[] =
queryResult?.findManyCommentThreads ?? [];
if (loading) {
return <></>;
}
if (!commentThreads.length) {
return (
<StyledTimelineEmptyContainer>
<StyledEmptyTimelineTitle>No activity yet</StyledEmptyTimelineTitle>
<StyledEmptyTimelineSubTitle>Create one:</StyledEmptyTimelineSubTitle>
<CommentThreadCreateButton
onNoteClick={() => openCreateCommandThread(entity)}
onNoteClick={() => openCreateCommandThread(entity, ActivityType.Note)}
onTaskClick={() => openCreateCommandThread(entity, ActivityType.Task)}
/>
</StyledTimelineEmptyContainer>
);
@ -222,7 +228,12 @@ export function Timeline({ entity }: { entity: CommentableEntity }) {
<StyledTopActionBar>
<StyledTimelineItemContainer>
<CommentThreadCreateButton
onNoteClick={() => openCreateCommandThread(entity)}
onNoteClick={() =>
openCreateCommandThread(entity, ActivityType.Note)
}
onTaskClick={() =>
openCreateCommandThread(entity, ActivityType.Task)
}
/>
</StyledTimelineItemContainer>
</StyledTopActionBar>