Extjs has a pretty cool Web Desktop. Though out of the box the Ext.ux.desktop.Desktop component is not stateful.  Meaning it won't remember what windows you last had open, their sizes, or their positions.  Fortunately it's relatively simple to get this working.  The following steps will work if you have an Extjs Web Desktop similar to the example linked above.  You'll also need a standard Extjs State Manager/Provider configured within your project.

Step 1: Make your Windows stateful

The Ext.ux.desktop.Desktop component uses Ext.window.Window components to display data.  Ext.window.Window components inherit the Ext.state.Stateful mixin allowing the Extjs State Manager to remember their size, location, and z-index relative to other Windows.  All you'll need to do with your Windows is add the "stateful: true" flag and assign them a stateId.

Step 2: Track which Windows are open

Making the Desktop stateful isn't as easy as simply setting the stateful and stateId properties, but it's not much harder.  As the Windows are already stateful and can track themselves, you only need to track which Windows were last open on the Desktop to determine it's last/complete state.

First you'll need to assign a stateId to the Desktop.  This will be used to get/set the Desktop's state through the Extjs State Manager.  Next you can override the Desktop's onWindowClose and createWindow methods to determine which Windows have opened and closed.  All this is doing is saving an array of strings (the Window's stateIds) to your Extjs State Manager/Provider.  When you open a new Window, add it's stateId to the Desktop's state array.  When you close a Window, remove it's stateId from the Desktop's state array.


Ext.define('MyProject.ux.desktop.Desktop', {
  extend: 'Ext.ux.desktop.Desktop',
  alias: 'widget.myproject-desktop',
  stateId: 'myproject-desktop',

  // ... other Desktop code here not relevant to this example would be here ...

  onWindowClose: function(win) {
    var state = Ext.state.Manager.get(this.stateId);
    var newState = { openWindows: Ext.Array.remove(state.openWindows, win.id) };
    Ext.state.Manager.set(this.stateId, newState);

    this.callParent(arguments);
  },

  createWindow: function(config) {
    var state = Ext.state.Manager.get(this.stateId) || {};
    var openWindows = state.openWindows || [];
    if (openWindows && !Ext.Array.contais(openWindows, config.id)) {
        var newState = { openWindows: Ext.Array.push(openWindows, win.id) };
        Ext.state.Manager.set(this.stateId, newState); 
    }

    return this.callParent(arguments);
  }
});

Step 3: Upon reload/refresh, create last open Windows (Profit!)

The last step is opening your previously opened Windows after a reload/refresh.  I handled this within the App, which houses the Desktop component.


Ext.define('MyProject.ui.App', {

  init: function() {
    // ... code not relevant to this example would be here ...
    
    this.desktop = new MyProject.ux.desktop.Desktop(desktopCfg);
    this._loadInitialModules();
  },

  _loadInitialModules: function() {
    var desktopState = Ext.state.Manager.get(this.desktop.stateId);

    var openWindows = desktopState.openWindows || [];
    Ext.Array.each(openWindows, function(windowId) {
      this.createWindow(this.getModule(windowId));
    }, this);
  }
});

That's it!  Users will love coming back to the Desktop in the state they last left it.

Comment