Premium support for our pure JavaScript UI components


Post by spjharper »

I'm trying to updrade a large application that used SenchaTouch 2.3 and the old TouchScheduler 1.0.6 to ExtJS 7 modern and the Bryntum Scheduler.
The blog post at: https://www.bryntum.com/blog/integrating-the-bryntum-scheduler-in-an-ext-js-modern-application/ was very useful and I am using the suggested SchedulerPanel to display a Bryntum Scheduler that is wrapped by an Ext.Panel.
I've been able to access the _scheduler from the Ext.Panel reference in controllers and call methods on the Scheduler.

But what I'm having trouble with is how to manipulate the EventStore and ResourceStore from within ExtJS controllers. The blog post only uses hard coded, static json stores.
Our app has a Ext List of Service Area resources that are displayed in a left Navigator (it's a Hospital application for managing the orders at Service Areas like XRay, CT, etc.)
So a Controller detects changes of Service Area makes a server request to get the resources in the area, then makes another to get the day's orders for each of those resources. All of this is ExtJS code that will update the ResourceStore and EventStore.

So I'm assuming the path I have to take is to convert my Ext.data.Model and Ext.data.Store instances to the equivalent Bryntum Scheduler pure js classes and access them in my Ext Controllers.
Has anyone done this level of integration? Is this the right approach?
Is there an example of this type of integration or any further documentation or blog posts that might help?

But there is also the problem that the EventStore is used to integrate with ExtJS code that displays a Dialog that is used to display all the information about the Patient and Order and also provide buttons for Starting/Stopping the order or invoking another dialog to create a Transport request for the Patient. All of this is existing ExtJS code that calls Ajax services to do the updates and I don't think the Scheduler's Event Editor can be used to do all this.

Post by dongryphon »

The best approach to answering your questions, I think, is to examine the Bryntum API docs for the base classes of EventModel and EventStore. They have many of the same features as their Ext JS counterparts, so using them should be very similar. The article you read points to an example app that is updated with new releases, so be sure to check it out for the latest code for things like SchedulerPanel.

Some thoughts on your general questions.

Talking to the Server
The stores configured in the example could be reconfigured to point to the API on your server in much the same way you would with an Ext JS proxy. The JS code in both Bryntum and Ext JS does not interpret the URL, so whether it points to a static JSON resource or a server API is not known on the JS side. They both issue XMLHttpRequest / Ajax and get back whatever comes from the other end.

Model/Store Instances
As with Ext JS components, Bryntum components communicate with instances of their own kind. The Bryntum scheduler requires a Bryntum EventStore which contains EventModel (or derived) records. Since those instances are not useful to Ext JS components, you may need the same data loaded into both types of stores, depending on the needs of your app. Because these are so similar, however, you may be able to copy data from one store to the other if making the extra ajax calls is an issue. If you go that way, be sure not to share data objects between records:
   extRec = new MyExtRecord(Ext.clone(bryntumRec.data));
Event Editor
The example app linked above does show a custom event editor written in Ext JS. While the standard event editor has many more features, if you don't need them or you need to add items to the editor, you can control that experience. The edits must go back to the Bryntum EventModel/Store for the scheduler to update properly. If you are able to configure the EventStore to work with your API, then that should be enough. If not, you may need to also update an Ext JS record/store to save your change.

Post by spjharper »

Thanks for the suggestion to use Ext.clone to copy data from Bryntum to Ext stores, that may prove useful.
But in examining the code more and trying to use Bryntum ResourceStore and EventStore, I've hit a wall.

The app being upgraded adds 3 fields to ResourceModel and over 20 to the EventModel.
From what I can see in the Guide and API docs the only way to add the fields is to declare a class the extends the appropriate model:
class SuperHero extends ResourceModel {
    static get fields() {
        return [
            // New custom fields:
            'powers', 
            'affiliation' 
        ];
    }
}
So I've tried that but then I assume I need to use ES6 import and export to get the new classes into the Ext code.
I've tried doing this and it fails at runtime with:
Uncaught SyntaxError: Cannot use import statement outside a module
I've done a lot of searches on using ES6 with ExtJS and finally found this which seems to indicate that it won't be doable until ExtJS 8:
https://stackoverflow.com/questions/59663966/ext-js-is-it-possible-with-open-tooling-and-ext-js-7-to-use-es6-class-syntax

So is there a way to add the fields to the ResourceModel and EventModel?

Also I'm not sure what's being done in scheduler.umd.js (we load it via a script tab from index.html) to make bryntum.scheduler available inside the ExtJS code.
I assume the webpackUniversalModuleDefinition function that gets executed as it's loaded has something to do with it.
Can we use something similar to bridge the ES6 <-> ExtJS differences that are making this upgrade difficult?

But if it's really true that ExtJS can't use ES6 classes until ExtJS 8, then Bryntum Scheduler is not a very robust component to use with ExtJS Modern for now.

Post by dongryphon »

In older Sencha frameworks you needed to declare a model's fields. This is not true in Ext JS 6+ (probably even 5+) and is also not true of Bryntum models. In other words, the data object passed to the constructor can contain whatever additional fields you want without you needing to declare your own model class and specify them in advance.

In the case of Bryntum models, the first instance constructed of a model will also define additional field accessors on the model class based on the properties of the data object.

I've added a reply to that StackOverflow thread to clarify what you can do with Sencha Cmd and without using Cmd. I would recommend not using Sencha Cmd if you want to use modern ES code techniques, like import/export. In this way, you would simply include ext-all.js in your page, and use modern JS build tools (webpack, rollup, or whatever you like) to build the rest of your app.

To offer more specific suggestions, it would help to know how you build your app. Sounds like with Sencha Cmd?

Post by spjharper »

We can't really pass the data on the ResourceStore and EventStore constructors for this App.
The user can choose, different Service Areas and each will have its own set of Resources (Xray, CT, etc. machines) and Events (orders to be performed on those machines.)
So the big question becomes, if we use Ajax operations to get data from the Server do the Stores have the same ability to add fields dynamically?
(BTW, I think the Bryntum documentation should mention somewhere that Stores don't really need Models extended if you want to add fields, don't recall seeing this any where.)

We were building the old SenchTouch/TouchScheduler app using SenchaCmd. We were also planning to use SenchaCmd 7 and ExtJS7 Modern with the upgraded version with Bryntum Scheduler. So have any of your customers actually used ext-all.js as you recommend in the StackOverflow post? Won't that make a bigger download?
The 'strict mode' and statics gotcha you mention seem daunting - we use both.
I'm really not sure that continuing with this upgrade is viable given all these restrictions.
It would be reassuring to know that a real app (and not a simple static data app like the Bryntum examples) has been able to blend ExtJS with the ES6 world of Bryntum Scheduler.

It seems like one approach may be to just use Bryntum Scheduler with Ext React and use full on npm tooling, but then that's pretty much a rewrite. We were hoping (and budgeting) for a fairly simple upgrade. (Although in our experience in upgrading from ExtJS 4 to 6 with other non SenchaTouch apps we've developed, it's never simple and never inexpensive.

Post by dongryphon »

There are many branch points to consider when planning an upgrade across such a large version range.

1. Ext JS 7 brings whole new paradigms to app architecture (view controllers, references and data binding being the larger of these). A straight "port" would obviously forego these opportunities.

2. Sticking w/Sencha Cmd means no import/export to use any ES6 modules. Switching to other build tools usually means using ext-all.js and while that is somewhat larger, being separate from your app code may lead to better cache outcomes (since the framework files won't be updated as often). In fact, many Cmd users request exactly that kind of support in their build. The size difference would be hard to pin down since a large amount of the framework gets included once you bring in grids, trees, etc..

3. Picking one of the Ext JS bridges (like ExtReact) may help connect Sencha, Bryntum and other ES6-based solutions going forward. It also means a completely different approach to writing app logic, so as you noted, surely a rewrite.

I'd not worry about ext-all.js size unless the app was being viewed by many first-time/one-time users. Sticky users would benefit from the cache and you'd have a hard time identifying much gain by eliminating the unused classes.

The browsers you need to support will play into the tooling options. What are your requirements on that side? In particular, do you need IE11 or old MS Edge support?

If you write Ext JS classes in modules, something like this would probably eliminate the need for callParent in most cases:
let superCls;

Ext.define('App.view.Foo', {
    extend : 'App.view.Base',
    // ...
    
    method(...args) {
        // return this.callParent([args]);
        return superCls.method.call(this, ...args);
    }
},
function () {
    superCls = App.view.Base.prototype;
});
The this.statics() call is just a shortcut for the class name of the class that declared the method:
Ext.define('App.view.Foo', {
    extend : 'App.view.Base',
    
    method() {
        // return this.statics().bar;
        return App.view.Foo.bar;
    }
});
Those modules store classes on the global scope, so there is no "export" but they can still be imported and built using webpack (for example).

I'll consult with some of the other folks Monday to see if I can find more in the way of examples.

Post by dongryphon »

I tried a quick webpack app that links Ext JS using its pre-built files. Worked pretty well.

https://github.com/dongryphon/extjs-webpack

Post by spjharper »

The SenchaTouch app we are trying to upgrade is designed to run on a Tablet that is at the ServiceArea.
However our customers being hospitals with IT departments that all seem to prefer MS, require us to support IE11 on all our desktop apps. Not sure if any customers use IE11 to run the SenchaTouch app on IE11 - will have to check. What are the implications if someone is using IE11? We have a React app (not Ext React) built using npm and webpack now, and it does run on IE11 (albeit slowly).

I found that we invoke callParent in 64 times in the code, so we'd have to use the workaround you suggest.
I've taken a quick look at your extjs-webpack example that you created.
But in looking at it I can't help feeling that our App is the first commercial app trying to use Bryntum Scheduler with ExtJS Modern. I've asked this already, but haven't gotten an answer. I feel that we may be experimenting with an "off label" use of Bryntum Scheduler.

I think where we are right now, is that I need to review all of this with my manager and some of our other developers.

Post by dongryphon »

Browser support is a question that impacts your needs from the transpiler. IE11 has nearly no ES6 language support, so the transpiler must do more than if you needed only current Chrome/Firefox/Safari. Not that this changes your code, just informs your webpack settings.

I created the example repo not because other apps aren't out there. I've helped another Ext JS customer myself to use the scheduler. Since we cannot share names or code from customers, it can feel like you say, but that is just a perception.

The example repo shows an alternative way to integrate modern ES6 libraries (like Bryntum Scheduler) with Ext JS. Ext JS only offers two basic approaches: use Sencha Cmd and forego modern ES6 import/export; use the pre-built library and then choose your own tooling. And as you see, using Cmd also has complications with using libraries built on ES6 classes when you need to transpile that syntax out.

Post by dongryphon »

I will put together a demo using Sencha's open tools this evening/tomorrow and let you know when I have that.

Post Reply