Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

index/style added runtime parameter dictionary inputs #190

Merged
merged 9 commits into from
Feb 10, 2024

Conversation

GeoDerp
Copy link
Contributor

@GeoDerp GeoDerp commented Feb 8, 2024

Related to: https://github.com/users/davidusb-geek/projects/1/views/1?pane=issue&itemId=52545404

Changed

  • index/style, added runtime parameter dictionary user inputs
  • index/style, deleted deprecated center align tags
  • style, tweaked button styling
  • index/style, added comments, formatted and reordered

Examples

(Dark mode)
Input: Box
Screenshot from 2024-02-08 23-06-16
Input: List
Screenshot from 2024-02-08 23-06-04

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Feb 8, 2024

This isn't polished yet, may still come back tomorrow and tweak. Would appreciate any help.

Copy link

codecov bot commented Feb 8, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (195e774) 89.84% compared to head (923d4e2) 89.84%.
Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #190   +/-   ##
=======================================
  Coverage   89.84%   89.84%           
=======================================
  Files           6        6           
  Lines        1645     1645           
=======================================
  Hits         1478     1478           
  Misses        167      167           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@davidusb-geek
Copy link
Owner

That actually look really really nice.
This could be very helpful for testing.
Nice work! You tell me when is ready so we can merge.

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Feb 8, 2024

That actually look really really nice.
This could be very helpful for testing.
Nice work! You tell me when is ready so we can merge.

In theory it's ready to go now. However, it will probably be good for me to have a look at it tomorrow morning and polish any possible bugs.

@purcell-lab
Copy link
Contributor

I couldn't see how to comment on the project board entry, so I'll put some thoughts here.

I help a lot of new users onboard with EMHASS.

From a user interface (UI) perspective, they load up EMHASS, then they go to this web page and start hitting the first button PerfectOpt (which doesn't appear to do anything), then they hit the second button DayAheadOpt (which also doesn't appear to do anything), then they randomly hit the ML buttons, which certainly doesn't appear to do anything.

I think there are too many confusing options on this front page and would welcome an 'Advanced' tab that 'hides' the functions that require configuration.

The workflow in my mind would be to have a the Post Data box up front, as people need to inject values first, I like the second concept with a different box for each key. Then have a DayAheadOpt button, then have a Publish button.

Some sort of running log or user feedback when which of these steps is selected would also be really valuable, because as it stands there is zero feedback when a button is pressed.. If possible having the log running in a side bar would be ideal. I have a really ugly hack using iframes to display the log next to some buttons, but that would be far superior in the EMHASS ingress page.

image

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Feb 8, 2024

These are good ideas.

I have actually thought about the logger on the page myself. However I have currently no idea how to achieve that.

pseudo code thought would be:

  • button gets triggered
  • logger logs inside the function triggered
  • the logs then get compiled and sent as an array as the function response.
  • python webserver reads that response and sends it as a return of some form to the webserver
  • JavaScript code interprets that code and appends it to a read only text box
    • alternatively the python code in the webserver could loop the array and generate html like what's happening in the table generation

I wonder if you can get all app.logger logs and append lines of it has changed

@purcell-lab
Copy link
Contributor

However I have currently no idea how to achieve that.

Something like the Logger capability on the devices would be ideal.

Screenshot_20240209-121759

@davidusb-geek
Copy link
Owner

I couldn't see how to comment on the project board entry, so I'll put some thoughts here.

I just added you to the project members. But we can continue our discussion here is ok.

From a user interface (UI) perspective, they load up EMHASS, then they go to this web page and start hitting the first button PerfectOpt (which doesn't appear to do anything), then they hit the second button DayAheadOpt (which also doesn't appear to do anything), then they randomly hit the ML buttons, which certainly doesn't appear to do anything.
I think there are too many confusing options on this front page and would welcome an 'Advanced' tab that 'hides' the functions that require configuration.

Thank you Mark for the REX, this is very important to improve!

I think that yes maybe we can hide some buttons and the text box in an "advanced" tab to avoid confusing users with all these options.

The workflow in my mind would be to have a the Post Data box up front, as people need to inject values first, I like the second concept with a different box for each key. Then have a DayAheadOpt button, then have a Publish button.

Agree, at least the "day-ahead" and "publish" buttons and the text box to add more data shoul be up front.
Also we should take one step at a time. I think that the text box functionality that @GeoDerp just added is great as it is right now and I really like the two options: a whole dictionary of data and the list option.

I have actually thought about the logger on the page myself. However I have currently no idea how to achieve that.

Of course that a logging functionality should be great. But I don't think it is completely necessary. I mean you can always have two browser tabs open, one for the webui and one for the logger.
But I do agree that we could add some responsiveness when pushing the buttons on the webui. An easy solution would be just to post a little message something like "Successful POST request sent to day-ahead optimization task" for example.
The logging functionality is great but requires a lot much more effort.

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Feb 9, 2024

Will require testing and refinding.
Added the following capabilities:

  • inputs keep state after refresh with localStorage, save on successful post
  • error alert pops up for JSON parse error
  • removed form tags
  • added status for post. tick and cross icons presented based on 201 post response
  • ml tasks have been hidden behind a button in the optimization tasks section (can be moved)

Looks Something like this: (dark theme)
on success
Screenshot from 2024-02-09 23-43-28


Json error and post loading
Screenshot from 2024-02-09 23-43-17

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Feb 9, 2024

I may want to strengthen the null exceptions with input lists. Otherwise this works (just forces one empty list to be on screen at all times)
Will like to spend more time testing strengthening every scenario (like if local storage is disabled). Any assistance for the bug hunting will be appreciated.

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Feb 10, 2024

Update: found a few bugs. Will keep you posted when I fix them

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Feb 10, 2024

I think Im pritty happy now.
For future reference. I believe we could modify the return make_response(msg, 201) to send back error log data if something went wrong. we could then tell the js to present the html alert box with the response error data.

js example being:

    async function formAction(action) {
        var data = inputToJson()
        if (data !== 0) { //don't run if there is an error in the data Json
            showChangeStatus("loading") // show loading div for status
            response = await fetch(`{{ basename }}/action/${action}`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(data), //post can only send data via strings
            }).then(saveStorage()) //save to storage if successful 
            showChangeStatus(response.status) //replace loading, show tick or cross
        }
        else {
            showChangeStatus("remove") //replace loading, show tick or cross with none 
        }
    }

    //function in control of status icons of post above
    function showChangeStatus(status) {
        var loading = document.getElementById("loader") //element showing status 
        if (status === "remove") { //show loading logo
            loading.innerHTML = "";
            loading.classList.remove("loading"); //append class with loading animation styling
        }
        else if (status === "loading") { //show loading logo
            loading.innerHTML = "";
            loading.classList.add("loading"); //append class with loading animation styling
        }
        else if (status === 201) { //then show a tick 
            loading.classList.remove("loading")
            loading.innerHTML = `<p class=tick>&#x2713;</p>`

        }
        else { //then show a cross 
            loading.classList.remove("loading")
            loading.innerHTML = `<p class=cross>&#x292C;</p>`
        }
    }

to

    async function formAction(action) {
        var data = inputToJson()
        if (data !== 0) { //don't run if there is an error in the data Json
            showChangeStatus("loading") // show loading div for status
            response = await fetch(`{{ basename }}/action/${action}`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(data), //post can only send data via strings
            }).then(saveStorage()) //save to storage if successful 
            showChangeStatus(response) //replace loading, show tick or cross
        }
        else {
            showChangeStatus("remove") //replace loading, show tick or cross with none 
        }
    }

    //function in control of status icons of post above
    function showChangeStatus(response) {
        var loading = document.getElementById("loader") //element showing status 
        if (response.status === "remove") { //show loading logo
            loading.innerHTML = "";
            loading.classList.remove("loading"); //append class with loading animation styling
        }
        else if (response.status === "loading") { //show loading logo
            loading.innerHTML = "";
            loading.classList.add("loading"); //append class with loading animation styling
        }
        else if (response.status === 201) { //then show a tick 
            loading.classList.remove("loading")
            loading.innerHTML = `<p class=tick>&#x2713;</p>`

        }
        else { //then show a cross 
            loading.classList.remove("loading")
            loading.innerHTML = `<p class=cross>&#x292C;</p>`
             document.getElementById("alert-text").textContent = "\r\n" + response.msg //or what the dict  response key is
             document.getElementById("alert").style.display = "block";
        }
    }

@GeoDerp
Copy link
Contributor Author

GeoDerp commented Feb 10, 2024

Feel free to set this as an issue so we can keep track of it if desired.

I think Im pritty happy now.
For future reference. I believe we could modify the return make_response(msg, 201) to send back error log data if something went wrong. we could then tell the js to present the html alert box with the response error data.

js example being:

    async function formAction(action) {
        var data = inputToJson()
        if (data !== 0) { //don't run if there is an error in the data Json
            showChangeStatus("loading") // show loading div for status
            response = await fetch(`{{ basename }}/action/${action}`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(data), //post can only send data via strings
            }).then(saveStorage()) //save to storage if successful 
            showChangeStatus(response.status) //replace loading, show tick or cross
        }
        else {
            showChangeStatus("remove") //replace loading, show tick or cross with none 
        }
    }

    //function in control of status icons of post above
    function showChangeStatus(status) {
        var loading = document.getElementById("loader") //element showing status 
        if (status === "remove") { //show loading logo
            loading.innerHTML = "";
            loading.classList.remove("loading"); //append class with loading animation styling
        }
        else if (status === "loading") { //show loading logo
            loading.innerHTML = "";
            loading.classList.add("loading"); //append class with loading animation styling
        }
        else if (status === 201) { //then show a tick 
            loading.classList.remove("loading")
            loading.innerHTML = `<p class=tick>&#x2713;</p>`

        }
        else { //then show a cross 
            loading.classList.remove("loading")
            loading.innerHTML = `<p class=cross>&#x292C;</p>`
        }
    }

to

    async function formAction(action) {
        var data = inputToJson()
        if (data !== 0) { //don't run if there is an error in the data Json
            showChangeStatus("loading") // show loading div for status
            response = await fetch(`{{ basename }}/action/${action}`, {
                method: "POST",
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(data), //post can only send data via strings
            }).then(saveStorage()) //save to storage if successful 
            showChangeStatus(response) //replace loading, show tick or cross
        }
        else {
            showChangeStatus("remove") //replace loading, show tick or cross with none 
        }
    }

    //function in control of status icons of post above
    function showChangeStatus(response) {
        var loading = document.getElementById("loader") //element showing status 
        if (response.status === "remove") { //show loading logo
            loading.innerHTML = "";
            loading.classList.remove("loading"); //append class with loading animation styling
        }
        else if (response.status === "loading") { //show loading logo
            loading.innerHTML = "";
            loading.classList.add("loading"); //append class with loading animation styling
        }
        else if (response.status === 201) { //then show a tick 
            loading.classList.remove("loading")
            loading.innerHTML = `<p class=tick>&#x2713;</p>`

        }
        else { //then show a cross 
            loading.classList.remove("loading")
            loading.innerHTML = `<p class=cross>&#x292C;</p>`
             document.getElementById("alert-text").textContent = "\r\n" + response.msg //or what the dict  response key is
             document.getElementById("alert").style.display = "block";
        }
    }

@davidusb-geek
Copy link
Owner

Feel free to set this as an issue so we can keep track of it if desired.

Could you please open the issue your self, or better add a new card with this task to the kanban.
I'm not sure to completely understand the issue

@davidusb-geek
Copy link
Owner

Merging and further testing...

@davidusb-geek davidusb-geek merged commit c858eda into davidusb-geek:master Feb 10, 2024
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants