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

Revert "Revert "feat: remove private prompts on related brain delete"" #876

Merged
merged 1 commit into from
Aug 7, 2023
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
12 changes: 12 additions & 0 deletions backend/core/routes/subscription_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
from fastapi import APIRouter, Depends, HTTPException
from models.brains import Brain
from models.brains_subscription_invitations import BrainSubscription
from models.prompt import PromptStatusEnum
from models.users import User
from pydantic import BaseModel
from repository.brain.create_brain_user import create_brain_user
from repository.brain.get_brain_by_id import get_brain_by_id
from repository.brain.get_brain_details import get_brain_details
from repository.brain.get_brain_for_user import get_brain_for_user
from repository.brain.update_user_rights import update_brain_user_rights
Expand All @@ -17,6 +19,8 @@
from repository.brain_subscription.subscription_invitation_service import (
SubscriptionInvitationService,
)
from repository.prompt.delete_prompt_py_id import delete_prompt_by_id
from repository.prompt.get_prompt_by_id import get_prompt_by_id
from repository.user.get_user_email_by_user_id import get_user_email_by_user_id
from repository.user.get_user_id_by_user_email import get_user_id_by_user_email

Expand Down Expand Up @@ -143,6 +147,14 @@ async def remove_user_subscription(
]

if len(brain_other_owners) == 0:
# Delete its prompt if it's private
deleting_brain = get_brain_by_id(brain_id)
if deleting_brain and deleting_brain.prompt_id:
deleting_brain_prompt = get_prompt_by_id(deleting_brain.prompt_id)
if deleting_brain_prompt is not None and (
deleting_brain_prompt.status == PromptStatusEnum.private
):
delete_prompt_by_id(deleting_brain.prompt_id)
brain.delete_brain(current_user.id)
else:
brain.delete_user_from_brain(current_user.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { TextArea } from "@/lib/components/ui/TextArea";
import { models, paidModels } from "@/lib/context/BrainConfigProvider/types";
import { defineMaxTokens } from "@/lib/helpers/defineMexTokens";

import { PublicPrompts } from "./components/PublicPrompts";
import { PublicPrompts } from "./components/PublicPrompts/PublicPrompts";
import { useSettingsTab } from "./hooks/useSettingsTab";

type SettingsTabProps = {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { PublicPromptsList } from "./components/PublicPromptsList/PublicPromptsList";
import { usePublicPrompts } from "./hooks/usePublicPrompts";

type PublicPromptsProps = {
onSelect: ({ title, content }: { title: string; content: string }) => void;
};

export const PublicPrompts = ({
onSelect,
}: PublicPromptsProps): JSX.Element => {
const { handleChange, publicPrompts } = usePublicPrompts({
onSelect,
});

return (
<PublicPromptsList
options={publicPrompts}
onChange={handleChange}
onSelect={onSelect}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { ChangeEvent } from "react";

import { Prompt } from "@/lib/types/Prompt";

import { usePublicPromptsList } from "./hooks/usePublicPromptsList";

type PublicPromptsListProps = {
options: Prompt[];
onChange: (event: ChangeEvent<HTMLSelectElement>) => void;
onSelect: ({ title, content }: { title: string; content: string }) => void;
};

export const PublicPromptsList = ({
options,
onChange,
onSelect,
}: PublicPromptsListProps): JSX.Element => {
const {
handleOptionClick,
isOpen,
selectRef,
selectedOption,
toggleDropdown,
} = usePublicPromptsList({
onChange,
onSelect,
});

return (
<div ref={selectRef} className="relative min-w-[200px] inline-block">
<button
onClick={toggleDropdown}
type="button"
className="px-4 py-2 w-full text-gray-700 bg-white border rounded-md focus:outline-none focus:border-blue-500"
>
{selectedOption ? selectedOption.title : "Select a Quivr Personality"}
</button>
{isOpen && (
<div className="absolute top-10 w-full bg-white border rounded-md shadow-lg">
{options.map((option) => (
<div
key={option.id}
className="px-4 py-2 cursor-pointer hover:bg-gray-100"
onClick={() => handleOptionClick(option)}
>
{option.title}
</div>
))}
</div>
)}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { ChangeEvent, useEffect, useRef, useState } from "react";

import { Prompt } from "@/lib/types/Prompt";

type UsePublicPromptsListProps = {
onChange: (event: ChangeEvent<HTMLSelectElement>) => void;
onSelect: ({ title, content }: { title: string; content: string }) => void;
};

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const usePublicPromptsList = ({
onChange,
onSelect,
}: UsePublicPromptsListProps) => {
const [isOpen, setIsOpen] = useState(false);
const [selectedOption, setSelectedOption] = useState<Prompt | null>(null);
const selectRef = useRef<HTMLDivElement>(null);

const toggleDropdown = () => {
setIsOpen((prevIsOpen) => !prevIsOpen);
};

const handleOptionClick = (option: Prompt) => {
setSelectedOption(option);
setIsOpen(false);
onChange({
target: { value: option.id },
} as ChangeEvent<HTMLSelectElement>);
onSelect({
title: option.title,
content: option.content,
});
};

const handleClickOutside = (event: MouseEvent) => {
if (
selectRef.current &&
!selectRef.current.contains(event.target as Node)
) {
setIsOpen(false);
}
};

useEffect(() => {
document.addEventListener("click", handleClickOutside, true);

return () => {
document.removeEventListener("click", handleClickOutside, true);
};
}, []);

return {
isOpen,
selectedOption,
selectRef,
toggleDropdown,
handleOptionClick,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./PublicPromptsList";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./PublicPromptsList";
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { ChangeEvent, useEffect, useState } from "react";

import { usePromptApi } from "@/lib/api/prompt/usePromptApi";
import { Prompt } from "@/lib/types/Prompt";

type UsePublicPromptsProps = {
onSelect: ({ title, content }: { title: string; content: string }) => void;
};

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const usePublicPrompts = ({ onSelect }: UsePublicPromptsProps) => {
const [publicPrompts, setPublicPrompts] = useState<Prompt[]>([]);
const { getPublicPrompts } = usePromptApi();

useEffect(() => {
const fetchPublicPrompts = async () => {
setPublicPrompts(await getPublicPrompts());
};
void fetchPublicPrompts();
}, []);

const handleChange = (event: ChangeEvent<HTMLSelectElement>) => {
const selectedPrompt = publicPrompts.find(
(prompt) => prompt.id === event.target.value
);
if (selectedPrompt) {
onSelect({
title: selectedPrompt.title,
content: selectedPrompt.content,
});
}
};

return {
publicPrompts,
handleChange,
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./PublicPrompts";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./PublicPrompts";