Thursday, 25 May 2017

Announcing: mapguide-react-layout 0.9

After a small hiatus (due to hacking on MapGuide proper and my day job), here's a new release of mapguide-react-layout.

Here's the highlights of this release.

Now available as an NPM module

This is the first release available on npm. The npm module allows you to customize the viewer in the following ways:
  • Creating your own custom viewer templates
  • Creating your own script commands
  • Customizing your viewer bundle by omitting features you will never use
Want to see how that's done? Check out the new example that demonstrates all of the above.

Short of cloning my github repo and hacking/building the source yourself, the npm module is the best way to fully customize nearly all aspects of the viewer.

Now re-uses the Fusion PHP backend

In previous releases, we bundled a separate copy of the PHP backend tailored to service the following commands:
  • Buffer
  • Query
  • Theme
  • FeatureInfo
  • Redline
  • QuickPlot
  • Search Commands
Once the need to make this a npm module arose, this idea proved to be un-workable.
  • We'd have to ask the user to make some intricate post-build set up in their build configurations to make sure the PHP backend content to a location relative to the viewer bundle so that the above commands will work.
  • Putting PHP code into npm, a JS package registry? Uh ... okay back to the drawing board!
So in the process of revising this idea, the solution turned out to be quite simple:

Just assume MapGuide is installed with Fusion and re-use its PHP backend services

And it turns out that this assumption was a very safe one. Like PHP, Fusion will always be installed with MapGuide on Windows or Linux.

And with this assumption, we just demand one requirement for anyone using this viewer or building a bundle with the npm module: You need to install it into a subdirectory of MapGuide's www directory, which I would assume you are already doing because that's what our current install instructions say!

With this change, my mission statement with this viewer needs a small refinement This is no longer a modern map viewer that is a replacement for Fusion. This is now a modern map viewer that happens to re-use some Fusion backend services.

Which is fine by me because another (useful) side-effect of this exercise is that ...

Partial support for Fusion viewer APIs

... I had to polyfill various client-side Fusion viewer APIs so that the existing front-end content for the above commands can work against the mapguide-react-layout viewer without any modifications required. A subset of Fusion events are also supported in this release.

However, do not expect full 100% replication of the Fusion viewer API here. If you're going to migrate to this viewer, I recommend you go the whole nine yards and take advantage of the simpler and cleaner viewer APIs offered by mapguide-react-layout

Updated and "smarter" Templates

This release includes a new redux state branch for viewer template element visibility.

With this branch we also have new redux actions to push changes to it. Applicable templates now subscribe to the state branch and be able to automatically toggle visibility of template elements in response to dispatched actions.

What this enables us to do is to apply some extra smarts to the Fusion templates. For example, running an InvokeURL command (targeted at the Task Pane) will automatically show/open the Task Pane because the template reducer function also listens on this particular InvokeURL action to push a [Task Pane is now visible] state, as demonstrated in the gif below

Notice how I didn't have to manually expand the Task Pane first? The template reducer function already took care of it because I ran an InvokeURL command to load the Query widget.

The LimeGold and TurquoiseYellow templates have been updated to use the new Tabs2 blueprint component as our existing Tabs component is deprecated and not to mention that Tabs2 actually plays nicer with our new redux state branch.

The sidebar and ajax-viewer templates can now work with Application Definitions under the following conditions:
  • Your appdef has a widget container named Toolbar that will house the primary toolbar
  • Your appdef has a widget container named MapContextMenu that will house the context menu
  • Your appdef has a widget container named TaskMenu that will house the menu in the Task Pane bar
If you create a new Application Definition document in Maestro, all of the above conditions will already be satisfied.

Also if you take a look at the Aqua template, the 3 element togglers on the top-right are gone now.

This is because we were able to find a suitable replacement for InvokeScript commands as described below.

Script Command Support (ie. The InvokeScript replacement)

This feature is the replacement for InvokeScript commands/widgets and currently requires using the npm module. The viewer provides a registry API that allows for custom commands to be registered with the viewer.

How can you link these commands to toolbars and menu items in your WebLayout/ApplicationDefinition? With the existing InvokeScript definition.

The key difference here is that this viewer completely ignores the inline script content part and just invokes the equivalent script command registered in the viewer by the same name as defined in the InvokeScript definition in the WebLayout/ApplicationDefinition.

As a result, the new methodology for using these types of commands is to "bake them in" to your own viewer bundle, while with this approach we still retain the existing authoring experience by re-using InvokeScript definitions. You just have to give it the same name as what they're registered under in the viewer bundle.

To illustrate this, the viewer by default has registered script commands for toggling the:
  • Task Pane
  • Legend
  • Selection Panel
These script commands leverage the new redux actions to push element visibility state to the layout template components, replicating the behaviour of their old InvokeScript counterparts.

Because they are also registered under the same names as their old InvokeScript counterparts, a standard new Application Definition (created by Maestro) will no longer show [X] ERROR placeholders for these commands when fed to any of the 5 ported Fusion templates.

As we how have replicated the old behaviour of the Aqua template, the hard-coded element togglers on the top-right are no longer needed.

Bing Maps Support

The viewer now supports Bing Maps as external base layers.

As mentioned previously, you will now need to acquire an API key to use Bing Maps as the API-key-less version will shut down on June 30, 2017. Fusion proper has the same problem and will also require an API key to use Bing Maps. The next release of MapGuide Maestro will have an updated Fusion editor to configure this.

Fusion Application Definitions passed to this viewer with Bing Maps support are assumed to be ones configured up with a Bing Maps API key and Bing Maps (not VirtualEarth) base layers.

Command Parameterization

This release implements initial support for parameterization of commands. In practical terms this means that the viewer will now start recognizing and support the various Fusion widget extension properties that you may have defined in the widgets of your Application Definition.

Currently, only the (recently ported over) geolocation command is covered, but the next release will begin to see greater support for other Fusion widgets.

API Documentation

With TypeDoc, we now have API documentation for the viewer.

This only currently covers the npm module, which won't really make much sense if you're trying to use the viewer from a "browser globals" context, which would be the case if you're trying to interact with the viewer from Task Pane content.

As a workaround, I've covered the applicable parts of the "browser globals" API in the ...

New Project Home Page

And this API documentation is linked from a brand-spanking new project home page!

Surprisingly, this was much harder to set up than originally thought. Turning on GitHub pages and getting it to link to the TypeDoc-generated API documentation was made difficult due to:
  • TypeDoc-generated documentation being prefixed with underscores
  • HTML files with underscores having a special meaning in Jekyll, the default static site generator for GitHub Pages that prevents us from linking to them.
Jekyll being written in Ruby, made dev/testing my project home pages on Windows a royal pain, so I had to look at other static site generators.

After a few days of evaluating different static site generators, the closest one that matched by basic needs of: 
  • Pumping out some static HTML pages from markdown files
  • Link to TypeDoc-generated HTML files from one of them
  • Have one or more theme that exudes some polish (hey, I build web applications, not web sites and definitely not designing web sites!)
was a PHP tool called couscous. It wasn't ideal. For example, deploy totally did not work for me, but there was fortunately a workaround. Compared to the other available options, this was the best of the lot for what I needed.

Hopefully the project site is informative enough to take you to where you need to go. If not, send me some feedback.

Other Changes
  • Viewer has been updated to use the latest and greatest React, Blueprint, TypeScript and OpenLayers.
  • Viewer uses the new OpenLayers ES2015 modules which means we now only use the parts of OL that we actually use and not inflate our viewer bundle with things we aren't using.
  • Viewer now 100% uses typings provided by npm @types. This means that we no longer need to use the external typings tool to acquire d.ts files, which is relevant to the npm module as you will get automatic TypeScript type definitions for mapguide-react-layout and its dependent libraries out of the box when you install the npm module.
  • Many other updated dependencies thanks to integration.
  • The viewer now supports frame targeting (ie. Target = SpecifiedFrame and you specified a frame name) for InvokeURL and Search commands
  • The viewer now supports running InvokeURL and Search commands in a "New Window". What we will actually do is run the command in a floating modal.

No comments: