Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7743e59fff |
@@ -3,6 +3,7 @@
|
||||
import { Command } from "cmdk";
|
||||
import { observer } from "mobx-react";
|
||||
import { useParams } from "next/navigation";
|
||||
import type { MouseEvent } from "react";
|
||||
// plane imports
|
||||
import type { IWorkspaceSearchResults } from "@plane/types";
|
||||
// hooks
|
||||
@@ -35,28 +36,43 @@ export const CommandPaletteSearchResults: React.FC<Props> = observer((props) =>
|
||||
if (section.length > 0) {
|
||||
return (
|
||||
<Command.Group key={key} heading={`${currentSection.title} search`}>
|
||||
{section.map((item: any) => (
|
||||
<Command.Item
|
||||
key={item.id}
|
||||
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"
|
||||
>
|
||||
<div className="flex items-center gap-2 overflow-hidden text-custom-text-200">
|
||||
{currentSection.icon}
|
||||
<p className="block flex-1 truncate">{currentSection.itemName(item)}</p>
|
||||
</div>
|
||||
</Command.Item>
|
||||
))}
|
||||
{section.map((item: any) => {
|
||||
const targetPath = currentSection.path(item, projectId);
|
||||
const itemProjectId =
|
||||
item?.project_id ||
|
||||
(Array.isArray(item?.project_ids) && item?.project_ids?.length > 0
|
||||
? item?.project_ids[0]
|
||||
: undefined);
|
||||
|
||||
const handleMetaClick = (event: MouseEvent<HTMLDivElement>) => {
|
||||
if (!event.metaKey && !event.ctrlKey) return;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
closePalette();
|
||||
window.open(targetPath, "_blank", "noopener,noreferrer");
|
||||
};
|
||||
|
||||
return (
|
||||
<Command.Item
|
||||
key={item.id}
|
||||
onMouseDown={handleMetaClick}
|
||||
onSelect={() => {
|
||||
closePalette();
|
||||
router.push(targetPath);
|
||||
if (itemProjectId) openProjectAndScrollToSidebar(itemProjectId);
|
||||
}}
|
||||
value={`${key}-${item?.id}-${item.name}-${item.project__identifier ?? ""}-${item.sequence_id ?? ""}`}
|
||||
className="focus:outline-none"
|
||||
>
|
||||
<div className="flex items-center gap-2 overflow-hidden text-custom-text-200">
|
||||
{currentSection.icon}
|
||||
<p className="block flex-1 truncate">{currentSection.itemName(item)}</p>
|
||||
</div>
|
||||
</Command.Item>
|
||||
);
|
||||
})}
|
||||
</Command.Group>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -177,7 +177,6 @@ export const MemberDropdownBase: React.FC<TMemberDropdownBaseProps> = observer((
|
||||
optionsClassName={optionsClassName}
|
||||
placement={placement}
|
||||
referenceElement={referenceElement}
|
||||
selectedMemberIds={Array.isArray(value) ? value : value ? [value] : []}
|
||||
/>
|
||||
)}
|
||||
</ComboDropDown>
|
||||
|
||||
@@ -29,7 +29,6 @@ interface Props {
|
||||
optionsClassName?: string;
|
||||
placement: Placement | undefined;
|
||||
referenceElement: HTMLButtonElement | null;
|
||||
selectedMemberIds?: string[];
|
||||
}
|
||||
|
||||
export const MemberOptions: React.FC<Props> = observer((props: Props) => {
|
||||
@@ -41,7 +40,6 @@ export const MemberOptions: React.FC<Props> = observer((props: Props) => {
|
||||
optionsClassName = "",
|
||||
placement,
|
||||
referenceElement,
|
||||
selectedMemberIds = [],
|
||||
} = props;
|
||||
// router
|
||||
const { workspaceSlug } = useParams();
|
||||
@@ -87,14 +85,8 @@ export const MemberOptions: React.FC<Props> = observer((props: Props) => {
|
||||
}
|
||||
};
|
||||
|
||||
const selectedMemberIdsSet = new Set(selectedMemberIds);
|
||||
|
||||
const options = memberIds
|
||||
?.map((userId) => {
|
||||
const isSuspended = isUserSuspended(userId, workspaceSlug?.toString());
|
||||
|
||||
if (isSuspended && !selectedMemberIdsSet.has(userId)) return null;
|
||||
|
||||
const userDetails = getUserDetails(userId);
|
||||
return {
|
||||
value: userId,
|
||||
@@ -102,30 +94,25 @@ export const MemberOptions: React.FC<Props> = observer((props: Props) => {
|
||||
content: (
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="w-4">
|
||||
{isSuspended ? (
|
||||
{isUserSuspended(userId, workspaceSlug?.toString()) ? (
|
||||
<SuspendedUserIcon className="h-3.5 w-3.5 text-custom-text-400" />
|
||||
) : (
|
||||
<Avatar name={userDetails?.display_name} src={getFileURL(userDetails?.avatar_url ?? "")} />
|
||||
)}
|
||||
</div>
|
||||
<span
|
||||
className={cn("flex-grow truncate", isSuspended ? "text-custom-text-400" : "")}
|
||||
className={cn(
|
||||
"flex-grow truncate",
|
||||
isUserSuspended(userId, workspaceSlug?.toString()) ? "text-custom-text-400" : ""
|
||||
)}
|
||||
>
|
||||
{currentUser?.id === userId ? t("you") : userDetails?.display_name}
|
||||
</span>
|
||||
</div>
|
||||
),
|
||||
isSuspended,
|
||||
};
|
||||
})
|
||||
.filter((o): o is NonNullable<typeof o> => !!o)
|
||||
?.sort((a, b) => {
|
||||
const isASelected = selectedMemberIdsSet.has(a.value);
|
||||
const isBSelected = selectedMemberIdsSet.has(b.value);
|
||||
|
||||
if (isASelected === isBSelected) return 0;
|
||||
return isASelected ? -1 : 1;
|
||||
});
|
||||
.filter((o) => !!o);
|
||||
|
||||
const filteredOptions =
|
||||
query === "" ? options : options?.filter((o) => o?.query.toLowerCase().includes(query.toLowerCase()));
|
||||
@@ -170,16 +157,18 @@ export const MemberOptions: React.FC<Props> = observer((props: Props) => {
|
||||
"flex w-full select-none items-center justify-between gap-2 truncate rounded px-1 py-1.5",
|
||||
active && "bg-custom-background-80",
|
||||
selected ? "text-custom-text-100" : "text-custom-text-200",
|
||||
option.isSuspended && !selected ? "cursor-not-allowed" : "cursor-pointer"
|
||||
isUserSuspended(option.value, workspaceSlug?.toString())
|
||||
? "cursor-not-allowed"
|
||||
: "cursor-pointer"
|
||||
)
|
||||
}
|
||||
disabled={option.isSuspended && !selectedMemberIdsSet.has(option.value)}
|
||||
disabled={isUserSuspended(option.value, workspaceSlug?.toString())}
|
||||
>
|
||||
{({ selected }) => (
|
||||
<>
|
||||
<span className="flex-grow truncate">{option.content}</span>
|
||||
{selected && <Check className="h-3.5 w-3.5 flex-shrink-0" />}
|
||||
{option.isSuspended && (
|
||||
{isUserSuspended(option.value, workspaceSlug?.toString()) && (
|
||||
<Pill variant={EPillVariant.DEFAULT} size={EPillSize.XS} className="border-none">
|
||||
Suspended
|
||||
</Pill>
|
||||
|
||||
Reference in New Issue
Block a user