fix: 💄 active links in back navigation on side actions

This commit is contained in:
Alexis Gousseau 2026-01-22 16:33:03 +01:00
parent b089dd66dc
commit e9049986ea

View file

@ -59,23 +59,36 @@ import str from "@/hooks/use-string";
import useTrans from "@/hooks/use-translations";
import { AppEnv, AuthProp, LaravelEnum } from "@/back/types/global";
type NavList = Array<{
type NavListProps = Array<{
/** Title of the group. */
title: string,
/** Condition to set the visibility of the group. */
show: boolean,
/** Links presents in the group. */
links: Array<{
/** Title of the button. */
title: string,
/** Main model of the button (used for route checking). */
model?: string,
/** External link of the button (if it's a not CRUD, just a simple link). */
link?: string,
/** Define some conditions for active or not the button (in addition to the route model checking if defined). */
activeCondition?: boolean[],
/** Condition to set the visibility of the button. */
show: boolean,
/** Lucide icon of the button. */
icon: ElementType,
/** Define some actions in side popover (like create/trash). */
actions?: (model: string) => ReactNode,
}>
}>
type CustomDropdownMenuItem = {
type CustomDropdownMenuItemProps = {
/** Link of the action. */
route: string;
policy?: boolean;
/** Lucide icon of the action. */
icon?: ElementType;
/** Translation of the action. */
trans?: string;
};
@ -89,7 +102,7 @@ export default function AppSidebar() {
const { state } = useSidebar();
const prevStateRef = useRef(state);
const isCollapsed = state === "collapsed";
const navList: NavList = [
const navList: NavListProps = [
{
title: useTrans("back.pages"),
show: true,
@ -135,10 +148,9 @@ export default function AppSidebar() {
show: authPolicies.news.viewAny || auth.policies.contact_counts.viewAny,
links: [
{
title: str(useTrans("models.classes.news", { choice: 2 }))
.ucFirst()
.value(),
title: str(useTrans("models.classes.news", { choice: 2 })).ucFirst().value(),
model: "news",
activeCondition: [route().current("back.news-categories.*"), route().current('back.news-tags.*')],
icon: NewspaperIcon,
show: auth.policies.news.viewAny,
actions: (model: string) => filterActions({
@ -159,36 +171,29 @@ export default function AppSidebar() {
<CustomDropdownMenuItem
route={route(`back.news-categories.index`)}
icon={FolderIcon}
trans={str(useTrans("models.classes.news-category", { choice: 2 }))
.ucFirst()
.value()}
trans={str(useTrans("models.classes.news-category", { choice: 2 })).ucFirst().value()}
/>
),
authPolicies.newsTags.viewAny && (
<CustomDropdownMenuItem
route={route(`back.news-tags.index`)}
icon={TagIcon}
trans={str(useTrans("models.classes.news-tag", { choice: 2 }))
.ucFirst()
.value()}
trans={str(useTrans("models.classes.news-tag", { choice: 2 })).ucFirst().value()}
/>
),
]
})
},
{
title: str(useTrans("models.classes.contact-count"))
.ucFirst()
.value(),
title: str(useTrans("models.classes.contact-count")).ucFirst().value(),
model: "contact-counts",
icon: ContactIcon,
show: auth.policies.contact_counts.viewAny,
},
{
title: str(useTrans("models.classes.document", { choice: 2 }))
.ucFirst()
.value(),
title: str(useTrans("models.classes.document", { choice: 2 })).ucFirst().value(),
model: "documents",
activeCondition: [route().current("back.document-categories.*"), route().current('back.document-tags.*')],
icon: FileInputIcon,
show: auth.policies.documents.viewAny,
actions: (model: string) => filterActions({
@ -202,29 +207,23 @@ export default function AppSidebar() {
<CustomDropdownMenuItem
icon={FolderIcon}
route={route(`back.document-categories.index`)}
trans={str(useTrans("models.classes.document-category", { choice: 2 }))
.ucFirst()
.value()}
trans={str(useTrans("models.classes.document-category", { choice: 2 })).ucFirst().value()}
/>
),
authPolicies.documentTags.create && (
<CustomDropdownMenuItem
icon={TagIcon}
route={route(`back.document-tags.index`)}
trans={str(useTrans("models.classes.document-tag", { choice: 2 }))
.ucFirst()
.value()}
trans={str(useTrans("models.classes.document-tag", { choice: 2 })).ucFirst().value()}
/>
)
]
})
},
{
title: str(useTrans("models.classes.company", { choice: 2 }))
.ucFirst()
.plural()
.value(),
title: str(useTrans("models.classes.company", { choice: 2 })).ucFirst().plural().value(),
model: "companies",
activeCondition: [route().current("back.company-activities.*"), route().current('back.company-sectors.*')],
icon: Building2Icon,
show: auth.policies.companies.viewAny,
actions: (model: string) => filterActions({
@ -322,7 +321,7 @@ export default function AppSidebar() {
route,
icon: Icon = Views.CREATION.icon,
trans = str(useTrans(`crud.actions.${Views.CREATION.label}`)).ucFirst().value(),
}: CustomDropdownMenuItem) => {
}: CustomDropdownMenuItemProps) => {
return (
<DropdownMenuItem className="p-0">
<Button variant="ghost" asChild>
@ -375,12 +374,10 @@ export default function AppSidebar() {
<SidebarMenu>
{navGroup.links.map((navLink) => {
if (navLink.show) {
const isActive = route().current(`back.${navLink.model}.*`) || navLink.activeCondition?.some(Boolean);
const sidebarButton = (
<SidebarMenuButton
className={`${route().current(`back.${navLink.model}.*`)
? "text-secondary-foreground"
: "text-primary-foreground"
}`}
className={isActive ? "text-secondary-foreground" : "text-primary-foreground"}
asChild
>
{navLink.link ? (
@ -405,10 +402,9 @@ export default function AppSidebar() {
);
return <SidebarMenuItem
key={navLink.title}
className={`transition-colors rounded-md ${route().current(
`back.${navLink.model}.*`,
) ? "bg-secondary text-secondary-foreground" : "bg-opacity-0"
}`}
className={
`transition-colors rounded-md ${isActive ? "bg-secondary text-secondary-foreground" : "bg-opacity-0"}`
}
>
{isCollapsed ? (
<Tooltip>
@ -426,10 +422,9 @@ export default function AppSidebar() {
<DropdownMenu>
<DropdownMenuTrigger asChild>
<SidebarMenuAction
className={`${route().current(
`back.${navLink.model}.*`,
) ? "text-secondary-foreground" : ""
} !top-0 !right-0 px-4 h-full`}
className={
`${isActive ? "text-secondary-foreground" : ""} !top-0 !right-0 px-4 h-full`
}
>
<MoreHorizontalIcon />
</SidebarMenuAction>