From b055102ebd6bfc12231e23f32bfbf19376aef866 Mon Sep 17 00:00:00 2001 From: flukx Date: Fri, 16 Aug 2024 15:33:29 +0200 Subject: [PATCH] add save button should be integrated in different way at different position .... --- flinventory_gui/search.py | 77 +++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 8 deletions(-) diff --git a/flinventory_gui/search.py b/flinventory_gui/search.py index c557277..33a5798 100644 --- a/flinventory_gui/search.py +++ b/flinventory_gui/search.py @@ -9,6 +9,7 @@ import nicegui from nicegui import ui from part import Part import part_list_io +import datacleanup def antilen(string: str): @@ -92,7 +93,12 @@ async def list_parts(ui_element: nicegui.ui.element, parts: Iterable[Part]) -> N ui_element.clear() with ((ui_element)): for part in parts: - with ui.card(): + card = ui.card() + # supplying card and part as default arguments makes it use the current + # value instead of the value at the time of usage + change_card = lambda event, c=card, p=part: show_part_changer(c, p) + with card: + print(f"Create card {id(card)} for {part.name}.") with ui.row(wrap=False): with ui.column(): with ui.row(): @@ -104,6 +110,7 @@ async def list_parts(ui_element: nicegui.ui.element, parts: Iterable[Part]) -> N else: if name_en != part.name: ui.label(text=f"({name_en})").style('font-size: 70%') + ui.button("🖉").on_click(change_card) other_names = ", ".join(itertools.chain( vars(part).get("name_alt_de", []), vars(part).get("name_alt_en", []))) @@ -120,9 +127,30 @@ async def list_parts(ui_element: nicegui.ui.element, parts: Iterable[Part]) -> N "height=100px").props("fit='scale-down'") -@ui.page("/") -def search_page() -> None: - """Create a NiceGUI page with a search input field and search results.""" +def load_data() -> list[Part]: + """Load data from text files. + + Could implement that data is only loaded when necessary. + Then an argument force would be useful to reload. + + Returns: + list of all things listed in the files + """ + options = get_file_names() + return part_list_io.get_parts(options) + + +def save_data(parts) -> None: + """Save parts to files.""" + options = get_file_names() + part_list_io.save_parts(parts, options.input_file, options.locations_file) + +def search_page(parts: list[Part]) -> None: + """Create a NiceGUI page with a search input field and search results. + + Args: + parts: list of parts to search in + """ print("(Re)build search page.") # UI container for the search results. results: Optional[ui.element] = None @@ -130,8 +158,8 @@ def search_page() -> None: # Search queries (max. 1) running. Here to be cancellable by different search coroutines. running_queries: list[asyncio.Task] = [] - options = get_file_names() - all_parts = part_list_io.get_parts(options) + # should use the parts as they are when clicked + ui.button("Save").on_click(lambda click_event_arguments, parts=parts: save_data(parts)) async def search(event: nicegui.events.ValueChangeEventArguments) -> None: """Search for cocktails as you type. @@ -149,7 +177,7 @@ def search_page() -> None: except asyncio.exceptions.CancelledError: # the next letter was already typed, do not search and rerender for this query return - query = asyncio.create_task(find_parts(all_parts, event.value)) + query = asyncio.create_task(find_parts(parts, event.value)) running_queries.append(query) try: start = time.monotonic() @@ -180,9 +208,42 @@ def search_page() -> None: results = ui.column() + +def show_part_changer(ui_element: nicegui.ui.element, part: Part, + save_function: Callable[[], None]) -> None: + """Clear content of ui element and instead display editing fields. + + Args: + ui_element: the ui element (e.g. a card) on which to show the part changing ui + part: the part to change + save_function: what to call when changing is done + """ + def delete_member(member, updated: nicegui.ui.input): + del vars(part)[member] + updated.set_value("") + input_fields = {} + def save_value(event, member): + """Copy input field value to part member.""" + if not event.value: + del(vars(part)[member]) + else: + vars(part)[member] = event.value + + print(f"Try to let edit {part.name} with {id(ui_element)}.") + ui_element.clear() + with ui_element: + for member in ("name_de", "name_en", "description_de", "description_en"): + with ui.row(): + ui.label(member + ":") + input_fields[member] = ui.input(part.get(member, "")).on_value_change( + lambda e, m=member: save_value(e, m)) + ui.button("❌").on_click(lambda m=member, i=input_fields[member]: delete_member(m, i)) + ui.button("Save").on_click(save_function) + + if __name__ in {"__main__", "__mp_main__"}: nicegui.app.add_static_files('/images_landscape', 'images_landscape') - search_page() + search_page(load_data()) ui.run(title="Fahrradteile", favicon="website_resources/favicon.ico", language="de",