From 2d2c0290e3097847442a5111de8207214be45a1f Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Tue, 24 Jun 2025 22:13:26 +0300 Subject: [PATCH] F: Add hide button for stats --- rsconcept/frontend/src/components/icons.tsx | 6 ++-- .../features/help/items/ui/help-rscard.tsx | 12 +++---- .../features/help/items/ui/help-rseditor.tsx | 4 +-- .../library/components/icon-show-sidebar.tsx | 23 +++++++++++++ .../library/components/toolbar-item-card.tsx | 28 +++++++++++++++- .../editor-oss-card/editor-oss-card.tsx | 33 ++++++++++++------- .../oss-page/editor-oss-card/oss-stats.tsx | 14 ++++++-- .../editor-constituenta.tsx | 3 +- .../toolbar-constituenta.tsx | 18 ++++------ .../editor-rsform-card/editor-rsform-card.tsx | 24 ++++++++++++-- .../editor-rsform-card/rsform-stats.tsx | 20 +++++++---- .../editor-rslist/toolbar-rslist.tsx | 5 +-- .../view-constituents/view-constituents.tsx | 9 +++-- rsconcept/frontend/src/index.css | 1 + rsconcept/frontend/src/stores/preferences.ts | 12 +++++++ rsconcept/frontend/src/styling/utilities.css | 6 ++++ 16 files changed, 162 insertions(+), 56 deletions(-) create mode 100644 rsconcept/frontend/src/features/library/components/icon-show-sidebar.tsx diff --git a/rsconcept/frontend/src/components/icons.tsx b/rsconcept/frontend/src/components/icons.tsx index bbef3f28..dfd1aaaa 100644 --- a/rsconcept/frontend/src/components/icons.tsx +++ b/rsconcept/frontend/src/components/icons.tsx @@ -25,6 +25,10 @@ export { LuQrCode as IconQR } from 'react-icons/lu'; export { LuFilterX as IconFilterReset } from 'react-icons/lu'; export {BiDownArrowCircle as IconOpenList } from 'react-icons/bi'; export { LuTriangleAlert as IconAlert } from 'react-icons/lu'; +export { LuPanelLeftOpen as IconLeftOpen } from 'react-icons/lu'; +export { LuPanelLeftClose as IconLeftClose } from 'react-icons/lu'; +export { LuPanelBottomOpen as IconBottomOpen } from 'react-icons/lu'; +export { LuPanelBottomClose as IconBottomClose } from 'react-icons/lu'; // ===== UI elements ======= export { BiX as IconClose } from 'react-icons/bi'; @@ -97,9 +101,7 @@ export { LuDatabase as IconDatabase } from 'react-icons/lu'; export { LuView as IconDBStructure } from 'react-icons/lu'; export { LuPlaneTakeoff as IconRESTapi } from 'react-icons/lu'; export { LuImage as IconImage } from 'react-icons/lu'; -export { TbColumns as IconList } from 'react-icons/tb'; export { GoVersions as IconVersions } from 'react-icons/go'; -export { TbColumnsOff as IconListOff } from 'react-icons/tb'; export { LuAtSign as IconTerm } from 'react-icons/lu'; export { LuSubscript as IconAlias } from 'react-icons/lu'; export { TbMathFunction as IconFormula } from 'react-icons/tb'; diff --git a/rsconcept/frontend/src/features/help/items/ui/help-rscard.tsx b/rsconcept/frontend/src/features/help/items/ui/help-rscard.tsx index d7ee9782..a063f7dc 100644 --- a/rsconcept/frontend/src/features/help/items/ui/help-rscard.tsx +++ b/rsconcept/frontend/src/features/help/items/ui/help-rscard.tsx @@ -1,9 +1,8 @@ import { - IconClone, IconDestroy, - IconDownload, IconEditor, IconImmutable, + IconLeftOpen, IconOSS, IconOwner, IconPublic, @@ -49,15 +48,12 @@ export function HelpRSCard() {
  • Неизменные схемы
  • -
  • - Клонировать – создать копию схемы -
  • -
  • - Загрузить/Выгрузить – взаимодействие с Экстеор -
  • Удалить – полностью удаляет схему из базы Портала
  • +
  • + Отображение статистики +
  • ); diff --git a/rsconcept/frontend/src/features/help/items/ui/help-rseditor.tsx b/rsconcept/frontend/src/features/help/items/ui/help-rseditor.tsx index 8ffe85bd..1154429d 100644 --- a/rsconcept/frontend/src/features/help/items/ui/help-rseditor.tsx +++ b/rsconcept/frontend/src/features/help/items/ui/help-rseditor.tsx @@ -5,7 +5,7 @@ import { IconEdit, IconFilter, IconKeyboard, - IconList, + IconLeftOpen, IconMoveDown, IconMoveUp, IconNewItem, @@ -37,7 +37,7 @@ export function HelpRSEditor() { переход к исходной
  • - список конституент + список конституент
  • сохранить: Ctrl + S diff --git a/rsconcept/frontend/src/features/library/components/icon-show-sidebar.tsx b/rsconcept/frontend/src/features/library/components/icon-show-sidebar.tsx new file mode 100644 index 00000000..9ea9351a --- /dev/null +++ b/rsconcept/frontend/src/features/library/components/icon-show-sidebar.tsx @@ -0,0 +1,23 @@ +import { type DomIconProps, IconBottomClose, IconBottomOpen, IconLeftClose, IconLeftOpen } from '@/components/icons'; + +/** Icon for sidebar visibility. */ +export function IconShowSidebar({ + value, + size = '1.25rem', + className, + isBottom +}: DomIconProps & { isBottom: boolean }) { + if (isBottom) { + if (value) { + return ; + } else { + return ; + } + } else { + if (value) { + return ; + } else { + return ; + } + } +} diff --git a/rsconcept/frontend/src/features/library/components/toolbar-item-card.tsx b/rsconcept/frontend/src/features/library/components/toolbar-item-card.tsx index 7b1040c3..3a2d4750 100644 --- a/rsconcept/frontend/src/features/library/components/toolbar-item-card.tsx +++ b/rsconcept/frontend/src/features/library/components/toolbar-item-card.tsx @@ -10,29 +10,46 @@ import { MiniButton } from '@/components/control'; import { IconDestroy, IconSave, IconShare } from '@/components/icons'; import { cn } from '@/components/utils'; import { useModificationStore } from '@/stores/modification'; +import { usePreferencesStore } from '@/stores/preferences'; import { tooltipText } from '@/utils/labels'; import { prepareTooltip, sharePage } from '@/utils/utils'; import { AccessPolicy, type ILibraryItem, LibraryItemType } from '../backend/types'; import { useMutatingLibrary } from '../backend/use-mutating-library'; +import { IconShowSidebar } from './icon-show-sidebar'; import { MiniSelectorOSS } from './mini-selector-oss'; interface ToolbarItemCardProps { className?: string; + isNarrow: boolean; onSubmit: () => void; isMutable: boolean; schema: ILibraryItem; deleteSchema: () => void; } -export function ToolbarItemCard({ className, schema, onSubmit, isMutable, deleteSchema }: ToolbarItemCardProps) { +export function ToolbarItemCard({ + className, + isNarrow, + schema, + onSubmit, + isMutable, + deleteSchema +}: ToolbarItemCardProps) { const role = useRoleStore(state => state.role); const router = useConceptNavigation(); const { isModified } = useModificationStore(); const isProcessing = useMutatingLibrary(); const canSave = isModified && !isProcessing; + const showRSFormStats = usePreferencesStore(state => state.showRSFormStats); + const toggleShowRSFormStats = usePreferencesStore(state => state.toggleShowRSFormStats); + const showOSSStats = usePreferencesStore(state => state.showOSSStats); + const toggleShowOSSStats = usePreferencesStore(state => state.toggleShowOSSStats); + const isRSForm = schema.item_type === LibraryItemType.RSFORM; + const isOSS = schema.item_type === LibraryItemType.OSS; + const ossSelector = (() => { if (schema.item_type !== LibraryItemType.RSFORM) { return null; @@ -76,6 +93,15 @@ export function ToolbarItemCard({ className, schema, onSubmit, isMutable, delete disabled={!isMutable || isProcessing || role < UserRole.OWNER} /> ) : null} + {(isRSForm || isOSS) && ( + + } + onClick={isRSForm ? toggleShowRSFormStats : toggleShowOSSStats} + /> + )} ); diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-card/editor-oss-card.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-card/editor-oss-card.tsx index 77c8ba46..7c0a3c9b 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-card/editor-oss-card.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-card/editor-oss-card.tsx @@ -4,7 +4,9 @@ import clsx from 'clsx'; import { EditorLibraryItem, ToolbarItemCard } from '@/features/library/components'; +import { useWindowSize } from '@/hooks/use-window-size'; import { useModificationStore } from '@/stores/modification'; +import { usePreferencesStore } from '@/stores/preferences'; import { globalIDs } from '@/utils/constants'; import { useOssEdit } from '../oss-edit-context'; @@ -12,9 +14,14 @@ import { useOssEdit } from '../oss-edit-context'; import { FormOSS } from './form-oss'; import { OssStats } from './oss-stats'; +const SIDELIST_LAYOUT_THRESHOLD = 768; // px + export function EditorOssCard() { const { schema, isMutable, deleteSchema } = useOssEdit(); const { isModified } = useModificationStore(); + const showOSSStats = usePreferencesStore(state => state.showOSSStats); + const windowSize = useWindowSize(); + const isNarrow = !!windowSize.width && windowSize.width <= SIDELIST_LAYOUT_THRESHOLD; function initiateSubmit() { const element = document.getElementById(globalIDs.library_item_editor) as HTMLFormElement; @@ -33,25 +40,29 @@ export function EditorOssCard() { } return ( - <> +
    -
    -
    - - -
    - +
    + +
    - + + +
    ); } diff --git a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-card/oss-stats.tsx b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-card/oss-stats.tsx index fb386872..fc726399 100644 --- a/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-card/oss-stats.tsx +++ b/rsconcept/frontend/src/features/oss/pages/oss-page/editor-oss-card/oss-stats.tsx @@ -13,12 +13,20 @@ import { type IOperationSchemaStats } from '../../../models/oss'; interface OssStatsProps { className?: string; + isMounted: boolean; stats: IOperationSchemaStats; } -export function OssStats({ className, stats }: OssStatsProps) { +export function OssStats({ className, isMounted, stats }: OssStatsProps) { return ( -
    + ); } diff --git a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-constituenta/editor-constituenta.tsx b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-constituenta/editor-constituenta.tsx index 4b7f57f3..0b86ed97 100644 --- a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-constituenta/editor-constituenta.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-constituenta/editor-constituenta.tsx @@ -96,6 +96,7 @@ export function EditorConstituenta() { onSubmit={initiateSubmit} onReset={() => setToggleReset(prev => !prev)} disabled={disabled} + isNarrow={isNarrow} />
    @@ -112,7 +113,7 @@ export function EditorConstituenta() { ) : null}
    diff --git a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-constituenta/toolbar-constituenta.tsx b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-constituenta/toolbar-constituenta.tsx index 46490e5d..edaf3af3 100644 --- a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-constituenta/toolbar-constituenta.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-constituenta/toolbar-constituenta.tsx @@ -1,19 +1,16 @@ 'use client'; -import clsx from 'clsx'; - import { urls, useConceptNavigation } from '@/app'; import { HelpTopic } from '@/features/help'; import { BadgeHelp } from '@/features/help/components'; import { MiniSelectorOSS } from '@/features/library/components'; +import { IconShowSidebar } from '@/features/library/components/icon-show-sidebar'; import { useFindPredecessor } from '@/features/oss/backend/use-find-predecessor'; import { MiniButton } from '@/components/control'; import { IconClone, IconDestroy, - IconList, - IconListOff, IconMoveDown, IconMoveUp, IconNewItem, @@ -21,6 +18,7 @@ import { IconReset, IconSave } from '@/components/icons'; +import { cn } from '@/components/utils'; import { useModificationStore } from '@/stores/modification'; import { usePreferencesStore } from '@/stores/preferences'; import { tooltipText } from '@/utils/labels'; @@ -34,6 +32,7 @@ interface ToolbarConstituentaProps { className?: string; activeCst: IConstituenta | null; disabled: boolean; + isNarrow: boolean; onSubmit: () => void; onReset: () => void; @@ -43,6 +42,7 @@ export function ToolbarConstituenta({ className, activeCst, disabled, + isNarrow, onSubmit, onReset @@ -80,7 +80,7 @@ export function ToolbarConstituenta({ } return ( -
    +
    {schema.oss.length > 0 ? ( - ) : ( - - ) - } + icon={} onClick={toggleList} /> diff --git a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-rsform-card/editor-rsform-card.tsx b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-rsform-card/editor-rsform-card.tsx index fa051222..4775223d 100644 --- a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-rsform-card/editor-rsform-card.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-rsform-card/editor-rsform-card.tsx @@ -1,8 +1,12 @@ 'use client'; +import clsx from 'clsx'; + import { EditorLibraryItem, ToolbarItemCard } from '@/features/library/components'; +import { useWindowSize } from '@/hooks/use-window-size'; import { useModificationStore } from '@/stores/modification'; +import { usePreferencesStore } from '@/stores/preferences'; import { globalIDs } from '@/utils/constants'; import { useRSEdit } from '../rsedit-context'; @@ -10,9 +14,14 @@ import { useRSEdit } from '../rsedit-context'; import { FormRSForm } from './form-rsform'; import { RSFormStats } from './rsform-stats'; +const SIDELIST_LAYOUT_THRESHOLD = 768; // px + export function EditorRSFormCard() { const { schema, isArchive, isMutable, deleteSchema, isAttachedToOSS } = useRSEdit(); const { isModified } = useModificationStore(); + const showRSFormStats = usePreferencesStore(state => state.showRSFormStats); + const windowSize = useWindowSize(); + const isNarrow = !!windowSize.width && windowSize.width <= SIDELIST_LAYOUT_THRESHOLD; function initiateSubmit() { const element = document.getElementById(globalIDs.library_item_editor) as HTMLFormElement; @@ -31,24 +40,33 @@ export function EditorRSFormCard() { } return ( -
    +
    -
    +
    ); diff --git a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-rsform-card/rsform-stats.tsx b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-rsform-card/rsform-stats.tsx index 97e8cacc..fe7dffa1 100644 --- a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-rsform-card/rsform-stats.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-rsform-card/rsform-stats.tsx @@ -1,5 +1,3 @@ -import clsx from 'clsx'; - import { IconChild, IconConvention, @@ -19,6 +17,7 @@ import { IconStatusProperty, IconTerminology } from '@/components/icons'; +import { cn } from '@/components/utils'; import { ValueStats } from '@/components/view'; import { type IRSFormStats } from '../../../models/rsform'; @@ -26,13 +25,22 @@ import { type IRSFormStats } from '../../../models/rsform'; interface RSFormStatsProps { className?: string; isArchive: boolean; + isMounted: boolean; stats: IRSFormStats; } -export function RSFormStats({ className, stats, isArchive }: RSFormStatsProps) { +export function RSFormStats({ className, stats, isArchive, isMounted }: RSFormStatsProps) { return ( -
    -
    +
    + ); } diff --git a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-rslist/toolbar-rslist.tsx b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-rslist/toolbar-rslist.tsx index a42571cb..35dc5fe2 100644 --- a/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-rslist/toolbar-rslist.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/rsform-page/editor-rslist/toolbar-rslist.tsx @@ -1,4 +1,4 @@ -import clsx from 'clsx'; +'use client'; import { HelpTopic } from '@/features/help'; import { BadgeHelp } from '@/features/help/components'; @@ -15,6 +15,7 @@ import { IconOpenList, IconReset } from '@/components/icons'; +import { cn } from '@/components/utils'; import { prefixes } from '@/utils/constants'; import { prepareTooltip } from '@/utils/utils'; @@ -46,7 +47,7 @@ export function ToolbarRSList({ className }: ToolbarRSListProps) { } = useRSEdit(); return ( -
    +
    {schema.oss.length > 0 ? ( diff --git a/rsconcept/frontend/src/index.css b/rsconcept/frontend/src/index.css index 3634211e..0b0487c2 100644 --- a/rsconcept/frontend/src/index.css +++ b/rsconcept/frontend/src/index.css @@ -91,6 +91,7 @@ --duration-modal: 300ms; --duration-fade: 300ms; --duration-move: 500ms; + --duration-transform: 1000ms; --duration-cycle: 1000ms; /* Custom animations */ diff --git a/rsconcept/frontend/src/stores/preferences.ts b/rsconcept/frontend/src/stores/preferences.ts index 3d2899f1..37e84053 100644 --- a/rsconcept/frontend/src/stores/preferences.ts +++ b/rsconcept/frontend/src/stores/preferences.ts @@ -20,6 +20,12 @@ interface PreferencesStore { showCstSideList: boolean; toggleShowCstSideList: () => void; + showRSFormStats: boolean; + toggleShowRSFormStats: () => void; + + showOSSStats: boolean; + toggleShowOSSStats: () => void; + showExpressionControls: boolean; toggleShowExpressionControls: () => void; } @@ -63,6 +69,12 @@ export const usePreferencesStore = create()( showCstSideList: true, toggleShowCstSideList: () => set(state => ({ showCstSideList: !state.showCstSideList })), + showRSFormStats: true, + toggleShowRSFormStats: () => set(state => ({ showRSFormStats: !state.showRSFormStats })), + + showOSSStats: true, + toggleShowOSSStats: () => set(state => ({ showOSSStats: !state.showOSSStats })), + showExpressionControls: true, toggleShowExpressionControls: () => set(state => ({ showExpressionControls: !state.showExpressionControls })) }), diff --git a/rsconcept/frontend/src/styling/utilities.css b/rsconcept/frontend/src/styling/utilities.css index a3302f6d..6abc7941 100644 --- a/rsconcept/frontend/src/styling/utilities.css +++ b/rsconcept/frontend/src/styling/utilities.css @@ -142,6 +142,12 @@ } } +@utility cc-animate-sidebar { + transition-property: max-width, opacity; + transition-timing-function: var(--ease-in-out); + transition-duration: var(--duration-transform); +} + @utility cc-animate-position { transition-property: transform top left bottom right margin padding; transition-timing-function: var(--ease-bezier);