view libervia/pages/lists/view/_browser/__init__.py @ 1406:cffa3ae4d0aa

pages (blog/view): move URL friendly code to backend tools: - the code to render an URL friendly is now in `sat.tools.common.regex` - user friendly extra text is now only displayed when no `-` is found in ID. This is a temporary transition behaviour because new blog items IDs are now user friendly by default, and thus extra text is not wanted anymore. For older IDs it is still needed though, and the presence of `-` is used to guess when an ID is user friendly or not.
author Goffi <goffi@goffi.org>
date Fri, 16 Apr 2021 18:44:49 +0200
parents 4ccf42d8aab7
children 6fdef01f6671
line wrap: on
line source

from browser import window, document, aio, bind
from invitation import InvitationManager
from javascript import JSON
from aio_bridge import Bridge, BridgeException
import dialog


bridge = Bridge()
lists_ns = window.lists_ns
pubsub_service = window.pubsub_service
pubsub_node = window.pubsub_node
list_type = window.list_type
try:
    affiliations = window.affiliations.to_dict()
except AttributeError:
    pass

@bind("#button_manage", "click")
def manage_click(evt):
    evt.stopPropagation()
    evt.preventDefault()
    pubsub_data = {
        "namespace": lists_ns,
        "service": pubsub_service,
        "node": pubsub_node
    }
    try:
        name = pubsub_node.split('_', 1)[1]
    except IndexError:
        pass
    else:
        name = name.strip()
        if name:
            pubsub_data['name'] = name
    manager = InvitationManager("pubsub", pubsub_data)
    manager.attach(affiliations=affiliations)


async def on_delete(evt):
    item_elt = evt.target.closest(".item")
    if item_elt is None:
        dialog.notification.show(
            "Can't find parent item element",
            level="error"
        )
        return
    item_elt.classList.add("selected_for_deletion")
    item = JSON.parse(item_elt.dataset.item)
    confirmed = await dialog.Confirm(
        f"{item['name']!r} will be deleted, are you sure?",
        ok_label="delete",
        ok_color="danger",
    ).ashow()
    item_elt.classList.remove("selected_for_deletion")
    if confirmed:
        try:
            await bridge.psItemRetract(pubsub_service, pubsub_node, item["id"], True)
        except Exception as e:
            dialog.notification.show(
                f"Can't delete list item: {e}",
                level="error"
            )
        else:
            dialog.notification.show("list item deleted successfuly")
            item_elt.remove()


async def on_next_state(evt):
    """Update item with next state

    Only used with grocery list at the moment
    """
    evt.stopPropagation()
    evt.preventDefault()
    # FIXME: states are currently hardcoded, it would be better to use schema
    item_elt = evt.target.closest(".item")
    if item_elt is None:
        dialog.notification.show(
            "Can't find parent item element",
            level="error"
        )
        return
    item = JSON.parse(item_elt.dataset.item)
    try:
        status = item["status"]
    except (KeyError, IndexError) as e:
        dialog.notification.show(
            f"Can't get item status: {e}",
            level="error"
        )
        status = "to_buy"
    if status == "to_buy":
        item["status"] = "bought"
        class_update_method = item_elt.classList.add
        checked = True
    elif status == "bought":
        item["status"] = "to_buy"
        checked = False
        class_update_method = item_elt.classList.remove
    else:
        print(status)
        dialog.notification.show(
            f"unexpected item status: {status!r}",
            level="error"
        )
        return
    item_elt.dataset.item = JSON.stringify(item)
    try:
        await bridge.listSet(
            pubsub_service,
            pubsub_node,
            {k: [v] for k,v in item.items()},
            "",
            item["id"],
            ""
        )
    except BridgeException as e:
        dialog.notification.show(
            f"Can't udate list item: {e.message}",
            level="error"
        )
    else:
        evt.target.checked = checked
        class_update_method("list-item-closed")


if list_type == "grocery":
    for elt in document.select('.click_to_delete'):
        elt.bind("click", lambda evt: aio.run(on_delete(evt)))

    for elt in document.select('.click_to_next_state'):
        elt.bind("click", lambda evt: aio.run(on_next_state(evt)))