From 8502fbf0a15025204d3b9384fc978ef0d09b3914 Mon Sep 17 00:00:00 2001
From: Erik Thuning <boooink@gmail.com>
Date: Tue, 1 Mar 2022 16:33:00 +0100
Subject: [PATCH] Initial implementation of search result detail output

---
 html/fragments.html     |  22 ++++++++-
 include/NewPage.php     |   2 +-
 include/Page.php        | 102 +++++++++++++++++++++++++---------------
 include/ProductPage.php |   6 +--
 include/SearchPage.php  |  31 +++++-------
 style.css               |  13 +++++
 6 files changed, 113 insertions(+), 63 deletions(-)

diff --git a/html/fragments.html b/html/fragments.html
index 409dc08..ee6f993 100644
--- a/html/fragments.html
+++ b/html/fragments.html
@@ -105,6 +105,26 @@
   </td>
 </tr>
 
+¤¤ product_detail_row ¤¤
+<tr>
+  <td class="status ¤status¤">
+  </td>
+  <td colspan="3">
+    <div class="minitable">
+      ¤details¤
+    </div>
+  </td>
+</tr>
+
+¤¤ product_detail ¤¤
+<span class="minitable_name">
+  ¤name¤
+</span>
+<span class="minitable_value">
+  ¤value¤
+</span>
+<br/>
+
 ¤¤ template_management ¤¤
 <div>
   <h2>Mallar</h2>
@@ -133,7 +153,7 @@
   </form>
 </div>
 
-¤¤ product_details ¤¤
+¤¤ product_form ¤¤
 <div id="product-details">
   <h2>Artikeldata</h2>
   <form id="product-data"
diff --git a/include/NewPage.php b/include/NewPage.php
index ffe6a48..dd0e15e 100644
--- a/include/NewPage.php
+++ b/include/NewPage.php
@@ -49,7 +49,7 @@ class NewPage extends Page {
                               'info' => $fields,
                               'label' => '',
                               'hidden' => 'hidden'),
-                        $this->fragments['product_details']);
+                        $this->fragments['product_form']);
         return $out;
     }
 }
diff --git a/include/Page.php b/include/Page.php
index 696bed7..8a79123 100644
--- a/include/Page.php
+++ b/include/Page.php
@@ -128,48 +128,72 @@ abstract class Page extends Responder {
                        $this->fragments['user_table']);
     }
 
+    final protected function build_product_row($product, $matches = null) {
+        $prodlink = replace(array('id' => $product->get_id(),
+                                  'name' => $product->get_name(),
+                                  'page' => 'products'),
+                            $this->fragments['item_link']);
+        $note = 'Tillgänglig';
+        $status = $product->get_status();
+        switch($status) {
+        case 'discarded':
+            $discarded = format_date($product->get_discardtime());
+            $note = 'Skrotad '.$discarded;
+            break;
+        case 'service':
+            $service = $product->get_active_service();
+            $note = 'På service sedan '
+                  .format_date($service->get_starttime());
+            break;
+        case 'on_loan':
+        case 'overdue':
+            $loan = $product->get_active_loan();
+            $user = $loan->get_user();
+            $replacements = array('name' => $user->get_displayname($this->ldap),
+                                  'id'   => $user->get_id(),
+                                  'page' => 'users');
+            $userlink = replace($replacements,
+                                $this->fragments['item_link']);
+            $note = 'Utlånad till '.$userlink;
+            if($loan->is_overdue()) {
+                $note .= ', försenad';
+            } else {
+                $note .= ', slutdatum '
+                      .format_date($loan->get_endtime());
+            }
+            break;
+        }
+        $out = replace(array('status'    => $status,
+                             'item_link' => $prodlink,
+                             'serial'    => $product->get_serial(),
+                             'note'      => $note),
+                       $this->fragments['product_row']);
+        if($matches) {
+            $details = $this->build_product_details($product, $matches);
+            $out .= replace(array('status'  => $status,
+                                  'details' => $details),
+                            $this->fragments['product_detail_row']);
+        }
+        return $out;
+    }
+
+    final protected function build_product_details($product, $matches) {
+        $out = '';
+        foreach($matches as $name => $value) {
+            if(is_array($value)) {
+                $value = implode(', ', $value);
+            }
+            $out .= replace(array('name'   => ucfirst($name),
+                                  'value'  => $value),
+                            $this->fragments['product_detail']);
+        }
+        return $out;
+    }
+
     final protected function build_product_table($products) {
         $rows = '';
         foreach($products as $product) {
-            $prodlink = replace(array('id' => $product->get_id(),
-                                      'name' => $product->get_name(),
-                                      'page' => 'products'),
-                                $this->fragments['item_link']);
-            $note = 'Tillgänglig';
-            $status = $product->get_status();
-            switch($status) {
-                case 'discarded':
-                    $discarded = format_date($product->get_discardtime());
-                    $note = 'Skrotad '.$discarded;
-                    break;
-                case 'service':
-                    $service = $product->get_active_service();
-                    $note = 'På service sedan '
-                                .format_date($service->get_starttime());
-                    break;
-                case 'on_loan':
-                case 'overdue':
-                    $loan = $product->get_active_loan();
-                    $user = $loan->get_user();
-                    $replacements = array('name' => $user->get_displayname($this->ldap),
-                                          'id'   => $user->get_id(),
-                                          'page' => 'users');
-                    $userlink = replace($replacements,
-                                        $this->fragments['item_link']);
-                    $note = 'Utlånad till '.$userlink;
-                    if($loan->is_overdue()) {
-                        $note .= ', försenad';
-                    } else {
-                        $note .= ', slutdatum '
-                                .format_date($loan->get_endtime());
-                    }
-                    break;
-            }
-            $rows .= replace(array('status' => $status,
-                                   'item_link' => $prodlink,
-                                   'serial' => $product->get_serial(),
-                                   'note' => $note),
-                             $this->fragments['product_row']);
+            $rows .= $this->build_product_row($product);
         }
         return replace(array('rows' => $rows),
                        $this->fragments['product_table']);
diff --git a/include/ProductPage.php b/include/ProductPage.php
index e385f62..afb25b1 100644
--- a/include/ProductPage.php
+++ b/include/ProductPage.php
@@ -38,12 +38,12 @@ class ProductPage extends Page {
                               $this->fragments['product_page']));
                 break;
             case 'show':
-                print($this->build_product_details());
+                print($this->build_product_form());
                 break;
         }
     }
     
-    private function build_product_details() {
+    private function build_product_form() {
         $info = '';
         foreach($this->product->get_info() as $key => $value) {
             $info .= replace(array('name' => ucfirst($key),
@@ -81,7 +81,7 @@ class ProductPage extends Page {
                 $fields['service'] = 'Avsluta service';
             }
         }
-        return replace($fields, $this->fragments['product_details']);
+        return replace($fields, $this->fragments['product_form']);
     }
 
     private function build_history_table($history) {
diff --git a/include/SearchPage.php b/include/SearchPage.php
index 2e9340b..cfe8c4a 100644
--- a/include/SearchPage.php
+++ b/include/SearchPage.php
@@ -182,47 +182,40 @@ class SearchPage extends Page {
                                   $this->fragments['search_term']);
             }
         }
-        $products = 'Inga artiklar hittade.';
+        $prod_table = 'Inga artiklar hittade.';
         if($this->product_hits) {
             $products = '';
             foreach($this->product_hits as $hit) {
-                $products .= $this->render_product($hit[0], $hit[1]);
+                $products .= $this->build_product_row($hit[0], $hit[1]);
             }
+            $prod_table = replace(array('rows' => $products),
+                                  $this->fragments['product_table']);
         }
-        $users = 'Inga användare hittade.';
+        $user_table = 'Inga användare hittade.';
         if($this->user_hits) {
             $users = '';
             foreach($this->user_hits as $hit) {
                 $users .= $this->render_user($hit[0], $hit[1]);
             }
+            $user_table = replace(array('rows' => $users),
+                                  $this->fragments['user_table']);
         }
+
         print(replace(array('terms' => $terms,
                             'hidden' => $hidden,
-                            'product_results' => $products,
-                            'user_results' => $users),
+                            'product_results' => $prod_table,
+                            'user_results' => $user_table),
                       $this->fragments['search_form']));
     }
 
-    private function render_product($product, $matches) {
-        $link = replace(array('id' => $product->get_id(),
-                              'name' => $product->get_name(),
-                              'page' => 'products'),
-                        $this->fragments['item_link']);
-
-        $data =  print_r($matches, true);
-        
-        return $link . '<br/>'
-             . $data . '<br/>';
-    }
-
     private function render_user($user, $matches) {
         $link = replace(array('id' => $user->get_id(),
                               'name' => $user->get_name(),
                               'page' => 'users'),
                         $this->fragments['item_link']);
 
-        $data =  print_r($matches, true);
-        
+        $data = print_r($matches, true);
+
         return $link . '<br/>'
              . $data . '<br/>';
     }
diff --git a/style.css b/style.css
index c1ec303..76a9990 100644
--- a/style.css
+++ b/style.css
@@ -117,6 +117,19 @@ thead th:nth-last-child(-n+2) {
    word-break: break-word;
 }
 
+.minitable {
+    display: grid;
+    grid-template-columns: [col] auto [col] auto [col] auto [col];
+}
+
+.minitable_name {
+    grid-column: col 1;
+}
+
+.minitable_value {
+    grid-column: col 2;
+}
+
 input:disabled, textarea:disabled {
     background-color: #ededed;
 }