Skip to content
This repository has been archived by the owner on Feb 8, 2024. It is now read-only.

Web UI improvements #7

Merged
merged 14 commits into from
Jul 4, 2020
Merged

Conversation

factormystic
Copy link
Contributor

@factormystic factormystic commented Jul 4, 2020

todo

  • disable WiFi input auto capitalization
  • trim WiFi form inputs
  • show project name in page header (instead of ESP8266)
  • add an optional "display name" configuration property
  • separate <input> types for different configuration data types (eg, char -> text, bool -> checkbox, int/float -> numeric)
  • add maxlength attribute for char types, set to configured length
  • figure out how to get a disabled attribute into these config inputs (and ideally, don't persist them if sent)
  • consider if number types should have a min/max/step, and if this can be enforced
  • show min/max next to config labels
  • infer min/max based on data type, unless provided
  • explicit step value of 1, unless provided
  • add a "hidden" option to avoid displaying the input control

discuss

  • ✔ linting configuration (eg, eslint)
    • will be future PR
  • ✔ why use document.querySelector(...).value for form inputs rather than data binding?
    • okay to refactor, but separate PR
  • ✔ thoughts on using actual true/false for boolean config rather than strings
    • agreed it was a good change

@factormystic factormystic marked this pull request as ready for review July 4, 2020 03:43
Copy link
Owner

@maakbaas maakbaas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great changes. Some of them were already on my list, but I did not get to them yet, but many of them I had not even thought of. In general I would merge this pull request, except for two points:

  1. Regarding the project name in the header: I like this idea, but what I don't like is that it is read straight from the JSON. This means that if somebody changes the project name in the GUI, the header will not be updated. Furthermore right now it is a hard requirement to have this project name as a configuration item. My proposal would be to read the project name dynamically, and include a fall back to for instance ESP8266 in case of an error, or in case the project name is not defined. And then add an explanation about this in the documentation.

  2. I like being able to give a configuration item a different name for the GUI, I also see the benefit in removing the data type for visual consistency, but personally I think it could be handy to see this data type in the interface, also to distinguish between different type of integers. Another way that would be acceptable for me could be to give a default min max for the different integer types, and a default step of 1.

I am curious what your thoughts are, and of course I can also work on this once we agree on an approach :).

@maakbaas
Copy link
Owner

maakbaas commented Jul 4, 2020

Also, regarding your three discussion points:

  • linting configuration (eg, eslint)

I am less familiar in this area, so if you have a proposal I am all ears.

  • why use document.querySelector(...).value for form inputs rather than data binding?

Probably because this is the approach I was most familiar with (I am self-taught in JS). I am open for improvements, as long as it does not add a lot of code/dependencies, to keep the footprint as low as possible

  • thoughts on using actual true/false for boolean config rather than strings

I see you already implemented this, and I agree this is much better than the strings approach!

@factormystic
Copy link
Contributor Author

  1. Regarding the project name in the header: I like this idea, but what I don't like is that it is read straight from the JSON. This means that if somebody changes the project name in the GUI, the header will not be updated. Furthermore right now it is a hard requirement to have this project name as a configuration item. My proposal would be to read the project name dynamically, and include a fall back to for instance ESP8266 in case of an error, or in case the project name is not defined. And then add an explanation about this in the documentation.

Good point. I'll move that commit to a separate PR draft for the time being and we can brainstorm about the right way to implement it. I did notice that projectName was mandatory config, but at least this specific code would work even if it was missing (it'd just be a blank header).

  1. I like being able to give a configuration item a different name for the GUI, I also see the benefit in removing the data type for visual consistency, but personally I think it could be handy to see this data type in the interface, also to distinguish between different type of integers. Another way that would be acceptable for me could be to give a default min max for the different integer types, and a default step of 1.

I suppose it's a question of who this page is for in an ideal project. Implementers know the data types --- they're the ones that wrote the config file. So I view it as a place for device users instead (and for small projects, that's the same person). I agree that showing the min/max in the UI would be nice, so I'll bring that back. The default step value in browsers is 1, so I think that's covered although the component could also provide an explicit fallback when undefined. Using a default min/max based on data type is a great idea, I assume it's possible right now to enter negative numbers for uints which is unhelpful.

Also looking at MDN docs for number inputs I noticed that there's a special any value for step, which means floats probably can use number inputs and therefore min/max. I'll give this a try too.

I am curious what your thoughts are, and of course I can also work on this once we agree on an approach :).

Sounds good 👍

(linter) I am less familiar in this area, so if you have a proposal I am all ears.

Basically what I think we'd want is to add a dev dependency on eslint, and a reasonable initial config file (such using their recommended defaults, and probably also eslint-plugin-react). The benefit is primarily so that contributors know what style to write code, but also to help avoid common pitfalls and make code quality improvements (eg, recommending const instead of var for variables that can be constants). This is VERY nice when combined with editors such as VS Code, where it can integrate directly and show recommendations in real time. I'll open a separate PR that does this, and then run the linter on the javascript, and you can see how you feel about that change independent of improvements in this PR.

Ideally we could do this for the cpp code as well, I had been looking into clang-tidy but I'm much less familiar with that part of the stack and I haven't yet got it set up.

(binding) Probably because this is the approach I was most familiar with (I am self-taught in JS). I am open for improvements, as long as it does not add a lot of code/dependencies, to keep the footprint as low as possible

No sweat, I'm familiar with JS patterns but haven't written much React (besides tutorials), so this is pretty fun for me to figure out. I believe that this would be a minor refactor inside the React components themselves without any new dependencies. I also don't expect much/any code size change. I'll put that in a separate PR as well so it can be considered separately.

(bools) I see you already implemented this, and I agree this is much better than the strings approach!

👍

@maakbaas
Copy link
Owner

maakbaas commented Jul 4, 2020

Good point. I'll move that commit to a separate PR draft for the time being and we can brainstorm about the right way to implement it. I did notice that projectName was mandatory config, but at least this specific code would work even if it was missing (it'd just be a blank header).

You are right that this parameter was already 'mandatory', because it is used in main.c, I forgot about that. Still I think of the main.c more as a template/getting started file, which would maybe be easier to change or modify by the user if they would want to remove projectName from the template configuration for some reason. I expect the typical user to be more skilled in the embedded side of things than the front-end side.

I suppose it's a question of who this page is for in an ideal project. Implementers know the data types --- they're the ones that wrote the config file. So I view it as a place for device users instead (and for small projects, that's the same person). I agree that showing the min/max in the UI would be nice, so I'll bring that back. The default step value in browsers is 1, so I think that's covered although the component could also provide an explicit fallback when undefined. Using a default min/max based on data type is a great idea, I assume it's possible right now to enter negative numbers for uints which is unhelpful.

Yes, very good points as well. For the first use case in which I want to use the framework myself, I had actually foreseen to maybe make a custom configuration page tailored more towards end-users. But your addition of the separate name field got me thinking that that would not be necessary. By adding for instance also a description field, or on top of the 'disabled' property a 'hidden' property, the page could be configured and tailored more towards the end-user application.

Haha, so many ideas right now. For my application I would need a color picker, but that can potentially also be added as a 'color' datatype that will add a color picker to the interface.

Basically what I think we'd want is to add a dev dependency on eslint, and a reasonable initial config file (such using their recommended defaults, and probably also eslint-plugin-react). The benefit is primarily so that contributors know what style to write code, but also to help avoid common pitfalls and make code quality improvements (eg, recommending const instead of var for variables that can be constants). This is VERY nice when combined with editors such as VS Code, where it can integrate directly and show recommendations in real time. I'll open a separate PR that does this, and then run the linter on the javascript, and you can see how you feel about that change independent of improvements in this PR.

Sounds awesome. I have some experience with linters in other languages, but did never set up eslint in my own toolchain yet.

Thanks a lot for your enthusiasm, and don't hesitate to let me know if and where I can assist (I am also learning a lot about Git, since I've mainly worked with SVN in the past and yours have been my first pull requests ;)).

- this is particularly useful when filling in the fields on mobile, where extra spaces might be added accidentally
- float is still `text`, to avoid the browser constraining the input to "step" increments
- since the data type of the config can now be represented by type-specific controls, removing the type/size label
- no server-side validation (yet?)
- use a checkbox UI (requires a little bit of special handling, both for layout and because we need to look at `checked` instead of `value`)
- switch from strings to actual boolean values
@factormystic factormystic force-pushed the web-ui-improvements branch from 34fe26f to 40930b0 Compare July 4, 2020 20:27
@factormystic
Copy link
Contributor Author

You are right that this parameter was already 'mandatory', because it is used in main.c, I forgot about that. Still I think of the main.c more as a template/getting started file, which would maybe be easier to change or modify by the user if they would want to remove projectName from the template configuration for some reason. I expect the typical user to be more skilled in the embedded side of things than the front-end side.

I think another part of it is, what is the expectation for how this project should be used? There's a few ways to think about it. For example, people who want to build apps on this framework might clone/fork and start editing/customizing whatever they want. Of course that's allowed, but it might not be helpful especially if people want to incorporate core changes into their projects later on. I'm still figuring that out myself.

One idea I had is to have people start a fresh repo for their own projects instead of fork, but then add this code as a git submodule. To reference an inspiration, this is how themes for the static blogging program Hugo typically work (explanation). The obvious problem is that's a pure web project whereas this is a compiled IoT project so I actually don't know if it can work, but conceptually I like the idea of pulling this project in as a dependency somehow, then in my own repo I have only my own configuration.json, main.cpp, etc, and can easily pull in updates.

I expect the typical user to be more skilled in the embedded side of things than the front-end side.

It's actually the opposite for me! Web stuff is my day job (although not React), and IoT is the hobby (keep that in mind when I send a future PR to make some cpp changes 😂...)

By adding for instance ... a 'hidden' property

Done

yours have been my first pull requests

Haha, congrats I guess. I had been thinking about a possible project for my ESP8266 and when I saw your project here show up on Hack-a-day recently I thought I would see if I could get it running. And that post mainly focused on making HTTPS calls w/o hardcoding cert thumbprints and didn't even mention the self-hosted config dashboard!

@factormystic factormystic requested a review from maakbaas July 4, 2020 20:47
@factormystic factormystic force-pushed the web-ui-improvements branch from 40930b0 to 52b5647 Compare July 4, 2020 20:51
@maakbaas maakbaas merged commit 205d81b into maakbaas:master Jul 4, 2020
@factormystic
Copy link
Contributor Author

Here's another question: Is the current handling of length from configuration.json correct? That defines the length of the char array in config.h, and that's supposed to be inclusive of a null byte, correct? Eg, if you define a string with "length": 32, should the actual max input value be 31? I'm actually not sure if that's true, just speculating?

@maakbaas
Copy link
Owner

maakbaas commented Jul 4, 2020

I think another part of it is, what is the expectation for how this project should be used? There's a few ways to think about it. For example, people who want to build apps on this framework might clone/fork and start editing/customizing whatever they want. Of course that's allowed, but it might not be helpful especially if people want to incorporate core changes into their projects later on. I'm still figuring that out myself.

One idea I had is to have people start a fresh repo for their own projects instead of fork, but then add this code as a git submodule. To reference an inspiration, this is how themes for the static blogging program Hugo typically work (explanation). The obvious problem is that's a pure web project whereas this is a compiled IoT project so I actually don't know if it can work, but conceptually I like the idea of pulling this project in as a dependency somehow, then in my own repo I have only my own configuration.json, main.cpp, etc, and can easily pull in updates.

Yes, it's again a good point. I will give it some thought. Another option could potentially be to make it into a PlatformIO library so that you can include it into your project in that way. But I need to look into this if among other things, you can then still have the benefits of the build hooks straight from a library.

It's actually the opposite for me! Web stuff is my day job (although not React), and IoT is the hobby (keep that in mind when I send a future PR to make some cpp changes 😂...)

I figured as much :)

Thanks, I have merged the pull request.

@maakbaas
Copy link
Owner

maakbaas commented Jul 4, 2020

Here's another question: Is the current handling of length from configuration.json correct? That defines the length of the char array in config.h, and that's supposed to be inclusive of a null byte, correct? Eg, if you define a string with "length": 32, should the actual max input value be 31? I'm actually not sure if that's true, just speculating?

You are right, fixed it in afd78e0

@factormystic factormystic deleted the web-ui-improvements branch July 4, 2020 21:37
@maakbaas
Copy link
Owner

maakbaas commented Nov 6, 2020

Finally got to implementing projectName as a title, as you did suggest here as well. Thanks :).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants