mirror of
https://github.com/n8n-io/n8n.git
synced 2026-08-29 01:39:24 +08:00
refactor(editor): Rename workflow reviews inbox route to /reviews (no-changelog) (#36824)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+4
-4
@@ -45,7 +45,7 @@ import { ResponseError } from '@n8n/rest-api-client';
|
||||
const { mockRouterPush, mockRouterResolve } = vi.hoisted(() => ({
|
||||
mockRouterPush: vi.fn(),
|
||||
mockRouterResolve: vi.fn(({ params }: { params: { reviewRequestId: string } }) => ({
|
||||
href: `/workflow-review-requests/${params.reviewRequestId}`,
|
||||
href: `/reviews/${params.reviewRequestId}`,
|
||||
})),
|
||||
}));
|
||||
|
||||
@@ -709,7 +709,7 @@ describe('WorkflowHeaderDraftPublishActions', () => {
|
||||
expect(mockShowToast).toHaveBeenCalledWith({
|
||||
type: 'success',
|
||||
title: 'Latest changes submitted to the existing review',
|
||||
message: '<a href="/workflow-review-requests/req-1">Open review</a>',
|
||||
message: '<a href="/reviews/req-1">Open review</a>',
|
||||
onClick: expect.any(Function),
|
||||
});
|
||||
const toastConfig = mockShowToast.mock.calls.at(-1)?.[0];
|
||||
@@ -816,7 +816,7 @@ describe('WorkflowHeaderDraftPublishActions', () => {
|
||||
expect(mockShowToast).toHaveBeenCalledWith({
|
||||
type: 'success',
|
||||
title: 'Workflow version submitted for review',
|
||||
message: '<a href="/workflow-review-requests/review-1">Open review</a>',
|
||||
message: '<a href="/reviews/review-1">Open review</a>',
|
||||
onClick: expect.any(Function),
|
||||
});
|
||||
});
|
||||
@@ -842,7 +842,7 @@ describe('WorkflowHeaderDraftPublishActions', () => {
|
||||
expect(mockShowToast).toHaveBeenCalledWith({
|
||||
type: 'success',
|
||||
title: 'Workflow version submitted for review',
|
||||
message: '<a href="/workflow-review-requests/review-1">Open review</a>',
|
||||
message: '<a href="/reviews/review-1">Open review</a>',
|
||||
onClick: expect.any(Function),
|
||||
});
|
||||
});
|
||||
|
||||
@@ -327,7 +327,7 @@ export const useProjectsStore = defineStore(STORES.PROJECTS, () => {
|
||||
setCurrentProject(null);
|
||||
}
|
||||
|
||||
if (newRoute?.path?.includes('workflow-review-requests')) {
|
||||
if (newRoute?.path?.includes('/reviews')) {
|
||||
projectNavActiveId.value = 'workflow-reviews';
|
||||
setCurrentProject(null);
|
||||
}
|
||||
|
||||
+2
-2
@@ -12,7 +12,7 @@ const router = createRouter({
|
||||
history: createMemoryHistory(),
|
||||
routes: [
|
||||
{
|
||||
path: '/workflow-review-requests/:reviewRequestId?',
|
||||
path: '/reviews/:reviewRequestId?',
|
||||
name: WORKFLOW_REVIEW_REQUESTS_VIEW,
|
||||
component: { template: '<div />' },
|
||||
},
|
||||
@@ -44,7 +44,7 @@ describe('WorkflowReviewSubmittedDialog', () => {
|
||||
|
||||
expect(getByRole('link', { name: 'your submission' })).toHaveAttribute(
|
||||
'href',
|
||||
'/workflow-review-requests/review-1',
|
||||
'/reviews/review-1',
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
+2
-5
@@ -50,7 +50,7 @@ const router = createRouter({
|
||||
history: createMemoryHistory(),
|
||||
routes: [
|
||||
{
|
||||
path: '/workflow-review-requests/:reviewRequestId?',
|
||||
path: '/reviews/:reviewRequestId?',
|
||||
name: WORKFLOW_REVIEW_REQUESTS_VIEW,
|
||||
component: { template: '<div />' },
|
||||
},
|
||||
@@ -129,10 +129,7 @@ describe('WorkflowUpdateReviewDialog', () => {
|
||||
it('links to the open review', async () => {
|
||||
const { getByRole } = await renderDialog();
|
||||
|
||||
expect(getByRole('link', { name: 'open review' })).toHaveAttribute(
|
||||
'href',
|
||||
'/workflow-review-requests/review-1',
|
||||
);
|
||||
expect(getByRole('link', { name: 'open review' })).toHaveAttribute('href', '/reviews/review-1');
|
||||
});
|
||||
|
||||
it('stays open without prefilling when no open review is known yet', async () => {
|
||||
|
||||
@@ -23,7 +23,7 @@ export const ReviewLinkedWorkflowsKey: InjectionKey<
|
||||
/**
|
||||
* Routing contract for the review inbox.
|
||||
*
|
||||
* Path: /workflow-review-requests/:reviewRequestId?
|
||||
* Path: /reviews/:reviewRequestId?
|
||||
* - `:reviewRequestId` is the open review (deep-linkable). Absent = inbox
|
||||
* with nothing selected. Selection always navigates via router.replace.
|
||||
*
|
||||
|
||||
@@ -15,7 +15,7 @@ export const WorkflowReviewsModule: FrontendModuleDescription = {
|
||||
icon: 'message-square-text',
|
||||
routes: [
|
||||
{
|
||||
path: '/workflow-review-requests/:reviewRequestId?',
|
||||
path: '/reviews/:reviewRequestId?',
|
||||
name: WORKFLOW_REVIEW_REQUESTS_VIEW,
|
||||
component: WorkflowReviewRequestsView,
|
||||
beforeEnter() {
|
||||
|
||||
+32
-38
@@ -42,7 +42,7 @@ const router = createRouter({
|
||||
history: createMemoryHistory(),
|
||||
routes: [
|
||||
{
|
||||
path: '/workflow-review-requests/:reviewRequestId?',
|
||||
path: '/reviews/:reviewRequestId?',
|
||||
name: WORKFLOW_REVIEW_REQUESTS_VIEW,
|
||||
component: { template: '<div />' },
|
||||
},
|
||||
@@ -110,7 +110,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
vi.mocked(useToast).mockReturnValue({ showError, showMessage } as unknown as ReturnType<
|
||||
typeof useToast
|
||||
>);
|
||||
await router.push('/workflow-review-requests');
|
||||
await router.push('/reviews');
|
||||
await router.isReady();
|
||||
|
||||
store = mockedStore(useReviewInboxStore);
|
||||
@@ -172,7 +172,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('fetches the route review detail on mount', async () => {
|
||||
await router.replace('/workflow-review-requests/req-1');
|
||||
await router.replace('/reviews/req-1');
|
||||
store.probeSettled = true;
|
||||
store.showSidebar = true;
|
||||
|
||||
@@ -183,7 +183,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('opens a review with its activity already loading', async () => {
|
||||
await router.replace('/workflow-review-requests/req-1');
|
||||
await router.replace('/reviews/req-1');
|
||||
store.probeSettled = true;
|
||||
store.showSidebar = true;
|
||||
|
||||
@@ -194,7 +194,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('swaps in the activity of the next review the viewer picks', async () => {
|
||||
await router.replace('/workflow-review-requests/req-1');
|
||||
await router.replace('/reviews/req-1');
|
||||
store.probeSettled = true;
|
||||
store.showSidebar = true;
|
||||
|
||||
@@ -207,7 +207,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('selects a review with replace and preserves the query', async () => {
|
||||
await router.replace('/workflow-review-requests?state=closed');
|
||||
await router.replace('/reviews?state=closed');
|
||||
store.probeSettled = true;
|
||||
store.showSidebar = true;
|
||||
const replaceSpy = vi.spyOn(router, 'replace');
|
||||
@@ -225,7 +225,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('drops the tab when selecting a different review, so it lands on Activity', async () => {
|
||||
await router.replace('/workflow-review-requests/req-2?state=closed&tab=changes');
|
||||
await router.replace('/reviews/req-2?state=closed&tab=changes');
|
||||
store.probeSettled = true;
|
||||
store.showSidebar = true;
|
||||
const replaceSpy = vi.spyOn(router, 'replace');
|
||||
@@ -241,7 +241,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('keeps the tab when re-selecting the review already open', async () => {
|
||||
await router.replace('/workflow-review-requests/req-1?tab=changes');
|
||||
await router.replace('/reviews/req-1?tab=changes');
|
||||
store.probeSettled = true;
|
||||
store.showSidebar = true;
|
||||
const replaceSpy = vi.spyOn(router, 'replace');
|
||||
@@ -257,7 +257,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('clears the selection back to the bare inbox path', async () => {
|
||||
await router.replace('/workflow-review-requests/req-1?state=closed');
|
||||
await router.replace('/reviews/req-1?state=closed');
|
||||
store.probeSettled = true;
|
||||
store.showSidebar = true;
|
||||
|
||||
@@ -267,13 +267,13 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
getByTestId('clear-review').click();
|
||||
await waitAllPromises();
|
||||
|
||||
expect(router.currentRoute.value.fullPath).toBe('/workflow-review-requests?state=closed');
|
||||
expect(router.currentRoute.value.fullPath).toBe('/reviews?state=closed');
|
||||
expect(router.currentRoute.value.params.reviewRequestId).toBe('');
|
||||
expect(store.clearDetail).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('shows the detail skeleton while deep-linked detail is loading', async () => {
|
||||
await router.replace('/workflow-review-requests/req-1');
|
||||
await router.replace('/reviews/req-1');
|
||||
store.probeSettled = true;
|
||||
store.showSidebar = true;
|
||||
store.detailLoading = true;
|
||||
@@ -287,7 +287,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('renders an inline not-found state without redirecting', async () => {
|
||||
await router.replace('/workflow-review-requests/missing');
|
||||
await router.replace('/reviews/missing');
|
||||
store.probeSettled = true;
|
||||
store.showSidebar = true;
|
||||
store.detailNotFound = true;
|
||||
@@ -298,11 +298,11 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
|
||||
expect(getByTestId('workflow-review-detail-not-found')).toBeInTheDocument();
|
||||
expect(replaceSpy).not.toHaveBeenCalled();
|
||||
expect(router.currentRoute.value.fullPath).toBe('/workflow-review-requests/missing');
|
||||
expect(router.currentRoute.value.fullPath).toBe('/reviews/missing');
|
||||
});
|
||||
|
||||
it('uses the list item until loaded detail is available', async () => {
|
||||
await router.replace('/workflow-review-requests/req-1');
|
||||
await router.replace('/reviews/req-1');
|
||||
store.probeSettled = true;
|
||||
store.showSidebar = true;
|
||||
// Resolved by id across sections, so it works from either one.
|
||||
@@ -326,7 +326,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('hydrates the tab from the query before probing', async () => {
|
||||
await router.replace('/workflow-review-requests?state=closed');
|
||||
await router.replace('/reviews?state=closed');
|
||||
renderComponent();
|
||||
await waitAllPromises();
|
||||
|
||||
@@ -335,7 +335,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('uses the open tab for an invalid state query', async () => {
|
||||
await router.replace('/workflow-review-requests?state=bogus');
|
||||
await router.replace('/reviews?state=bogus');
|
||||
renderComponent();
|
||||
await waitAllPromises();
|
||||
|
||||
@@ -343,7 +343,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('writes tab changes to the query and preserves the selected review', async () => {
|
||||
await router.replace('/workflow-review-requests/req-1');
|
||||
await router.replace('/reviews/req-1');
|
||||
store.probeSettled = true;
|
||||
store.showSidebar = true;
|
||||
|
||||
@@ -368,7 +368,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
await waitAllPromises();
|
||||
store.setActiveTab.mockClear();
|
||||
|
||||
await router.replace('/workflow-review-requests?state=closed');
|
||||
await router.replace('/reviews?state=closed');
|
||||
await waitAllPromises();
|
||||
|
||||
expect(store.setActiveTab).toHaveBeenCalledWith('closed');
|
||||
@@ -390,7 +390,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('passes a single flat section on the closed tab', async () => {
|
||||
await router.replace('/workflow-review-requests?state=closed');
|
||||
await router.replace('/reviews?state=closed');
|
||||
|
||||
const { getByTestId } = renderComponent();
|
||||
await waitAllPromises();
|
||||
@@ -413,7 +413,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
|
||||
describe('detail tabs', () => {
|
||||
beforeEach(async () => {
|
||||
await router.replace('/workflow-review-requests/req-1');
|
||||
await router.replace('/reviews/req-1');
|
||||
store.probeSettled = true;
|
||||
store.showSidebar = true;
|
||||
store.detail = createDetail();
|
||||
@@ -428,7 +428,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('hydrates the changes tab from the query', async () => {
|
||||
await router.replace('/workflow-review-requests/req-1?tab=changes');
|
||||
await router.replace('/reviews/req-1?tab=changes');
|
||||
|
||||
const { getByTestId, queryByTestId } = renderComponent();
|
||||
await waitAllPromises();
|
||||
@@ -438,7 +438,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('falls back to the activity tab for an invalid tab query', async () => {
|
||||
await router.replace('/workflow-review-requests/req-1?tab=bogus');
|
||||
await router.replace('/reviews/req-1?tab=bogus');
|
||||
|
||||
const { getByTestId } = renderComponent();
|
||||
await waitAllPromises();
|
||||
@@ -447,7 +447,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
it('writes the tab to the query preserving selection and state', async () => {
|
||||
await router.replace('/workflow-review-requests/req-1?state=closed');
|
||||
await router.replace('/reviews/req-1?state=closed');
|
||||
|
||||
const { getByRole } = renderComponent();
|
||||
await waitAllPromises();
|
||||
@@ -480,7 +480,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await router.replace('/workflow-review-requests/req-1');
|
||||
await router.replace('/reviews/req-1');
|
||||
store.probeSettled = true;
|
||||
store.showSidebar = true;
|
||||
store.detail = createDetail();
|
||||
@@ -604,9 +604,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
getByTestId('approve-review').click();
|
||||
await waitAllPromises();
|
||||
|
||||
expect(router.currentRoute.value.fullPath).toBe(
|
||||
'/workflow-review-requests/req-1?state=closed',
|
||||
);
|
||||
expect(router.currentRoute.value.fullPath).toBe('/reviews/req-1?state=closed');
|
||||
expect(router.currentRoute.value.params.reviewRequestId).toBe('req-1');
|
||||
});
|
||||
|
||||
@@ -623,9 +621,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
getByTestId('approve-review').click();
|
||||
await waitAllPromises();
|
||||
|
||||
expect(router.currentRoute.value.fullPath).toBe(
|
||||
'/workflow-review-requests/req-1?state=closed',
|
||||
);
|
||||
expect(router.currentRoute.value.fullPath).toBe('/reviews/req-1?state=closed');
|
||||
});
|
||||
|
||||
it('stays on the open tab when the review stays open', async () => {
|
||||
@@ -639,11 +635,11 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
getByTestId('request-changes').click();
|
||||
await waitAllPromises();
|
||||
|
||||
expect(router.currentRoute.value.fullPath).toBe('/workflow-review-requests/req-1');
|
||||
expect(router.currentRoute.value.fullPath).toBe('/reviews/req-1');
|
||||
});
|
||||
|
||||
it('does not renavigate when already on the closed tab', async () => {
|
||||
await router.replace('/workflow-review-requests/req-1?state=closed');
|
||||
await router.replace('/reviews/req-1?state=closed');
|
||||
store.activeTab = 'closed';
|
||||
|
||||
const { getByTestId } = renderComponent();
|
||||
@@ -654,9 +650,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
await waitAllPromises();
|
||||
|
||||
expect(replaceSpy).not.toHaveBeenCalled();
|
||||
expect(router.currentRoute.value.fullPath).toBe(
|
||||
'/workflow-review-requests/req-1?state=closed',
|
||||
);
|
||||
expect(router.currentRoute.value.fullPath).toBe('/reviews/req-1?state=closed');
|
||||
});
|
||||
|
||||
it('shows an error toast when the decision fails', async () => {
|
||||
@@ -724,7 +718,7 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
const { getByTestId } = renderComponent();
|
||||
await waitAllPromises();
|
||||
getByTestId('approve-review').click();
|
||||
await router.replace('/workflow-review-requests/req-2');
|
||||
await router.replace('/reviews/req-2');
|
||||
await waitAllPromises();
|
||||
activityStore.fetchFeed.mockClear();
|
||||
|
||||
@@ -749,13 +743,13 @@ describe('WorkflowReviewRequestsView', () => {
|
||||
const { getByTestId } = renderComponent();
|
||||
await waitAllPromises();
|
||||
getByTestId('approve-review').click();
|
||||
await router.replace('/workflow-review-requests/req-2');
|
||||
await router.replace('/reviews/req-2');
|
||||
await waitAllPromises();
|
||||
|
||||
resolveDecision();
|
||||
await waitAllPromises();
|
||||
|
||||
expect(router.currentRoute.value.fullPath).toBe('/workflow-review-requests/req-2');
|
||||
expect(router.currentRoute.value.fullPath).toBe('/reviews/req-2');
|
||||
});
|
||||
|
||||
it('shows no publish toast once the viewer has left the page', async () => {
|
||||
|
||||
Reference in New Issue
Block a user