From bf30effde1bd8d74f1d9c49e418e59854ac5edeb Mon Sep 17 00:00:00 2001
From: tpoisseau <22891227+tpoisseau@users.noreply.github.com>
Date: Fri, 13 Feb 2026 15:21:17 +0100
Subject: [PATCH] feat: implement panels tab
Closes: https://github.com/cheminfo/nmrium/issues/3947
---
.../general_settings_dialog_body.tsx | 3 +
.../tabs/panels_tab.tsx | 152 ++++++++++++++++++
.../tanstack_general_settings/validation.ts | 94 ++++++++++-
3 files changed, 244 insertions(+), 5 deletions(-)
create mode 100644 src/component/modal/setting/tanstack_general_settings/tabs/panels_tab.tsx
diff --git a/src/component/modal/setting/tanstack_general_settings/general_settings_dialog_body.tsx b/src/component/modal/setting/tanstack_general_settings/general_settings_dialog_body.tsx
index eb33e0db0..d7f71c3ec 100644
--- a/src/component/modal/setting/tanstack_general_settings/general_settings_dialog_body.tsx
+++ b/src/component/modal/setting/tanstack_general_settings/general_settings_dialog_body.tsx
@@ -6,6 +6,7 @@ import { StyledDialogBody } from '../../../elements/StyledDialogBody.tsx';
import { ExportTab } from './tabs/export_tab.tsx';
import { GeneralTab } from './tabs/general_tab.tsx';
+import { PanelsTab } from './tabs/panels_tab.tsx';
import { defaultGeneralSettingsFormValues } from './validation.ts';
const Tabs = styled(BPTabs)`
@@ -43,6 +44,8 @@ export const GeneralSettingsDialogBody = withForm({
panel={}
/>
+ } />
+
} />
diff --git a/src/component/modal/setting/tanstack_general_settings/tabs/panels_tab.tsx b/src/component/modal/setting/tanstack_general_settings/tabs/panels_tab.tsx
new file mode 100644
index 000000000..e81a4d03a
--- /dev/null
+++ b/src/component/modal/setting/tanstack_general_settings/tabs/panels_tab.tsx
@@ -0,0 +1,152 @@
+import { withFieldGroup, withForm } from 'react-science/ui';
+
+import {
+ defaultGeneralSettingsFormValues,
+ displayPanelsStatus,
+} from '../validation.ts';
+
+export const PanelsTab = withForm({
+ defaultValues: defaultGeneralSettingsFormValues,
+ render: ({ form }) => {
+ const { Section, AppField } = form;
+ return (
+ <>
+
+
+ {({ Checkbox }) => }
+
+
+
+
+
+
+
+ >
+ );
+ },
+});
+
+const SpectraSettings = withFieldGroup({
+ defaultValues: defaultGeneralSettingsFormValues.display.panels,
+ render: ({ group }) => {
+ const { Section, AppField } = group;
+
+ return (
+
+
+ {({ Select }) => (
+
+ )}
+
+
+ {({ Select }) => (
+
+ )}
+
+
+ {({ Select }) => (
+
+ )}
+
+
+ {({ Select }) => (
+
+ )}
+
+
+ );
+ },
+});
+
+const Spectra1dSettings = withFieldGroup({
+ defaultValues: defaultGeneralSettingsFormValues.display.panels,
+ render: ({ group }) => {
+ const { Section, AppField } = group;
+
+ return (
+
+
+ {({ Select }) => }
+
+
+ {({ Select }) => (
+
+ )}
+
+
+ {({ Select }) => (
+
+ )}
+
+
+ {({ Select }) => (
+
+ )}
+
+
+ {({ Select }) => (
+
+ )}
+
+
+ );
+ },
+});
+
+const Spectra2dSettings = withFieldGroup({
+ defaultValues: defaultGeneralSettingsFormValues.display.panels,
+ render: ({ group }) => {
+ const { Section, AppField } = group;
+
+ return (
+
+
+ {({ Select }) => }
+
+
+ );
+ },
+});
+
+const ChemicalSettings = withFieldGroup({
+ defaultValues: defaultGeneralSettingsFormValues.display.panels,
+ render: ({ group }) => {
+ const { Section, AppField } = group;
+
+ return (
+
+
+ {({ Select }) => (
+
+ )}
+
+
+ {({ Select }) => (
+
+ )}
+
+
+ {({ Select }) => (
+
+ )}
+
+
+ {({ Select }) => (
+
+ )}
+
+
+ {({ Select }) => (
+
+ )}
+
+
+ );
+ },
+});
diff --git a/src/component/modal/setting/tanstack_general_settings/validation.ts b/src/component/modal/setting/tanstack_general_settings/validation.ts
index 6a9c15c75..876fa2cca 100644
--- a/src/component/modal/setting/tanstack_general_settings/validation.ts
+++ b/src/component/modal/setting/tanstack_general_settings/validation.ts
@@ -48,12 +48,93 @@ const generalValidation = z.object({
loggingLevel: z.enum(loggingLevel).optional(),
});
-const displayValidation = z.object({
- general: z.object({
- experimentalFeatures: z.object({
- display: z.boolean(),
- }),
+const displayGeneralValidation = z.object({
+ experimentalFeatures: z.object({
+ display: z.boolean(),
}),
+ hidePanelsBar: z.boolean().optional(),
+});
+
+export const displayPanelsStatus = [
+ { label: 'Hidden', value: 'hidden' } as const,
+ { label: 'Available', value: 'available' } as const,
+ { label: 'Active', value: 'active' } as const,
+ { label: 'Open', value: 'open' } as const,
+];
+type PanelStatus = (typeof displayPanelsStatus)[number]['value'];
+const panelStatusValidation = z.enum(displayPanelsStatus.map((s) => s.value));
+const panelCodec = z.codec(
+ panelStatusValidation,
+ z
+ .object({
+ display: z.boolean(),
+ visible: z.boolean(),
+ open: z.boolean().optional(),
+ })
+ .optional(),
+ {
+ encode: (status) => {
+ const { display = false, visible = false, open = false } = status ?? {};
+ let value: PanelStatus = 'hidden';
+ const isActive = visible && display;
+
+ if (isActive && open) {
+ value = 'open';
+ } else if (isActive) {
+ value = 'active';
+ } else if (visible) {
+ value = 'available';
+ }
+
+ return value;
+ },
+ decode: (status) => {
+ let visible = false;
+ let display = false;
+ let open = false;
+
+ if (status === 'available') {
+ visible = true;
+ }
+
+ if (status === 'active') {
+ visible = true;
+ display = true;
+ }
+ if (status === 'open') {
+ visible = true;
+ display = true;
+ open = true;
+ }
+
+ return { open, visible, display };
+ },
+ },
+);
+
+const displayPanelsValidation = z
+ .object({
+ spectraPanel: panelCodec,
+ informationPanel: panelCodec,
+ peaksPanel: panelCodec,
+ integralsPanel: panelCodec,
+ rangesPanel: panelCodec,
+ structuresPanel: panelCodec,
+ processingsPanel: panelCodec,
+ zonesPanel: panelCodec,
+ summaryPanel: panelCodec,
+ multipleSpectraAnalysisPanel: panelCodec,
+ databasePanel: panelCodec,
+ predictionPanel: panelCodec,
+ automaticAssignmentPanel: panelCodec,
+ matrixGenerationPanel: panelCodec,
+ simulationPanel: panelCodec,
+ })
+ .optional();
+
+const displayValidation = z.object({
+ general: displayGeneralValidation,
+ panels: displayPanelsValidation,
});
/**
@@ -130,6 +211,9 @@ export const defaultGeneralSettingsFormValues: z.input<
display: false,
},
},
+ panels: displayPanelsValidation.encode(
+ workspaceDefaultProperties.display.panels,
+ ),
},
export: exportPreferencesValidation.encode(workspaceDefaultProperties.export),
};