Reworked loan display to accommodate loan notes

Loans are no longer displayed as a unified table, but instead each loan
gets a "card" that contains the relevant data for the loan.

This has had a fairly major html/css re-work as a side effect. Most views are
now structured with two div-based columns so as to avoid the large blank areas
that pure grid can lead to when elements are very different in height.
This commit is contained in:
Erik Thuning 2025-03-18 13:39:48 +01:00
parent afb3020a34
commit c8e3ff0212
7 changed files with 1060 additions and 1108 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -38,18 +38,19 @@ class NewPage extends Page {
$this->fragments['tag']);
}
}
$out = replace(array('template' => $template),
$this->fragments['template_management']);
$out .= replace(array('id' => '',
'name' => '',
'brand' => '',
'serial' => '',
'invoice' => '',
'tags' => $tags,
'info' => $fields,
'label' => '',
'hidden' => 'hidden'),
$this->fragments['product_details']);
$out = replace(array('id' => '',
'name' => '',
'brand' => '',
'serial' => '',
'invoice' => '',
'tags' => $tags,
'info' => $fields,
'label' => '',
'label_hidden' => 'hidden',
'hidden' => 'hidden'),
$this->fragments['product_details']);
$out .= replace(array('template' => $template),
$this->fragments['template_management']);
return $out;
}
}

@ -233,10 +233,15 @@ abstract class Page extends Responder {
'page' => 'users'),
$this->fragments['item_link']);
}
$note = '';
$notes = $loan->get_notes();
$hidden = 'hidden';
if($notes) {
$hidden = '';
}
$misc = '';
if($status !== 'inactive_loan') {
$extend = format_date($loan->get_endtime());
$note = replace(array('id' => $product->get_id(),
$misc = replace(array('id' => $product->get_id(),
'end_new' => $extend),
$this->fragments['loan_extend_form']);
}
@ -251,11 +256,12 @@ abstract class Page extends Responder {
'start_date' => format_date($start),
'end_date' => format_date($end),
'initiator' => $initiator_name,
'note' => $note),
$this->fragments['user_loan_table_row']);
'hidden' => $hidden,
'notes' => $notes,
'misc' => $misc),
$this->fragments['user_loan_card']);
}
return replace(array('rows' => $rows),
$this->fragments['user_loan_table']);
return $rows;
}
final protected function build_seen_table($products, $inventory) {

@ -112,14 +112,18 @@ class ProductPage extends Page {
$rows = '';
foreach($history as $event) {
$status = $event->get_status();
$itemlink = 'Service';
$userlink = 'Service';
$start = $event->get_starttime();
$end = $event->get_returntime();
$notes = $event->get_notes();
$hidden = 'hidden';
if($notes) {
$hidden = '';
}
$initiator = $event->get_initiator();
$initiator_name = i18n('Unknown');
$initiator_link = i18n('Unknown');
if($initiator) {
$initiator_name = replace(
$initiator_link = replace(
array('id' => $initiator->get_id(),
'name' => $initiator->get_name(),
'page' => 'users'),
@ -129,7 +133,7 @@ class ProductPage extends Page {
if($event instanceof Loan) {
$user = $event->get_user();
$product = $event->get_product();
$itemlink = replace(array('id' => $user->get_id(),
$userlink = replace(array('id' => $user->get_id(),
'name' => $user->get_name(),
'page' => 'users'),
$this->fragments['item_link']);
@ -142,16 +146,16 @@ class ProductPage extends Page {
}
}
$rows .= replace(array('status' => $status,
'name' => $itemlink,
'name' => $userlink,
'start_date' => format_date($start),
'end_date' => format_date($end),
'initiator' => $initiator_name,
'initiator' => $initiator_link,
'hidden' => $hidden,
'notes' => $notes,
'misc' => $misc),
$this->fragments['product_loan_table_row']);
$this->fragments['product_loan_card']);
}
return replace(array('rows' => $rows),
$this->fragments['product_loan_table']);
return $rows;
}

103
style.css

@ -10,6 +10,18 @@ ul {
padding-left: 15px;
}
#contents {
display: grid;
grid-template-columns: [col] auto [col] auto [col];
grid-template-rows: auto [row] repeat(3, auto [row]);
grid-template-areas: "header header"
"first second"
"third fourth";
gap: 1rem;
justify-items: start;
align-items: start;
}
#message {
position: absolute;
top: 5px;
@ -54,7 +66,7 @@ ul {
}
input[type="text"].narrow {
width: 6em;
width: 6rem;
}
.hidden {
@ -65,6 +77,40 @@ form {
margin-bottom: 5px;
}
.column {
display: flex;
flex-direction: column;
align-items: stretch;
gap: 1rem;
}
.loan {
display: grid;
grid-template-columns: 5px 1fr;
grid-template-rows: auto auto;
grid-auto-rows: auto;
background-color: #d7e0eb;
margin-bottom: 1rem;
margin-top: 1rem;
}
.loan .status {
grid-row: 1 / -1;
grid-column: 1 / 2;
}
.loan .data {
grid-row: 1;
grid-column: 2;
}
.loan .misc {
grid-row: 2;
grid-column: 2;
justify-self: end;
padding: 2px 5px;
}
table {
border-collapse: collapse;
}
@ -76,31 +122,35 @@ td, th {
padding: 2px 5px;
}
td.available {
background-color: #a3a86b;
td.notes {
white-space: pre-wrap;
}
td.status, th.status {
.status {
width: 5px;
}
td.on_loan, td.active_loan {
.status.available {
background-color: #a3a86b;
}
.status.on_loan, .status.active_loan {
background-color: #acdee6;
}
td.inactive_loan {
.status.inactive_loan {
background-color: #cdebf0;
}
td.overdue, td.overdue_loan {
.status.overdue, .status.overdue_loan {
background-color: #d95e00;
}
td.discarded {
.status.discarded {
background-color: #a0a0a0;
}
td.service, td.active_service, td.inactive_service {
.status.service, .status.active_service, .status.inactive_service {
background-color: #e7e08d;
}
@ -142,15 +192,15 @@ input:disabled, textarea:disabled {
input[type="text"].newtag,
input[type="text"].newfield {
width: 11.5em;
width: 10.5rem;
}
tbody.fixedwidth > tr > td {
min-width: 11.5em;
min-width: 10.5rem;
}
input[type="text"].newtemplate {
width: 8em;
width: 8rem;
}
.minibutton {
@ -188,43 +238,14 @@ h1 {
grid-area: header;
}
#product-details {
grid-column: col 1 / col 2;
grid-row: row 1 / row 3;
}
#user-select {
grid-area: first;
}
#user-table {
grid-area: first;
}
#user-details {
grid-area: first;
}
#active-loans {
grid-area: third;
}
#inactive-loans {
grid-area: fourth;
}
#public-message {
grid-area: first / first / second / second;
}
#product-checkout {
grid-area: third;
}
#product-create {
grid-area: first;
}
#product-table {
grid-area: first;
}

@ -351,16 +351,3 @@ button:disabled, input[type="submit"]:disabled {
width: calc(100% - 8px);
}
}
#contents {
display: grid;
grid-template-columns: [col] auto [col] auto [col];
grid-template-rows: auto [row] repeat(3, auto [row]);
grid-template-areas: "header header"
"first second"
"third fourth"
"fifth sixth";
grid-gap: 1rem;
justify-items: start;
align-items: start;
}