Skip to content

Commit 2acada3

Browse files
committed
feat: bulk add issues to cycle, style: favicon, avatar in members page
1 parent 3d25194 commit 2acada3

File tree

20 files changed

+575
-452
lines changed

20 files changed

+575
-452
lines changed

apps/app/components/command-palette/index.tsx

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { useRouter } from "next/router";
44
// swr
55
import { mutate } from "swr";
66
// react hook form
7-
import { SubmitHandler, useForm } from "react-hook-form";
7+
import { Controller, SubmitHandler, useForm } from "react-hook-form";
88
// headless ui
99
import { Combobox, Dialog, Transition } from "@headlessui/react";
1010
// hooks
@@ -17,6 +17,7 @@ import {
1717
FolderIcon,
1818
RectangleStackIcon,
1919
ClipboardDocumentListIcon,
20+
ArrowPathIcon,
2021
} from "@heroicons/react/24/outline";
2122
// commons
2223
import { classNames, copyTextToClipboard } from "constants/common";
@@ -27,7 +28,7 @@ import CreateUpdateIssuesModal from "components/project/issues/CreateUpdateIssue
2728
import CreateUpdateCycleModal from "components/project/cycles/CreateUpdateCyclesModal";
2829
// types
2930
import { IIssue, IProject, IssueResponse } from "types";
30-
import { Button } from "ui";
31+
import { Button, SearchListbox } from "ui";
3132
import issuesServices from "lib/services/issues.services";
3233
// fetch keys
3334
import { PROJECTS_LIST, PROJECT_ISSUES_LIST } from "constants/fetch-keys";
@@ -40,6 +41,7 @@ type ItemType = {
4041

4142
type FormInput = {
4243
issue_ids: string[];
44+
cycleId: string;
4345
};
4446

4547
const CommandPalette: React.FC = () => {
@@ -69,6 +71,7 @@ const CommandPalette: React.FC = () => {
6971
register,
7072
formState: { errors, isSubmitting },
7173
handleSubmit,
74+
control,
7275
reset,
7376
setError,
7477
} = useForm<FormInput>();
@@ -143,10 +146,24 @@ const CommandPalette: React.FC = () => {
143146
);
144147

145148
const handleDelete: SubmitHandler<FormInput> = (data) => {
146-
if (activeWorkspace && activeProject && data.issue_ids) {
149+
if (!data.issue_ids || data.issue_ids.length === 0) {
150+
setToastAlert({
151+
title: "Error",
152+
type: "error",
153+
message: "Please select atleast one issue",
154+
});
155+
return;
156+
}
157+
158+
if (activeWorkspace && activeProject) {
147159
issuesServices
148160
.bulkDeleteIssues(activeWorkspace.slug, activeProject.id, data)
149161
.then((res) => {
162+
setToastAlert({
163+
title: "Success",
164+
type: "success",
165+
message: res.message,
166+
});
150167
mutate<IssueResponse>(
151168
PROJECT_ISSUES_LIST(activeWorkspace.slug, activeProject.id),
152169
(prevData) => {
@@ -170,10 +187,30 @@ const CommandPalette: React.FC = () => {
170187
};
171188

172189
const handleAddToCycle: SubmitHandler<FormInput> = (data) => {
173-
if (activeWorkspace && activeProject && data.issue_ids) {
190+
if (!data.issue_ids || data.issue_ids.length === 0) {
191+
setToastAlert({
192+
title: "Error",
193+
type: "error",
194+
message: "Please select atleast one issue",
195+
});
196+
return;
197+
}
198+
199+
if (!data.cycleId) {
200+
setToastAlert({
201+
title: "Error",
202+
type: "error",
203+
message: "Please select a cycle",
204+
});
205+
return;
206+
}
207+
208+
if (activeWorkspace && activeProject) {
174209
issuesServices
175-
.bulkAddIssuesToCycle(activeWorkspace.slug, activeProject.id, "", data)
176-
.then((res) => {})
210+
.bulkAddIssuesToCycle(activeWorkspace.slug, activeProject.id, data.cycleId, data)
211+
.then((res) => {
212+
console.log(res);
213+
})
177214
.catch((e) => {
178215
console.log(e);
179216
});
@@ -230,7 +267,7 @@ const CommandPalette: React.FC = () => {
230267
leaveFrom="opacity-100 scale-100"
231268
leaveTo="opacity-0 scale-95"
232269
>
233-
<Dialog.Panel className="mx-auto max-w-2xl transform divide-y divide-gray-500 divide-opacity-10 overflow-hidden rounded-xl bg-white bg-opacity-80 shadow-2xl ring-1 ring-black ring-opacity-5 backdrop-blur backdrop-filter transition-all">
270+
<Dialog.Panel className="relative mx-auto max-w-2xl transform divide-y divide-gray-500 divide-opacity-10 rounded-xl bg-white bg-opacity-80 shadow-2xl ring-1 ring-black ring-opacity-5 backdrop-blur backdrop-filter transition-all">
234271
<form>
235272
<Combobox
236273
// onChange={(item: ItemType) => {
@@ -369,6 +406,23 @@ const CommandPalette: React.FC = () => {
369406

370407
<div className="flex justify-between items-center gap-2 p-3">
371408
<div className="flex items-center gap-2">
409+
<Controller
410+
control={control}
411+
name="cycleId"
412+
render={({ field: { value, onChange } }) => (
413+
<SearchListbox
414+
title="Cycle"
415+
optionsFontsize="sm"
416+
options={cycles?.map((cycle) => {
417+
return { value: cycle.id, display: cycle.name };
418+
})}
419+
multiple={false}
420+
value={value}
421+
onChange={onChange}
422+
icon={<ArrowPathIcon className="h-4 w-4 text-gray-400" />}
423+
/>
424+
)}
425+
/>
372426
<Button onClick={handleSubmit(handleAddToCycle)} size="sm">
373427
Add to Cycle
374428
</Button>

apps/app/components/command-palette/shortcuts.tsx

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const ShortcutsModal: React.FC<Props> = ({ isOpen, setIsOpen }) => {
3737
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
3838
>
3939
<Dialog.Panel className="relative transform overflow-hidden rounded-lg bg-white text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-lg">
40-
<div className="bg-white p-8">
40+
<div className="bg-white p-5">
4141
<div className="sm:flex sm:items-start">
4242
<div className="text-center sm:text-left w-full">
4343
<Dialog.Title
@@ -59,37 +59,46 @@ const ShortcutsModal: React.FC<Props> = ({ isOpen, setIsOpen }) => {
5959
{
6060
title: "Navigation",
6161
shortcuts: [
62-
{ key: "Ctrl + /", description: "To open navigator" },
63-
{ key: "↑", description: "Move up" },
64-
{ key: "↓", description: "Move down" },
65-
{ key: "←", description: "Move left" },
66-
{ key: "→", description: "Move right" },
67-
{ key: "Enter", description: "Select" },
68-
{ key: "Esc", description: "Close" },
62+
{ keys: "ctrl,/", description: "To open navigator" },
63+
{ keys: "↑", description: "Move up" },
64+
{ keys: "↓", description: "Move down" },
65+
{ keys: "←", description: "Move left" },
66+
{ keys: "→", description: "Move right" },
67+
{ keys: "Enter", description: "Select" },
68+
{ keys: "Esc", description: "Close" },
6969
],
7070
},
7171
{
7272
title: "Common",
7373
shortcuts: [
74-
{ key: "Ctrl + p", description: "To create project" },
75-
{ key: "Ctrl + i", description: "To create issue" },
76-
{ key: "Ctrl + q", description: "To create cycle" },
77-
{ key: "Ctrl + h", description: "To open shortcuts guide" },
74+
{ keys: "ctrl,p", description: "To create project" },
75+
{ keys: "ctrl,i", description: "To create issue" },
76+
{ keys: "ctrl,q", description: "To create cycle" },
77+
{ keys: "ctrl,h", description: "To open shortcuts guide" },
7878
{
79-
key: "Ctrl + alt + c",
79+
keys: "ctrl,alt,c",
8080
description: "To copy issue url when on issue detail page.",
8181
},
8282
],
8383
},
8484
].map(({ title, shortcuts }) => (
85-
<div className="w-full flex flex-col" key={title}>
85+
<div key={title} className="w-full flex flex-col">
8686
<p className="font-medium mb-4">{title}</p>
8787
<div className="flex flex-col gap-y-3">
88-
{shortcuts.map(({ key, description }) => (
89-
<div className="flex justify-between" key={key}>
88+
{shortcuts.map(({ keys, description }, index) => (
89+
<div key={index} className="flex justify-between">
9090
<p className="text-sm text-gray-500">{description}</p>
91-
<div className="flex gap-x-1">
92-
<kbd className="bg-gray-200 text-sm px-1 rounded">{key}</kbd>
91+
<div className="flex items-center gap-x-1">
92+
{keys.split(",").map((key, index) => (
93+
<span key={index} className="flex items-center gap-1">
94+
<kbd className="bg-gray-200 text-sm px-1 rounded">
95+
{key}
96+
</kbd>
97+
{/* {index !== keys.split(",").length - 1 ? (
98+
<span className="text-xs">+</span>
99+
) : null} */}
100+
</span>
101+
))}
93102
</div>
94103
</div>
95104
))}

apps/app/components/lexical/toolbar/block-type-select.tsx

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,8 @@ import {
2121
$isListNode,
2222
ListNode,
2323
} from "@lexical/list";
24-
import {
25-
$isParentElementRTL,
26-
$isAtNodeEnd,
27-
$wrapNodes,
28-
} from "@lexical/selection";
29-
import {
30-
$createHeadingNode,
31-
$createQuoteNode,
32-
$isHeadingNode,
33-
} from "@lexical/rich-text";
24+
import { $isParentElementRTL, $isAtNodeEnd, $wrapNodes } from "@lexical/selection";
25+
import { $createHeadingNode, $createQuoteNode, $isHeadingNode } from "@lexical/rich-text";
3426
import {
3527
$createCodeNode,
3628
$isCodeNode,
@@ -50,15 +42,7 @@ const BLOCK_DATA = [
5042
{ type: "ul", name: "Bulleted List" },
5143
];
5244

53-
const supportedBlockTypes = new Set([
54-
"paragraph",
55-
"quote",
56-
"code",
57-
"h1",
58-
"h2",
59-
"ul",
60-
"ol",
61-
]);
45+
const supportedBlockTypes = new Set(["paragraph", "quote", "code", "h1", "h2", "ul", "ol"]);
6246

6347
const blockTypeToBlockName: any = {
6448
code: "Code Block",
@@ -84,8 +68,7 @@ export const BlockTypeSelect: FC<BlockTypeSelectProps> = (props) => {
8468
// refs
8569
const dropDownRef = useRef<any>(null);
8670
// states
87-
const [showBlockOptionsDropDown, setShowBlockOptionsDropDown] =
88-
useState(false);
71+
const [showBlockOptionsDropDown, setShowBlockOptionsDropDown] = useState(false);
8972

9073
useEffect(() => {
9174
const toolbar = toolbarRef.current;
@@ -205,6 +188,7 @@ export const BlockTypeSelect: FC<BlockTypeSelectProps> = (props) => {
205188
return (
206189
<div className="relative">
207190
<button
191+
type="button"
208192
className="p-2 mr-2 text-sm flex items-center"
209193
onClick={() => setShowBlockOptionsDropDown(!showBlockOptionsDropDown)}
210194
aria-label="Formatting Options"

0 commit comments

Comments
 (0)