Skip to content
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

Link folders #1258

Open
wants to merge 185 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
185 commits
Select commit Hold shift + click to select a range
3302927
update the db schema
devkiran Sep 11, 2024
f3f69e4
add folder endpoints
devkiran Sep 11, 2024
980388c
assign a folder to a link
devkiran Sep 11, 2024
b8812c0
update recordLink
devkiran Sep 11, 2024
1780a15
Filter links by folder
devkiran Sep 11, 2024
4aa7aa6
fix the tests
devkiran Sep 11, 2024
cf16265
Merge branch 'main' into link-folders
devkiran Sep 11, 2024
00735ed
Merge branch 'main' into link-folders
devkiran Sep 12, 2024
bdc4080
add some tests
devkiran Sep 12, 2024
ef1dd6b
Delete folder after tests
devkiran Sep 12, 2024
e85c45a
add foldersLimit
devkiran Sep 12, 2024
0081e14
Update the openapi spec
devkiran Sep 12, 2024
d68a7dd
convert null to empty string
devkiran Sep 12, 2024
93d2fc8
fix the build
devkiran Sep 12, 2024
3fc6aeb
missed some spot
devkiran Sep 12, 2024
0afc9d1
Merge branch 'main' into link-folders
devkiran Sep 16, 2024
06f6f06
add folder permissions
devkiran Sep 16, 2024
80bd2ca
wip ACL
devkiran Sep 16, 2024
3d794e8
Merge branch 'main' into link-folders
steven-tey Sep 17, 2024
3951f5e
Merge branch 'main' into link-folders
devkiran Sep 17, 2024
70a35b8
list folders with links count
devkiran Sep 17, 2024
874a442
add DELETE /api/folders/[folderId]/users
devkiran Sep 17, 2024
c50828a
wip folder permissions
devkiran Sep 17, 2024
b68ea8d
Merge branch 'main' into link-folders
steven-tey Sep 17, 2024
e0946d5
add folder switcher
devkiran Sep 17, 2024
7da9097
Merge branch 'link-folders' of https://github.com/dubinc/dub into lin…
devkiran Sep 17, 2024
746e0a5
filter the links by folderId
devkiran Sep 17, 2024
52fde36
fix temp
devkiran Sep 17, 2024
36c1b53
update the folder listing with new UI
devkiran Sep 17, 2024
8781bb2
update title
devkiran Sep 18, 2024
6a921dc
Merge branch 'main' into link-folders
devkiran Sep 18, 2024
e26cdaf
format
devkiran Sep 18, 2024
2d5b400
rename the model
devkiran Sep 18, 2024
47d5ecf
add create modal form
devkiran Sep 18, 2024
f9d8474
display links count for each folder
devkiran Sep 18, 2024
61d7d19
add folder actions + rename folder
devkiran Sep 18, 2024
e5f34ab
delete folder modal
devkiran Sep 18, 2024
b4e4d19
Add workspace access to create folder modal
devkiran Sep 18, 2024
7ddabee
update styles
devkiran Sep 18, 2024
791e155
add description
devkiran Sep 18, 2024
0f95d85
wip folder members page
devkiran Sep 18, 2024
555a60f
format
devkiran Sep 18, 2024
72c897f
Merge branch 'main' into link-folders
devkiran Sep 18, 2024
905cd28
add MoveLinkToFolderModal
devkiran Sep 18, 2024
886ad76
wip move link to folder
devkiran Sep 18, 2024
10e5ad9
update the workspace access via UI
devkiran Sep 20, 2024
eb299a6
format
devkiran Sep 20, 2024
0e441c2
handle the very length name
devkiran Sep 20, 2024
cc5b648
folder access request
devkiran Sep 20, 2024
b089f03
Merge branch 'main' into link-folders
steven-tey Sep 20, 2024
a35edec
wip users folder access
devkiran Sep 20, 2024
5e8289b
Merge branch 'main' into link-folders
devkiran Sep 20, 2024
9ba76b9
Merge branch 'link-folders' of https://github.com/dubinc/dub into lin…
devkiran Sep 20, 2024
9948ab7
update roles and access level
devkiran Sep 20, 2024
033a5de
fix the select options
devkiran Sep 20, 2024
e21ca12
fix the folder role
devkiran Sep 20, 2024
83c6b94
disable edit for non-owner
devkiran Sep 20, 2024
59beb10
Merge branch 'main' into link-folders
devkiran Sep 21, 2024
6cc06c4
update folder permissions
devkiran Sep 21, 2024
a9ce5c6
apply folder permissions on UI
devkiran Sep 21, 2024
5b0bbca
more permission checks
devkiran Sep 21, 2024
e5da4f1
folder user role update
devkiran Sep 21, 2024
7a1b278
prevent current user from updating their own role
devkiran Sep 21, 2024
d685fd8
Display "All links" folder at the beginning of the folders list
devkiran Sep 21, 2024
7fe8e6b
fix types
devkiran Sep 21, 2024
495cccf
fix links count
devkiran Sep 21, 2024
bc8c532
Fix the count of links in a folder
devkiran Sep 21, 2024
e548f70
remove console.log
devkiran Sep 21, 2024
0f4c8e0
add search box
devkiran Sep 21, 2024
8648037
format
devkiran Sep 21, 2024
17d8edc
handle the permissions in UI
devkiran Sep 22, 2024
50ee561
send linkCount
devkiran Sep 22, 2024
56cc0df
Merge branch 'main' into link-folders
devkiran Sep 23, 2024
547bf64
move link to a folder
devkiran Sep 23, 2024
ac989c4
apply folder permission on link level
devkiran Sep 23, 2024
9b2d884
add throwIfInvalidFolderAccess
devkiran Sep 23, 2024
3a13f22
create folder from links page
devkiran Sep 23, 2024
b6a8eaf
display selected folder
devkiran Sep 23, 2024
9f0814d
create a link within the selected folder
devkiran Sep 23, 2024
3ea3734
add folder actions
devkiran Sep 23, 2024
968710d
send email to the owner asking for edit access
devkiran Sep 23, 2024
97f8202
Refresh the users list after updating the folder access level
devkiran Sep 23, 2024
225b97d
handle no access for the user
devkiran Sep 23, 2024
0520078
format
devkiran Sep 23, 2024
d94c110
display the folder access requested status
devkiran Sep 23, 2024
4972a42
some rename
devkiran Sep 23, 2024
d0269d1
add logo next to the workspace level access dropdown
devkiran Sep 23, 2024
a3109c1
add folder logos
devkiran Sep 23, 2024
1eed399
Merge branch 'main' into link-folders
devkiran Sep 23, 2024
d17b7c8
some fixes
devkiran Sep 23, 2024
4cd28c3
Merge branch 'link-folders' of https://github.com/dubinc/dub into lin…
devkiran Sep 23, 2024
22d2cca
Merge branch 'main' into link-folders
devkiran Sep 24, 2024
f617804
add folder access check
devkiran Sep 24, 2024
fc36812
apply folder permissions
devkiran Sep 24, 2024
fd58701
check for folder permissions and filter
devkiran Sep 24, 2024
4256506
some permission check
devkiran Sep 24, 2024
5bba119
rename
devkiran Sep 24, 2024
f959c55
update methods
devkiran Sep 24, 2024
276c52d
hide the create link if the user doesn't have access to folder
devkiran Sep 24, 2024
cc7caaf
update folder icons
devkiran Sep 24, 2024
6e03f97
fix icons
devkiran Sep 24, 2024
6f975dd
add request access button on links page
devkiran Sep 24, 2024
0cf26a9
add missing permissions
devkiran Sep 24, 2024
0913c70
update
devkiran Sep 24, 2024
b62d8e7
Merge branch 'main' into link-folders
devkiran Sep 24, 2024
73ea8d7
update ui
devkiran Sep 24, 2024
e31c74c
add getFolderOrThrow
devkiran Sep 24, 2024
96ee2fa
folder permission fixes
devkiran Sep 24, 2024
b10be87
Merge branch 'main' into link-folders
steven-tey Sep 25, 2024
c53c646
add bg color
devkiran Sep 25, 2024
64b25d2
add the step progress at the bottom
devkiran Sep 25, 2024
4617364
Merge branch 'link-folders' of https://github.com/dubinc/dub into lin…
devkiran Sep 25, 2024
fe93979
support folder search
devkiran Sep 25, 2024
2e52306
rename types
devkiran Sep 25, 2024
fcc85bf
make the folder shortcut works
devkiran Sep 25, 2024
e109c75
Merge branch 'main' into link-folders
devkiran Sep 25, 2024
663a7f2
some cleanup
devkiran Sep 25, 2024
6be02aa
consistent method name
devkiran Sep 25, 2024
e9bfa89
Fix fetching links
devkiran Sep 25, 2024
4fad662
filter analytics by folderId
devkiran Sep 25, 2024
a7f73b0
remove console.log
devkiran Sep 25, 2024
f3a4f44
add folderId to events API
devkiran Sep 25, 2024
b0fa0e9
update analytics and events
devkiran Sep 25, 2024
fcae3e2
fix query
devkiran Sep 25, 2024
a90d7fb
Merge branch 'main' into link-folders
devkiran Sep 25, 2024
48506d7
Merge branch 'main' into link-folders
steven-tey Sep 26, 2024
6038587
Merge branch 'main' into link-folders
steven-tey Sep 26, 2024
1e5da4d
update count of links
devkiran Sep 26, 2024
aac2ad2
update the analytics & events
devkiran Sep 26, 2024
5918f65
small tweaks
devkiran Sep 26, 2024
9920802
format
devkiran Sep 26, 2024
a87476e
use useKeyboardShortcut
devkiran Sep 26, 2024
16e85cd
update types
devkiran Sep 26, 2024
c982bb9
rename method
devkiran Sep 26, 2024
160d25f
format
devkiran Sep 26, 2024
f359b97
make the RESEND_API_KEY optional
devkiran Sep 27, 2024
07f4ba6
setup mailhog
devkiran Sep 27, 2024
f9571de
Revert "setup mailhog"
devkiran Sep 27, 2024
8e10fa1
Revert "make the RESEND_API_KEY optional"
devkiran Sep 27, 2024
4fe194e
Merge branch 'main' into link-folders
devkiran Sep 27, 2024
07b6e84
Merge branch 'main' into link-folders
devkiran Sep 28, 2024
f7a0c45
Merge branch 'main' into link-folders
steven-tey Oct 1, 2024
b6ac239
Merge branch 'main' into link-folders
steven-tey Oct 2, 2024
b20bbd4
Merge branch 'main' into link-folders
steven-tey Oct 2, 2024
55abe0f
Merge branch 'main' into link-folders
devkiran Oct 4, 2024
295ae9a
fix the links filter
devkiran Oct 4, 2024
f6d303d
format
devkiran Oct 4, 2024
8c54dd6
Merge branch 'main' into link-folders
devkiran Oct 4, 2024
d64a49a
add unsorted label
devkiran Oct 4, 2024
e292869
rename
devkiran Oct 4, 2024
e09cbc7
Merge branch 'main' into link-folders
steven-tey Oct 4, 2024
39c090b
Merge branch 'main' into link-folders
steven-tey Oct 6, 2024
f942544
Update index.tsx
steven-tey Oct 6, 2024
03daa60
Merge branch 'main' into link-folders
steven-tey Oct 6, 2024
9793da1
Merge branch 'main' into link-folders
devkiran Oct 7, 2024
1b3a7aa
add feature flag
devkiran Oct 7, 2024
c38f7f7
Merge branch 'main' into link-folders
steven-tey Oct 7, 2024
3d87472
Merge branch 'main' into link-folders
devkiran Oct 9, 2024
4bf4f82
Merge branch 'side-nav-layout' into link-folders
devkiran Oct 9, 2024
744cc5f
fix conflicts
devkiran Oct 9, 2024
b9b54f3
small fix
devkiran Oct 9, 2024
ccf1959
another fix
devkiran Oct 9, 2024
52e6052
Merge branch 'main' into link-folders
steven-tey Oct 10, 2024
cae3c74
Merge branch 'main' into link-folders
steven-tey Oct 11, 2024
1367985
Merge branch 'main' into link-folders
steven-tey Oct 11, 2024
4ee0eaf
Merge branch 'main' into link-folders
steven-tey Oct 13, 2024
671b702
Merge branch 'main' into link-folders
steven-tey Oct 14, 2024
bc935d8
Merge branch 'main' into link-folders
steven-tey Oct 14, 2024
ba1f3eb
Merge branch 'main' into link-folders
steven-tey Oct 14, 2024
b4039a6
Merge branch 'main' into link-folders
steven-tey Oct 15, 2024
84f4a58
Merge branch 'main' into link-folders
steven-tey Oct 15, 2024
98286d7
Merge branch 'main' into link-folders
devkiran Oct 17, 2024
9c2ce86
Merge branch 'main' into link-folders
steven-tey Oct 17, 2024
893a273
Merge branch 'main' into link-folders
steven-tey Oct 18, 2024
edbfdd7
Merge branch 'main' into link-folders
steven-tey Oct 20, 2024
a77e2f6
Update folder switcher for new app layout
TWilson023 Oct 21, 2024
7a155bc
Move folders into Library
TWilson023 Oct 21, 2024
4dbc6ad
Merge branch 'main' into link-folders
TWilson023 Oct 22, 2024
dead48f
Add permissions panel
TWilson023 Oct 22, 2024
5c3e705
Truncation fixes
TWilson023 Oct 22, 2024
28256f0
Merge branch 'main' into link-folders
devkiran Nov 12, 2024
b490d6e
match Prisma versions
devkiran Nov 12, 2024
aadad24
fix types
devkiran Nov 12, 2024
2dd1897
format
devkiran Nov 12, 2024
38a5037
update pnpm-lock
devkiran Nov 12, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions apps/web/app/api/analytics/export/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@ import { getDomainOrThrow } from "@/lib/api/domains/get-domain-or-throw";
import { getLinkOrThrow } from "@/lib/api/links/get-link-or-throw";
import { throwIfClicksUsageExceeded } from "@/lib/api/links/usage-checks";
import { withWorkspace } from "@/lib/auth";
import { getFolders } from "@/lib/folder/get-folders";
import { checkFolderPermission } from "@/lib/folder/permissions";
import { analyticsQuerySchema } from "@/lib/zod/schemas/analytics";
import { Link } from "@prisma/client";
import JSZip from "jszip";

// GET /api/analytics/export – get export data for analytics
export const GET = withWorkspace(
async ({ searchParams, workspace }) => {
async ({ searchParams, workspace, session }) => {
throwIfClicksUsageExceeded(workspace);

const parsedParams = analyticsQuerySchema.parse(searchParams);

const { interval, start, end, linkId, externalId, domain, key } =
const { interval, start, end, linkId, externalId, domain, key, folderId } =
parsedParams;

let link: Link | null = null;
Expand All @@ -35,6 +37,29 @@ export const GET = withWorkspace(
});
}

if (link && link.folderId) {
await checkFolderPermission({
folderId: link.folderId,
workspaceId: workspace.id,
userId: session.user.id,
requiredPermission: "folders.read",
});
}

if (folderId) {
await checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId,
requiredPermission: "folders.read",
});
}

const folders = await getFolders({
workspaceId: workspace.id,
userId: session.user.id,
});

validDateRangeForPlan({
plan: workspace.plan,
interval,
Expand All @@ -59,7 +84,9 @@ export const GET = withWorkspace(
...(link && { linkId: link.id }),
event: "clicks",
groupBy: endpoint,
allowedFolderIds: folders.map((folder) => folder.id),
});

if (!response || response.length === 0) return;

const csvData = convertToCSV(response);
Expand Down
34 changes: 31 additions & 3 deletions apps/web/app/api/analytics/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { getDomainOrThrow } from "@/lib/api/domains/get-domain-or-throw";
import { getLinkOrThrow } from "@/lib/api/links/get-link-or-throw";
import { throwIfClicksUsageExceeded } from "@/lib/api/links/usage-checks";
import { withWorkspace } from "@/lib/auth";
import { getFolders } from "@/lib/folder/get-folders";
import { checkFolderPermission } from "@/lib/folder/permissions";
import {
analyticsPathParamsSchema,
analyticsQuerySchema,
Expand All @@ -14,7 +16,7 @@ import { NextResponse } from "next/server";

// GET /api/analytics – get analytics
export const GET = withWorkspace(
async ({ params, searchParams, workspace }) => {
async ({ params, searchParams, workspace, session }) => {
throwIfClicksUsageExceeded(workspace);

let { eventType: oldEvent, endpoint: oldType } =
Expand All @@ -38,9 +40,14 @@ export const GET = withWorkspace(
externalId,
domain,
key,
folderId,
} = parsedParams;

let link: Link | null = null;

event = oldEvent || event;
groupBy = oldType || groupBy;

if (domain) {
await getDomainOrThrow({ workspace, domain });
}
Expand All @@ -55,8 +62,28 @@ export const GET = withWorkspace(
});
}

event = oldEvent || event;
groupBy = oldType || groupBy;
if (link && link.folderId) {
await checkFolderPermission({
folderId: link.folderId,
workspaceId: workspace.id,
userId: session.user.id,
requiredPermission: "folders.read",
});
}

if (folderId) {
await checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId,
requiredPermission: "folders.read",
});
}

const folders = await getFolders({
workspaceId: workspace.id,
userId: session.user.id,
});

validDateRangeForPlan({
plan: workspace.plan,
Expand All @@ -81,6 +108,7 @@ export const GET = withWorkspace(
...(link && { linkId: link.id }),
workspaceId: workspace.id,
isDeprecatedClicksEndpoint,
allowedFolderIds: folders.map((folder) => folder.id),
});

return NextResponse.json(response);
Expand Down
1 change: 1 addition & 0 deletions apps/web/app/api/cron/domains/transfer/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export async function POST(req: Request) {
key: link.key,
url: link.url,
tag_ids: [],
folder_id: null,
workspace_id: newWorkspaceId,
created_at: link.createdAt,
})),
Expand Down
1 change: 1 addition & 0 deletions apps/web/app/api/domains/[domain]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export const PATCH = withWorkspace(
key: link.key,
url: link.url,
tag_ids: link.tags.map((tag) => tag.tagId),
folder_id: link.folderId,
workspace_id: link.projectId,
created_at: link.createdAt,
})),
Expand Down
31 changes: 29 additions & 2 deletions apps/web/app/api/events/export/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { getDomainOrThrow } from "@/lib/api/domains/get-domain-or-throw";
import { getLinkOrThrow } from "@/lib/api/links/get-link-or-throw";
import { throwIfClicksUsageExceeded } from "@/lib/api/links/usage-checks";
import { withWorkspace } from "@/lib/auth";
import { getFolders } from "@/lib/folder/get-folders";
import { checkFolderPermission } from "@/lib/folder/permissions";
import { eventsQuerySchema } from "@/lib/zod/schemas/analytics";
import { clickEventResponseSchema } from "@/lib/zod/schemas/clicks";
import { leadEventResponseSchema } from "@/lib/zod/schemas/leads";
Expand Down Expand Up @@ -39,7 +41,7 @@ const columnAccessors = {

// GET /api/events/export – get export data for analytics
export const GET = withWorkspace(
async ({ searchParams, workspace }) => {
async ({ searchParams, workspace, session }) => {
throwIfClicksUsageExceeded(workspace);

const parsedParams = eventsQuerySchema
Expand All @@ -53,7 +55,8 @@ export const GET = withWorkspace(
)
.parse(searchParams);

const { event, domain, interval, start, end, columns, key } = parsedParams;
const { event, domain, interval, start, end, columns, key, folderId } =
parsedParams;

if (domain) {
await getDomainOrThrow({ workspace, domain });
Expand All @@ -62,6 +65,29 @@ export const GET = withWorkspace(
const link =
domain && key ? await getLinkOrThrow({ workspace, domain, key }) : null;

if (link && link.folderId) {
await checkFolderPermission({
folderId: link.folderId,
workspaceId: workspace.id,
userId: session.user.id,
requiredPermission: "folders.read",
});
}

if (folderId) {
await checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId,
requiredPermission: "folders.read",
});
}

const folders = await getFolders({
workspaceId: workspace.id,
userId: session.user.id,
});

validDateRangeForPlan({
plan: workspace.plan,
interval,
Expand All @@ -75,6 +101,7 @@ export const GET = withWorkspace(
...(link && { linkId: link.id }),
workspaceId: workspace.id,
limit: 100000,
allowedFolderIds: folders.map((folder) => folder.id),
});

const data = response.map((row) =>
Expand Down
42 changes: 39 additions & 3 deletions apps/web/app/api/events/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,30 @@ import { getDomainOrThrow } from "@/lib/api/domains/get-domain-or-throw";
import { getLinkOrThrow } from "@/lib/api/links/get-link-or-throw";
import { throwIfClicksUsageExceeded } from "@/lib/api/links/usage-checks";
import { withWorkspace } from "@/lib/auth";
import { getFolders } from "@/lib/folder/get-folders";
import { checkFolderPermission } from "@/lib/folder/permissions";
import { eventsQuerySchema } from "@/lib/zod/schemas/analytics";
import { Link } from "@prisma/client";
import { NextResponse } from "next/server";

export const GET = withWorkspace(
async ({ searchParams, workspace }) => {
async ({ searchParams, workspace, session }) => {
throwIfClicksUsageExceeded(workspace);

const parsedParams = eventsQuerySchema.parse(searchParams);

let { event, interval, start, end, linkId, externalId, domain, key } =
parsedParams;
let {
event,
interval,
start,
end,
linkId,
externalId,
domain,
key,
folderId,
} = parsedParams;

let link: Link | null = null;

if (domain) {
Expand All @@ -32,6 +44,29 @@ export const GET = withWorkspace(
});
}

if (link && link.folderId) {
await checkFolderPermission({
folderId: link.folderId,
workspaceId: workspace.id,
userId: session.user.id,
requiredPermission: "folders.read",
});
}

if (folderId) {
await checkFolderPermission({
workspaceId: workspace.id,
userId: session.user.id,
folderId,
requiredPermission: "folders.read",
});
}

const folders = await getFolders({
workspaceId: workspace.id,
userId: session.user.id,
});

validDateRangeForPlan({
plan: workspace.plan,
interval,
Expand All @@ -45,6 +80,7 @@ export const GET = withWorkspace(
event,
...(link && { linkId: link.id }),
workspaceId: workspace.id,
allowedFolderIds: folders.map((folder) => folder.id),
});

return NextResponse.json(response);
Expand Down
Loading
Loading