Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 31 additions & 27 deletions apps/app/components/command-palette/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,50 +102,54 @@ const CommandPalette: React.FC = () => {
!(e.target instanceof HTMLInputElement) &&
!(e.target as Element).classList?.contains("remirror-editor")
) {
if ((e.ctrlKey || e.metaKey) && e.key === "k") {
if ((e.ctrlKey || e.metaKey) && (e.key === "k" || e.key === "K")) {
e.preventDefault();
setIsPaletteOpen(true);
} else if (e.ctrlKey && e.key === "c") {
console.log("Text copied");
} else if (e.key === "c") {
} else if (e.ctrlKey && (e.key === "c" || e.key === "C")) {
if (e.altKey) {
e.preventDefault();
if (!router.query.issueId) return;

const url = new URL(window.location.href);
console.log(url);
copyTextToClipboard(url.href)
.then(() => {
setToastAlert({
type: "success",
title: "Copied to clipboard",
});
})
.catch(() => {
setToastAlert({
type: "error",
title: "Some error occurred",
});
});
console.log("URL Copied");
} else {
console.log("Text copied");
}
} else if (e.key === "c" || e.key === "C") {
e.preventDefault();
setIsIssueModalOpen(true);
} else if (e.key === "p") {
} else if (e.key === "p" || e.key === "P") {
e.preventDefault();
setIsProjectModalOpen(true);
} else if ((e.ctrlKey || e.metaKey) && e.key === "b") {
} else if ((e.ctrlKey || e.metaKey) && (e.key === "b" || e.key === "B")) {
e.preventDefault();
toggleCollapsed();
} else if (e.key === "h") {
} else if (e.key === "h" || e.key === "H") {
e.preventDefault();
setIsShortcutsModalOpen(true);
} else if (e.key === "q") {
} else if (e.key === "q" || e.key === "Q") {
e.preventDefault();
setIsCreateCycleModalOpen(true);
} else if (e.key === "m") {
} else if (e.key === "m" || e.key === "M") {
e.preventDefault();
setIsCreateModuleModalOpen(true);
} else if (e.key === "Delete") {
e.preventDefault();
setIsBulkDeleteIssuesModalOpen(true);
} else if ((e.ctrlKey || e.metaKey) && e.altKey && e.key === "c") {
e.preventDefault();
if (!router.query.issueId) return;

const url = new URL(window.location.href);
copyTextToClipboard(url.href)
.then(() => {
setToastAlert({
type: "success",
title: "Copied to clipboard",
});
})
.catch(() => {
setToastAlert({
type: "error",
title: "Some error occurred",
});
});
}
}
},
Expand Down
14 changes: 7 additions & 7 deletions apps/app/components/command-palette/shortcuts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const shortcuts = [
{
title: "Navigation",
shortcuts: [
{ keys: "ctrl,cmd,k", description: "To open navigator" },
{ keys: "Ctrl,Cmd,K", description: "To open navigator" },
{ keys: "↑", description: "Move up" },
{ keys: "↓", description: "Move down" },
{ keys: "←", description: "Move left" },
Expand All @@ -27,14 +27,14 @@ const shortcuts = [
{
title: "Common",
shortcuts: [
{ keys: "p", description: "To create project" },
{ keys: "c", description: "To create issue" },
{ keys: "q", description: "To create cycle" },
{ keys: "m", description: "To create module" },
{ keys: "P", description: "To create project" },
{ keys: "C", description: "To create issue" },
{ keys: "Q", description: "To create cycle" },
{ keys: "M", description: "To create module" },
{ keys: "Delete", description: "To bulk delete issues" },
{ keys: "h", description: "To open shortcuts guide" },
{ keys: "H", description: "To open shortcuts guide" },
{
keys: "ctrl,cmd,alt,c",
keys: "Ctrl,Cmd,Alt,C",
description: "To copy issue url when on issue detail page.",
},
],
Expand Down
75 changes: 68 additions & 7 deletions apps/app/components/common/board-view/single-issue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,16 @@ import { AssigneesList, CustomDatePicker } from "components/ui";
import { renderShortNumericDateFormat, findHowManyDaysLeft } from "helpers/date-time.helper";
import { addSpaceIfCamelCase } from "helpers/string.helper";
// types
import { IIssue, IUserLite, IWorkspaceMember, Properties, UserAuth } from "types";
import {
CycleIssueResponse,
IIssue,
IssueResponse,
IUserLite,
IWorkspaceMember,
ModuleIssueResponse,
Properties,
UserAuth,
} from "types";
// common
import { PRIORITIES } from "constants/";
import {
Expand Down Expand Up @@ -80,6 +89,60 @@ const SingleBoardIssue: React.FC<Props> = ({
const partialUpdateIssue = (formData: Partial<IIssue>) => {
if (!workspaceSlug || !projectId) return;

if (typeId) {
mutate<CycleIssueResponse[]>(
CYCLE_ISSUES(typeId ?? ""),
(prevData) => {
const updatedIssues = (prevData ?? []).map((p) => {
if (p.issue_detail.id === issue.id) {
return {
...p,
issue_detail: {
...p.issue_detail,
...formData,
},
};
}
return p;
});
return [...updatedIssues];
},
false
);

mutate<ModuleIssueResponse[]>(
MODULE_ISSUES(typeId ?? ""),
(prevData) => {
const updatedIssues = (prevData ?? []).map((p) => {
if (p.issue_detail.id === issue.id) {
return {
...p,
issue_detail: {
...p.issue_detail,
...formData,
},
};
}
return p;
});
return [...updatedIssues];
},
false
);
}

mutate<IssueResponse>(
PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string),
(prevData) => ({
...(prevData as IssueResponse),
results: (prevData?.results ?? []).map((p) => {
if (p.id === issue.id) return { ...p, ...formData };
return p;
}),
}),
false
);

issuesService
.patchIssue(workspaceSlug as string, projectId as string, issue.id, formData)
.then((res) => {
Expand Down Expand Up @@ -270,13 +333,11 @@ const SingleBoardIssue: React.FC<Props> = ({
<CustomDatePicker
placeholder="N/A"
value={issue?.target_date}
onChange={(val: Date) => {
onChange={(val) =>
partialUpdateIssue({
target_date: val
? `${val.getFullYear()}-${val.getMonth() + 1}-${val.getDate()}`
: null,
});
}}
target_date: val,
})
}
className={issue?.target_date ? "w-[6.5rem]" : "w-[3rem] text-center"}
/>
{/* <DatePicker
Expand Down
105 changes: 71 additions & 34 deletions apps/app/components/common/list-view/single-issue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import { useRouter } from "next/router";

import useSWR, { mutate } from "swr";

// react-datepicker
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
// services
import issuesService from "services/issues.service";
import workspaceService from "services/workspace.service";
Expand All @@ -18,13 +15,19 @@ import { Listbox, Transition } from "@headlessui/react";
import { CustomMenu, CustomSelect, AssigneesList, Avatar, CustomDatePicker } from "components/ui";
// components
import ConfirmIssueDeletion from "components/project/issues/confirm-issue-deletion";
// icons
import { CalendarDaysIcon } from "@heroicons/react/24/outline";
// helpers
import { renderShortNumericDateFormat, findHowManyDaysLeft } from "helpers/date-time.helper";
import { addSpaceIfCamelCase } from "helpers/string.helper";
// types
import { IIssue, IWorkspaceMember, Properties, UserAuth } from "types";
import {
CycleIssueResponse,
IIssue,
IssueResponse,
IWorkspaceMember,
ModuleIssueResponse,
Properties,
UserAuth,
} from "types";
// fetch-keys
import {
CYCLE_ISSUES,
Expand Down Expand Up @@ -76,6 +79,60 @@ const SingleListIssue: React.FC<Props> = ({
const partialUpdateIssue = (formData: Partial<IIssue>) => {
if (!workspaceSlug || !projectId) return;

if (typeId) {
mutate<CycleIssueResponse[]>(
CYCLE_ISSUES(typeId ?? ""),
(prevData) => {
const updatedIssues = (prevData ?? []).map((p) => {
if (p.issue_detail.id === issue.id) {
return {
...p,
issue_detail: {
...p.issue_detail,
...formData,
},
};
}
return p;
});
return [...updatedIssues];
},
false
);

mutate<ModuleIssueResponse[]>(
MODULE_ISSUES(typeId ?? ""),
(prevData) => {
const updatedIssues = (prevData ?? []).map((p) => {
if (p.issue_detail.id === issue.id) {
return {
...p,
issue_detail: {
...p.issue_detail,
...formData,
},
};
}
return p;
});
return [...updatedIssues];
},
false
);
}

mutate<IssueResponse>(
PROJECT_ISSUES_LIST(workspaceSlug as string, projectId as string),
(prevData) => ({
...(prevData as IssueResponse),
results: (prevData?.results ?? []).map((p) => {
if (p.id === issue.id) return { ...p, ...formData };
return p;
}),
}),
false
);

issuesService
.patchIssue(workspaceSlug as string, projectId as string, issue.id, formData)
.then((res) => {
Expand Down Expand Up @@ -255,44 +312,24 @@ const SingleListIssue: React.FC<Props> = ({
<CustomDatePicker
placeholder="N/A"
value={issue?.target_date}
onChange={(val: Date) => {
onChange={(val) =>
partialUpdateIssue({
target_date: val
? `${val.getFullYear()}-${val.getMonth() + 1}-${val.getDate()}`
: null,
});
}}
target_date: val,
})
}
className={issue?.target_date ? "w-[6.5rem]" : "w-[3rem] text-center"}
/>
{/* <DatePicker
placeholderText="N/A"
value={
issue?.target_date ? `${renderShortNumericDateFormat(issue.target_date)}` : "N/A"
}
selected={issue?.target_date ? new Date(issue.target_date) : null}
onChange={(val: Date) => {
partialUpdateIssue({
target_date: val
? `${val.getFullYear()}-${val.getMonth() + 1}-${val.getDate()}`
: null,
});
}}
dateFormat="dd-MM-yyyy"
className={`cursor-pointer rounded-md border px-2 py-[3px] text-xs shadow-sm duration-300 hover:bg-gray-100 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 ${
issue?.target_date ? "w-[4.5rem]" : "w-[3rem] text-center"
}`}
isClearable
/> */}
<div className="absolute bottom-full right-0 z-10 mb-2 hidden whitespace-nowrap rounded-md bg-white p-2 shadow-md group-hover:block">
<h5 className="mb-1 font-medium text-gray-900">Due date</h5>
<div>{renderShortNumericDateFormat(issue.target_date ?? "")}</div>
<div>
{issue.target_date &&
(issue.target_date < new Date().toISOString()
{issue.target_date
? issue.target_date < new Date().toISOString()
? `Due date has passed by ${findHowManyDaysLeft(issue.target_date)} days`
: findHowManyDaysLeft(issue.target_date) <= 3
? `Due date is in ${findHowManyDaysLeft(issue.target_date)} days`
: "Due date")}
: "Due date"
: "N/A"}
</div>
</div>
</div>
Expand Down
Loading