Uibuilder and vue-bottom-navigation

Hi everyone,

After my first experience with the dashboard I'm ready to move forward to the next level. So my eye dropped on the uibuilder. To be honest I already looked at it long time ago, but since I wasn't familiar at that time with node-red and dashboard itself I was quickly overwelmed by it's complexity (at least that how it looked to me at that time :slight_smile: )

The goal is to have a home dashboard in the end.

So last week I dove into it. To start simple I just created my index page which shows data from a weatherstation I made based on ESP8266 and a BME280 sensor. The ESP8266 sends data to my MQTT.

What I got working so far with uibuilder:

  • Can read messages from my mqtt server and have them displayed.
  • Based upon payload from one of the messages: make an icon switch between battery charging or not (as the weatherstation is powered by a solar panel)
  • Have the Toast example working with (at the moment) a simple inject node in my flow.

The reason for posting here is that I can not get to work the navigation I would like to implement which you can find here: https://github.com/imanmalekian31/vue-bottom-navigation

I tried following this guide: https://github.com/TotallyInformation/node-red-contrib-uibuilder/wiki/Load-Vue-components-without-a-build-step-(modern-browsers-only) but to no avail.

I have installed the front-end library from node-red interface.
In my home folder I have .node-red/node_modules/bottom-navigation-vue/....
I added:

<VueBottomNavigation :options="options" v-model="selected" />

in my index.html. Also in the following form

<VueBottomNavigation :options="options" v-model="selected"></VueBottomNavigation>

as the console complains about the "trailing solidus"

Then added in my index.js:

var vueTST = new Vue({
    el: '#vueTST',
    
    components: { VueBottomNavigation },

    data: {
        batStatus: 0,
        selected: 1,
          options: [
            {
              id: 1,
              icon: "fas fa-home",
              title: "Home",
              childs: [
                { id: 101, icon: "fas fa-tshirt", title: "Products" },
                { id: 102, icon: "fas fa-tag", title: "Discount" },
                { id: 103, icon: "fas fa-gifts", title: "Gifts", badge: 7 },
              ],
            },
            { id: 2, icon: "fas fa-wallet", title: "Wallet" },
            {
              id: 3,
              icon: "fas fa-plus",
              title: "Setting",
              childs: [
                { id: 301, icon: "fas fa-bookmark", title: "Bookmarks" },
                { id: 302, icon: "fas fa-tasks", title: "Tasks" },
                { id: 303, icon: "fas fa-tachometer-alt", title: "Dashboard" },
                { id: 304, icon: "fas fa-ticket-alt", title: "Tickets" },
              ],
            },
            { id: 4, icon: "fas fa-bell", title: "Notification", badge: 15 },
            { id: 5, icon: "fas fa-user", title: "Account" },
          ],
        },

Then the console complains about:
**Uncaught ReferenceError: VueBottomNavigation is not defined**

So I add:

import VueBottomNavigation from "bottom-navigation-vue";

above the var vueTST from the previous snippet, but then I get:

Uncaught TypeError: Failed to resolve module specifier "bottom-navigation-vue". Relative references must start with either "/", "./", or "../".

I tried almost every path in front of "bottom-navigation-vue" (aka uibuilder/vendor/.. and such) but no success either (404 not found)

So then I followed the Wiki I referenced earlier with a separate .js but I got same error in the end. So I'm running in circles here. I'm quiet sure the problem has something to do with accessing the module but I can't get my head around the way it's supposed to work.

Can someone shed a light on what I'm missing?

Sorry for the long post but I wanted to be as complete as possible.

regards,
pom

EDIT:
I would like to add the path ../uibuilder/vendor/bottom-navigation-vue resolves (so no 404) but I have no clue to what I need to point the code (I tried every .js and .vue file but no luck). These are the contents:

$ tree
โ”œโ”€โ”€ babel.config.js
โ”œโ”€โ”€ LICENSE
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ public
โ”‚   โ”œโ”€โ”€ favicon.ico
โ”‚   โ””โ”€โ”€ index.html
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ src
โ”‚   โ”œโ”€โ”€ App.vue
โ”‚   โ”œโ”€โ”€ assets
โ”‚   โ”‚   โ”œโ”€โ”€ github-logo.png
โ”‚   โ”‚   โ””โ”€โ”€ logo.png
โ”‚   โ”œโ”€โ”€ components
โ”‚   โ”‚   โ””โ”€โ”€ BottomNavigation.vue
โ”‚   โ”œโ”€โ”€ install.js
โ”‚   โ””โ”€โ”€ main.js
โ””โ”€โ”€ vue.config.js

Hi there. At first sight, it looks like a poorly cooked Vue component. But I need to have a closer look.


So the default entry point of ../uibuilder/vendor/bottom-navigation-vue/src/install.js (which you can see in the packages package.json file or from uibuilders details page) still requires an import statement which only works with a build step. Still investigating.

Hi @TotallyInformation,

Thx for your reply.

Let me first give you a big thumbs up on the work you have put in the uibuilder and the followup you are doing in every post related to that uibuilder in the forum (and now again). That shows some dedication. Appreciate that very much.

If I understand your reply correctly the line in my index.js "should" be:

import VueBottomNavigation from "../uibuilder/vendor/bottom-navigation-vue/src/install.js";

as pointed out by the "vendor client libraries" from the uibuilder index, correct?

Or, and this is maybe the missing link, do I need to have this in my index.html in some form?

<script type="module" src="../uibuilder/vendor/bottom-navigation-vue/src/install.js"></script>

(I just tried the above but it doesn't work, but maybe the form isn't entirely correct)

regards,
pom

Not tried using module style yet. Tried to get it working using http-vue-loader but it definitely doesn't work with that.

Also, the style of coding used is pretty appalling to be honest. A really bad example of a Vue component.

Will try using modules. No I won't because I can immediately see that it won't work at all. There is no compiled version of the vue component and therefore you cannot load it as a module.

I'm afraid the only way to use this component is to run it through a build step to get the javascript and use that. Sorry. A badly/lazily written component.

Thx again for your time and effort.

Since you where talking about "poorly" cooked earlier, I'm now looking into this tutorial:

maybe that will help me continueing.

But since you're talking about a rather "appaling" coding style etc... I'm not sure I want to use this module in the end...

You, by any chance, don't have an example of or experience with a bottom navigation that looks (kind off) similar (similarity is not a must, but that works conveniently at least) I have found multiple navigation bars, but hard to choose. For this one I have only looked at the position (bottom) and style. As I have no clue on how to judge the code quality.

Not really produced anything like that I'm afraid so no direct experience.

However, you could grab the actual part of his code that does the real work and use that directly as a .vue file in your build since you are going to likely do a build anyway:

vue-bottom-navigation/BottomNavigation.vue at master ยท imanmalekian31/vue-bottom-navigation (github.com)

ermmmm... now you got me.

what do you mean by "you are likely going to do a build anyway"

Do you mean that (even if his code should have worked from the first time) I should do a build? from what then? from my entire finished project?

regards,
Pom

EDIT: Is that what is explained here:

EDIT2 talking about that tutorial:
For the sake of knowledge and learning I stripped out everything from the bottom navigation and followed the tutorial to build the app. However when I add

if (typeof require != "undefined") {
 var uibuilder = require('node-red-contrib-uibuilder/nodes/src/uibuilderfe.js')
 require("./index.css")
}

on top of my index.js the webpage breaks. Console talks about undefined 'start' and 'onChange', properties of uibuilder (which seems undeclared at that point)
2 things I have noticed:
my uibuilderfe.js is not located in the path mentioned in the tutorial but rather:
node-red-contrib-uibuilder/front-end/src/uibuilderfe.js
However that doesn't fix the issue either.
It seems the "if" is never executed.
When I put the
var uibuilder = require('node-red-contrib-uibuilder/front-end/src/uibuilderfe.js')
outside the "if" console complains about:
Uncaught ReferenceError: require is not defined
What I probably should get also when the "if" is 'true'...

So I must be doing something wrong or ... ?

You referenced the tutorial on building external modules so I thought you were going down that route.

Yes, that should link up with the tutorial you referenced.

Oh dear, I've just realised how out-of-date that WIKI entry of mine is! It really is hard to keep everything current when you are on your own with thousands of lines of code and hundreds of pages of documentation! :exploding_head:

Not your fault at all, using Webpack isn't easy if you've not done it before. Best to find a stand-alone tutorial to use first and then adapt it to uibuilder. Just remember that each uibuilder node gets a folder named after the URL you set in the node. In that folder are two sub-folders src and dist. When using a build stage, you need to tell the build tool that the source code is in src and that you want the final (distribution) code in dist. Other than that, most everything else will be as written in tutorials.

What you may find easier though is to try using Snowpack. It is very much easier to use than Webpack. If you do use Snowpack, don't try to use the development server until you are more familiar with how things work. Just do a build on each change of your source code and reload the uibuilder web page.

This is from the vNext tech docs:


Status: Incomplete

Snowpack's development server does not dynamically update the build directory and so does not directly integrate with uibuilder. You can still use Snowpack to package code for uibulder however.

See the general Front-end Builds page for background information on what a build step is and what tools you might want.

This page covers the installation and configuration of the Snowpack build tool to use with uibuilder.

Important note: This how-to may use the command-line. When it does, it is assuming that the starting folder is the root of your uibuilder project on your Node-RED server. For example, if you have a uibuilder node with a URL set to myapp, your start folder is likely to be something like ~/.node-red/uibuilder/myapp.

Make sure you have a package.json file (run npm init -y if not), then:

  1. Install Snowpack

  2. Install the Vue or other plugin's as needed - npm install --save-dev @snowpack/plugin-vue

  3. Run npx snowpack init

  4. Configure your snowpack configuration file as shown below.

  5. Run npx snowpack dev to use the development server (don't forget to change the .html links and the uibuilder.start namespace). Or, run npx snowpack build to update the dist folder ready for use.

Note that you have to use npx to run snowpack when it is installed locally as recommended. Alternatively, you can set up an npm script in your package.json file, in that case, you don't need to use npx since npm will know where the snowpack executable exists.

Don't forget to change the uibuilder node's advanced settings to use the dist folder once you have built your code.

Default Snowpack config file

snowpack.config.js

// Snowpack Configuration File
// See all supported options: https://www.snowpack.dev/reference/configuration
/** @type {import("snowpack").SnowpackUserConfig } */

module.exports = {
    mount: {
        // Use the ./src folder for source files
        'src': '/'
    },

    plugins: [
        '@snowpack/plugin-vue', // Only if using VueJS
    ],

    packageOptions: {
        /* ... */
    },

    devOptions: {
        /* ... */
    },

    buildOptions: {
        // Use the ./dist folder for build files
        'out': 'dist',
    },

}

Once more appreciate the time you invest in this project.

I got a feeling the build route is leading me more and more away from my initial goal. The home dashboard. I know and understand too little at the moment on how vue and bootstrap work to entirely understand what I should be doing and what I should get in the end.
I donโ€™t want too waste to much of your time either :slight_smile:

Today I managed to include another (top) bootstrap-vue navigation without any hassle. However I still struggle to make use of other components (which you find left and right on the internet) besides the default. But Iโ€™m opening another thread for that to keep things separated.

Regards,
Pom

Like you i was (and still am) straggling to understand this process of building applications
and using most of the code examples that require a build step.

I found Webpack a bit complicated and didnt have a chance to test Snowpack yet but
i tested the vue-bottom-navigation using Parcel bundler.

Their example was indeed a bit messy and didnt include a lot of info of how to use it.

I uploaded an example with some basic instructions on Github uib-template-bottom-navigation if you want to have a go.

1 Like

WoW :open_mouth:

Thanks a billion. Iโ€™ll have a go at it. Do I understand correctly that when I change anything, even unrelated to the bottom navigation, I need to do a npm build ?
And does nodered needs to be restarted then afterwards?

yes you need to build everytime you make a change to the code of that page .. npm run build
but in package.json there is a second script command that you can run with npm run dev
that keeps watching for any file changes and rebuilds a bit faster.

no need for Node-red restart .. possibly a refresh of the browser page

I'm hoping to automate this in a future release.

Having to do a rebuild is the least of my problems I'm having today with this :slight_smile:
If it works in the end, fine for me.

I was just asking confirmation to make sure I'm not missing anything.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.