From 9d7b0c6daafa7d1a8b83605c0d5493dc7dcd5a83 Mon Sep 17 00:00:00 2001 From: LAKHAN BAHETI Date: Mon, 4 Dec 2023 17:19:39 +0530 Subject: [PATCH] chore: issue update status in peek view --- .../issue-peek-overview/issue-detail.tsx | 41 ++++++++----------- .../issues/issue-peek-overview/view.tsx | 38 ++++++++++++++--- .../project-issues/project/issue.store.ts | 14 ++++++- web/store/issues/types.ts | 3 ++ 4 files changed, 67 insertions(+), 29 deletions(-) diff --git a/web/components/issues/issue-peek-overview/issue-detail.tsx b/web/components/issues/issue-peek-overview/issue-detail.tsx index 60d20483e..763d3acf3 100644 --- a/web/components/issues/issue-peek-overview/issue-detail.tsx +++ b/web/components/issues/issue-peek-overview/issue-detail.tsx @@ -25,19 +25,32 @@ interface IPeekOverviewIssueDetails { issueUpdate: (issue: Partial) => void; issueReactionCreate: (reaction: string) => void; issueReactionRemove: (reaction: string) => void; + setShowAlert: (value: boolean) => void; } export const PeekOverviewIssueDetails: FC = (props) => { - const { workspaceSlug, issue, issueReactions, user, issueUpdate, issueReactionCreate, issueReactionRemove } = props; + const { + workspaceSlug, + issue, + issueReactions, + user, + issueUpdate, + issueReactionCreate, + issueReactionRemove, + setShowAlert, + } = props; // store - const { user: userStore } = useMobxStore(); + const { + user: userStore, + projectIssues: { isSubmitting, setIsSubmitting }, + } = useMobxStore(); const { currentProjectRole } = userStore; const isAllowed = [15, 20].includes(currentProjectRole || 0); // states - const [isSubmitting, setIsSubmitting] = useState<"submitting" | "submitted" | "saved">("saved"); + const [characterLimit, setCharacterLimit] = useState(false); // hooks - const { setShowAlert } = useReloadConfirmations(); + const editorSuggestions = useEditorSuggestions(); const { @@ -75,20 +88,9 @@ export const PeekOverviewIssueDetails: FC = (props) = }, [issueTitleCurrentValue, localTitleValue]); const debouncedFormSave = debounce(async () => { - handleSubmit(handleDescriptionFormSubmit)().finally(() => setIsSubmitting("submitted")); + handleSubmit(handleDescriptionFormSubmit)(); }, 1500); - useEffect(() => { - if (isSubmitting === "submitted") { - setShowAlert(false); - setTimeout(async () => { - setIsSubmitting("saved"); - }, 2000); - } else if (isSubmitting === "submitting") { - setShowAlert(true); - } - }, [isSubmitting, setShowAlert]); - // reset form values useEffect(() => { if (!issue) return; @@ -171,13 +173,6 @@ export const PeekOverviewIssueDetails: FC = (props) = /> )} /> -
- {isSubmitting === "submitting" ? "Saving..." : "Saved"} -
= observer((props) => { const router = useRouter(); const { peekIssueId } = router.query as { peekIssueId: string }; - const { user: userStore, issueDetail: issueDetailStore } = useMobxStore(); + const { + user: userStore, + issueDetail: issueDetailStore, + projectIssues: { isSubmitting, setIsSubmitting }, + } = useMobxStore(); const [peekMode, setPeekMode] = useState("side-peek"); const [deleteIssueModal, setDeleteIssueModal] = useState(false); + const { setShowAlert } = useReloadConfirmations(); + const updateRoutePeekId = () => { if (issueId != peekIssueId) { issueDetailStore.setPeekId(issueId); @@ -136,6 +143,17 @@ export const IssueView: FC = observer((props) => { const currentMode = peekOptions.find((m) => m.key === peekMode); + useEffect(() => { + if (isSubmitting === "submitted") { + setShowAlert(false); + setTimeout(async () => { + setIsSubmitting("saved"); + }, 2000); + } else if (isSubmitting === "submitting") { + setShowAlert(true); + } + }, [isSubmitting, setShowAlert]); + return ( <> {issue && !isArchived && ( @@ -235,12 +253,20 @@ export const IssueView: FC = observer((props) => { {issueSubscription && issueSubscription.subscribed ? "Unsubscribe" : "Subscribe"} )} +
+ {isSubmitting !== "submitted" && isSubmitting !== "saved" && ( + + )} + + {isSubmitting === "submitting" ? "Saving..." : "Saved"} + +
{!disableUserActions && ( )} @@ -261,6 +287,7 @@ export const IssueView: FC = observer((props) => {
)} = observer((props) => {
) => Promise; removeIssue: (workspaceSlug: string, projectId: string, issueId: string) => Promise; quickAddIssue: (workspaceSlug: string, projectId: string, data: IIssue) => Promise; + setIsSubmitting: (value: TIssueUpdateStatus) => void; viewFlags: ViewFlags; } export class ProjectIssuesStore extends IssueBaseStore implements IProjectIssuesStore { loader: TLoader = "init-loader"; + isSubmitting: TIssueUpdateStatus = "saved"; issues: { [project_id: string]: IIssueResponse } | undefined = undefined; // root store rootStore; @@ -48,6 +51,7 @@ export class ProjectIssuesStore extends IssueBaseStore implements IProjectIssues // observable loader: observable.ref, issues: observable.ref, + isSubmitting: observable.ref, // computed getIssues: computed, getIssuesIds: computed, @@ -57,6 +61,7 @@ export class ProjectIssuesStore extends IssueBaseStore implements IProjectIssues updateIssue: action, removeIssue: action, quickAddIssue: action, + setIsSubmitting: action, }); this.rootStore = _rootStore; @@ -72,6 +77,10 @@ export class ProjectIssuesStore extends IssueBaseStore implements IProjectIssues }); } + setIsSubmitting = (value: "submitting" | "submitted" | "saved") => { + this.isSubmitting = value; + }; + get getIssues() { const projectId = this.rootStore?.project.projectId; if (!projectId || !this.issues || !this.issues[projectId]) return undefined; @@ -157,11 +166,14 @@ export class ProjectIssuesStore extends IssueBaseStore implements IProjectIssues _issues[projectId][issueId] = { ..._issues[projectId][issueId], ...data }; runInAction(() => { + this.isSubmitting = "submitting"; this.issues = _issues; }); const response = await this.issueService.patchIssue(workspaceSlug, projectId, issueId, data); + this.isSubmitting = "submitted"; + return response; } catch (error) { this.fetchIssues(workspaceSlug, projectId, "mutation"); diff --git a/web/store/issues/types.ts b/web/store/issues/types.ts index 9330aba01..dbdc6d516 100644 --- a/web/store/issues/types.ts +++ b/web/store/issues/types.ts @@ -31,3 +31,6 @@ export interface ViewFlags { enableIssueCreation: boolean; enableInlineEditing: boolean; } + +// issue update status +export type TIssueUpdateStatus = "saved" | "submitting" | "submitted";