Skip to content

[WEB-3978] chore: cmd k search result redirection improvements #7012

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
25 changes: 25 additions & 0 deletions web/core/components/command-palette/actions/helper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { store } from "@/lib/store-context";

export const openProjectAndScrollToSidebar = (itemProjectId: string | undefined) => {
if (!itemProjectId) {
console.warn("No project id provided. Cannot open project and scroll to sidebar.");
return;
}
// open the project list
store.commandPalette.toggleProjectListOpen(itemProjectId, true);
// scroll to the element
const scrollElementId = `sidebar-${itemProjectId}-JOINED`;
const scrollElement = document.getElementById(scrollElementId);
// if the element exists, scroll to it
if (scrollElement) {
setTimeout(() => {
scrollElement.scrollIntoView({ behavior: "smooth", block: "start" });
// Restart the highlight animation every time
scrollElement.style.animation = "none";
// Trigger a reflow to ensure the animation is restarted
void scrollElement.offsetWidth;
// Restart the highlight animation
scrollElement.style.animation = "highlight 2s ease-in-out";
});
}
};
13 changes: 11 additions & 2 deletions web/core/components/command-palette/actions/search-results.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
"use client";

import { Command } from "cmdk";
import { observer } from "mobx-react";
import { useParams } from "next/navigation";
// plane imports
import { IWorkspaceSearchResults } from "@plane/types";
// hooks
import { useAppRouter } from "@/hooks/use-app-router";
// plane web imports
import { commandGroups } from "@/plane-web/components/command-palette";
// helpers
import { openProjectAndScrollToSidebar } from "./helper";

type Props = {
closePalette: () => void;
results: IWorkspaceSearchResults;
};

export const CommandPaletteSearchResults: React.FC<Props> = (props) => {
export const CommandPaletteSearchResults: React.FC<Props> = observer((props) => {
const { closePalette, results } = props;
// router
const router = useAppRouter();
Expand All @@ -38,6 +41,12 @@ export const CommandPaletteSearchResults: React.FC<Props> = (props) => {
onSelect={() => {
closePalette();
router.push(currentSection.path(item, projectId));
const itemProjectId =
item?.project_id ||
(Array.isArray(item?.project_ids) && item?.project_ids?.length > 0
? item?.project_ids[0]
: undefined);
if (itemProjectId) openProjectAndScrollToSidebar(itemProjectId);
}}
value={`${key}-${item?.id}-${item.name}-${item.project__identifier ?? ""}-${item.sequence_id ?? ""}`}
className="focus:outline-none"
Expand All @@ -54,4 +63,4 @@ export const CommandPaletteSearchResults: React.FC<Props> = (props) => {
})}
</>
);
};
});
9 changes: 6 additions & 3 deletions web/core/components/workspace/sidebar/projects-list-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { LeaveProjectModal, PublishProjectModal } from "@/components/project";
// helpers
import { cn } from "@/helpers/common.helper";
// hooks
import { useAppTheme, useEventTracker, useProject, useUserPermissions } from "@/hooks/store";
import { useAppTheme, useCommandPalette, useEventTracker, useProject, useUserPermissions } from "@/hooks/store";
import { usePlatformOS } from "@/hooks/use-platform-os";
// plane-web components
import { ProjectNavigationRoot } from "@/plane-web/components/sidebar";
Expand Down Expand Up @@ -64,12 +64,13 @@ export const SidebarProjectsListItem: React.FC<Props> = observer((props) => {
const { getPartialProjectById } = useProject();
const { isMobile } = usePlatformOS();
const { allowPermissions } = useUserPermissions();
const { getIsProjectListOpen, toggleProjectListOpen } = useCommandPalette();
// states
const [leaveProjectModalOpen, setLeaveProjectModal] = useState(false);
const [publishModalOpen, setPublishModal] = useState(false);
const [isMenuActive, setIsMenuActive] = useState(false);
const [isDragging, setIsDragging] = useState(false);
const [isProjectListOpen, setIsProjectListOpen] = useState(false);
const isProjectListOpen = getIsProjectListOpen(projectId);
const [instruction, setInstruction] = useState<"DRAG_OVER" | "DRAG_BELOW" | undefined>(undefined);
// refs
const actionSectionRef = useRef<HTMLDivElement | null>(null);
Expand All @@ -79,6 +80,8 @@ export const SidebarProjectsListItem: React.FC<Props> = observer((props) => {
const { workspaceSlug, projectId: URLProjectId } = useParams();
// derived values
const project = getPartialProjectById(projectId);
// toggle project list open
const setIsProjectListOpen = (value: boolean) => toggleProjectListOpen(projectId, value);
// auth
const isAdmin = allowPermissions(
[EUserPermissions.ADMIN],
Expand Down Expand Up @@ -198,7 +201,7 @@ export const SidebarProjectsListItem: React.FC<Props> = observer((props) => {
if (URLProjectId === project.id) setIsProjectListOpen(true);
}, [URLProjectId]);

const handleItemClick = () => setIsProjectListOpen((prev) => !prev);
const handleItemClick = () => setIsProjectListOpen(!isProjectListOpen);
return (
<>
<PublishProjectModal isOpen={publishModalOpen} project={project} onClose={() => setPublishModal(false)} />
Expand Down
19 changes: 19 additions & 0 deletions web/core/store/base-command-palette.store.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { observable, action, makeObservable } from "mobx";
import { computedFn } from "mobx-utils";
import {
EIssuesStoreType,
TCreateModalStoreTypes,
Expand Down Expand Up @@ -26,6 +27,8 @@ export interface IBaseCommandPaletteStore {
isBulkDeleteIssueModalOpen: boolean;
createIssueStoreType: TCreateModalStoreTypes;
allStickiesModal: boolean;
projectListOpenMap: Record<string, boolean>;
getIsProjectListOpen: (projectId: string) => boolean;
// toggle actions
toggleCommandPaletteModal: (value?: boolean) => void;
toggleShortcutModal: (value?: boolean) => void;
Expand All @@ -38,6 +41,7 @@ export interface IBaseCommandPaletteStore {
toggleDeleteIssueModal: (value?: boolean) => void;
toggleBulkDeleteIssueModal: (value?: boolean) => void;
toggleAllStickiesModal: (value?: boolean) => void;
toggleProjectListOpen: (projectId: string, value?: boolean) => void;
}

export abstract class BaseCommandPaletteStore implements IBaseCommandPaletteStore {
Expand All @@ -54,6 +58,7 @@ export abstract class BaseCommandPaletteStore implements IBaseCommandPaletteStor
createPageModal: TCreatePageModal = DEFAULT_CREATE_PAGE_MODAL_DATA;
createIssueStoreType: TCreateModalStoreTypes = EIssuesStoreType.PROJECT;
allStickiesModal: boolean = false;
projectListOpenMap: Record<string, boolean> = {};

constructor() {
makeObservable(this, {
Expand All @@ -70,6 +75,7 @@ export abstract class BaseCommandPaletteStore implements IBaseCommandPaletteStor
createPageModal: observable,
createIssueStoreType: observable,
allStickiesModal: observable,
projectListOpenMap: observable,
// projectPages: computed,
// toggle actions
toggleCommandPaletteModal: action,
Expand All @@ -83,6 +89,7 @@ export abstract class BaseCommandPaletteStore implements IBaseCommandPaletteStor
toggleDeleteIssueModal: action,
toggleBulkDeleteIssueModal: action,
toggleAllStickiesModal: action,
toggleProjectListOpen: action,
});
}

Expand All @@ -104,6 +111,18 @@ export abstract class BaseCommandPaletteStore implements IBaseCommandPaletteStor
this.allStickiesModal
);
}
// computedFn
getIsProjectListOpen = computedFn((projectId: string) => this.projectListOpenMap[projectId]);

/**
* Toggles the project list open state
* @param projectId
* @param value
*/
toggleProjectListOpen = (projectId: string, value?: boolean) => {
if (value !== undefined) this.projectListOpenMap[projectId] = value;
else this.projectListOpenMap[projectId] = !this.projectListOpenMap[projectId];
};

/**
* Toggles the command palette modal
Expand Down
11 changes: 11 additions & 0 deletions web/styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -942,3 +942,14 @@ div.web-view-spinner div.bar12 {
.animate-fade-out {
animation: fadeOut 500ms ease-in 100ms forwards;
}

@keyframes highlight {
0% {
background-color: rgba(var(--color-background-90), 1);
border-radius: 4px;
}
100% {
background-color: transparent;
border-radius: 4px;
}
}