From 5fa9fd17918398c3681ce2b22e2add0ffc5328ac Mon Sep 17 00:00:00 2001 From: hamed-musallam <35760236+hamed-musallam@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:03:38 +0200 Subject: [PATCH] feat: improve filter selection and editing behavior (#3265) * feat: create ReadOnly component to block editing and show a message * refactor: reverse the order of filter action buttons * refactor: apodization filter restore,reset,save, and cancel actions * refactor: baseline correction filter restore,reset,save, and cancel actions * refactor: zero filling filter restore,reset,save, and cancel actions * refactor: exclusion zones filter restore,reset,save, and cancel actions * refactor: pashe correction filter restore,reset,save, and cancel actions * refactor: shift filter restore,reset,save, and cancel actions * test: fix selectors * refactor: filter action buttons * fix: enable editing just in the active filter * refactor: rename reset button titles * refactor: do not reset the spectrum after applying changes --- .../{Header.tsx => HeaderContainer.tsx} | 2 +- src/component/elements/ReadOnly.tsx | 78 +++++ .../header/AutoPeakPickingOptionPanel.tsx | 6 +- src/component/header/Header.tsx | 18 +- ...{HeaderContainer.tsx => HeaderWrapper.tsx} | 2 +- .../header/RangesPickingOptionPanel.tsx | 6 +- .../header/SimpleApodizationOptionsPanel.tsx | 6 +- .../SimpleBaseLineCorrectionOptionsPanel.tsx | 6 +- .../SimplePhaseCorrectionOptionsPanel.tsx | 6 +- ...implePhaseCorrectionTwoDimensionsPanel.tsx | 6 +- .../header/SimpleZeroFillingOptionsPanel.tsx | 6 +- src/component/header/Zones2DOptionPanel.tsx | 6 +- src/component/main/InnerNMRiumContents.tsx | 2 +- .../Filters/ApodizationOptionsPanel.tsx | 72 +++-- .../BaseLineCorrectionOptionsPanel.tsx | 72 +++-- .../Filters/ExclusionZonesOptionsPanel.tsx | 46 +-- .../Filters/FilterActionButtons.tsx | 30 +- .../Filters/FiltersSectionsPanel.tsx | 50 +++- .../Filters/PhaseCorrectionOptionsPanel.tsx | 44 +-- ...aseCorrectionTwoDimensionsOptionsPanel.tsx | 117 +++++--- .../Filters/ShiftOptionsPanel.tsx | 50 ++-- .../Filters/ZeroFillingOptionsPanel.tsx | 68 +++-- .../panels/filtersPanel/Filters/index.tsx | 10 +- .../reducer/actions/FiltersActions.ts | 283 ++++-------------- test-e2e/NmriumPage/index.ts | 4 +- test-e2e/panels/filters.test.ts | 8 +- 26 files changed, 523 insertions(+), 481 deletions(-) rename src/component/elements/{Header.tsx => HeaderContainer.tsx} (93%) create mode 100644 src/component/elements/ReadOnly.tsx rename src/component/header/{HeaderContainer.tsx => HeaderWrapper.tsx} (83%) diff --git a/src/component/elements/Header.tsx b/src/component/elements/HeaderContainer.tsx similarity index 93% rename from src/component/elements/Header.tsx rename to src/component/elements/HeaderContainer.tsx index 5a81b186f..7646a4e2c 100644 --- a/src/component/elements/Header.tsx +++ b/src/component/elements/HeaderContainer.tsx @@ -20,7 +20,7 @@ const styles: Record<'header', CSSProperties> = { }, }; -export function Header(props: HeaderProps) { +export function HeaderContainer(props: HeaderProps) { const { children, style: { leftStyle = {}, rightStyle = {}, containerStyle = {} } = {}, diff --git a/src/component/elements/ReadOnly.tsx b/src/component/elements/ReadOnly.tsx new file mode 100644 index 000000000..9cc56631d --- /dev/null +++ b/src/component/elements/ReadOnly.tsx @@ -0,0 +1,78 @@ +/** @jsxImportSource @emotion/react */ +import { keyframes } from '@emotion/react'; +import styled from '@emotion/styled'; +import { ReactNode, useState } from 'react'; +import { IoLockClosedOutline } from 'react-icons/io5'; + +const fadeIn = keyframes` + from { + opacity: 0; + transform: translateY(-10px); + } + to { + opacity: 1; + transform: translateY(0); + } +`; + +const Overlay = styled.div` + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; + cursor: not-allowed; +`; + +const MessageContainer = styled.div<{ show: boolean }>` + background-color: white; + padding: 16px; + border-radius: 5px; + align-items: center; + box-shadow: 0 2px 10px rgb(0 0 0 / 10%); + display: ${({ show }) => (show ? 'flex' : 'none')}; + animation: ${fadeIn} 0.3s ease; + gap: 8px; +`; + +interface ReadOnlyProps { + enabled: boolean; + children: ReactNode; + message?: string; + messageDisplayDuration?: number; +} + +export function ReadOnly(props: ReadOnlyProps) { + const { + enabled, + children, + message = 'Read only', + messageDisplayDuration = 800, + } = props; + const [showMessage, setShowMessage] = useState(false); + + function handleOverlayClick() { + setShowMessage(true); + setTimeout(() => setShowMessage(false), messageDisplayDuration); + } + + return ( +
+ {children} + {enabled && ( + + + + {message} + + + )} +
+ ); +} diff --git a/src/component/header/AutoPeakPickingOptionPanel.tsx b/src/component/header/AutoPeakPickingOptionPanel.tsx index 93494beee..9b3e787a5 100644 --- a/src/component/header/AutoPeakPickingOptionPanel.tsx +++ b/src/component/header/AutoPeakPickingOptionPanel.tsx @@ -14,7 +14,7 @@ import { } from '../hooks/useCheckPointsNumberInWindowArea'; import { headerLabelStyle } from './Header'; -import { HeaderContainer } from './HeaderContainer'; +import { HeaderWrapper } from './HeaderWrapper'; type Direction = 'positive' | 'negative' | 'both'; @@ -85,7 +85,7 @@ export function AutoPeakPickingOptionPanel() { } return ( - + @@ -134,6 +134,6 @@ export function AutoPeakPickingOptionPanel() { > Apply - + ); } diff --git a/src/component/header/Header.tsx b/src/component/header/Header.tsx index d9bc0b61b..a921fd269 100644 --- a/src/component/header/Header.tsx +++ b/src/component/header/Header.tsx @@ -16,7 +16,7 @@ import { useWorkspacesList, } from '../context/PreferencesContext'; import Button from '../elements/Button'; -import { Header } from '../elements/Header'; +import { HeaderContainer } from '../elements/HeaderContainer'; import { LabelStyle } from '../elements/Label'; import DropDownButton, { DropDownListItem, @@ -30,7 +30,7 @@ import WorkspaceItem from '../modal/setting/WorkspaceItem'; import { options } from '../toolbar/ToolTypes'; import { AutoPeakPickingOptionPanel } from './AutoPeakPickingOptionPanel'; -import { HeaderContainer } from './HeaderContainer'; +import { HeaderWrapper } from './HeaderWrapper'; import RangesPickingOptionPanel from './RangesPickingOptionPanel'; import { SimpleApodizationOptionsPanel } from './SimpleApodizationOptionsPanel'; import { SimpleBaseLineCorrectionOptionsPanel } from './SimpleBaseLineCorrectionOptionsPanel'; @@ -134,10 +134,10 @@ function HeaderInner(props: HeaderInnerProps) { return (
-
- {selectedPanel}
- - + - - + + ); } @@ -241,7 +241,7 @@ function SaveButton() { const MemoizedHeader = memo(HeaderInner); -export default function HeaderWrapper() { +export function Header() { const { toolOptions: { selectedOptionPanel }, height, diff --git a/src/component/header/HeaderContainer.tsx b/src/component/header/HeaderWrapper.tsx similarity index 83% rename from src/component/header/HeaderContainer.tsx rename to src/component/header/HeaderWrapper.tsx index 06c4dcf89..7634f088b 100644 --- a/src/component/header/HeaderContainer.tsx +++ b/src/component/header/HeaderWrapper.tsx @@ -9,7 +9,7 @@ interface HeaderContainerProps { children: ReactNode; } -export function HeaderContainer(props: HeaderContainerProps) { +export function HeaderWrapper(props: HeaderContainerProps) { const { style = {}, children } = props; return
{children}
; } diff --git a/src/component/header/RangesPickingOptionPanel.tsx b/src/component/header/RangesPickingOptionPanel.tsx index bce82ce1f..e256fc833 100644 --- a/src/component/header/RangesPickingOptionPanel.tsx +++ b/src/component/header/RangesPickingOptionPanel.tsx @@ -13,7 +13,7 @@ import { } from '../hooks/useCheckPointsNumberInWindowArea'; import { headerLabelStyle } from './Header'; -import { HeaderContainer } from './HeaderContainer'; +import { HeaderWrapper } from './HeaderWrapper'; interface AutoRangesOptions { minMaxRatio: number; @@ -60,7 +60,7 @@ function RangesPickingOptionPanel() { } return ( - + + ); } diff --git a/src/component/header/SimpleApodizationOptionsPanel.tsx b/src/component/header/SimpleApodizationOptionsPanel.tsx index bd15df30f..e986f7d36 100644 --- a/src/component/header/SimpleApodizationOptionsPanel.tsx +++ b/src/component/header/SimpleApodizationOptionsPanel.tsx @@ -9,7 +9,7 @@ import { useFilter } from '../hooks/useFilter'; import { useSharedApodization } from '../panels/filtersPanel/Filters/hooks/useSharedApodization'; import { headerLabelStyle } from './Header'; -import { HeaderContainer } from './HeaderContainer'; +import { HeaderWrapper } from './HeaderWrapper'; interface ApodizationOptionsInnerPanelProps { filter: Filter | null; @@ -32,7 +32,7 @@ function ApodizationOptionsInnerPanel( register('livePreview'); return ( - + + ); } diff --git a/src/component/header/SimpleBaseLineCorrectionOptionsPanel.tsx b/src/component/header/SimpleBaseLineCorrectionOptionsPanel.tsx index 6da19b142..99d58420c 100644 --- a/src/component/header/SimpleBaseLineCorrectionOptionsPanel.tsx +++ b/src/component/header/SimpleBaseLineCorrectionOptionsPanel.tsx @@ -15,7 +15,7 @@ import { } from '../panels/filtersPanel/Filters/hooks/useBaselineCorrection'; import { headerLabelStyle } from './Header'; -import { HeaderContainer } from './HeaderContainer'; +import { HeaderWrapper } from './HeaderWrapper'; interface BaseLineCorrectionInnerPanelProps { filter: Filter | null; @@ -39,7 +39,7 @@ function BaseLineCorrectionInnerPanel( register(`livePreview`); return ( - +