comparison libervia/pages/lists/view/_browser/__init__.py @ 1395:4ccf42d8aab7

browser (lists/view): `grocery` list specialised behaviour: if the list is a `grocery` list, user can change status directly in list view, delete an item, and do a quick item creation without having to use the `create` button.
author Goffi <goffi@goffi.org>
date Sat, 27 Feb 2021 21:08:42 +0100
parents a84383c659b4
children 6fdef01f6671
comparison
equal deleted inserted replaced
1394:72f9639594b2 1395:4ccf42d8aab7
1 from browser import window, bind 1 from browser import window, document, aio, bind
2 from invitation import InvitationManager 2 from invitation import InvitationManager
3 from javascript import JSON
4 from aio_bridge import Bridge, BridgeException
5 import dialog
3 6
4 7
8 bridge = Bridge()
5 lists_ns = window.lists_ns 9 lists_ns = window.lists_ns
6 pubsub_service = window.pubsub_service 10 pubsub_service = window.pubsub_service
7 pubsub_node = window.pubsub_node 11 pubsub_node = window.pubsub_node
12 list_type = window.list_type
8 try: 13 try:
9 affiliations = window.affiliations.to_dict() 14 affiliations = window.affiliations.to_dict()
10 except AttributeError: 15 except AttributeError:
11 pass 16 pass
12 17
27 name = name.strip() 32 name = name.strip()
28 if name: 33 if name:
29 pubsub_data['name'] = name 34 pubsub_data['name'] = name
30 manager = InvitationManager("pubsub", pubsub_data) 35 manager = InvitationManager("pubsub", pubsub_data)
31 manager.attach(affiliations=affiliations) 36 manager.attach(affiliations=affiliations)
37
38
39 async def on_delete(evt):
40 item_elt = evt.target.closest(".item")
41 if item_elt is None:
42 dialog.notification.show(
43 "Can't find parent item element",
44 level="error"
45 )
46 return
47 item_elt.classList.add("selected_for_deletion")
48 item = JSON.parse(item_elt.dataset.item)
49 confirmed = await dialog.Confirm(
50 f"{item['name']!r} will be deleted, are you sure?",
51 ok_label="delete",
52 ok_color="danger",
53 ).ashow()
54 item_elt.classList.remove("selected_for_deletion")
55 if confirmed:
56 try:
57 await bridge.psItemRetract(pubsub_service, pubsub_node, item["id"], True)
58 except Exception as e:
59 dialog.notification.show(
60 f"Can't delete list item: {e}",
61 level="error"
62 )
63 else:
64 dialog.notification.show("list item deleted successfuly")
65 item_elt.remove()
66
67
68 async def on_next_state(evt):
69 """Update item with next state
70
71 Only used with grocery list at the moment
72 """
73 evt.stopPropagation()
74 evt.preventDefault()
75 # FIXME: states are currently hardcoded, it would be better to use schema
76 item_elt = evt.target.closest(".item")
77 if item_elt is None:
78 dialog.notification.show(
79 "Can't find parent item element",
80 level="error"
81 )
82 return
83 item = JSON.parse(item_elt.dataset.item)
84 try:
85 status = item["status"]
86 except (KeyError, IndexError) as e:
87 dialog.notification.show(
88 f"Can't get item status: {e}",
89 level="error"
90 )
91 status = "to_buy"
92 if status == "to_buy":
93 item["status"] = "bought"
94 class_update_method = item_elt.classList.add
95 checked = True
96 elif status == "bought":
97 item["status"] = "to_buy"
98 checked = False
99 class_update_method = item_elt.classList.remove
100 else:
101 print(status)
102 dialog.notification.show(
103 f"unexpected item status: {status!r}",
104 level="error"
105 )
106 return
107 item_elt.dataset.item = JSON.stringify(item)
108 try:
109 await bridge.listSet(
110 pubsub_service,
111 pubsub_node,
112 {k: [v] for k,v in item.items()},
113 "",
114 item["id"],
115 ""
116 )
117 except BridgeException as e:
118 dialog.notification.show(
119 f"Can't udate list item: {e.message}",
120 level="error"
121 )
122 else:
123 evt.target.checked = checked
124 class_update_method("list-item-closed")
125
126
127 if list_type == "grocery":
128 for elt in document.select('.click_to_delete'):
129 elt.bind("click", lambda evt: aio.run(on_delete(evt)))
130
131 for elt in document.select('.click_to_next_state'):
132 elt.bind("click", lambda evt: aio.run(on_next_state(evt)))
133