F: Introduce AI UI
This commit is contained in:
parent
f61a8636f6
commit
a03c5d7fe8
58
rsconcept/frontend/src/app/navigation/menu-ai.tsx
Normal file
58
rsconcept/frontend/src/app/navigation/menu-ai.tsx
Normal file
|
@ -0,0 +1,58 @@
|
|||
import { useAuth } from '@/features/auth/backend/use-auth';
|
||||
|
||||
import { Dropdown, DropdownButton, useDropdown } from '@/components/dropdown';
|
||||
import { IconAssistant, IconChat, IconTemplates } from '@/components/icons';
|
||||
import { globalIDs } from '@/utils/constants';
|
||||
import { notImplemented } from '@/utils/utils';
|
||||
|
||||
import { urls } from '../urls';
|
||||
|
||||
import { NavigationButton } from './navigation-button';
|
||||
import { useConceptNavigation } from './navigation-context';
|
||||
|
||||
export function MenuAI() {
|
||||
const router = useConceptNavigation();
|
||||
const menu = useDropdown();
|
||||
const { user } = useAuth();
|
||||
|
||||
function navigateTemplates(event: React.MouseEvent<Element>) {
|
||||
menu.hide();
|
||||
router.push({ path: urls.prompt_templates, newTab: event.ctrlKey || event.metaKey });
|
||||
}
|
||||
|
||||
function handleCreatePrompt(event: React.MouseEvent<Element>) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
menu.hide();
|
||||
notImplemented();
|
||||
}
|
||||
|
||||
return (
|
||||
<div ref={menu.ref} onBlur={menu.handleBlur} className='flex items-center justify-start relative h-full'>
|
||||
<NavigationButton
|
||||
title='ИИ помощник' //
|
||||
hideTitle={menu.isOpen}
|
||||
aria-expanded={menu.isOpen}
|
||||
aria-controls={globalIDs.ai_dropdown}
|
||||
icon={<IconAssistant size='1.5rem' />}
|
||||
onClick={menu.toggle}
|
||||
/>
|
||||
|
||||
<Dropdown id={globalIDs.ai_dropdown} className='min-w-[12ch] max-w-48' stretchLeft isOpen={menu.isOpen}>
|
||||
<DropdownButton
|
||||
text='Запрос'
|
||||
title='Создать запрос'
|
||||
icon={<IconChat size='1rem' />}
|
||||
onClick={handleCreatePrompt}
|
||||
/>
|
||||
<DropdownButton
|
||||
text='Шаблоны'
|
||||
title={user?.is_staff ? 'Шаблоны запросов' : 'Доступно только зарегистрированным пользователям'}
|
||||
icon={<IconTemplates size='1rem' />}
|
||||
onClick={navigateTemplates}
|
||||
disabled={!user?.is_staff}
|
||||
/>
|
||||
</Dropdown>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -9,11 +9,11 @@ import { useConceptNavigation } from './navigation-context';
|
|||
import { UserButton } from './user-button';
|
||||
import { UserDropdown } from './user-dropdown';
|
||||
|
||||
export function UserMenu() {
|
||||
export function MenuUser() {
|
||||
const router = useConceptNavigation();
|
||||
const menu = useDropdown();
|
||||
return (
|
||||
<div ref={menu.ref} onBlur={menu.handleBlur} className='flex items-center justify-start relative h-full pr-2'>
|
||||
<div ref={menu.ref} onBlur={menu.handleBlur} className='flex items-center justify-start relative h-full'>
|
||||
<Suspense fallback={<Loader circular scale={1.5} />}>
|
||||
<UserButton
|
||||
onLogin={() => router.push({ path: urls.login, force: true })}
|
|
@ -24,7 +24,7 @@ export function NavigationButton({ icon, title, hideTitle, className, style, onC
|
|||
style={style}
|
||||
>
|
||||
{icon ? icon : null}
|
||||
{text ? <span className='hidden sm:inline'>{text}</span> : null}
|
||||
{text ? <span className='hidden md:inline'>{text}</span> : null}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,10 +8,11 @@ import { useDialogsStore } from '@/stores/dialogs';
|
|||
import { urls } from '../urls';
|
||||
|
||||
import { Logo } from './logo';
|
||||
import { MenuAI } from './menu-ai';
|
||||
import { MenuUser } from './menu-user';
|
||||
import { NavigationButton } from './navigation-button';
|
||||
import { useConceptNavigation } from './navigation-context';
|
||||
import { ToggleNavigation } from './toggle-navigation';
|
||||
import { UserMenu } from './user-menu';
|
||||
|
||||
export function Navigation() {
|
||||
const { push } = useConceptNavigation();
|
||||
|
@ -41,11 +42,13 @@ export function Navigation() {
|
|||
<div className='flex items-center mr-auto cursor-pointer' onClick={!size.isSmall ? navigateHome : undefined}>
|
||||
<Logo />
|
||||
</div>
|
||||
<div className='flex gap-2 items-center'>
|
||||
<div className='flex gap-2 items-center pr-2'>
|
||||
<NavigationButton text='Новая схема' icon={<IconNewItem2 size='1.5rem' />} onClick={navigateCreateNew} />
|
||||
<NavigationButton text='Библиотека' icon={<IconLibrary2 size='1.5rem' />} onClick={navigateLibrary} />
|
||||
<NavigationButton text='Справка' icon={<IconManuals size='1.5rem' />} onClick={navigateHelp} />
|
||||
<UserMenu />
|
||||
|
||||
<MenuAI />
|
||||
<MenuUser />
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
|
|
@ -19,7 +19,8 @@ export const routes = {
|
|||
rsforms: 'rsforms',
|
||||
oss: 'oss',
|
||||
icons: 'icons',
|
||||
database_schema: 'database-schema'
|
||||
database_schema: 'database-schema',
|
||||
prompt_templates: 'prompt-templates'
|
||||
} as const;
|
||||
|
||||
/** Internal navigation URLs. */
|
||||
|
@ -37,6 +38,7 @@ export const urls = {
|
|||
library: `/${routes.library}`,
|
||||
library_filter: (strategy: string) => `/library?filter=${strategy}`,
|
||||
create_schema: `/${routes.create_schema}`,
|
||||
prompt_templates: `/${routes.prompt_templates}`,
|
||||
manuals: `/${routes.manuals}`,
|
||||
help_topic: (topic: string) => `/manuals?topic=${topic}`,
|
||||
schema: (id: number | string, version?: number | string) =>
|
||||
|
|
|
@ -63,6 +63,8 @@ export { PiFileCsv as IconCSV } from 'react-icons/pi';
|
|||
|
||||
// ==== User status =======
|
||||
export { LuCircleUserRound as IconUser } from 'react-icons/lu';
|
||||
export { FaUserAstronaut as IconAssistant } from 'react-icons/fa6';
|
||||
export { IoChatbubblesOutline as IconChat } from 'react-icons/io5';
|
||||
export { FaCircleUser as IconUser2 } from 'react-icons/fa6';
|
||||
export { TbUserEdit as IconEditor } from 'react-icons/tb';
|
||||
export { TbUserSearch as IconUserSearch } from 'react-icons/tb';
|
||||
|
|
|
@ -79,7 +79,8 @@ export const globalIDs = {
|
|||
library_item_editor: 'library_item_editor',
|
||||
constituenta_editor: 'constituenta_editor',
|
||||
graph_schemas: 'graph_schemas_tooltip',
|
||||
user_dropdown: 'user_dropdown'
|
||||
user_dropdown: 'user_dropdown',
|
||||
ai_dropdown: 'ai_dropdown'
|
||||
} as const;
|
||||
|
||||
/** Prefixes for generating unique keys for lists. */
|
||||
|
|
Loading…
Reference in New Issue
Block a user