diff --git a/src/core/localization/gettext/template/common.pot b/src/core/localization/gettext/template/common.pot index 2817b81d2..f5b1dfc9b 100644 --- a/src/core/localization/gettext/template/common.pot +++ b/src/core/localization/gettext/template/common.pot @@ -5,8 +5,8 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -"POT-Creation-Date: 2022-12-08T12:34:57.903Z\n" -"PO-Revision-Date: 2022-12-08T12:34:57.903Z\n" +"POT-Creation-Date: 2022-12-12T16:48:08.625Z\n" +"PO-Revision-Date: 2022-12-12T16:48:08.625Z\n" #: km msgid "km" diff --git a/src/core/store/columnContext.tsx b/src/core/store/columnContext.tsx index b56498a77..38dd5b7a5 100644 --- a/src/core/store/columnContext.tsx +++ b/src/core/store/columnContext.tsx @@ -14,9 +14,10 @@ export type PanelMeta = { closeCb: () => void; minHeight: number; getOpenState: () => boolean; + panelId?: string; }; -class PanelsRepository { +export class PanelsRepository { panels = new Set(); add(panel: PanelMeta) { @@ -38,15 +39,20 @@ class PanelsRepository { panel.resizableNode.style.height = newHeight + 'px'; } - /* Returns array with [panel, panelHeight] entries */ - getPanelsWithExtraSpace() { - return Array.from(this.panels).reduce((acc: [PanelMeta, number][], c) => { - const height = c.resizableNode.getBoundingClientRect().height; - if (height > c.minHeight) { - acc.push([c, height]); + getPanelsWithExtraSpace(): [[PanelMeta, number, number][], number] { + let totalExtraSpace = 0; + const panelsWithSizes: [PanelMeta, number, number][] = []; + + this.panels.forEach((panel) => { + const height = panel.resizableNode.getBoundingClientRect().height; + if (height > panel.minHeight) { + const extraSpace = height - panel.minHeight; + panelsWithSizes.push([panel, height, extraSpace]); + totalExtraSpace += extraSpace; } - return acc; - }, []); + }); + + return [panelsWithSizes, totalExtraSpace]; } getPanelsWithOpenState() { @@ -104,7 +110,7 @@ export class Resizer { ); } - /* 1. Adjust size when column size changed (window resize) */ + /* 2. Adjust size when column size changed (window resize) */ const containerEl = this.limiter.current; if (containerEl !== null) { const containerObserver = new ResizeObserver((containerElements) => { @@ -131,16 +137,26 @@ export class Resizer { } } + // why not resize first and close only after? + // then we have scenario when we shrinked all the panels and still have to close some + // after closing free space left but the panels are already shrinked _adjustPanelsHeight(diff: number) { // Get all children with height more than minimal - const cardsWithExtraSpace = this.panels.getPanelsWithExtraSpace(); - if (cardsWithExtraSpace.length > 0) { - // Reduce cards height - const reduceSize = Math.ceil(diff / cardsWithExtraSpace.length); - cardsWithExtraSpace.forEach(([card, currentHeight]) => { - this.panels.adjustToHeight(card, currentHeight - reduceSize); + const [cardsWithExtraSpace, totalExtraSpace] = this.panels.getPanelsWithExtraSpace(); + // If it's possible to free all the space needed by resizing - start resizing + if (totalExtraSpace > diff) { + // store the amount left to reduce + let leftToReduce = diff; + + cardsWithExtraSpace.forEach(([card, currentHeight, availableExtraSpace]) => { + // Reduce first card as much as needed + if (leftToReduce) { + const reduceAmount = + availableExtraSpace > leftToReduce ? leftToReduce : availableExtraSpace; + this.panels.adjustToHeight(card, currentHeight - reduceAmount); + leftToReduce = leftToReduce - reduceAmount; + } }); - // In case no children with extra space } else { // Close first opened card const openedPanels = this.panels.getPanelsWithOpenState(); diff --git a/src/features/analytics_panel/components/AnalyticsPanel/AnalyticsPanel.tsx b/src/features/analytics_panel/components/AnalyticsPanel/AnalyticsPanel.tsx index 1e6eece8b..7cfaa2c22 100644 --- a/src/features/analytics_panel/components/AnalyticsPanel/AnalyticsPanel.tsx +++ b/src/features/analytics_panel/components/AnalyticsPanel/AnalyticsPanel.tsx @@ -1,13 +1,15 @@ import { Panel, PanelIcon } from '@konturio/ui-kit'; -import { lazy, useCallback, useState } from 'react'; +import { lazy, useCallback, useLayoutEffect, useRef, useState } from 'react'; import clsx from 'clsx'; import { Analytics24 } from '@konturio/default-icons'; +import { useAtom } from '@reatom/react'; import { i18n } from '~core/localization'; import { panelClasses } from '~components/Panel'; import { IS_MOBILE_QUERY, useMediaQuery } from '~utils/hooks/useMediaQuery'; import { useAutoCollapsePanel } from '~utils/hooks/useAutoCollapsePanel'; import { useHeightResizer } from '~utils/hooks/useResizer'; import { MIN_HEIGHT } from '../../constants'; +import { analyticsResourceAtom } from '../../atoms/analyticsResource'; import styles from './AnalyticsPanel.module.css'; const LazyLoadedAnalyticsContainer = lazy( @@ -17,7 +19,15 @@ const LazyLoadedAnalyticsContainer = lazy( export function AnalyticsPanel() { const [isOpen, setIsOpen] = useState(true); const isMobile = useMediaQuery(IS_MOBILE_QUERY); - const handleRefChange = useHeightResizer(setIsOpen, isOpen, MIN_HEIGHT); + const [analyticsResourceState] = useAtom(analyticsResourceAtom); + const contentRef = useRef(null); + const [contentHeight, setContentHeight] = useState(MIN_HEIGHT); + + const handleRefChange = useHeightResizer(setIsOpen, isOpen, contentHeight, 'analytics'); + + useLayoutEffect(() => { + contentRef.current && setContentHeight(contentRef.current.scrollHeight); + }, [contentRef, analyticsResourceState]); const togglePanel = useCallback(() => { setIsOpen((prevState) => !prevState); @@ -54,7 +64,7 @@ export function AnalyticsPanel() { contentClassName={styles.contentWrap} contentContainerRef={handleRefChange} > -
+
diff --git a/src/features/events_list/components/EventsPanel/EventsPanel.tsx b/src/features/events_list/components/EventsPanel/EventsPanel.tsx index 1f8741eb5..705283ac7 100644 --- a/src/features/events_list/components/EventsPanel/EventsPanel.tsx +++ b/src/features/events_list/components/EventsPanel/EventsPanel.tsx @@ -11,7 +11,7 @@ import { useAutoCollapsePanel } from '~utils/hooks/useAutoCollapsePanel'; import { panelClasses } from '~components/Panel'; import { useHeightResizer } from '~utils/hooks/useResizer'; import { useShortPanelState } from '~utils/hooks/useShortPanelState'; -import { MIN_HEIGHT, MIN_SHORT_STATE_HEIGHT } from '../../constants'; +import { MIN_HEIGHT } from '../../constants'; import { FullState } from '../FullState/FullState'; import { ShortState } from '../ShortState/ShortState'; import s from './EventsPanel.module.css'; @@ -32,7 +32,8 @@ export function EventsPanel({ const handleRefChange = useHeightResizer( (isOpen) => !isOpen && setPanelState('closed'), isOpen, - isShort ? MIN_SHORT_STATE_HEIGHT : MIN_HEIGHT, + MIN_HEIGHT, + 'event_list', ); const openFullState = useCallback(() => { diff --git a/src/features/events_list/components/ShortState/ShortState.tsx b/src/features/events_list/components/ShortState/ShortState.tsx index 8fc023b8a..b14e7eafc 100644 --- a/src/features/events_list/components/ShortState/ShortState.tsx +++ b/src/features/events_list/components/ShortState/ShortState.tsx @@ -3,31 +3,12 @@ import { useAtom } from '@reatom/react'; import { useEffect, useState } from 'react'; import { i18n } from '~core/localization'; import { currentEventResourceAtom } from '~core/shared_state/currentEventResource'; -import { eventListResourceAtom } from '~features/events_list/atoms/eventListResource'; -import { EpisodeTimelineToggle } from '../EpisodeTimelineToggle/EpisodeTimelineToggle'; -import { EventCard } from '../EventCard/EventCard'; +import { eventListResourceAtom } from '../../atoms/eventListResource'; import { CurrentEvent } from '../CurrentEvent/CurrentEvent'; import s from './ShortState.module.css'; import type { MouseEventHandler } from 'react'; import type { Event } from '~core/types'; -const SingleEventCard = ({ - event, - hasTimeline, -}: { - event: Event; - hasTimeline?: boolean; -}) => ( - : null - } - externalUrls={event.externalUrls} - /> -); - export function ShortState({ hasTimeline, openFullState, @@ -54,11 +35,7 @@ export function ShortState({ if (!event && currentEvent) setEvent(currentEvent); }, [currentEvent, event, setEvent]); - const eventInfo = event ? ( - - ) : ( - - ); + const eventInfo = event ? : null; const panelContent = eventInfo || (
diff --git a/src/utils/hooks/useResizer.tsx b/src/utils/hooks/useResizer.tsx index ff37e1d65..29c8b66ac 100644 --- a/src/utils/hooks/useResizer.tsx +++ b/src/utils/hooks/useResizer.tsx @@ -8,6 +8,7 @@ export const useHeightResizer = ( setIsOpen: (value: SetStateAction) => void, isOpen: boolean, minHeight: number, + panelId?: string, ) => { const columnContext = useColumnContext(); const openStateRef = useRef(isOpen); @@ -44,12 +45,13 @@ export const useHeightResizer = ( closeCb: () => setIsOpen(false), minHeight, getOpenState: () => openStateRef.current, + panelId, }; // UseCallback not have cleanup like useEffect, this is workaround cleanup.current = columnContext.addPanel(panel); } }, - [columnContext, setIsOpen, minHeight], + [columnContext, setIsOpen, minHeight, panelId], ); return handleRefChange; diff --git a/src/widgets/LayersAndLegends/components/LayersAndLegendsWidget.tsx b/src/widgets/LayersAndLegends/components/LayersAndLegendsWidget.tsx index a21d67cdb..ad25aa8dd 100644 --- a/src/widgets/LayersAndLegends/components/LayersAndLegendsWidget.tsx +++ b/src/widgets/LayersAndLegends/components/LayersAndLegendsWidget.tsx @@ -30,6 +30,7 @@ export function LayersAndLegendsWidget({ layersProps, legendProps }: PanelProps) (isOpen) => !isOpen && setPanelState('closed'), isOpen, minHeight, + 'legend_and_layers', ); const onPanelIconClick = useCallback(() => {