Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Persistent unused panels (always keep alive) #718

Open
p3yman opened this issue Sep 19, 2024 · 7 comments · May be fixed by #778
Open

Persistent unused panels (always keep alive) #718

p3yman opened this issue Sep 19, 2024 · 7 comments · May be fixed by #778

Comments

@p3yman
Copy link

p3yman commented Sep 19, 2024

Is your feature request related to a problem? Please describe.
Hello 👋
I'm working on a project that changes the layout using dockviewApi.fromJSON to load different layouts but from a fixed list of panels. So, in one layout I could have only one panel visible and in another, I have 2 columns of 3 and 2 panels side by side.
These panels show iframes which is important to be kept alive on changing the layout.
The current state of DockView to my understanding is that using fromJSON will cause removing all the extra panels. Is there any way around it?

Describe the solution you'd like
I'm not sure what's the best solution here. I saw #397 but it seems it's not available anymore.

Describe alternatives you've considered
I'm trying to see if using portals and mirroring (somehow) could work here. Or maybe move the extra ones to a floating group and hide that.

@mathuo
Copy link
Owner

mathuo commented Oct 12, 2024

You can render a panel as always visible which will prevent the element being unmounted and instead this element will be absolutly positions and hidden as required (which prevents things like iframe unload issues). Some docs on that are here

That state is persisted when calling toJSON() however fromJSON() will entirely replace the layout, is that the point you are trying to make? That you are interested in keeping state alive when calling fromJSON() if those panels already exist?

@p3yman
Copy link
Author

p3yman commented Oct 14, 2024

Hi @mathuo ,
My exact problem is that I need to re-call the fromJSON but it'll kill everything.
I tried implementing a manual algo to first make everything floating (adding panels, moving them to a floating group, and hide using CSS) and then parse the tree and whenever see a panel use moveTo instead of addPanel and it works. Just not the prettiest thing. Maybe a helper like rearrangeFromJSON that does the same thing in a better way.

@artaommahe
Copy link

artaommahe commented Oct 24, 2024

@mathuo we have the similar issue. We have the set of panels, some of them are terminals (xtermjs) or iframes to some stuff inside a sandbox (like a web application), and we want to add a 'Reset layout' button so when user messed up with it they can return back to the initial state (we don't allow to remove panels btw). With the current implementation of the dockview all panels are destroyed and then re-created (fromJSON call), so the state of iframes is lost.

@p3yman
Copy link
Author

p3yman commented Nov 27, 2024

@mathuo any thoughts on this?

@artaommahe
Copy link

artaommahe commented Nov 27, 2024

just in case, i've ended up with this copy of dockviewApi.fromJSON implementation that just moves panels around without re-creating them. But we're not shipping it cause it relies too much on dockview's internal api and will break frequently on lib's updates

export const setDockviewLayout = (dockviewApi: DockviewApi, layout: SerializedDockview) => {
  const { width, height } = dockviewApi;

  // move all current panels to a float group
  const [firstPanel, ...restPanels] = dockviewApi.panels;
  dockviewApi.addFloatingGroup(firstPanel);
  const floatingGroup = firstPanel.group;
  restPanels.forEach(panel => panel.api.moveTo({ group: floatingGroup }));

  (dockviewApi['component']['gridview'] as Gridview).deserialize(layout.grid, {
    fromJSON: (node: ISerializedLeafNode<GroupPanelViewState>) => {
      const { id, views, activeView } = node.data;

      if (typeof id !== 'string') {
        throw new Error('group id must be of type string');
      }

      const group = dockviewApi['component'].createGroup({ id });

      dockviewApi['component']._onDidAddGroup.fire(group);

      let activePanel: IDockviewPanel | undefined;

      for (const child of views) {
        const panel = dockviewApi.getPanel(child);

        if (!panel) {
          return;
        }

        panel.api.moveTo({ group });

        if (activeView === panel.id) {
          activePanel = panel;
        }
      }

      activePanel?.api.setActive();

      if (!group.activePanel && group.panels.length > 0) {
        const panel = group.panels[group.panels.length - 1];
        panel.api.setActive();
      }

      return group;
    },
  });

  dockviewApi.layout(width, height, true);

  dockviewApi['component']._onDidLayoutFromJSON.fire();
};

@mathuo mathuo linked a pull request Nov 30, 2024 that will close this issue
@mathuo
Copy link
Owner

mathuo commented Nov 30, 2024

Let me try a couple of approaches, I think we can integrate such behaviours into the deserialization methods.

@p3yman
Copy link
Author

p3yman commented Dec 2, 2024

@mathuo really appreciate it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants