90 lines
3.1 KiB
TypeScript
90 lines
3.1 KiB
TypeScript
/**
|
|
* Copyright (c) 2023-present Plane Software, Inc. and contributors
|
|
* SPDX-License-Identifier: AGPL-3.0-only
|
|
* See the LICENSE file for details.
|
|
*/
|
|
|
|
import { observer } from "mobx-react";
|
|
// plane imports
|
|
import { EUserPermissionsLevel } from "@plane/constants";
|
|
import { useTranslation } from "@plane/i18n";
|
|
import type { ICustomSearchSelectOption } from "@plane/types";
|
|
import { BreadcrumbNavigationSearchDropdown } from "@plane/ui";
|
|
// components
|
|
import type { TNavigationItem } from "@/components/workspace/sidebar/project-navigation";
|
|
// hooks
|
|
import { useProject } from "@/hooks/store/use-project";
|
|
import { useAppRouter } from "@/hooks/use-app-router";
|
|
import { useUserPermissions } from "@/hooks/store/user";
|
|
// local imports
|
|
import { getProjectFeatureNavigation } from "../projects/navigation/helper";
|
|
|
|
type TProjectFeatureBreadcrumbProps = {
|
|
workspaceSlug: string;
|
|
projectId: string;
|
|
featureKey: TNavigationItem["key"];
|
|
isLast?: boolean;
|
|
additionalNavigationItems?: TNavigationItem[];
|
|
};
|
|
|
|
export const ProjectFeatureBreadcrumb = observer(function ProjectFeatureBreadcrumb(
|
|
props: TProjectFeatureBreadcrumbProps
|
|
) {
|
|
const { workspaceSlug, projectId, featureKey, isLast = false, additionalNavigationItems } = props;
|
|
const { t } = useTranslation();
|
|
const router = useAppRouter();
|
|
// store hooks
|
|
const { getPartialProjectById } = useProject();
|
|
const { allowPermissions } = useUserPermissions();
|
|
// derived values
|
|
const project = getPartialProjectById(projectId);
|
|
|
|
if (!project) return null;
|
|
|
|
const navigationItems = getProjectFeatureNavigation(workspaceSlug, projectId, project);
|
|
|
|
// if additional navigation items are provided, add them to the navigation items
|
|
const allNavigationItems = [...(additionalNavigationItems || []), ...navigationItems];
|
|
|
|
const availableNavigationItems = allNavigationItems.filter(
|
|
(item) =>
|
|
item.shouldRender &&
|
|
allowPermissions(item.access, EUserPermissionsLevel.PROJECT, workspaceSlug.toString(), projectId.toString())
|
|
);
|
|
|
|
const currentNavigationItem = availableNavigationItems.find((item) => item.key === featureKey);
|
|
const Icon = currentNavigationItem?.icon;
|
|
const name = currentNavigationItem ? t(currentNavigationItem.i18n_key) : undefined;
|
|
|
|
const switcherOptions = availableNavigationItems.map(
|
|
(item): ICustomSearchSelectOption => ({
|
|
value: item.key,
|
|
query: t(item.i18n_key),
|
|
content: (
|
|
<div className="flex items-center gap-2">
|
|
<item.icon className="h-3.5 w-3.5 text-tertiary" />
|
|
<span>{t(item.i18n_key)}</span>
|
|
</div>
|
|
),
|
|
})
|
|
);
|
|
|
|
return (
|
|
<BreadcrumbNavigationSearchDropdown
|
|
selectedItem={featureKey}
|
|
navigationItems={switcherOptions}
|
|
onChange={(value: string) => {
|
|
const nextNavigationItem = availableNavigationItems.find((item) => item.key === value);
|
|
if (nextNavigationItem?.href) {
|
|
router.push(nextNavigationItem.href);
|
|
}
|
|
}}
|
|
title={name}
|
|
icon={Icon ? <Icon className="h-3.5 w-3.5 text-tertiary" /> : undefined}
|
|
isLast={isLast}
|
|
openOnLabelClick
|
|
showLastChevron={false}
|
|
/>
|
|
);
|
|
});
|