Prechádzať zdrojové kódy

fix: Panel KeepDOM with trim (#1046)

July 3 dní pred
rodič
commit
66ba86db4e

+ 12 - 11
packages/plugins/panel-manager-plugin/src/components/panel-layer/panel.tsx

@@ -13,16 +13,18 @@ import { usePanelManager } from '../../hooks/use-panel-manager';
 import { usePanelStore } from '../../hooks/use-panel';
 import { PanelContext } from '../../contexts';
 
-const PanelItem: React.FC<{ panel: PanelEntity }> = ({ panel }) => {
+const PanelItem: React.FC<{ panel: PanelEntity; hidden?: boolean }> = ({ panel, hidden }) => {
   const panelManager = usePanelManager();
   const ref = useRef<HTMLDivElement>(null);
 
   const isHorizontal = ['right', 'docked-right'].includes(panel.area);
 
-  const { size, fullscreen, visible } = usePanelStore((s) => ({ size: s.size, fullscreen: s.fullscreen, visible: s.visible }));
+  const { size, fullscreen } = usePanelStore((s) => ({
+    size: s.size,
+    fullscreen: s.fullscreen,
+  }));
 
   const [layerSize, setLayerSize] = useState(size);
-  const [displayStyle, setDisplayStyle] = useState({});
 
   const currentSize = fullscreen ? layerSize : size;
 
@@ -62,12 +64,6 @@ const PanelItem: React.FC<{ panel: PanelEntity }> = ({ panel }) => {
     return () => observer.disconnect();
   }, [fullscreen]);
 
-  useEffect(() => {
-    if (panel.keepDOM) {
-      setDisplayStyle({ display: visible ? 'block' : 'none' });
-    }
-  }, [visible]);
-
   return (
     <div
       className={clsx(
@@ -76,7 +72,12 @@ const PanelItem: React.FC<{ panel: PanelEntity }> = ({ panel }) => {
       )}
       key={panel.id}
       ref={ref}
-      style={{ ...displayStyle, ...panel.factory.style, ...panel.config.style, ...sizeStyle }}
+      style={{
+        display: hidden ? 'none' : 'block',
+        ...panel.factory.style,
+        ...panel.config.style,
+        ...sizeStyle,
+      }}
     >
       {panel.resizable &&
         panelManager.config.resizeBarRender({
@@ -106,7 +107,7 @@ export const PanelArea: React.FC<{ area: Area }> = ({ area }) => {
     <>
       {panels.map((panel) => (
         <PanelContext.Provider value={panel} key={panel.id}>
-          <PanelItem panel={panel} />
+          <PanelItem panel={panel} hidden={panel.keepDOM && !panel.visible} />
         </PanelContext.Provider>
       ))}
     </>

+ 27 - 22
packages/plugins/panel-manager-plugin/src/services/panel-manager.ts

@@ -41,24 +41,28 @@ export class PanelManager {
     }
 
     const sameKeyPanels = this.getPanels(area).filter((p) => p.key === key);
-    if (!factory.allowDuplicates && sameKeyPanels.length) {
-      !factory.keepDOM && sameKeyPanels.forEach((p) => this.remove(p.id));
-    }
 
     if (factory.keepDOM && sameKeyPanels.length) {
-      sameKeyPanels[0].visible = true;
-      return;
+      const [panel] = sameKeyPanels;
+      // move to last
+      this.panels.delete(panel.id);
+      this.panels.set(panel.id, panel);
+      panel.visible = true;
+    } else {
+      if (!factory.allowDuplicates && sameKeyPanels.length) {
+        sameKeyPanels.forEach((p) => this.remove(p.id));
+      }
+      const panel = this.createPanel({
+        factory,
+        config: {
+          area,
+          ...options,
+        },
+      });
+
+      this.panels.set(panel.id, panel);
     }
 
-    const panel = this.createPanel({
-      factory,
-      config: {
-        area,
-        ...options,
-      },
-    });
-
-    this.panels.set(panel.id, panel);
     this.trim(area);
     this.onPanelsChangeEvent.fire();
   }
@@ -68,18 +72,14 @@ export class PanelManager {
     const panels = this.getPanels();
     const closedPanels = key ? panels.filter((p) => p.key === key) : panels;
     closedPanels.forEach((panel) => {
-      if (panel.keepDOM) {
-        panel.visible = false;
-        return;
-      }
-
-      this.remove(panel.id)
+      this.remove(panel.id);
     });
     this.onPanelsChangeEvent.fire();
   }
 
   private trim(area: Area) {
-    const panels = this.getPanels(area).filter((p) => !p.keepDOM);
+    /** 1. general panel; 2. keepDOM visible panel */
+    const panels = this.getPanels(area).filter((p) => !p.keepDOM || p.visible);
     const areaConfig = this.getAreaConfig(area);
     while (panels.length > areaConfig.max) {
       const removed = panels.shift();
@@ -91,7 +91,12 @@ export class PanelManager {
 
   private remove(id: string) {
     const panel = this.panels.get(id);
-    if (panel) {
+    if (!panel) {
+      return;
+    }
+    if (panel.keepDOM) {
+      panel.visible = false;
+    } else {
       panel.dispose();
       this.panels.delete(id);
     }