mirror of
https://github.com/IRBorisov/ConceptPortal.git
synced 2025-08-14 12:50:37 +03:00
F: Improve Sidepanel UI
This commit is contained in:
parent
176ad744fe
commit
1af6f87824
|
@ -23,6 +23,7 @@ export function ApplicationLayout() {
|
||||||
const viewportHeight = useViewportHeight();
|
const viewportHeight = useViewportHeight();
|
||||||
const noNavigationAnimation = useAppLayoutStore(state => state.noNavigationAnimation);
|
const noNavigationAnimation = useAppLayoutStore(state => state.noNavigationAnimation);
|
||||||
const noNavigation = useAppLayoutStore(state => state.noNavigation);
|
const noNavigation = useAppLayoutStore(state => state.noNavigation);
|
||||||
|
const toastBottom = useAppLayoutStore(state => state.toastBottom);
|
||||||
const noFooter = useAppLayoutStore(state => state.noFooter);
|
const noFooter = useAppLayoutStore(state => state.noFooter);
|
||||||
const activeDialog = useDialogsStore(state => state.active);
|
const activeDialog = useDialogsStore(state => state.active);
|
||||||
|
|
||||||
|
@ -35,6 +36,8 @@ export function ApplicationLayout() {
|
||||||
autoClose={3000}
|
autoClose={3000}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
pauseOnFocusLoss={false}
|
pauseOnFocusLoss={false}
|
||||||
|
position={toastBottom ? 'bottom-right' : 'top-right'}
|
||||||
|
newestOnTop={toastBottom}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Suspense fallback={<ModalLoader />}>
|
<Suspense fallback={<ModalLoader />}>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Suspense } from 'react';
|
import { Suspense, useEffect } from 'react';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { useDebounce } from 'use-debounce';
|
import { useDebounce } from 'use-debounce';
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ interface SidePanelProps {
|
||||||
|
|
||||||
export function SidePanel({ isMounted, className }: SidePanelProps) {
|
export function SidePanel({ isMounted, className }: SidePanelProps) {
|
||||||
const noNavigationAnimation = useAppLayoutStore(state => state.noNavigationAnimation);
|
const noNavigationAnimation = useAppLayoutStore(state => state.noNavigationAnimation);
|
||||||
|
const setToastBottom = useAppLayoutStore(state => state.setToastBottom);
|
||||||
const { schema, isMutable, selectedItems } = useOssEdit();
|
const { schema, isMutable, selectedItems } = useOssEdit();
|
||||||
const selectedOperation =
|
const selectedOperation =
|
||||||
selectedItems.length === 1 && selectedItems[0].nodeType === NodeType.OPERATION ? selectedItems[0] : null;
|
selectedItems.length === 1 && selectedItems[0].nodeType === NodeType.OPERATION ? selectedItems[0] : null;
|
||||||
|
@ -32,8 +33,14 @@ export function SidePanel({ isMounted, className }: SidePanelProps) {
|
||||||
|
|
||||||
const [debouncedMounted] = useDebounce(isMounted, PARAMETER.moveDuration);
|
const [debouncedMounted] = useDebounce(isMounted, PARAMETER.moveDuration);
|
||||||
const closePanel = usePreferencesStore(state => state.toggleShowOssSidePanel);
|
const closePanel = usePreferencesStore(state => state.toggleShowOssSidePanel);
|
||||||
|
const showPanel = usePreferencesStore(state => state.showOssSidePanel);
|
||||||
const sidePanelHeight = useMainHeight();
|
const sidePanelHeight = useMainHeight();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setToastBottom(showPanel);
|
||||||
|
return () => setToastBottom(false);
|
||||||
|
}, [setToastBottom, showPanel]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside
|
<aside
|
||||||
className={cn(
|
className={cn(
|
||||||
|
|
|
@ -4,18 +4,23 @@ import { CstType, type IConstituentaBasicsDTO, type ICreateConstituentaDTO } fro
|
||||||
import { useCreateConstituenta } from '@/features/rsform/backend/use-create-constituenta';
|
import { useCreateConstituenta } from '@/features/rsform/backend/use-create-constituenta';
|
||||||
import { useMoveConstituents } from '@/features/rsform/backend/use-move-constituents';
|
import { useMoveConstituents } from '@/features/rsform/backend/use-move-constituents';
|
||||||
import { useMutatingRSForm } from '@/features/rsform/backend/use-mutating-rsform';
|
import { useMutatingRSForm } from '@/features/rsform/backend/use-mutating-rsform';
|
||||||
|
import { useResetAliases } from '@/features/rsform/backend/use-reset-aliases';
|
||||||
|
import { useRestoreOrder } from '@/features/rsform/backend/use-restore-order';
|
||||||
import { generateAlias } from '@/features/rsform/models/rsform-api';
|
import { generateAlias } from '@/features/rsform/models/rsform-api';
|
||||||
import { useCstSearchStore } from '@/features/rsform/stores/cst-search';
|
import { useCstSearchStore } from '@/features/rsform/stores/cst-search';
|
||||||
|
|
||||||
import { MiniButton } from '@/components/control';
|
import { MiniButton } from '@/components/control';
|
||||||
|
import { Dropdown, DropdownButton, useDropdown } from '@/components/dropdown';
|
||||||
import {
|
import {
|
||||||
IconClone,
|
IconClone,
|
||||||
IconDestroy,
|
IconDestroy,
|
||||||
IconEdit2,
|
IconEdit2,
|
||||||
|
IconGenerateNames,
|
||||||
IconMoveDown,
|
IconMoveDown,
|
||||||
IconMoveUp,
|
IconMoveUp,
|
||||||
IconNewItem,
|
IconNewItem,
|
||||||
IconRSForm,
|
IconRSForm,
|
||||||
|
IconSortList,
|
||||||
IconTree,
|
IconTree,
|
||||||
IconTypeGraph
|
IconTypeGraph
|
||||||
} from '@/components/icons';
|
} from '@/components/icons';
|
||||||
|
@ -43,6 +48,7 @@ export function ToolbarSchema({
|
||||||
isMutable,
|
isMutable,
|
||||||
className
|
className
|
||||||
}: ToolbarSchemaProps) {
|
}: ToolbarSchemaProps) {
|
||||||
|
const menuSchema = useDropdown();
|
||||||
const router = useConceptNavigation();
|
const router = useConceptNavigation();
|
||||||
const isProcessing = useMutatingRSForm();
|
const isProcessing = useMutatingRSForm();
|
||||||
const searchText = useCstSearchStore(state => state.query);
|
const searchText = useCstSearchStore(state => state.query);
|
||||||
|
@ -54,6 +60,8 @@ export function ToolbarSchema({
|
||||||
const showTermGraph = useDialogsStore(state => state.showShowTermGraph);
|
const showTermGraph = useDialogsStore(state => state.showShowTermGraph);
|
||||||
const { moveConstituents } = useMoveConstituents();
|
const { moveConstituents } = useMoveConstituents();
|
||||||
const { createConstituenta } = useCreateConstituenta();
|
const { createConstituenta } = useCreateConstituenta();
|
||||||
|
const { resetAliases } = useResetAliases();
|
||||||
|
const { restoreOrder } = useRestoreOrder();
|
||||||
|
|
||||||
function navigateRSForm() {
|
function navigateRSForm() {
|
||||||
router.push({ path: urls.schema(schema.id) });
|
router.push({ path: urls.schema(schema.id) });
|
||||||
|
@ -181,14 +189,50 @@ export function ToolbarSchema({
|
||||||
showTermGraph({ schema: schema });
|
showTermGraph({ schema: schema });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleReindex() {
|
||||||
|
menuSchema.hide();
|
||||||
|
void resetAliases({ itemID: schema.id });
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleRestoreOrder() {
|
||||||
|
menuSchema.hide();
|
||||||
|
void restoreOrder({ itemID: schema.id });
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn('flex gap-0.5', className)}>
|
<div className={cn('flex gap-0.5', className)}>
|
||||||
|
<div ref={menuSchema.ref} onBlur={menuSchema.handleBlur} className='flex relative items-center'>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
|
title='Редактирование концептуальной схемы'
|
||||||
|
hideTitle={menuSchema.isOpen}
|
||||||
|
icon={<IconRSForm size='1rem' className='icon-primary' />}
|
||||||
|
onClick={menuSchema.toggle}
|
||||||
|
/>
|
||||||
|
<Dropdown isOpen={menuSchema.isOpen} margin='mt-0.5'>
|
||||||
|
<DropdownButton
|
||||||
|
text='Упорядочить список'
|
||||||
|
titleHtml='Упорядочить список, исходя из <br/>логики типов и связей конституент'
|
||||||
|
aria-label='Упорядочить список, исходя из логики типов и связей конституент'
|
||||||
|
icon={<IconSortList size='1rem' className='icon-primary' />}
|
||||||
|
onClick={handleRestoreOrder}
|
||||||
|
disabled={!isMutable || isProcessing}
|
||||||
|
/>
|
||||||
|
<DropdownButton
|
||||||
|
text='Порядковые имена'
|
||||||
|
titleHtml='Присвоить порядковые имена <br/>и обновить выражения'
|
||||||
|
aria-label='Присвоить порядковые имена и обновить выражения'
|
||||||
|
icon={<IconGenerateNames size='1rem' className='icon-primary' />}
|
||||||
|
onClick={handleReindex}
|
||||||
|
disabled={!isMutable || isProcessing}
|
||||||
|
/>
|
||||||
|
<DropdownButton
|
||||||
title='Перейти к концептуальной схеме'
|
title='Перейти к концептуальной схеме'
|
||||||
|
text='перейти к схеме'
|
||||||
icon={<IconRSForm size='1rem' className='icon-primary' />}
|
icon={<IconRSForm size='1rem' className='icon-primary' />}
|
||||||
onClick={navigateRSForm}
|
onClick={navigateRSForm}
|
||||||
/>
|
/>
|
||||||
|
</Dropdown>
|
||||||
|
</div>
|
||||||
<MiniButton
|
<MiniButton
|
||||||
title='Редактировать конституенту'
|
title='Редактировать конституенту'
|
||||||
icon={<IconEdit2 size='1rem' className='icon-primary' />}
|
icon={<IconEdit2 size='1rem' className='icon-primary' />}
|
||||||
|
|
|
@ -10,6 +10,9 @@ interface AppLayoutStore {
|
||||||
|
|
||||||
noFooter: boolean;
|
noFooter: boolean;
|
||||||
hideFooter: (value?: boolean) => void;
|
hideFooter: (value?: boolean) => void;
|
||||||
|
|
||||||
|
toastBottom: boolean;
|
||||||
|
setToastBottom: (value: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useAppLayoutStore = create<AppLayoutStore>()(set => ({
|
export const useAppLayoutStore = create<AppLayoutStore>()(set => ({
|
||||||
|
@ -26,7 +29,10 @@ export const useAppLayoutStore = create<AppLayoutStore>()(set => ({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
noFooter: false,
|
noFooter: false,
|
||||||
hideFooter: value => set({ noFooter: value ?? true })
|
hideFooter: value => set({ noFooter: value ?? true }),
|
||||||
|
|
||||||
|
toastBottom: false,
|
||||||
|
setToastBottom: value => set({ toastBottom: value })
|
||||||
}));
|
}));
|
||||||
|
|
||||||
/** Utility function that returns the height of the main area. */
|
/** Utility function that returns the height of the main area. */
|
||||||
|
|
Loading…
Reference in New Issue
Block a user