Open kirin-ri opened 8 months ago
/* CollapsibleArea.css */
.collapsible-area {
border: 1px solid #ccc;
border-radius: 5px;
margin: 10px;
}
.collapsible-header {
background-color: #f0f0f0;
padding: 10px;
cursor: pointer;
}
.collapsible-content {
padding: 10px;
}
// ReferenceBar.tsx
import React from 'react';
import CollapsibleArea from './CollapsibleArea';
interface ReferenceBarProps {
referenceList: string[];
}
const ReferenceBar: React.FC<ReferenceBarProps> = ({ referenceList }) => {
return (
<div>
<CollapsibleArea title="参照列表" items={referenceList} />
</div>
);
};
export default ReferenceBar;
// MainComponent.tsx
import React from 'react';
import ReferenceBar from './ReferenceBar';
const MainComponent: React.FC = () => {
const referenceList = ["Item 1", "Item 2", "Item 3"]; // 你的参照列表
return (
<div className="main-component">
{/* 其他内容 */}
<ReferenceBar referenceList={referenceList} />
{/* 其他内容 */}
</div>
);
};
export default MainComponent;
import { useContext, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useCreateReducer } from '@/hooks/useCreateReducer';
import { savePrompts } from '@/utils/app/prompts';
import { OpenAIModels } from '@/types/openai';
import { Prompt } from '@/types/prompt';
import HomeContext from '@/pages/api/home/home.context';
import { PromptFolders } from './components/PromptFolders';
import { PromptbarSettings } from './components/PromptbarSettings';
import { Prompts } from './components/Prompts';
import Sidebar from '../Sidebar';
import PromptbarContext from './PromptBar.context';
import { PromptbarInitialState, initialState } from './Promptbar.state';
import { v4 as uuidv4 } from 'uuid';
const Promptbar = () => {
const { t } = useTranslation('promptbar');
const promptBarContextValue = useCreateReducer<PromptbarInitialState>({
initialState,
});
const {
state: { prompts, defaultModelId, showPromptbar },
dispatch: homeDispatch,
handleCreateFolder,
} = useContext(HomeContext);
const {
state: { searchTerm, filteredPrompts },
dispatch: promptDispatch,
} = promptBarContextValue;
const handleTogglePromptbar = () => {
homeDispatch({ field: 'showPromptbar', value: !showPromptbar });
localStorage.setItem('showPromptbar', JSON.stringify(!showPromptbar));
};
const handleCreatePrompt = () => {
if (defaultModelId) {
const newPrompt: Prompt = {
id: uuidv4(),
name: `Prompt ${prompts.length + 1}`,
description: '',
content: '',
model: OpenAIModels[defaultModelId],
folderId: null,
};
const updatedPrompts = [...prompts, newPrompt];
homeDispatch({ field: 'prompts', value: updatedPrompts });
savePrompts(updatedPrompts);
}
};
const handleDeletePrompt = (prompt: Prompt) => {
const updatedPrompts = prompts.filter((p) => p.id !== prompt.id);
homeDispatch({ field: 'prompts', value: updatedPrompts });
savePrompts(updatedPrompts);
};
const handleUpdatePrompt = (prompt: Prompt) => {
const updatedPrompts = prompts.map((p) => {
if (p.id === prompt.id) {
return prompt;
}
return p;
});
homeDispatch({ field: 'prompts', value: updatedPrompts });
savePrompts(updatedPrompts);
};
const handleDrop = (e: any) => {
if (e.dataTransfer) {
const prompt = JSON.parse(e.dataTransfer.getData('prompt'));
const updatedPrompt = {
...prompt,
folderId: e.target.dataset.folderId,
};
handleUpdatePrompt(updatedPrompt);
e.target.style.background = 'none';
}
};
useEffect(() => {
if (searchTerm) {
promptDispatch({
field: 'filteredPrompts',
value: prompts.filter((prompt) => {
const searchable =
prompt.name.toLowerCase() +
' ' +
prompt.description.toLowerCase() +
' ' +
prompt.content.toLowerCase();
return searchable.includes(searchTerm.toLowerCase());
}),
});
} else {
promptDispatch({ field: 'filteredPrompts', value: prompts });
}
}, [searchTerm, prompts]);
return (
<PromptbarContext.Provider
value={{
...promptBarContextValue,
handleCreatePrompt,
handleDeletePrompt,
handleUpdatePrompt,
}}
>
<Sidebar<Prompt>
side={'right'}
isOpen={showPromptbar}
addItemButtonTitle={t('New prompt')}
itemComponent={
<Prompts
prompts={filteredPrompts.filter((prompt) => !prompt.folderId)}
/>
}
folderComponent={<PromptFolders />}
items={filteredPrompts}
searchTerm={searchTerm}
handleSearchTerm={(searchTerm: string) =>
promptDispatch({ field: 'searchTerm', value: searchTerm })
}
toggleOpen={handleTogglePromptbar}
handleCreateItem={handleCreatePrompt}
handleCreateFolder={() => handleCreateFolder(t('New folder'), 'prompt')}
handleDrop={handleDrop}
/>
</PromptbarContext.Provider>
);
};
export default Promptbar;
import React, { useState, useEffect, useContext } from 'react';
// 假设您的样式已经由其他全局或父组件CSS文件定义
// 引入HomeContext或者相应的上下文,如果您管理展示状态的逻辑位于全局状态中
import HomeContext from '@/pages/api/home/home.context';
interface Reference {
id: string;
title: string;
description: string;
}
const references: Reference[] = [
{ id: '1', title: '文献1', description: '这是文献1的描述' },
{ id: '2', title: '文献2', description: '这是文献2的描述' },
// 更多文献...
];
const ReferencesSidebar = () => {
// 如果是使用全局状态管理展示/收起状态
const { state: { showReferencesSidebar }, dispatch: homeDispatch } = useContext(HomeContext);
// 本地组件级别的展示/收起状态,如果不使用全局状态管理
// const [showReferencesSidebar, setShowReferencesSidebar] = useState(true);
const handleToggleSidebar = () => {
// 如果使用全局状态
homeDispatch({ type: 'TOGGLE_REFERENCES_SIDEBAR' });
// 如果使用本地状态
// setShowReferencesSidebar(!showReferencesSidebar);
};
return (
<aside className={`sidebar ${showReferencesSidebar ? 'open' : 'closed'}`}>
<button onClick={handleToggleSidebar}>
{showReferencesSidebar ? '收起' : '展示'}
</button>
<h2>参考文献</h2>
<ul>
{references.map(ref => (
<li key={ref.id}>
<h3>{ref.title}</h3>
<p>{ref.description}</p>
</li>
))}
</ul>
</aside>
);
};
export default ReferencesSidebar;
import React, { useState } from 'react';
interface Reference {
id: string;
title: string;
description: string;
}
const references: Reference[] = [
{ id: '1', title: '文献1', description: '这是文献1的描述' },
{ id: '2', title: '文献2', description: '这是文献2的描述' },
// 添加更多文献...
];
const ReferencesSidebar = () => {
// 使用组件状态控制侧边栏显示或隐藏
const [isSidebarVisible, setIsSidebarVisible] = useState(true);
// 处理侧边栏显示和隐藏的逻辑
const handleToggleSidebar = () => {
setIsSidebarVisible(!isSidebarVisible);
};
return (
<aside className={`sidebar ${isSidebarVisible ? 'open' : 'closed'}`}>
<button onClick={handleToggleSidebar}>
{isSidebarVisible ? '收起' : '展示'}
</button>
<h2>参考文献</h2>
<ul>
{references.map(ref => (
<li key={ref.id}>
<h3>{ref.title}</h3>
<p>{ref.description}</p>
</li>
))}
</ul>
</aside>
);
};
export default ReferencesSidebar;
import React, { useState } from 'react';
import './ReferencesSidebar.css'; // 确保此CSS文件与组件位于同一目录
interface Reference {
id: string;
title: string;
description: string;
}
const references: Reference[] = [
{ id: '1', title: '文献1', description: '这是文献1的描述' },
{ id: '2', title: '文献2', description: '这是文献2的描述' },
// 添加更多文献...
];
const ReferencesSidebar = () => {
const [isSidebarVisible, setIsSidebarVisible] = useState(true);
const handleToggleSidebar = () => {
setIsSidebarVisible(!isSidebarVisible);
};
return (
<aside className={`sidebar ${isSidebarVisible ? 'open' : 'closed'}`}>
<button onClick={handleToggleSidebar} className="toggle-button">
{isSidebarVisible ? '收起' : '展示'}
</button>
<h2>参考文献</h2>
<ul>
{references.map(ref => (
<li key={ref.id} className="reference-item">
<h3>{ref.title}</h3>
<p>{ref.description}</p>
</li>
))}
</ul>
</aside>
);
};
export default ReferencesSidebar;
.sidebar {
width: 250px;
position: fixed;
right: 0;
top: 0;
bottom: 0;
background-color: #f0f0f0;
overflow-y: auto;
padding: 20px;
transition: transform 0.3s ease;
}
.sidebar.closed {
transform: translateX(100%);
}
.toggle-button {
margin-bottom: 15px;
cursor: pointer;
}
ul {
list-style-type: none;
padding: 0;
}
.reference-item {
background-color: #ffffff;
margin-bottom: 10px;
padding: 15px;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
border-radius: 5px;
}
.reference-item h3 {
margin-top: 0;
}
.reference-item p {
margin-bottom: 0;
}
error - ./components/Referencebar/ReferencesSidebar.css
Global CSS cannot be imported from files other than your Custom
Import trace for requested module: ./components/Referencebar/ReferencesSidebar.css ./components/Referencebar/ReferencesSidebar.tsx ./components/Referencebar/index.ts ./pages/api/home/home.tsx ./pages/api/home/index.ts
import { IconFolderPlus, IconMistOff, IconPlus } from '@tabler/icons-react';
import { ReactNode } from 'react';
import { useTranslation } from 'react-i18next';
import {
CloseSidebarButton,
OpenSidebarButton,
} from './components/OpenCloseButton';
import Search from '../Search';
interface Props<T> {
isOpen: boolean;
side: 'left' | 'right';
items: T[];
toggleOpen: () => void;
}
const ReferenceSidebar = <T,>({
isOpen,
side,
items,
toggleOpen,
}: Props<T>) => {
const { t } = useTranslation('promptbar');
const allowDrop = (e: any) => {
e.preventDefault();
};
const highlightDrop = (e: any) => {
e.target.style.background = '#343541';
};
const removeHighlight = (e: any) => {
e.target.style.background = 'none';
};
return isOpen ? (
<div>
<div
className={`fixed top-0 ${side}-0 z-40 flex h-full w-[260px] flex-none flex-col space-y-2 bg-[#202123] p-2 text-[14px] transition-all sm:relative sm:top-0`}
>参照リスト
<div className="flex items-center">
</div>
<CloseSidebarButton onClick={toggleOpen} side={side} />
</div></div>
) : (
<OpenSidebarButton onClick={toggleOpen} side={side} />
);
};
export default ReferenceSidebar;
import React from 'react';
import { useTranslation } from 'react-i18next';
import { CloseSidebarButton, OpenSidebarButton } from './components/OpenCloseButton';
import styles from './ReferenceSidebar.module.css'; // 确保引入了CSS模块
interface Reference {
id: string;
title: string;
description: string;
}
interface Props<T> {
isOpen: boolean;
side: 'left' | 'right';
items: T[];
toggleOpen: () => void;
}
// 假设传入的items就是Reference类型的数组
const ReferenceSidebar = ({
isOpen,
side,
items,
toggleOpen,
}: Props<Reference>) => {
const { t } = useTranslation('promptbar');
return isOpen ? (
<div
className={`fixed top-0 ${side}-0 z-40 h-full w-[260px] flex-none flex-col p-2 bg-[#202123] text-white transition-all`}
>
<div className="flex items-center justify-between">
<h2 className={styles.sidebarTitle}>{t('referenceList')}</h2>
<CloseSidebarButton onClick={toggleOpen} side={side} />
</div>
<ul className={styles.referenceList}>
{items.map((ref) => (
<li key={ref.id} className={styles.referenceItem}>
<h3 className={styles.referenceTitle}>{ref.title}</h3>
<p className={styles.referenceDescription}>{ref.description}</p>
</li>
))}
</ul>
</div>
) : (
<OpenSidebarButton onClick={toggleOpen} side={side} />
);
};
export default ReferenceSidebar;
import React from 'react';
import { useTranslation } from 'react-i18next';
import { IconFolderPlus, IconMistOff, IconPlus } from '@tabler/icons-react';
import {
CloseSidebarButton,
OpenSidebarButton,
} from './components/OpenCloseButton';
import Search from '../Search';
// 参考文献の型定義
interface Reference {
id: string;
title: string;
description: string;
}
interface Props {
isOpen: boolean;
side: 'left' | 'right';
items: Reference[];
toggleOpen: () => void;
}
const ReferenceSidebar: React.FC<Props> = ({
isOpen,
side,
items,
toggleOpen,
}) => {
const { t } = useTranslation('promptbar');
return isOpen ? (
<div
className={`fixed top-0 ${side}-0 z-40 h-full w-[260px] flex-none flex-col bg-[#202123] p-2 text-[14px] transition-all`}
>
<div className="flex items-center justify-between">
<h2 className="text-white">{t('references')}</h2>
<CloseSidebarButton onClick={toggleOpen} side={side} />
</div>
<Search /> {/* サイドバー内で検索コンポーネントを使用する場合 */}
<ul className="mt-4 space-y-2 overflow-y-auto">
{items.map((item) => (
<li
key={item.id}
className="p-2 bg-[#343541] rounded-md text-white"
>
<h3>{item.title}</h3>
<p>{item.description}</p>
</li>
))}
</ul>
</div>
) : (
<OpenSidebarButton onClick={toggleOpen} side={side} />
);
};
export default ReferenceSidebar;
import { IconFolderPlus, IconMistOff, IconPlus } from '@tabler/icons-react'; import { ReactNode } from 'react'; import { useTranslation } from 'react-i18next';
import { CloseSidebarButton, OpenSidebarButton, } from './components/OpenCloseButton';
interface Reference { id: string; title: string; description: string; }
interface Props
const ReferenceSidebar = ({
isOpen,
side,
items,
toggleOpen,
}: Props
const allowDrop = (e: any) => { e.preventDefault(); };
const highlightDrop = (e: any) => { e.target.style.background = '#343541'; };
const removeHighlight = (e: any) => { e.target.style.background = 'none'; };
const itemsample = [ {id:'1',title:'実績発電原子炉に係る新規制基準の考え方について.pdf',description:'…見直しを行うために「発電用軽水型原子炉の新規制基準に関する検討チーム」(以下「検討チーム」という。)を組織し、発電用軽水型原子炉の新規制基準策定のための検討を開始した。検討チームの会合…'}, {id:'2',title:'実績発電原子炉に係る新規制基準の考え方について.pdf',description:'…見直しを行うために「発電用軽水型原子炉の新規制基準に関する検討チーム」(以下「検討チーム」という。)を組織し、発電用軽水型原子炉の新規制基準策定のための検討を開始した。検討チームの会合…'}, ]
const listItemStyle = { marginBottom: '10px', } return isOpen ? (
{item.description}
</div>
) : (
); };
export default ReferenceSidebar; ``
import { IconFolderPlus, IconMistOff, IconPlus } from '@tabler/icons-react';
import { ReactNode } from 'react';
import { useTranslation } from 'react-i18next';
import {
CloseSidebarButton,
OpenSidebarButton,
} from './components/OpenCloseButton';
interface Reference {
id: string;
title: string;
description: string;
}
interface Props<T> {
isOpen: boolean;
side: 'left' | 'right';
items: T[];
toggleOpen: () => void;
}
const ReferenceSidebar = ({
isOpen,
side,
items,
toggleOpen,
}: Props<Reference>) => {
const { t } = useTranslation('promptbar');
const allowDrop = (e: any) => {
e.preventDefault();
};
const highlightDrop = (e: any) => {
e.target.style.background = '#343541';
};
const removeHighlight = (e: any) => {
e.target.style.background = 'none';
};
const itemsample = [
{id:'1',title:'実績発電原子炉に係る新規制基準の考え方について.pdf',description:'…見直しを行うために「発電用軽水型原子炉の新規制基準に関する検討チーム」(以下「検討チーム」という。)を組織し、発電用軽水型原子炉の新規制基準策定のための検討を開始した。検討チームの会合…'},
{id:'2',title:'実績発電原子炉に係る新規制基準の考え方について.pdf',description:'…見直しを行うために「発電用軽水型原子炉の新規制基準に関する検討チーム」(以下「検討チーム」という。)を組織し、発電用軽水型原子炉の新規制基準策定のための検討を開始した。検討チームの会合…'},
]
const listItemStyle = {
marginBottom: '10px',
}
return isOpen ? (
<div>
<div className={`fixed top-0 ${side}-0 z-40 flex h-full w-[260px] flex-none flex-col space-y-2 bg-[#202123] p-2 text-[14px] transition-all sm:relative sm:top-0`}>
参照リスト
<ul>
{itemsample.map((item) => (
<li
key={item.id}
className="p-2 bg-[#343541] rounded-md text-white"
style={listItemStyle}
>
<h3>{item.title}</h3>
<p>{item.description}</p>
</li>
))}
</ul>
<CloseSidebarButton onClick={toggleOpen} side={side} />
</div>
</div>
) : (
<OpenSidebarButton onClick={toggleOpen} side={side} />
);
};
export default ReferenceSidebar;