Please Note This forum exists for community support for the Mango product family and the Radix IoT Platform. Although Radix IoT employees participate in this forum from time to time, there is no guarantee of a response to anything posted here, nor can Radix IoT, LLC guarantee the accuracy of any information expressed or conveyed. Specific project questions from customers with active support contracts are asked to send requests to support@radixiot.com.

Radix IoT Website Mango 3 Documentation Website Mango 4 Documentation Website

Native desktop app with NodeJS / Electron without having to think about how to solve browser issues


  • Dear Mango community,

    I don't know if it is the right forum section for this but it seemed like so.

    Sometimes while doing your Mango projects you might come into a situation where your clients cannot use Chrome or a modern browser due to the limitations of their own internal policy, be it some restrictions on computer usage or whatever.

    For that sometimes it is required to create your own cross-platform application which your client can use to get to their Mango instance. This actually creates your own application and you can distribute the application to your users while commissioning.

    NodeJS and Electron is quite good solution to solve this. Even better solution without having to learn all the steps in NodeJS and Electron is Nativefier.

    https://nodejs.org/en/download/
    https://github.com/jiahaog/nativefier

    Tutorial is on the github page above.

    This lets you create an cross-platform application for any website by just running one command on the NodeJS command line to create your own application easily.

    I am not the developer for this but just searching around the internet I stumbled upon a easy solution without having to learn really anything and thought it would be useful for the community.

    The post is made just to share to the community as there are many users who are not so good in modern web development but might come into these troubles while trying to sell your solution to your customer.


  • @thomaseinasto said in Native desktop app with NodeJS / Electron without having to think about how to solve browser issues:

    https://github.com/jiahaog/nativefier

    This is awesome, ill give it a try. Not sure if you saw on the latest UI release that service workers are part of the package. So you can install a chrome app of the mango instance.


  • @CraigWeb

    Oh awsome. But if I am not mistaken chrome app requires the user to install chrome on the PC. Electron solves this by wrapping the Chrome engine to its application without user realizing that they are actually using chrome browser.

    We have had some clients who have company policy not to use google chrome or any browser in the manufacturing computers which created trouble for us to talk them into creating an exception for us.


  • Yes correct it does require chrome to be installed but it's still quite cool and handy for the clients who demand an app. Ive had my fair share from corporate ITC policies its a nightmare.


  • Yep as @CraigWeb said we have been expending a bit of effort recently turning Mango into a PWA (Progressive Web App). We have implemented a service worker which pre-caches all the assets for fast startup time. The next UI module release will let you customize the application name and colors via the UI settings page.

    Next things on our plate for the PWA are:

    • A startup progress screen in the new UI
    • Better offline behavior (currently it just displays a pretty awful looking error message)
    • Push notifications for events (This might be a few releases away, its not as easy as it sounds)

    I gave nativefier a go and it seems to work pretty flawlessly with Mango. Thanks for the heads up, its nice thing to know about. I'll have to do a bit more reading about it but since it is a wrapper around the web app I would assume you can just create the app once and the web app will update itself via the service worker. Very nice.

    We probably wont distribute any native apps like this but it is a very useful tool for people in your scenario.


  • Here's a screenshot showing the command to build the app, the output, and the running app for those interested -
    0_1568387775335_f035eea9-6f3d-47bf-8970-be5cd7d65907-image.png


  • @Jared-Wiltshire

    Is it possible to add custom buttons to <md-toolbar> of the UI simply without doing changes in overrides? I would like to add a userModule component which brings window actions to the toolbar ( minimise, maximise, close)

    Adding custom css so that the toolbar would be draggable can be done in UI settings via custom css and it works perfectly with electron.

    Idea is something like this, so that user would not see the header of the application but everything is styled in css:

    0_1571058857934_8adb39a9-e78c-4cf6-b48c-5bb7523713ed-image.png

    Thanks
    Thomas


  • You can in fact add a button to the toolbar, this is a user module that I use while developing that adds a button to clear the translations cache in the backend.

    define(['angular', 'require'], function(angular, require) {
        'use strict';
    
        const userModule = angular.module('userModule', ['maUiApp']);
    
        run.$inject = ['$rootScope', 'maTranslate', '$templateCache'];
        function run($rootScope, Translate, $templateCache) {
            const userActionsUrl = 'userActions.html';
            $templateCache.put(userActionsUrl,
                `<md-button class="md-icon-button" ng-click="clearTranslations()">
                    <md-icon>restore_page</md-icon>
                </md-button>`);
            $rootScope.userActions = userActionsUrl;
            $rootScope.clearTranslations = () => {
                Translate.clearCache().then(() => {
                    window.location.reload();
                });
            };
        }
        
        userModule.run(run);
        
        return userModule;
    }); // define
    

  • Thanks @Jared-Wiltshire

    App works perfectly with buttons so that Mango is looking like a real app with buttons. Is it possible to inject them behind help button so that it would look better?

    0_1571163280269_1c745c87-661d-4435-a9ae-4d1b6f7a0dd2-image.png

    Anyone who is interested:

    Solved this by first creating preloader.js file in the folder where app will be created with following code. There are several options I guess but this was just one of the easiest to accomplish:

    function sd() {
    	const remote = require('electron').remote;
    	var currentwindow = remote.getCurrentWindow();
    	var logFn = console.log;
    
    console.log = function(arg1) {
    
       if (arg1 == 'close-electron'){
    	   
            let windows = remote.getCurrentWindow();
            windows.close();	
    		
       }else if (arg1 == 'maximize-electron'){
    	   
    	   if(currentwindow.isMaximized()){
    			let windows = remote.getCurrentWindow();
    			windows.unmaximize();
    	   }else{
    			let windows = remote.getCurrentWindow();
    			windows.maximize();
    	   }
    	   
       }else if (arg1 == 'minimize-electron'){
    	   
    	   let windows = remote.getCurrentWindow();
           windows.minimize();
    		
       }else{
    	   
    	   logFn(arg1)
    	   
       }
       
    }
    
    }
    
    sd();
    
    
    
    

    Following code actually rewrites console.log function to a custom function in a global scope within the application.

    Then add usermodule by modifying @Jared-Wiltshire usermodule like this:

    define(['angular', 'require'], function(angular, require) {
        'use strict';
    var electron = false;
    const userModule = angular.module('userModule', ['maUiApp','ngLocale']);
    
                    var userAgent = navigator.userAgent.toLowerCase();
                    console.log(userAgent)
                    if (userAgent == 'electron') {
                        electron = true
                    }else{
                        electron = false;
                    }
    if (electron){
        
        run.$inject = ['$rootScope', 'maTranslate', '$templateCache'];
        function run($rootScope, Translate, $templateCache) {
            const userActionsUrl = 'userActions.html';
            $templateCache.put(userActionsUrl,
                `
                <md-button class="md-icon-button" ng-click="minimize()">
                    <md-icon>more_horiz</md-icon>
                </md-button>
                <md-button class="md-icon-button" ng-click="maximize()">
                    <md-icon>fullscreen</md-icon>
                </md-button>
                <md-button class="md-icon-button" ng-click="close()">
                    <md-icon>close</md-icon>
                </md-button>`);
                
            $rootScope.userActions = userActionsUrl;
            $rootScope.close = () => {
                console.log('close-electron');
            };
            $rootScope.maximize = () => {
                console.log('maximize-electron');
            };
            $rootScope.minimize = () => {
                console.log('minimize-electron');
            };
        }
        
        userModule.run(run);     
        
    }      
            return userModule;
        
        }); // define
    

    This module actually console.logs commands which are analyzed in a function located in preloader.js file and only activates when userAgent is called 'electron' which we will define in a final function below.

    Add also your custom css in mango UI settings to make header draggable.

    .ma-ui-main-toolbar{
        
        -webkit-app-region: drag;
        
    }
    button {
        
        -webkit-app-region: no-drag;
        
    }
    md-input-container{
        -webkit-app-region: no-drag;
    }
    
    .ma-ui-tools > div[ng-include=userActions] {
      order: 1;
    }
    

    Finally, ensure that you are using nativefier version 7.6.10 so that injection actually would work correctly. Check your version with nativefier -v, should output as

    7.6.10
    

    If not then following command will allow you to install correct version from npm.

    npm install -g nativefier@7.6.10
    

    Now create app with following command:

    nativefier -u electron -e 2.0.8 http://url-to-mangoinstance --browserwindow-options "{ \"webPreferences\": { \"nodeIntegration\":true } }" --inject preloader.js --hide-window-frame
    

    -u specifies your useragent which is electron,
    -e specifies electron version (use 2.0.8 so that --inject would be successful.
    your link to the mango instance
    --browserwindows-options JSON string for specifing electron browser options. see https://electronjs.org/docs/api/browser-window#new-browserwindowoptions
    (we are using nodeIntegration to enable electron in front-end)
    --inject The file to inject to the page after DOM has loaded.
    --hide-window-frame Hide windows framing because we will be using mango header which css we have enabled in UI settings.

    You have now created the application for your Mango instance.


  • @thomaseinasto said in Native desktop app with NodeJS / Electron without having to think about how to solve browser issues:

    Is it possible to inject them behind help button so that it would look better?

    It's not possible to change the position in the markup no. But you can change the order in which they are displayed using CSS.

    .ma-ui-tools > div[ng-include=userActions] {
      order: 1;
    }
    

  • Thanks @Jared-Wiltshire for helping out.

    This solved it, I edited the previous post for css also, so that users would be able to copy-paste without missing out the ordering.

    Final result :

    0_1571203579903_442354f8-87b5-455c-9e3f-8cb1682201f2-image.png

    Thomas