-
-
Notifications
You must be signed in to change notification settings - Fork 11.4k
Remove members-forward route #27040
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
base: main
Are you sure you want to change the base?
Remove members-forward route #27040
Changes from all commits
7ec7bf4
b826ec1
a6eb894
ffd6dff
74c1fe2
be7637e
c8d6501
d4d2dc4
583b041
1146f41
f01eb5f
9697d4d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,11 +17,13 @@ import { useNavigationExpanded } from "./hooks/use-navigation-preferences"; | |
| import { NavCustomViews } from "./nav-custom-views"; | ||
| import { NavMemberViews } from "./nav-member-views"; | ||
| import { useMemberSidebarViews } from "./member-sidebar-views"; | ||
| import { getMembersNavActiveRoutes, isMembersNavActive } from "./nav-content.helpers"; | ||
| import { isMembersNavActive } from "./nav-content.helpers"; | ||
| import { useCustomSidebarViews } from "./use-custom-sidebar-views"; | ||
| import { useEmberRouting } from "@/ember-bridge"; | ||
| import { useFeatureFlag } from "@/hooks/use-feature-flag"; | ||
|
|
||
| const LEGACY_MEMBERS_ACTIVE_ROUTES = ['members', 'member', 'member.new']; | ||
|
|
||
| function PostsNavItemContent({isActive, to}: {isActive: boolean; to: string}) { | ||
| return ( | ||
| <> | ||
|
|
@@ -92,20 +94,20 @@ function NavContent({ ...props }: React.ComponentProps<typeof SidebarGroup>) { | |
| const isPublishedPostsRouteActive = routing.isRouteActive('posts', {type: 'published'}); | ||
| const hasActivePostChild = isDraftPostsRouteActive || isScheduledPostsRouteActive || isPublishedPostsRouteActive || postCustomViews.some(view => view.isActive); | ||
| const postsExpanded = savedPostsExpanded; | ||
| const isOnMembersForward = location.pathname === '/members-forward'; | ||
| const hasActiveMemberView = isOnMembersForward && memberViews.some(view => view.isActive); | ||
| const isOnMembersRoute = location.pathname === '/members' || location.pathname === '/members/import'; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The new check only treats Useful? React with 👍 / 👎. |
||
| const hasActiveMemberView = memberViews.some(view => view.isActive); | ||
| const membersExpanded = savedMembersExpanded; | ||
| const membersNavActive = isMembersNavActive({ | ||
| membersForwardEnabled, | ||
| isOnMembersForward, | ||
| isOnMembersRoute, | ||
| hasActiveMemberView, | ||
| isMembersExpanded: membersExpanded, | ||
| isLegacyMembersRouteActive: routing.isRouteActive(getMembersNavActiveRoutes()) | ||
| isLegacyMembersRouteActive: routing.isRouteActive(LEGACY_MEMBERS_ACTIVE_ROUTES) | ||
| }); | ||
| const postsRoute = routing.getRouteUrl('posts'); | ||
| const isPostsRouteActive = routing.isRouteActive('posts'); | ||
| const postsNavActive = isPostsRouteActive || (!postsExpanded && hasActivePostChild); | ||
| const membersRoute = membersForwardEnabled ? 'members-forward' : routing.getRouteUrl('members'); | ||
| const membersRoute = routing.getRouteUrl('members'); | ||
|
|
||
| return ( | ||
| <SidebarGroup {...props}> | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| import {render, screen} from '@testing-library/react'; | ||
| import React from 'react'; | ||
| import {beforeEach, describe, expect, it, vi} from 'vitest'; | ||
| import {MembersRouteGate} from './members-route-gate'; | ||
|
|
||
| const {mockUseLocation, mockUseFeatureFlag} = vi.hoisted(() => ({ | ||
| mockUseLocation: vi.fn(), | ||
| mockUseFeatureFlag: vi.fn() | ||
| })); | ||
|
|
||
| vi.mock('@tryghost/admin-x-framework', () => ({ | ||
| Outlet: () => React.createElement('div', {'data-testid': 'outlet'}), | ||
| useLocation: mockUseLocation | ||
| })); | ||
|
|
||
| vi.mock('./ember-bridge', () => ({ | ||
| EmberFallback: () => React.createElement('div', {'data-testid': 'ember-fallback'}) | ||
| })); | ||
|
|
||
| vi.mock('./hooks/use-feature-flag', () => ({ | ||
| useFeatureFlag: mockUseFeatureFlag | ||
| })); | ||
|
|
||
| describe('MembersRouteGate', () => { | ||
| beforeEach(() => { | ||
| mockUseFeatureFlag.mockReturnValue(false); | ||
| mockUseLocation.mockReturnValue({pathname: '/members'}); | ||
| }); | ||
|
|
||
| it('delegates /members/ to Ember when the flag is disabled', () => { | ||
| mockUseLocation.mockReturnValue({pathname: '/members/'}); | ||
|
|
||
| render(<MembersRouteGate />); | ||
|
|
||
| expect(screen.getByTestId('ember-fallback')).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('delegates /members/import to Ember when the flag is disabled', () => { | ||
| mockUseLocation.mockReturnValue({pathname: '/members/import'}); | ||
|
|
||
| render(<MembersRouteGate />); | ||
|
|
||
| expect(screen.getByTestId('ember-fallback')).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('renders React routes when the flag is enabled', () => { | ||
| mockUseFeatureFlag.mockReturnValue(true); | ||
| mockUseLocation.mockReturnValue({pathname: '/members/import'}); | ||
|
|
||
| render(<MembersRouteGate />); | ||
|
|
||
| expect(screen.getByTestId('outlet')).toBeInTheDocument(); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import {Outlet} from "@tryghost/admin-x-framework"; | ||
| import {EmberFallback} from "./ember-bridge"; | ||
| import {useFeatureFlag} from "./hooks/use-feature-flag"; | ||
|
|
||
| export function MembersRouteGate() { | ||
| const membersForwardEnabled = useFeatureFlag("membersForward"); | ||
|
|
||
| if (!membersForwardEnabled) { | ||
| return <EmberFallback />; | ||
| } | ||
|
|
||
| return <Outlet />; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The members route gate now explicitly treats
/members/as the members list, but this check only matches'/members', so a trailing-slash URL leaves all member saved views inactive even when the filter matches. This creates inconsistent sidebar state for bookmarked/manual/members/URLs; normalizing trailing slashes here (as done in the gate) avoids that mismatch.Useful? React with 👍 / 👎.