Skip to content
Merged
Changes from 1 commit
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
94 changes: 67 additions & 27 deletions web/core/components/command-palette/command-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const CommandModal: React.FC = observer(() => {
page: [],
},
});
const [isWorkspaceLevel, setIsWorkspaceLevel] = useState(false);
const [isWorkspaceLevel, setIsWorkspaceLevel] = useState(true);
const [pages, setPages] = useState<string[]>([]);
// plane hooks
const { t } = useTranslation();
Expand Down Expand Up @@ -176,22 +176,62 @@ export const CommandModal: React.FC = observer(() => {
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<Dialog.Panel className="relative flex w-full max-w-2xl transform items-center justify-center divide-y divide-custom-border-200 divide-opacity-10 rounded-lg bg-custom-background-100 shadow-custom-shadow-md transition-all">
<Dialog.Panel className="relative flex w-full max-w-2xl transform flex-col items-center justify-center divide-y divide-custom-border-200 divide-opacity-10 rounded-lg bg-custom-background-100 shadow-custom-shadow-md transition-all">
<div className="w-full max-w-2xl">
<Command
filter={(value, search) => {
if (value.toLowerCase().includes(search.toLowerCase())) return 1;
return 0;
}}
onKeyDown={(e) => {
// when search term is not empty, esc should clear the search term
if (e.key === "Escape" && searchTerm) setSearchTerm("");
shouldFilter={searchTerm.length > 0}
onKeyDown={(e: any) => {
if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
e.preventDefault();
e.stopPropagation();
closePalette();
return;
}

if (e.key === 'Tab') {
e.preventDefault();
const commandList = document.querySelector('[cmdk-list]');
const items = commandList?.querySelectorAll('[cmdk-item]') || [];
const selectedItem = commandList?.querySelector('[aria-selected="true"]');

if (items.length === 0) return;

const currentIndex = Array.from(items).indexOf(selectedItem as Element);
let nextIndex;

// when user tries to close the modal with esc
if (e.key === "Escape" && !page && !searchTerm) closePalette();
if (e.shiftKey) {
nextIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;
} else {
nextIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;
}

const nextItem = items[nextIndex] as HTMLElement;

if (nextItem) {
nextItem.setAttribute('aria-selected', 'true');
selectedItem?.setAttribute('aria-selected', 'false');
nextItem.focus();
nextItem.scrollIntoView({
behavior: 'smooth',
block: 'nearest'
});
}
}

if (e.key === "Escape" && searchTerm) {
e.preventDefault();
setSearchTerm("");
}

if (e.key === "Escape" && !page && !searchTerm) {
e.preventDefault();
closePalette();
}

// Escape goes to previous page
// Backspace goes to previous page when search is empty
if (e.key === "Escape" || (e.key === "Backspace" && !searchTerm)) {
e.preventDefault();
setPages((pages) => pages.slice(0, -1));
Expand All @@ -200,7 +240,7 @@ export const CommandModal: React.FC = observer(() => {
}}
>
<div
className={`flex gap-4 p-3 pb-0 sm:items-center ${
className={`flex gap-4 pb-0 sm:items-center ${
issueDetails ? "flex-col justify-between sm:flex-row" : "justify-end"
}`}
>
Expand All @@ -216,23 +256,6 @@ export const CommandModal: React.FC = observer(() => {
{issueDetails.name}
</div>
)}
{projectId && (
<Tooltip tooltipContent="Toggle workspace level search" isMobile={isMobile}>
<div className="flex flex-shrink-0 cursor-pointer items-center gap-1 self-end text-xs sm:self-center">
<button
type="button"
onClick={() => setIsWorkspaceLevel((prevData) => !prevData)}
className="flex-shrink-0"
>
Workspace Level
</button>
<ToggleSwitch
value={isWorkspaceLevel}
onChange={() => setIsWorkspaceLevel((prevData) => !prevData)}
/>
</div>
</Tooltip>
)}
</div>
<div className="relative">
<Search
Expand Down Expand Up @@ -413,6 +436,23 @@ export const CommandModal: React.FC = observer(() => {
</Command.List>
</Command>
</div>

{/* Bottom overlay */}
<div className="w-full flex items-center justify-between px-4 py-2 border-t border-custom-border-200 bg-custom-background-90/80 rounded-b-lg">
<div className="flex items-center gap-2">
<span className="text-xs text-custom-text-300">Actions</span>
<kbd className="px-2 py-1 text-xs rounded bg-custom-background-80">⌘</kbd>
<kbd className="px-2 py-1 text-xs rounded bg-custom-background-80">K</kbd>
</div>
<div className="flex items-center gap-2">
<span className="text-xs text-custom-text-300">Workspace Level</span>
<ToggleSwitch
value={isWorkspaceLevel}
onChange={() => setIsWorkspaceLevel((prevData) => !prevData)}
size="sm"
/>
</div>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
Expand Down
Loading