svv/items.py
changeset 53 06dad873204d
parent 48 06fa83c8c0bb
child 55 433842c04ab1
--- a/svv/items.py	Mon Jan 10 17:50:21 2011 +0200
+++ b/svv/items.py	Mon Jan 10 17:51:08 2011 +0200
@@ -70,57 +70,40 @@
             self.render_select_input(name, [(0, u"---")] + parent_items, parent_id)
         )
 
-    def render (self, action, legend=u"Laitejuttu", return_url=None, delete_action=None) :
+    def render (self, action, legend=u"Laitetiedot", return_url=None) :
         """
             Render <form> HTML
 
                 return_url          - URL for reset button
-                delete_action       - (optional) URL to delete-item option
         """
 
-        return (
-            html.form(action=action, method='POST')(
-                html.fieldset(
-                    html.legend(legend),
-
-                    html.ol(
-                        self.render_form_field('item_parent', u"Case", u"Missä laite sijaitsee", (
-                            self.render_parent_select('item_parent', self.item_parent_id)
-                        )),
+        return html.form(action=action, method='POST')(
+            html.fieldset(
+                html.legend(legend),
 
-                        self.render_form_field('item_name', u"Nimi", u"Lyhyt nimi", (
-                            self.render_text_input('item_name', self.item_name)
-                        )),
-
-                        self.render_form_field('item_detail', u"Kuvaus", u"Tarkempi kuvaus", (
-                            self.render_text_input('item_detail', self.item_detail, multiline=True)
-                        )),
+                html.ol(
+                    self.render_form_field('item_parent', u"Case", u"Missä laite sijaitsee", (
+                        self.render_parent_select('item_parent', self.item_parent_id)
+                    )),
 
-                        self.render_form_field('item_quantity', u"Kappalemäärä", u"Jos on esim. useampi piuha/adapter, kirjaa niitten määrä; muuten jätä tyhjäksi", (
-                            self.render_text_input('item_quantity', self.item_quantity)
-                        )),
-                        
-                        html.li(
-                            self.render_submit_button(u"Tallenna"),
-                            self.render_reset_button(u"Palaa inventaariin", return_url) if return_url else None,
-                        ),
+                    self.render_form_field('item_name', u"Nimi", u"Lyhyt nimi", (
+                        self.render_text_input('item_name', self.item_name)
+                    )),
+
+                    self.render_form_field('item_detail', u"Kuvaus", u"Tarkempi kuvaus", (
+                        self.render_text_input('item_detail', self.item_detail, multiline=True)
+                    )),
+
+                    self.render_form_field('item_quantity', u"Kappalemäärä", u"Jos on esim. useampi piuha/adapter, kirjaa niitten määrä; muuten jätä tyhjäksi", (
+                        self.render_text_input('item_quantity', self.item_quantity)
+                    )),
+                    
+                    html.li(
+                        self.render_submit_button(u"Tallenna"),
+                        self.render_reset_button(u"Palaa inventaariin", return_url) if return_url else None,
                     ),
                 ),
             ),
-
-            html.form(action=delete_action, method='POST')(
-                html.fieldset(
-                    html.legend(u"Poistaminen"),
-
-                    html.input(type='hidden', name='items', value=self.item_id),
-
-                    html.ol(
-                        html.li(
-                            html.input(type='submit', name='delete', value=u"Poista"),
-                        )
-                    )
-                ),
-            ) if delete_action else None
         )
 
     def process (self, data) :
@@ -180,48 +163,97 @@
         # list of items to delete
         self.items = []
     
-    def render_items_list (self, name, items) :
+    def load (self, items) :
         """
-            Render list of items to delete.
+            Init set of items to delete
         """
 
-        def render_items (items) :
-            return (
-                html.ul(
-                    render_item(item) for item in items
-                ) if items else None
-            )
-
+        self.items = items
 
-        def render_item (item) :
-            return html.li(
-                html.input(type='hidden', name='items', value=item.id),
-                item.name,
-                render_items(item.children),
+    def render_items_list (self, name, items, visible=None) :
+        """
+            Render list of items to delete.
+
+                visible         - display list of items in addition the rendering the <input>'s
+        """
+
+        def render_items (items, visible) :
+            if not items :
+                # blank
+                return None
+
+            elif visible :
+                # nested list
+                return html.ul(
+                    render_item(item, True) for item in items
+                )
+
+            else :
+                # just the controls
+                return [render_item(item, False) for item in items]
+
+        def render_item (item, visible) :
+            # the form field
+            field = html.input(type='hidden', name='items', value=item.id),
+
+            if visible :
+                return html.li(
+                    field,
+
+                    item.name if visible else None,
+
+                    render_items(item.children, visible),
+                )
+            else :
+                # just the input
+                return field
+        
+        if visible :
+            # div with nested <li>s
+            return html.div(class_='value')(
+                render_items(items, True),
             )
+        else :
+            # just the <input>s
+            return render_items(items, False)
 
-        return html.div(class_='value')(
-            render_items(items),
-        )
-
-    def render (self, action, return_url) :
+    def render (self, legend=None, delete_action=None, confirm_action=None, return_url=None, item_listing=None) :
         """
             Render form with list of target items, and a confirm button
+                
+                legend              - form title
+                delete_action       - URL for initial confirm stage submit
+                confirm_action      - URL for final delete stage submit
+                reutrn_url          - URL for cancel button
+                item_listing        - display recursive item listing for confirmation
+
+            Supply either delete_action or confirm_action, but not both
         """
 
+        action = delete_action or confirm_action
+
         return html.form(action=action, method='POST')(
             html.fieldset(
-                html.legend(u"Poistettavat laitteet"),
+                html.legend(legend),
 
                 html.ol(
-                    self.render_form_field('items', u"Poistettavat laitteet", u"Kaikki listatut laitteet poistetaan inventaarista", (
-                        self.render_items_list('items', self.items)
-                    )),
+                    (
+                        # full UI field
+                        (self.render_form_field('items', u"Poistettavat laitteet", u"Kaikki listatut laitteet poistetaan inventaarista", (
+                            self.render_items_list('items', self.items, visible=True)
+                        ))) 
+
+                            if item_listing else 
+                        
+                        # raw field with just the <input>s
+                        (self.render_items_list('items', self.items, visible=False))
+                    ),
 
                     html.li(
-                        self.render_submit_button(u"Varmista", 'confirm'),
+                        self.render_submit_button(u"Poista") if delete_action else None,
+                        self.render_submit_button(u"Varmista", 'confirm') if confirm_action else None,
                         
-                        self.render_reset_button(u"Peruuta", return_url),
+                        self.render_reset_button(u"Peruuta", return_url) if return_url else None,
                     ),
                 )
             )
@@ -321,19 +353,59 @@
                 # re-render form
                 return
 
+    def render_subitems_table (self, subitems) :
+        """
+            Render listing of child items in this item
+        """
+            
+        return ItemTable(self).render(subitems, parent=self.item)
+        
+
+    def render_delete_form (self) :
+        """
+            Render delete form for this item
+        """
+
+        form = DeleteItemForm(self.session)
+        form.load([self.item])
+
+        return form.render(
+            legend          = u"Poistaminen",
+
+            delete_action  = self.url_for(DeleteItemView),
+
+            item_listing    = False,
+        )
+
     def render_content (self, id) :
         """
             View item's info
         """
+        
+        # ourselves
+        item = self.item
 
+        # items in this item
+        subitems = item.children
+        
         return (
-            html.h1(u"Laite #%d" % self.item.id),
+            html.h1("(#%d) %s" % (item.id, item.name)),
+
+            html.h3(
+                html.raw(u"Sijaitsee %s:ssa" % (
+                    html.a(href=self.url_for(ItemView, id=item.parent.id))(item.parent.name)
+                )),
+            ) if item.parent else None,
+            
+            self.render_subitems_table(subitems) if subitems else None,
 
             self.form.render(
                 action          = self.url_for(ItemView, id=id), 
                 return_url      = self.url_for(InventoryView),
-                delete_action   = self.url_for(DeleteItemView),
             ),
+
+            # delete form
+            self.render_delete_form(),
         )
 
 class NewItemView (PageHandler) :
@@ -435,9 +507,96 @@
     
     def render_content (self) :
         return (
-            self.form.render(action=self.url_for(DeleteItemView), return_url=self.url_for(InventoryView))
+            self.form.render(
+                legend          = u"Poistettavat laitteet",
+
+                confirm_action   = self.url_for(DeleteItemView),
+
+                return_url      = self.url_for(InventoryView),
+
+                item_listing    = True,
+            )
         )
 
+class ItemTable (object) :
+    """
+        Table of items
+    """
+
+    def __init__ (self, handler) :
+        """
+                handler         - the AppHandler we are running under, used for url_for etc.
+        """
+
+        self.handler = handler
+
+    def url_for (self, *args, **kwargs) :
+        """
+            Proxy to handler
+        """
+
+        return self.handler.url_for(*args, **kwargs)
+
+    def render (self, items, parent=None) :
+        """
+            Render table for given set of items. If parent is given, those items are assumed to be the children of that
+            item.
+        """
+
+        return html.table(
+            html.caption(
+                u"Kalustolistaus",
+                (
+                    html.a(href=self.url_for(ItemView, id=parent.id))(
+                        parent.name
+                    ) if parent else None
+                ),
+            ),
+        
+            html.thead(
+                html.tr(
+                    html.th(title) for title in (
+                        u"#ID",
+                        u"Case" if not parent else None,
+                        u"Nimi",
+                        u"Kuvaus",
+                        u"Määrä",
+                    ) if title
+                ),
+            ),
+
+            html.tbody(
+                html.tr(id=('item-%d' % item.id))(
+                    html.td(
+                        html.a(href=self.url_for(ItemView, id=item.id))(
+                            u'#%d' % item.id
+                        )
+                    ),
+
+                    html.td(
+                        html.a(href=self.url_for(ItemView, id=item.parent.id))(
+                            item.parent.name
+                        ) if item.parent else None
+                    ) if not parent else None,
+
+                    html.td(
+                        html.a(href=self.url_for(ItemView, id=item.id))(
+                            item.name
+                        )
+                    ),
+
+                    html.td(
+                        item.detail
+                    ),
+
+                    html.td(
+                        "%d kpl" % item.quantity if item.quantity else None
+                    ),
+                ) for item in items
+            )
+        )
+
+
 class InventoryView (PageHandler) :
     """
         Display overview of all items
@@ -454,52 +613,8 @@
 
         # listing of inventory items
         items = self.session.query(Item).order_by(Item.parent).all()
-
-        return html.table(
-            html.caption("Kalustolistaus"),
         
-            html.thead(
-                html.tr(
-                    html.th(title) for title in (
-                        u"#ID",
-                        u"Case",
-                        u"Nimi",
-                        u"Kuvaus",
-                        u"Määrä",
-                    )
-                ),
-            ),
-
-            html.tbody(
-                html.tr(id=('item-%d' % item.id))(
-                    html.td(
-                        html.a(href=self.url_for(ItemView, id=item.id))(
-                            u'#%d' % item.id
-                        )
-                    ),
-
-                    html.td(
-                        html.a(href=self.url_for(ItemView, id=item.parent.id))(
-                            item.parent.name
-                        ) if item.parent else None
-                    ),
-
-                    html.td(
-                        html.a(href=self.url_for(ItemView, id=item.id))(
-                            item.name
-                        )
-                    ),
-
-                    html.td(
-                        item.detail
-                    ),
-
-                    html.td(
-                        "%d kpl" % item.quantity if item.quantity else None
-                    ),
-                ) for item in items
-            )
-        )
+        return ItemTable(self).render(items)
 
     def render_item_form (self) :
         """