Skip to content

Commit 0d5a8c5

Browse files
authored
fix: 404 when view deleted (#1390)
1 parent d173f86 commit 0d5a8c5

3 files changed

Lines changed: 42 additions & 9 deletions

File tree

apps/nestjs-backend/src/features/user/last-visit/last-visit.service.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ export class LastVisitService {
8585
orderBy: {
8686
order: 'asc',
8787
},
88+
where: {
89+
deletedTime: null,
90+
},
8891
},
8992
},
9093
where: {
@@ -115,6 +118,9 @@ export class LastVisitService {
115118
orderBy: {
116119
order: 'asc',
117120
},
121+
where: {
122+
deletedTime: null,
123+
},
118124
},
119125
},
120126
where: {

apps/nestjs-backend/test/user-last-visit.e2e-spec.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
permanentDeleteTable,
1515
updateUserLastVisit,
1616
} from '@teable/openapi';
17-
import { initApp } from './utils/init-app';
17+
import { getViews, initApp } from './utils/init-app';
1818

1919
describe('OpenAPI OAuthController (e2e)', () => {
2020
let app: INestApplication;
@@ -154,4 +154,22 @@ describe('OpenAPI OAuthController (e2e)', () => {
154154
},
155155
});
156156
});
157+
158+
it('should fallback to default view when delete a view without any visit', async () => {
159+
await createView(table1.id, { type: ViewType.Grid, name: 'view2', order: 1 });
160+
161+
await deleteView(table1.id, table1.views[0].id);
162+
const views = await getViews(table1.id);
163+
164+
const res = await getUserLastVisit({
165+
resourceType: LastVisitResourceType.Table,
166+
parentResourceId: base.id,
167+
});
168+
169+
expect(res.data).toEqual({
170+
resourceId: table1.id,
171+
childResourceId: views[0].id,
172+
resourceType: LastVisitResourceType.Table,
173+
});
174+
});
157175
});

apps/nextjs-app/src/pages/base/[baseId].tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,24 +52,33 @@ export const getServerSideProps: GetServerSideProps = withEnv(
5252
ensureLogin(
5353
withAuthSSR(async (context, ssrApi) => {
5454
const { baseId } = context.query;
55-
const userLastVisit = await ssrApi.getUserLastVisit(
56-
LastVisitResourceType.Table,
57-
baseId as string
58-
);
55+
const [userLastVisit, tables] = await Promise.all([
56+
ssrApi.getUserLastVisit(LastVisitResourceType.Table, baseId as string),
57+
ssrApi.getTables(baseId as string),
58+
]);
59+
60+
if (tables.length && userLastVisit && userLastVisit.childResourceId) {
61+
// if userLastVisit.resourceId has no permission to the tables, redirect to the first table
62+
if (tables.find((table) => table.id === userLastVisit.resourceId)) {
63+
return {
64+
redirect: {
65+
destination: `/base/${baseId}/${userLastVisit.resourceId}/${userLastVisit.childResourceId}`,
66+
permanent: false,
67+
},
68+
};
69+
}
5970

60-
if (userLastVisit && userLastVisit.childResourceId) {
6171
return {
6272
redirect: {
63-
destination: `/base/${baseId}/${userLastVisit.resourceId}/${userLastVisit.childResourceId}`,
73+
destination: `/base/${baseId}/${tables[0].id}/${tables[0].defaultViewId}`,
6474
permanent: false,
6575
},
6676
};
6777
}
6878

6979
const queryClient = new QueryClient();
7080

71-
const [tables] = await Promise.all([
72-
ssrApi.getTables(baseId as string),
81+
await Promise.all([
7382
queryClient.fetchQuery({
7483
queryKey: ReactQueryKeys.base(baseId as string),
7584
queryFn: ({ queryKey }) =>

0 commit comments

Comments
 (0)