Skip to content

Commit 9549313

Browse files
anmolsinghbhatialifeiscontent
authored andcommitted
[WEB-3357 | WEB-3363 | WEB-3370] chore: command-k enhancement and fixes (#6600)
* fix: command-k work item actions * chore: command k work item context indicator improvement and default vale for workspace toggle updated * chore: code refactor
1 parent 95c9125 commit 9549313

File tree

5 files changed

+79
-92
lines changed

5 files changed

+79
-92
lines changed

web/core/components/command-palette/actions/issue-actions/actions-list.tsx

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@ import { Command } from "cmdk";
44
import { observer } from "mobx-react";
55
import { useParams } from "next/navigation";
66
import { LinkIcon, Signal, Trash2, UserMinus2, UserPlus2, Users } from "lucide-react";
7-
import { EIssuesStoreType } from "@plane/constants";
87
import { TIssue } from "@plane/types";
98
// hooks
109
import { DoubleCircleIcon, TOAST_TYPE, setToast } from "@plane/ui";
1110
// helpers
1211
import { copyTextToClipboard } from "@/helpers/string.helper";
1312
// hooks
14-
import { useCommandPalette, useIssues, useUser } from "@/hooks/store";
13+
import { useCommandPalette, useIssueDetail, useUser } from "@/hooks/store";
1514

1615
type Props = {
1716
closePalette: () => void;
@@ -27,9 +26,7 @@ export const CommandPaletteIssueActions: React.FC<Props> = observer((props) => {
2726
// router
2827
const { workspaceSlug, projectId, issueId } = useParams();
2928
// hooks
30-
const {
31-
issues: { updateIssue },
32-
} = useIssues(EIssuesStoreType.PROJECT);
29+
const { updateIssue } = useIssueDetail();
3330
const { toggleCommandPaletteModal, toggleDeleteIssueModal } = useCommandPalette();
3431
const { data: currentUser } = useUser();
3532

@@ -65,16 +62,10 @@ export const CommandPaletteIssueActions: React.FC<Props> = observer((props) => {
6562
const url = new URL(window.location.href);
6663
copyTextToClipboard(url.href)
6764
.then(() => {
68-
setToast({
69-
type: TOAST_TYPE.SUCCESS,
70-
title: "Copied to clipboard",
71-
});
65+
setToast({ type: TOAST_TYPE.SUCCESS, title: "Copied to clipboard" });
7266
})
7367
.catch(() => {
74-
setToast({
75-
type: TOAST_TYPE.ERROR,
76-
title: "Some error occurred",
77-
});
68+
setToast({ type: TOAST_TYPE.ERROR, title: "Some error occurred" });
7869
});
7970
};
8071

web/core/components/command-palette/actions/issue-actions/change-assignee.tsx

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,23 @@ import { Command } from "cmdk";
44
import { observer } from "mobx-react";
55
import { useParams } from "next/navigation";
66
import { Check } from "lucide-react";
7-
// plane constants
8-
import { EIssuesStoreType } from "@plane/constants";
97
// plane types
108
import { TIssue } from "@plane/types";
119
// plane ui
1210
import { Avatar } from "@plane/ui";
1311
// helpers
1412
import { getFileURL } from "@/helpers/file.helper";
1513
// hooks
16-
import { useIssues, useMember } from "@/hooks/store";
14+
import { useIssueDetail, useMember } from "@/hooks/store";
1715

18-
type Props = {
19-
closePalette: () => void;
20-
issue: TIssue;
21-
};
16+
type Props = { closePalette: () => void; issue: TIssue };
2217

2318
export const ChangeIssueAssignee: React.FC<Props> = observer((props) => {
2419
const { closePalette, issue } = props;
2520
// router params
2621
const { workspaceSlug, projectId } = useParams();
2722
// store
28-
const {
29-
issues: { updateIssue },
30-
} = useIssues(EIssuesStoreType.PROJECT);
23+
const { updateIssue } = useIssueDetail();
3124
const {
3225
project: { projectMemberIds, getProjectMemberDetails },
3326
} = useMember();

web/core/components/command-palette/actions/issue-actions/change-priority.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,23 @@ import { observer } from "mobx-react";
55
import { useParams } from "next/navigation";
66
import { Check } from "lucide-react";
77
// plane constants
8-
import { EIssuesStoreType, ISSUE_PRIORITIES } from "@plane/constants";
8+
import { ISSUE_PRIORITIES } from "@plane/constants";
99
// plane types
1010
import { TIssue, TIssuePriorities } from "@plane/types";
1111
// mobx store
1212
import { PriorityIcon } from "@plane/ui";
13-
import { useIssues } from "@/hooks/store";
13+
import { useIssueDetail } from "@/hooks/store";
1414
// ui
1515
// types
1616
// constants
1717

18-
type Props = {
19-
closePalette: () => void;
20-
issue: TIssue;
21-
};
18+
type Props = { closePalette: () => void; issue: TIssue };
2219

2320
export const ChangeIssuePriority: React.FC<Props> = observer((props) => {
2421
const { closePalette, issue } = props;
2522
// router params
2623
const { workspaceSlug, projectId } = useParams();
27-
const {
28-
issues: { updateIssue },
29-
} = useIssues(EIssuesStoreType.PROJECT);
24+
const { updateIssue } = useIssueDetail();
3025

3126
const submitChanges = async (formData: Partial<TIssue>) => {
3227
if (!workspaceSlug || !projectId || !issue) return;

web/core/components/command-palette/actions/issue-actions/change-state.tsx

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,21 @@ import { observer } from "mobx-react";
55
import { useParams } from "next/navigation";
66
// hooks
77
import { Check } from "lucide-react";
8-
import { EIssuesStoreType } from "@plane/constants";
98
import { TIssue } from "@plane/types";
109
import { Spinner, StateGroupIcon } from "@plane/ui";
11-
import { useProjectState, useIssues } from "@/hooks/store";
10+
import { useProjectState, useIssueDetail } from "@/hooks/store";
1211
// ui
1312
// icons
1413
// types
1514

16-
type Props = {
17-
closePalette: () => void;
18-
issue: TIssue;
19-
};
15+
type Props = { closePalette: () => void; issue: TIssue };
2016

2117
export const ChangeIssueState: React.FC<Props> = observer((props) => {
2218
const { closePalette, issue } = props;
2319
// router params
2420
const { workspaceSlug, projectId } = useParams();
2521
// store hooks
26-
const {
27-
issues: { updateIssue },
28-
} = useIssues(EIssuesStoreType.PROJECT);
22+
const { updateIssue } = useIssueDetail();
2923
const { projectStates } = useProjectState();
3024

3125
const submitChanges = async (formData: Partial<TIssue>) => {

web/core/components/command-palette/command-modal.tsx

Lines changed: 65 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import { Command } from "cmdk";
55
import { observer } from "mobx-react";
66
import { useParams } from "next/navigation";
77
import useSWR from "swr";
8-
import { CommandIcon, FolderPlus, Search, Settings } from "lucide-react";
8+
import { CommandIcon, FolderPlus, Search, Settings, X } from "lucide-react";
99
import { Dialog, Transition } from "@headlessui/react";
1010
// plane imports
1111
import { EUserPermissions, EUserPermissionsLevel } from "@plane/constants";
1212
import { useTranslation } from "@plane/i18n";
1313
import { IWorkspaceSearchResults } from "@plane/types";
1414
import { LayersIcon, Loader, ToggleSwitch } from "@plane/ui";
15+
import { cn } from "@plane/utils";
1516
// components
1617
import {
1718
ChangeIssueAssignee,
@@ -56,18 +57,11 @@ export const CommandModal: React.FC = observer(() => {
5657
const [isSearching, setIsSearching] = useState(false);
5758
const [searchTerm, setSearchTerm] = useState("");
5859
const [results, setResults] = useState<IWorkspaceSearchResults>({
59-
results: {
60-
workspace: [],
61-
project: [],
62-
issue: [],
63-
cycle: [],
64-
module: [],
65-
issue_view: [],
66-
page: [],
67-
},
60+
results: { workspace: [], project: [], issue: [], cycle: [], module: [], issue_view: [], page: [] },
6861
});
69-
const [isWorkspaceLevel, setIsWorkspaceLevel] = useState(true);
62+
const [isWorkspaceLevel, setIsWorkspaceLevel] = useState(false);
7063
const [pages, setPages] = useState<string[]>([]);
64+
const [searchInIssue, setSearchInIssue] = useState(false);
7165
// plane hooks
7266
const { t } = useTranslation();
7367
// hooks
@@ -96,6 +90,20 @@ export const CommandModal: React.FC = observer(() => {
9690
: null
9791
);
9892

93+
useEffect(() => {
94+
if (issueDetails && isCommandPaletteOpen) {
95+
setSearchInIssue(true);
96+
}
97+
}, [issueDetails, isCommandPaletteOpen]);
98+
99+
useEffect(() => {
100+
if (!projectId && !isWorkspaceLevel) {
101+
setIsWorkspaceLevel(true);
102+
} else {
103+
setIsWorkspaceLevel(false);
104+
}
105+
}, [projectId]);
106+
99107
const closePalette = () => {
100108
toggleCommandPaletteModal(false);
101109
};
@@ -133,15 +141,7 @@ export const CommandModal: React.FC = observer(() => {
133141
});
134142
} else {
135143
setResults({
136-
results: {
137-
workspace: [],
138-
project: [],
139-
issue: [],
140-
cycle: [],
141-
module: [],
142-
issue_view: [],
143-
page: [],
144-
},
144+
results: { workspace: [], project: [], issue: [], cycle: [], module: [], issue_view: [], page: [] },
145145
});
146146
setIsLoading(false);
147147
setIsSearching(false);
@@ -152,7 +152,16 @@ export const CommandModal: React.FC = observer(() => {
152152

153153
return (
154154
<Transition.Root show={isCommandPaletteOpen} afterLeave={() => setSearchTerm("")} as={React.Fragment}>
155-
<Dialog as="div" className="relative z-30" onClose={() => closePalette()}>
155+
<Dialog
156+
as="div"
157+
className="relative z-30"
158+
onClose={() => {
159+
closePalette();
160+
if (searchInIssue) {
161+
setSearchInIssue(true);
162+
}
163+
}}
164+
>
156165
<Transition.Child
157166
as={React.Fragment}
158167
enter="ease-out duration-300"
@@ -213,10 +222,7 @@ export const CommandModal: React.FC = observer(() => {
213222
nextItem.setAttribute("aria-selected", "true");
214223
selectedItem?.setAttribute("aria-selected", "false");
215224
nextItem.focus();
216-
nextItem.scrollIntoView({
217-
behavior: "smooth",
218-
block: "nearest",
219-
});
225+
nextItem.scrollIntoView({ behavior: "smooth", block: "nearest" });
220226
}
221227
}
222228

@@ -237,32 +243,40 @@ export const CommandModal: React.FC = observer(() => {
237243
}
238244
}}
239245
>
240-
<div
241-
className={`flex gap-4 pb-0 sm:items-center ${
242-
issueDetails ? "flex-col justify-between sm:flex-row" : "justify-end"
243-
}`}
244-
>
245-
{issueDetails && (
246-
<div className="flex gap-2 items-center overflow-hidden truncate rounded-md bg-custom-background-80 p-2 text-xs font-medium text-custom-text-200">
247-
{issueDetails.project_id && (
248-
<IssueIdentifier
249-
issueId={issueDetails.id}
250-
projectId={issueDetails.project_id}
251-
textContainerClassName="text-xs font-medium text-custom-text-200"
252-
/>
253-
)}
254-
{issueDetails.name}
255-
</div>
256-
)}
257-
</div>
258-
<div className="relative">
259-
<Search
260-
className="pointer-events-none absolute left-4 top-1/2 h-4 w-4 -translate-y-1/2 text-custom-text-200"
261-
aria-hidden="true"
262-
strokeWidth={2}
263-
/>
246+
<div className="relative flex items-center px-4 border-0 border-b border-custom-border-200">
247+
<div className="flex items-center gap-2 flex-shrink-0">
248+
<Search
249+
className="h-4 w-4 text-custom-text-200 flex-shrink-0"
250+
aria-hidden="true"
251+
strokeWidth={2}
252+
/>
253+
{searchInIssue && issueDetails && (
254+
<>
255+
<span className="flex items-center text-sm">Update in:</span>
256+
<span className="flex items-center gap-1 rounded px-1.5 py-1 text-sm bg-custom-primary-100/10 ">
257+
{issueDetails.project_id && (
258+
<IssueIdentifier
259+
issueId={issueDetails.id}
260+
projectId={issueDetails.project_id}
261+
textContainerClassName="text-sm text-custom-primary-200"
262+
/>
263+
)}
264+
<X
265+
size={12}
266+
strokeWidth={2}
267+
className="flex-shrink-0 cursor-pointer"
268+
onClick={() => {
269+
setSearchInIssue(false);
270+
}}
271+
/>
272+
</span>
273+
</>
274+
)}
275+
</div>
264276
<Command.Input
265-
className="w-full border-0 border-b border-custom-border-200 bg-transparent p-4 pl-11 text-sm text-custom-text-100 outline-none placeholder:text-custom-text-400 focus:ring-0"
277+
className={cn(
278+
"w-full bg-transparent p-4 text-sm text-custom-text-100 outline-none placeholder:text-custom-text-400 focus:ring-0"
279+
)}
266280
placeholder={placeholder}
267281
value={searchTerm}
268282
onValueChange={(e) => setSearchTerm(e)}
@@ -308,7 +322,7 @@ export const CommandModal: React.FC = observer(() => {
308322
{!page && (
309323
<>
310324
{/* issue actions */}
311-
{issueId && (
325+
{issueId && issueDetails && searchInIssue && (
312326
<CommandPaletteIssueActions
313327
closePalette={closePalette}
314328
issueDetails={issueDetails}

0 commit comments

Comments
 (0)