diff --git a/web/components/command-palette/command-pallette.tsx b/web/components/command-palette/command-pallette.tsx index 507d8a49c..f183de9c6 100644 --- a/web/components/command-palette/command-pallette.tsx +++ b/web/components/command-palette/command-pallette.tsx @@ -41,7 +41,7 @@ export const CommandPalette: React.FC = observer(() => { const [isCreateUpdatePageModalOpen, setIsCreateUpdatePageModalOpen] = useState(false); const router = useRouter(); - const { workspaceSlug, projectId, issueId, inboxId } = router.query; + const { workspaceSlug, projectId, issueId, inboxId, cycleId, moduleId } = router.query; const { user } = useUser(); @@ -183,6 +183,13 @@ export const CommandPalette: React.FC = observer(() => { isOpen={isIssueModalOpen} handleClose={() => setIsIssueModalOpen(false)} fieldsToShow={inboxId ? ["name", "description", "priority"] : ["all"]} + prePopulateData={ + cycleId + ? { cycle: cycleId.toString() } + : moduleId + ? { module: moduleId.toString() } + : undefined + } /> , }, - blocks: { + blocked_by: { message: (activity) => { if (activity.old_value === "") return ( @@ -176,6 +177,44 @@ const activityDetails: { }, icon: , }, + duplicate: { + message: (activity) => { + if (activity.old_value === "") + return ( + <> + marked this issue as duplicate of{" "} + {activity.new_value}. + + ); + else + return ( + <> + removed this issue as a duplicate of{" "} + {activity.old_value}. + + ); + }, + icon: , + }, + relates_to: { + message: (activity) => { + if (activity.old_value === "") + return ( + <> + marked that this issue relates to{" "} + {activity.new_value}. + + ); + else + return ( + <> + removed the relation from{" "} + {activity.old_value}. + + ); + }, + icon: , + }, cycles: { message: (activity, showIssue, workspaceSlug) => { if (activity.verb === "created") diff --git a/web/components/core/views/issues-view.tsx b/web/components/core/views/issues-view.tsx index 98b687207..55eefc396 100644 --- a/web/components/core/views/issues-view.tsx +++ b/web/components/core/views/issues-view.tsx @@ -23,7 +23,6 @@ import { CreateUpdateIssueModal, DeleteIssueModal, DeleteDraftIssueModal, - IssuePeekOverview, CreateUpdateDraftIssueModal, } from "components/issues"; import { CreateUpdateViewModal } from "components/views"; @@ -484,15 +483,7 @@ export const IssuesView: React.FC = ({ } : null } - fieldsToShow={[ - "name", - "description", - "label", - "assignee", - "priority", - "dueDate", - "priority", - ]} + fieldsToShow={["all"]} /> = (props) => { }; const handleDeletion = async () => { - if (!workspaceSlug || !data) return; + if (!workspaceSlug || !data || !user) return; setIsDeleteLoading(true); await issueServices - .deleteDraftIssue(workspaceSlug as string, data.project, data.id) + .deleteDraftIssue(workspaceSlug as string, data.project, data.id, user) .then(() => { setIsDeleteLoading(false); handleClose(); diff --git a/web/components/issues/draft-issue-modal.tsx b/web/components/issues/draft-issue-modal.tsx index 489a09d18..3b0664cb8 100644 --- a/web/components/issues/draft-issue-modal.tsx +++ b/web/components/issues/draft-issue-modal.tsx @@ -14,6 +14,7 @@ import useIssuesView from "hooks/use-issues-view"; import useCalendarIssuesView from "hooks/use-calendar-issues-view"; import useToast from "hooks/use-toast"; import useSpreadsheetIssuesView from "hooks/use-spreadsheet-issues-view"; +import useLocalStorage from "hooks/use-local-storage"; import useProjects from "hooks/use-projects"; import useMyIssues from "hooks/my-issues/use-my-issues"; // components @@ -79,6 +80,8 @@ export const CreateUpdateDraftIssueModal: React.FC = ({ const { user } = useUser(); const { projects } = useProjects(); + const { clearValue: clearDraftIssueLocalStorage } = useLocalStorage("draftedIssue", {}); + const { groupedIssues, mutateMyIssues } = useMyIssues(workspaceSlug?.toString()); const { setToastAlert } = useToast(); @@ -111,11 +114,14 @@ export const CreateUpdateDraftIssueModal: React.FC = ({ return; } + if (prePopulateData && prePopulateData.project) + return setActiveProject(prePopulateData.project); + // if data is not present, set active project to the project // in the url. This has the least priority. if (projects && projects.length > 0 && !activeProject) setActiveProject(projects?.find((p) => p.id === projectId)?.id ?? projects?.[0].id ?? null); - }, [activeProject, data, projectId, projects, isOpen]); + }, [activeProject, data, projectId, projects, isOpen, prePopulateData]); const calendarFetchKey = cycleId ? CYCLE_ISSUES_WITH_PARAMS(cycleId.toString(), calendarParams) @@ -228,6 +234,8 @@ export const CreateUpdateDraftIssueModal: React.FC = ({ if (!data) await createIssue(payload); else await updateIssue(payload); + clearDraftIssueLocalStorage(); + if (onSubmit) await onSubmit(payload); }; diff --git a/web/components/issues/form.tsx b/web/components/issues/form.tsx index e6b4f9e08..2e53f3866 100644 --- a/web/components/issues/form.tsx +++ b/web/components/issues/form.tsx @@ -8,7 +8,6 @@ import { Controller, useForm } from "react-hook-form"; import aiService from "services/ai.service"; // hooks import useToast from "hooks/use-toast"; -import useLocalStorage from "hooks/use-local-storage"; // components import { GptAssistantModal } from "components/core"; import { ParentIssuesListModal } from "components/issues"; @@ -62,11 +61,9 @@ export interface IssueFormProps { setActiveProject: React.Dispatch>; createMore: boolean; setCreateMore: React.Dispatch>; - handleClose: () => void; handleDiscardClose: () => void; status: boolean; user: ICurrentUserResponse | undefined; - setIsConfirmDiscardOpen: React.Dispatch>; handleFormDirty: (payload: Partial | null) => void; fieldsToShow: ( | "project" @@ -107,8 +104,6 @@ export const IssueForm: FC = (props) => { const [gptAssistantModal, setGptAssistantModal] = useState(false); const [iAmFeelingLucky, setIAmFeelingLucky] = useState(false); - const { setValue: setValueInLocalStorage } = useLocalStorage("draftedIssue", null); - const editorRef = useRef(null); const router = useRouter(); @@ -139,9 +134,11 @@ export const IssueForm: FC = (props) => { state: getValues("state"), priority: getValues("priority"), assignees: getValues("assignees"), - target_date: getValues("target_date"), labels: getValues("labels"), + start_date: getValues("start_date"), + target_date: getValues("target_date"), project: getValues("project"), + parent: getValues("parent"), }; useEffect(() => { @@ -571,8 +568,6 @@ export const IssueForm: FC = (props) => {
{ - const data = JSON.stringify(getValues()); - setValueInLocalStorage(data); handleDiscardClose(); }} > diff --git a/web/components/issues/modal.tsx b/web/components/issues/modal.tsx index d6ab43491..65580c94a 100644 --- a/web/components/issues/modal.tsx +++ b/web/components/issues/modal.tsx @@ -19,6 +19,7 @@ import useInboxView from "hooks/use-inbox-view"; import useSpreadsheetIssuesView from "hooks/use-spreadsheet-issues-view"; import useProjects from "hooks/use-projects"; import useMyIssues from "hooks/my-issues/use-my-issues"; +import useLocalStorage from "hooks/use-local-storage"; // components import { IssueForm, ConfirmIssueDiscard } from "components/issues"; // types @@ -92,10 +93,11 @@ export const CreateUpdateIssueModal: React.FC = ({ const { groupedIssues, mutateMyIssues } = useMyIssues(workspaceSlug?.toString()); + const { setValue: setValueInLocalStorage, clearValue: clearLocalStorageValue } = + useLocalStorage("draftedIssue", {}); + const { setToastAlert } = useToast(); - if (cycleId) prePopulateData = { ...prePopulateData, cycle: cycleId as string }; - if (moduleId) prePopulateData = { ...prePopulateData, module: moduleId as string }; if (router.asPath.includes("my-issues") || router.asPath.includes("assigned")) prePopulateData = { ...prePopulateData, @@ -103,6 +105,13 @@ export const CreateUpdateIssueModal: React.FC = ({ }; const onClose = () => { + if (!showConfirmDiscard) handleClose(); + if (formDirtyState === null) return setActiveProject(null); + const data = JSON.stringify(formDirtyState); + setValueInLocalStorage(data); + }; + + const onDiscardClose = () => { if (formDirtyState !== null) { setShowConfirmDiscard(true); } else { @@ -111,11 +120,6 @@ export const CreateUpdateIssueModal: React.FC = ({ } }; - const onDiscardClose = () => { - handleClose(); - setActiveProject(null); - }; - const handleFormDirty = (data: any) => { setFormDirtyState(data); }; @@ -397,6 +401,7 @@ export const CreateUpdateIssueModal: React.FC = ({ setActiveProject(null); setFormDirtyState(null); setShowConfirmDiscard(false); + clearLocalStorageValue(); }} /> @@ -431,9 +436,7 @@ export const CreateUpdateIssueModal: React.FC = ({ initialData={data ?? prePopulateData} createMore={createMore} setCreateMore={setCreateMore} - handleClose={onClose} handleDiscardClose={onDiscardClose} - setIsConfirmDiscardOpen={setShowConfirmDiscard} projectId={activeProject ?? ""} setActiveProject={setActiveProject} status={data ? true : false} diff --git a/web/components/issues/sidebar-select/blocked.tsx b/web/components/issues/sidebar-select/blocked.tsx index 9554a83ba..d7e448377 100644 --- a/web/components/issues/sidebar-select/blocked.tsx +++ b/web/components/issues/sidebar-select/blocked.tsx @@ -73,7 +73,7 @@ export const SidebarBlockedSelect: React.FC = ({ ...selectedIssues.map((issue) => ({ issue: issueId as string, relation_type: "blocked_by" as const, - related_issue_detail: issue.blocked_issue_detail, + issue_detail: issue.blocked_issue_detail, related_issue: issue.blocked_issue_detail.id, })), ], @@ -111,17 +111,17 @@ export const SidebarBlockedSelect: React.FC = ({ {blockedByIssue && blockedByIssue.length > 0 ? blockedByIssue.map((relation) => (
- {`${relation.related_issue_detail?.project_detail.identifier}-${relation.related_issue_detail?.sequence_id}`} + {`${relation.issue_detail?.project_detail.identifier}-${relation.issue_detail?.sequence_id}`}