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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

[馃悰 BUG] When a table has a lot of content, updates to it are not always reflected in the visuals #1397

Open
2 tasks done
gbritoda opened this issue Jun 12, 2024 · 1 comment
Labels
馃柊 GUI Related to GUI 馃挜Malfunction Addresses an identified problem. 馃煥 Priority: Medium Not blocking but should be addressed

Comments

@gbritoda
Copy link

gbritoda commented Jun 12, 2024

What went wrong? 馃

Raised in Discord first: https://discord.com/channels/1125797687476887563/1242498359093100667

I have a table that contains a bunch of different information, some of the rows have different "categories" though, and I want to be able to filter through these categories.

I did that through a selector on the side (not a dropdown one). The default category selected is "All", to show all, when a category is selected it changes a variable called selected_category, then on a callback called by the on_change of the selector will modify the contents of the table to only show the rows belonging to that category, followed by a state.refresh(table), because the table is part of another python object.

However that doesn't always work, in fact I can consistently get into a state where the table does not refresh, but if I refresh the page the changes are made. From the logs and from this it seems the table indeed does change but the change is not reflected visually. The table does have the rebuild property turned on.

Recorded a gif of an example code. Although it took a while for me to actually reproduce it because I made a much "lighter" version. You can see in the beginning of the gif that I was stuck, I refreshed and kept clicking multiple times until I managed to get it again. With this example was quite difficult but with my actual application (which is big) is a bit easy to get to that state

There might be a few quirks (e.g. taipy_thread) that you might find it unecessary. It's just something I made back in 2.4 and unsure if it still needed

This is the code used in the above Gif:

import threading
from taipy.gui import Gui, Markdown, get_state_id, invoke_callback
from time import sleep

# Categories
ALL_CAT = "All"
MEAT_CAT = "Meat"
SALAD_CAT = "Salad"
CHEESE_CAT = "Cheese"

class FoodMenu:
    def __init__(self) -> None:
        self.load_menu()
        self.columns = [
            "Food", "Price"
        ]
        self.current_selected_category = ALL_CAT
        self.update_content_being_shown()
        self.selector_active = True

    def load_menu(self):
        self.categories = [ALL_CAT, MEAT_CAT, SALAD_CAT, CHEESE_CAT]
        meat = [(f"fish{i}", f"拢{i}.50") for i in range(100)]
        salad = [(f"lettuce{i}", "拢1") for i in range(50)]
        cheese = [(f"brie{i}", f"拢{i}.{i}") for i in range(200)]
        self.menu = {
            MEAT_CAT: meat,
            SALAD_CAT: salad,
            CHEESE_CAT: cheese,
            ALL_CAT: meat + salad + cheese
        }
        

    def update_content_being_shown(self):
        # self.showing_content is a filtered and reorganised version of self.menu
        self.showing_content = self.get_content_for_category(self.current_selected_category)

    def get_content_for_category(self, category:str):
        content = {}
        for i in range(len(self.columns)):
            content[self.columns[i]] = [menu_info[i] for menu_info in self.menu[category]]
        return content

FOOD_MENU = FoodMenu()

page = Markdown("""
<|{FOOD_MENU.current_selected_category}|selector|lov={FOOD_MENU.categories}|active={FOOD_MENU.selector_active}|on_change=on_category_selection_change|>

<|{FOOD_MENU.showing_content}|table|columns={FOOD_MENU.columns}|show_all|rebuild|filter|number_format=%,|hover_text=List of available food|width=100%|>
""")

def taipy_thread(state, callback, args):
    """Creates a thread that TaiPy can handle"""
    state_id = get_state_id(state)
    return threading.Thread(target=invoke_callback, args=[GUI_OBJ, state_id, callback, args], daemon=True)


def on_category_selection_change(state):
    print(f"Displayed category changed to {state.FOOD_MENU.current_selected_category}")
    if state.FOOD_MENU.selector_active == False:
        return
    else:
        # The updating is done on a different thread to allow TaiPy to swiftly re-render the selector as inactive.
        # If the updating is done in this callback the visual effects wont be seen live as this thread 'hogs' whatever
        # taipy does in the background to update visual elements. At least it is what I have seen?
        taipy_thread(state, update_displayed_content_and_reenable_selection, args=[]).run()

def update_displayed_content_and_reenable_selection(state):
    state.FOOD_MENU.selector_active = False
    state.refresh('FOOD_MENU')
    print("Updating displayed content")
    SIDE_MENU_INACTIVE_FOR = 0.4
    try:
        state.FOOD_MENU.update_content_being_shown()
        state.refresh('FOOD_MENU')
        # A little wait time to extend the inactive state of the selector
        # allows time for the web browser to load the filtered menu and enhances the UX a bit
        # There's no way to tell when an element has finished loading unfortunately
        print(f"Selection menu inactive for {SIDE_MENU_INACTIVE_FOR} seconds")
        sleep(SIDE_MENU_INACTIVE_FOR)
    finally:
        state.FOOD_MENU.selector_active = True
        state.refresh('FOOD_MENU')
        print("Finished updating displayed content")


GUI_OBJ = Gui(page=page)
GUI_OBJ.run(
    use_reloader=True
)

Expected Behavior

When clicking the buttons to change the table category, the table contents should update accordingly and not freeze

Steps to Reproduce Issue

Run the code snippet in the description, click the category buttons multiple times until the table freezes.

Solution Proposed

No response

Screenshots

No response

Runtime Environment

No response

Browsers

Chrome, Firefox

OS

Linux

Version of Taipy

3.0.0

Additional Context

No response

Code of Conduct

  • I have checked the existing issues.
  • I am willing to work on this issue (optional)
@gbritoda gbritoda added the 馃挜Malfunction Addresses an identified problem. label Jun 12, 2024
@FlorianJacta FlorianJacta added 馃柊 GUI Related to GUI 馃煥 Priority: Medium Not blocking but should be addressed labels Jun 12, 2024
@FlorianJacta
Copy link
Member

Thank you for writing the issue! We discussed it with @FredLL-Avaiga and shown it the issue first hand some time ago

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
馃柊 GUI Related to GUI 馃挜Malfunction Addresses an identified problem. 馃煥 Priority: Medium Not blocking but should be addressed
Projects
None yet
Development

No branches or pull requests

2 participants