Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
65 changes: 0 additions & 65 deletions apps/web/actions/caps/get-shared-spaces.ts

This file was deleted.

62 changes: 0 additions & 62 deletions apps/web/actions/folders/createFolder.ts

This file was deleted.

53 changes: 33 additions & 20 deletions apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ import {
DialogTitle,
Input,
} from "@cap/ui";
import type { Folder } from "@cap/web-domain";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix type import: Folder.FolderColor is not a named type import

Using Folder.FolderColor with import type { Folder } is likely a type error. Import the color type directly and use it in the mutation payload.

Apply this diff:

-import type { Folder } from "@cap/web-domain";
+import type { FolderColor } from "@cap/web-domain";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import type { Folder } from "@cap/web-domain";
import type { FolderColor } from "@cap/web-domain";
🤖 Prompt for AI Agents
In apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx around line
12, the code imports only "Folder" and then uses "Folder.FolderColor" which is
not a valid named type import; update the import to also pull the color type
directly (e.g. import type { Folder, FolderColor } from "@cap/web-domain") and
change any usage of Folder.FolderColor in the mutation payload and related type
annotations to use FolderColor instead.

import { faFolderPlus } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import clsx from "clsx";
import { Option } from "effect";
import { useRouter } from "next/navigation";
import React, { useEffect, useRef, useState } from "react";
import { toast } from "sonner";
import { createFolder } from "@/actions/folders/createFolder";
import { useEffectMutation } from "@/lib/EffectRuntime";
import { withRpc } from "@/lib/Rpcs";
import { BlueFolder, NormalFolder, RedFolder, YellowFolder } from "./Folders";

interface Props {
Expand Down Expand Up @@ -54,31 +58,33 @@ export const NewFolderDialog: React.FC<Props> = ({
>(null);
const [folderName, setFolderName] = useState<string>("");
const folderRefs = useRef<Record<string, any>>({});
const [loading, setLoading] = useState<boolean>(false);
const router = useRouter();

useEffect(() => {
if (!open) setSelectedColor(null);
}, [open]);

const createFolderHandler = async () => {
if (!selectedColor) return;
try {
setLoading(true);
await createFolder({
name: folderName,
color: selectedColor,
spaceId,
});
const createFolder = useEffectMutation({
mutationFn: (data: { name: string; color: Folder.FolderColor }) =>
withRpc((r) =>
r.FolderCreate({
name: data.name,
color: data.color,
spaceId: Option.fromNullable(spaceId),
parentId: Option.none(),
}),
),
Comment on lines +68 to +76
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Align the mutation payload type with the corrected import

Update the payload type to reference FolderColor (imported directly) instead of Folder.FolderColor.

Apply this diff:

-  mutationFn: (data: { name: string; color: Folder.FolderColor }) =>
+  mutationFn: (data: { name: string; color: FolderColor }) =>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
mutationFn: (data: { name: string; color: Folder.FolderColor }) =>
withRpc((r) =>
r.FolderCreate({
name: data.name,
color: data.color,
spaceId: Option.fromNullable(spaceId),
parentId: Option.none(),
}),
),
mutationFn: (data: { name: string; color: FolderColor }) =>
withRpc((r) =>
r.FolderCreate({
name: data.name,
color: data.color,
spaceId: Option.fromNullable(spaceId),
parentId: Option.none(),
}),
),
🤖 Prompt for AI Agents
In apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx around lines
68 to 76, the mutation payload type currently uses Folder.FolderColor but the
module import provides FolderColor directly; update the type annotation to use
FolderColor instead of Folder.FolderColor (i.e., change (data: { name: string;
color: Folder.FolderColor }) to (data: { name: string; color: FolderColor }) ),
and ensure the FolderColor import is present at the top of the file.

onSuccess: () => {
Comment on lines +67 to +77
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Align mutation payload type with FolderColor and trim the name

Use FolderColor for the color type and send a trimmed name to avoid leading/trailing spaces.

Apply this diff:

-  const createFolder = useEffectMutation({
-    mutationFn: (data: { name: string; color: Folder.FolderColor }) =>
+  const createFolder = useEffectMutation({
+    mutationFn: (data: { name: string; color: FolderColor }) =>
       withRpc((r) =>
         r.FolderCreate({
-          name: data.name,
+          name: data.name.trim(),
           color: data.color,
           spaceId: Option.fromNullable(spaceId),
           parentId: Option.none(),
         }),
       ),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const createFolder = useEffectMutation({
mutationFn: (data: { name: string; color: Folder.FolderColor }) =>
withRpc((r) =>
r.FolderCreate({
name: data.name,
color: data.color,
spaceId: Option.fromNullable(spaceId),
parentId: Option.none(),
}),
),
onSuccess: () => {
const createFolder = useEffectMutation({
mutationFn: (data: { name: string; color: FolderColor }) =>
withRpc((r) =>
r.FolderCreate({
name: data.name.trim(),
color: data.color,
spaceId: Option.fromNullable(spaceId),
parentId: Option.none(),
}),
),
onSuccess: () => {
🤖 Prompt for AI Agents
In apps/web/app/(org)/dashboard/caps/components/NewFolderDialog.tsx around lines
67 to 77, the mutation payload uses an incorrect/loose color type and sends the
raw name; update the mutationFn signature to accept color as Folder.FolderColor
and send a trimmed name by calling data.name.trim() when building the
FolderCreate RPC payload (leave spaceId and parentId handling unchanged).

setFolderName("");
setSelectedColor(null);
onOpenChange(false);
router.refresh();
toast.success("Folder created successfully");
} catch (error: any) {
},
onError: () => {
toast.error("Failed to create folder");
} finally {
setLoading(false);
}
};
},
});

return (
<Dialog open={open} onOpenChange={onOpenChange}>
Expand Down Expand Up @@ -141,13 +147,20 @@ export const NewFolderDialog: React.FC<Props> = ({
Cancel
</Button>
<Button
onClick={createFolderHandler}
onClick={() => {
if (selectedColor === null) return;
createFolder.mutate({ name: folderName, color: selectedColor });
}}
size="sm"
spinner={loading}
spinner={createFolder.isPending}
variant="dark"
disabled={!selectedColor || !folderName.trim().length || loading}
disabled={
!selectedColor ||
!folderName.trim().length ||
createFolder.isPending
}
>
{loading ? "Creating..." : "Create"}
{createFolder.isPending ? "Creating..." : "Create"}
</Button>
</DialogFooter>
</DialogContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ import {
DialogTitle,
Input,
} from "@cap/ui";
import type { Folder } from "@cap/web-domain";
import { faFolderPlus } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import clsx from "clsx";
import { Option } from "effect";
import { useRouter } from "next/navigation";
import React, { useEffect, useRef, useState } from "react";
import { toast } from "sonner";
import { createFolder } from "@/actions/folders/createFolder";
import { useEffectMutation } from "@/lib/EffectRuntime";
import { withRpc } from "@/lib/Rpcs";
import { useDashboardContext } from "../../../Contexts";
import {
BlueFolder,
Expand All @@ -26,7 +30,7 @@ import {
interface Props {
open: boolean;
onOpenChange: (open: boolean) => void;
parentFolderId: string;
parentFolderId: Folder.FolderId;
}

const FolderOptions = [
Expand Down Expand Up @@ -62,8 +66,8 @@ export const SubfolderDialog: React.FC<Props> = ({
>(null);
const [folderName, setFolderName] = useState<string>("");
const folderRefs = useRef<Record<string, any>>({});
const [loading, setLoading] = useState<boolean>(false);
const { activeSpace } = useDashboardContext();
const router = useRouter();

useEffect(() => {
if (!open) {
Expand All @@ -72,26 +76,27 @@ export const SubfolderDialog: React.FC<Props> = ({
}
}, [open]);

const createSubfolderHandler = async () => {
if (!selectedColor) return;
try {
setLoading(true);
await createFolder({
name: folderName,
color: selectedColor,
parentId: parentFolderId,
spaceId: activeSpace?.id,
});
const createSubfolder = useEffectMutation({
mutationFn: (data: { name: string; color: Folder.FolderColor }) =>
withRpc((r) =>
r.FolderCreate({
name: data.name,
color: data.color,
spaceId: Option.fromNullable(activeSpace?.id),
parentId: Option.some(parentFolderId),
}),
),
onSuccess: () => {
setFolderName("");
setSelectedColor(null);
onOpenChange(false);
router.refresh();
toast.success("Subfolder created successfully");
} catch (error: any) {
},
onError: () => {
toast.error("Failed to create subfolder");
} finally {
setLoading(false);
}
};
},
});

return (
<Dialog open={open} onOpenChange={onOpenChange}>
Expand Down Expand Up @@ -154,11 +159,21 @@ export const SubfolderDialog: React.FC<Props> = ({
Cancel
</Button>
<Button
onClick={createSubfolderHandler}
onClick={() => {
if (selectedColor === null) return;
createSubfolder.mutate({
name: folderName,
color: selectedColor,
});
}}
size="sm"
spinner={loading}
spinner={createSubfolder.isPending}
variant="dark"
disabled={!selectedColor || !folderName.trim().length || loading}
disabled={
!selectedColor ||
!folderName.trim().length ||
createSubfolder.isPending
}
>
Create
</Button>
Expand Down
7 changes: 6 additions & 1 deletion packages/web-backend/src/Auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ export const HttpAuthMiddlewareLive = Layer.effect(
),
);

return { id: user.id, email: user.email };
return {
id: user.id,
email: user.email,
activeOrgId: user.activeOrganizationId,
};
}).pipe(
Effect.provideService(Database, database),
Effect.catchTags({
Expand All @@ -70,6 +74,7 @@ export const provideOptionalAuth = <E, R>(
CurrentUser.context({
id: user.id,
email: user.email,
activeOrgId: user.activeOrganizationId,
}),
),
Option.match({
Expand Down
9 changes: 9 additions & 0 deletions packages/web-backend/src/Folders/FoldersRpcs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,15 @@ export const FolderRpcsLive = Folder.FolderRpcs.toLayer(
() => new InternalError({ type: "database" }),
),
),
FolderCreate: (data) =>
folders
.create(data)
.pipe(
Effect.catchTag(
"DatabaseError",
() => new InternalError({ type: "database" }),
),
),
};
}),
);
Loading
Loading