Skip to content
Draft
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
34 changes: 33 additions & 1 deletion nextjs/src/actions/brains.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use server';
import { DEFAULT_SORT, MODULE_ACTIONS, MODULES, REVALIDATE_TAG_NAME, ROLE_TYPE } from '@/utils/constant';
import { DEFAULT_SORT, MODULE_ACTIONS, MODULES, REVALIDATE_TAG_NAME, ROLE_TYPE, BRAIN_ID_REQUIRED } from '@/utils/constant';
import { revalidateTagging, serverApi } from './serverApi';
import { getSessionUser } from '@/utils/handleAuth';
import { FormatUserType, ObjectType } from '@/types/common';
Expand Down Expand Up @@ -285,4 +285,36 @@ export const convertToSharedAction = async (brainId: string, data: { members?: O
revalidateTagging(response, `${REVALIDATE_TAG_NAME.BRAIN}-${sessionUser.companyId}`),
]);
return response;
};

export const leaveBrainAction = async (brainId: string) => {
const sessionUser = await getSessionUser();

if (!brainId) {
return {
status: 400,
code: 'ERROR',
message: BRAIN_ID_REQUIRED,
data: {}
};
}

if (!sessionUser?._id) {
return {
status: 401,
code: 'ERROR',
message: 'Authentication required',
data: {}
};
}

const response = await serverApi({
action: MODULE_ACTIONS.UNSHARE,
parameters: [brainId],
data: { user_id: sessionUser._id }
});

await revalidateTagging(response, `${REVALIDATE_TAG_NAME.BRAIN}-${sessionUser.companyId}`);

return response;
};
67 changes: 45 additions & 22 deletions nextjs/src/components/Brains/BrainList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import Link from 'next/link';
import Image from 'next/image';
import ConvertToSharedModal from './ConvertToSharedModal';
import { ShareBrainIcon } from '@/icons/Share';
import LeaveBrainButton from './LeaveBrainButton';

type DefaultEditOptionProps = {
onEdit: () => void;
Expand All @@ -53,6 +54,7 @@ type CommonListProps = {
b: BrainListType;
currentUser: SetUserData;
closeSidebar: () => void;
onBrainLeave?: (brainId: string) => void;
}

type LinkItemsProps = {
Expand Down Expand Up @@ -188,7 +190,6 @@ const DefaultEditOption = React.memo(
className="edit-collapse-title"
onClick={handleEditBrain}
>

<SettingsIcon width={14}
height={16} className="w-[14] h-4 object-contain fill-b4 me-2.5" />
Manage
Expand All @@ -199,7 +200,7 @@ const DefaultEditOption = React.memo(
}
);

export const CommonList = ({ b, currentUser, closeSidebar }: CommonListProps) => {
export const CommonList = ({ b, currentUser, closeSidebar, onBrainLeave }: CommonListProps) => {

const dispatch = useDispatch();
const router = useRouter();
Expand All @@ -209,7 +210,7 @@ export const CommonList = ({ b, currentUser, closeSidebar }: CommonListProps) =>
const [isEditing, setIsEditing] = useState(false);
const [editedTitle, setEditedTitle] = useState(b.title);
const inputRef = useRef(null);
const buttonRef=useRef(null)
const buttonRef = useRef(null);
const [deleteBrain, isDeletePending] = useServerAction(deleteBrainAction);
const [updateBrain, isUpdatePending] = useServerAction(updateBrainAction);
const [showConvertModal, setShowConvertModal] = useState(false);
Expand All @@ -227,6 +228,8 @@ export const CommonList = ({ b, currentUser, closeSidebar }: CommonListProps) =>
return getRandomCharacter();
}, [b?._id]); // Only changes if brain ID changes

const isOwner = b.user.id === currentUser._id;

const handleEditClick = () => {
setIsEditing(true);
setEditedTitle(b.title); // Reset editedTitle to the current title
Expand Down Expand Up @@ -258,16 +261,16 @@ export const CommonList = ({ b, currentUser, closeSidebar }: CommonListProps) =>


const handleSaveClick = async () => {
if(b.title !==inputRef.current.value){
if(b.title !== inputRef.current.value){
const payload = {
title: editedTitle,
isShare: b?.isShare,
workspaceId: b?.workspaceId
};

const response:any=await updateBrain(payload, b?._id);
const response: any = await updateBrain(payload, b?._id);

if(response?.code=='ERROR'){
if(response?.code == 'ERROR'){
setEditedTitle(b?.title)
}
setIsEditing(false)
Expand Down Expand Up @@ -320,8 +323,7 @@ export const CommonList = ({ b, currentUser, closeSidebar }: CommonListProps) =>

return (
<>

<ConvertToSharedModal
<ConvertToSharedModal
open={showConvertModal}
close={() => setShowConvertModal(false)}
brain={b}
Expand All @@ -347,8 +349,15 @@ export const CommonList = ({ b, currentUser, closeSidebar }: CommonListProps) =>
height={20}
className="mr-2 flex-shrink-0 rounded collapsed-brain-logo"
/>
) : <Image src={defaultCharacter.image} alt={b.title} width={20} height={20} className="mr-2 flex-shrink-0 rounded collapsed-brain-logo" />
}
) : (
<Image
src={defaultCharacter.image}
alt={b.title}
width={20}
height={20}
className="mr-2 flex-shrink-0 rounded collapsed-brain-logo"
/>
)}
{isEditing ? (
<input
type="text"
Expand Down Expand Up @@ -378,18 +387,32 @@ export const CommonList = ({ b, currentUser, closeSidebar }: CommonListProps) =>
</button>
) : null}
{b?.slug != `default-brain-${currentUser?._id}` &&
b?.slug !== GENERAL_BRAIN_SLUG &&
((currentUser?.roleCode === ROLE_TYPE.USER &&
b.user.id === currentUser?._id) ||
currentUser?.roleCode !== ROLE_TYPE.USER) && (
<DefaultEditOption
onEdit={handleEditClick}
handleEditBrain={() => handleEditBrain(b)}
handleDeleteBrain={() => handleDeleteBrain(b)}
handleConvertToShared={!b.isShare ? handleConvertToShared : undefined}
isDeletePending={isDeletePending}
isPrivate={!b.isShare}
/>
b?.slug !== GENERAL_BRAIN_SLUG && (
<>
{currentUser?.roleCode === ROLE_TYPE.USER && !isOwner && (
<div onClick={(e) => e.stopPropagation()}>
<LeaveBrainButton
brainId={b._id}
brainTitle={b.title}
buttonClassName="ml-auto md:opacity-0 group-hover:opacity-100 dropdown-action transparent-ghost-btn btn-round btn-round-icon"
iconClassName="w-5 h-auto md:w-4"
hideLabel={true}
onLeaveSuccess={onBrainLeave}
/>
</div>
)}
{((currentUser?.roleCode === ROLE_TYPE.USER && isOwner) ||
currentUser?.roleCode !== ROLE_TYPE.USER) && (
<DefaultEditOption
onEdit={handleEditClick}
handleEditBrain={() => handleEditBrain(b)}
handleDeleteBrain={() => handleDeleteBrain(b)}
handleConvertToShared={!b.isShare ? handleConvertToShared : undefined}
isDeletePending={isDeletePending}
isPrivate={!b.isShare}
/>
)}
</>
)}
</button>
</TooltipTrigger>
Expand Down
20 changes: 10 additions & 10 deletions nextjs/src/components/Brains/ConvertToSharedModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Toast from '@/utils/toast';
import { convertBrainToShared } from '@/lib/slices/brain/brainlist';
import { useForm } from 'react-hook-form';
import ValidationError from '@/widgets/ValidationError';
import { CONVERT_TO_SHARED_SUCCESS, CONVERT_TO_SHARED_ERROR } from '@/utils/constant';

interface ConvertToSharedModalProps {
open: boolean;
Expand Down Expand Up @@ -116,20 +117,19 @@ const ConvertToSharedModal = ({ open, close, brain }: ConvertToSharedModalProps)
})) || [],
customInstruction,
};

const response = await runAction(brain._id, payload);

if (response?.code === 'SUCCESS') {
// Update Redux state
dispatch(convertBrainToShared({
brainId: brain._id,
convertedBrain: response.data
}));
Toast('Converted to Shared! Members and teams now have access.');

Toast(response?.message || CONVERT_TO_SHARED_SUCCESS);
close();
} else {
Toast(response?.message || 'We couldn’t convert this brain. Please try again.');
Toast(response?.message || CONVERT_TO_SHARED_ERROR);
}
} catch (error) {
Toast('We couldn’t convert this brain. Please try again.');
Expand All @@ -150,7 +150,7 @@ const ConvertToSharedModal = ({ open, close, brain }: ConvertToSharedModalProps)
Convert to Shared Brain
</DialogTitle>
<DialogDescription className="small-description text-font-14 leading-[24px] text-b5 font-normal ml-9">
Convert "{brain?.title}" to a shared brain and invite team members to collaborate.
Convert "{brain?.title}" to a shared brain and invite team members to collaborate.
This will make the brain accessible to selected users and teams.
</DialogDescription>
</DialogHeader>
Expand Down Expand Up @@ -233,9 +233,9 @@ const ConvertToSharedModal = ({ open, close, brain }: ConvertToSharedModalProps)
</div>

<div className="flex items-center justify-center my-[30px]">
<button
className="btn btn-black"
type="submit"
<button
className="btn btn-black"
type="submit"
disabled={isPending}
>
{isPending ? 'Converting...' : 'Convert to Shared'}
Expand Down
Loading