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 (
-
-
-
+
-
-
+
+
);
}
@@ -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 (
-
+
+
);
}
diff --git a/src/component/header/SimplePhaseCorrectionOptionsPanel.tsx b/src/component/header/SimplePhaseCorrectionOptionsPanel.tsx
index 6275c443f..36dc50699 100644
--- a/src/component/header/SimplePhaseCorrectionOptionsPanel.tsx
+++ b/src/component/header/SimplePhaseCorrectionOptionsPanel.tsx
@@ -11,7 +11,7 @@ import {
usePhaseCorrection,
} from '../panels/filtersPanel/Filters/hooks/usePhaseCorrection';
-import { HeaderContainer } from './HeaderContainer';
+import { HeaderWrapper } from './HeaderWrapper';
export function SimplePhaseCorrectionOptionsPanel() {
const filter = useFilter(Filters.phaseCorrection.id);
@@ -27,7 +27,7 @@ export function SimplePhaseCorrectionOptionsPanel() {
} = usePhaseCorrection(filter);
return (
-
+