3 Commits

Author SHA1 Message Date
Wrongecho
70216f97b9 Contacts API - Contact must be archived before deletion 2026-09-02 07:45:39 +00:00
johnnyq
9e8c4d002a Shorten Description, Text dark IP and make table smaller in IPs 2026-09-01 18:54:44 -04:00
johnnyq
0c690c4e51 Fix 3 Digit octet fix on IP address for IMask plugin 2026-09-01 18:24:46 -04:00
6 changed files with 31 additions and 35 deletions

View File

@@ -556,11 +556,6 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$asset_type = escapeHtml($row['asset_type']);
$asset_name = escapeHtml($row['asset_name']);
$asset_description = escapeHtml($row['asset_description']);
if ($asset_description) {
$asset_description_display = $asset_description;
} else {
$asset_description_display = "-";
}
$asset_make = escapeHtml($row['asset_make']);
$asset_model = escapeHtml($row['asset_model']);
$asset_serial = escapeHtml($row['asset_serial']);

View File

@@ -268,12 +268,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
$category_name = escapeHtml($row['category_name']);
$account_name = escapeHtml($row['account_name']);
$expense_account_id = intval($row['expense_account_id']);
$client_name = escapeHtml($row['client_name']);
if(empty($client_name)) {
$client_name_display = "-";
} else {
$client_name_display = $client_name;
}
$client_name = escapeHtml($row['client_name']) ?: '-';
$expense_client_id = intval($row['expense_client_id']);
if (empty($expense_receipt)) {
@@ -307,7 +302,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
<td><?= $vendor_name ?></td>
<td class="text-end font-monospace"><?= numfmt_format_currency($currency_format, $expense_amount, $expense_currency_code) ?></td>
<td><?= $account_name ?></td>
<td><?= $client_name_display ?></td>
<td><?= $client_name ?></td>
<td>
<div class="dropdown dropstart text-center">
<button class="btn btn-secondary btn-sm" type="button" data-bs-toggle="dropdown">

View File

@@ -224,7 +224,7 @@ if (mysqli_num_rows($sql) == 0) {
<form id="bulkActions" action="post.php" method="post">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<table class="table table-striped table-borderless table-hover mb-0">
<table class="table table-striped table-borderless table-hover table-sm mb-0">
<thead class="text-dark <?php if ($num_rows[0] == 0) { echo "d-none"; } ?>">
<tr>
<td class="checkbox-column border-end">
@@ -233,17 +233,17 @@ if (mysqli_num_rows($sql) == 0) {
</div>
</td>
<th>
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=ip_address&order=<?= $disp ?>">
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=ip_address&order=<?= $disp ?>">
IP Address <?php if ($sort == 'ip_address') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=ip_hostname&order=<?= $disp ?>">
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=ip_hostname&order=<?= $disp ?>">
Hostname <?php if ($sort == 'ip_hostname') { echo $order_icon; } ?>
</a>
</th>
<th>
<a class="text-secondary" href="?<?= $url_query_strings_sort ?>&sort=ip_description&order=<?= $disp ?>">
<a class="text-dark" href="?<?= $url_query_strings_sort ?>&sort=ip_description&order=<?= $disp ?>">
Description <?php if ($sort == 'ip_description') { echo $order_icon; } ?>
</a>
</th>
@@ -256,8 +256,8 @@ if (mysqli_num_rows($sql) == 0) {
while ($row = mysqli_fetch_assoc($sql_ips)) {
$ip_id = intval($row['ip_id']);
$ip_address = escapeHtml($row['ip_address']);
$ip_hostname = escapeHtml($row['ip_hostname']);
$ip_description = escapeHtml($row['ip_description']);
$ip_hostname = escapeHtml($row['ip_hostname']) ?: '-';
$ip_description = escapeHtml($row['ip_description']) ?: '-';
?>
<tr>

View File

@@ -232,12 +232,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
while ($row = mysqli_fetch_assoc($sql)) {
$product_id = intval($row['product_id']);
$product_name = escapeHtml($row['product_name']);
$product_description = escapeHtml($row['product_description']);
if (empty($product_description)) {
$product_description_display = "-";
} else {
$product_description_display = "<div style='white-space:pre-line'>$product_description</div>";
}
$product_description = escapeHtml($row['product_description']) ?: '-';
$product_qty = intval($row['product_qty']);
$product_code = escapeHtml($row['product_code']);
$product_location = escapeHtml($row['product_location']) ?: '-';
@@ -267,7 +262,7 @@ $num_rows = mysqli_fetch_row(mysqli_query($mysqli, "SELECT FOUND_ROWS()"));
</a>
</td>
<td><?= $category_name ?></td>
<td><?= $product_description_display ?></td>
<td><div style='white-space:pre-line'><?= $product_description ?></div></td>
<?php if ($type_filter == 'product') { ?>
<td><?= $product_qty ?></td>
<td><?= $product_location ?></td>

View File

@@ -12,10 +12,10 @@ $contact_id = intval($_POST['contact_id']);
$delete_count = false;
if (!empty($contact_id)) {
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT contact_name FROM contacts WHERE contact_id = $contact_id AND contact_client_id = $client_id LIMIT 1"));
$row = mysqli_fetch_assoc(mysqli_query($mysqli, "SELECT contact_name FROM contacts WHERE contact_id = $contact_id AND contact_client_id = $client_id AND contact_archived_at IS NOT NULL LIMIT 1"));
$contact_name = escapeSql($row['contact_name'] ?? '');
$delete_sql = mysqli_query($mysqli, "DELETE FROM contacts WHERE contact_id = $contact_id AND contact_client_id = $client_id LIMIT 1");
$delete_sql = mysqli_query($mysqli, "DELETE FROM contacts WHERE contact_id = $contact_id AND contact_client_id = $client_id AND contact_archived_at IS NOT NULL LIMIT 1");
// Check delete & get affected rows
if ($delete_sql && !empty($contact_name)) {

View File

@@ -568,15 +568,26 @@ function itflowInit() {
el.dataset.imaskReady = '1';
var spec = el.getAttribute('data-inputmask') || '';
if (spec.indexOf('ip') !== -1) {
// A pattern mask built from MaskedRange blocks will not advance past the dot
// until the block reaches its maxLength, so 10.0.0.1 had to be entered as
// 010.000.000.001. A regex mask has no per-block completeness rule - it tests
// the whole value on every keystroke, so partial input like "10.0." is valid on
// its own. Octets are still bounded to 0-255 and leading zeros are still
// accepted, matching what jquery.inputmask's 'ip' alias allowed.
//
// interface_ip / asset_ip are varchar(200) and hold free text as well - 'DHCP'
// is written there by the checkbox on these same modals. Masking a value like
// that would strip it to nothing the moment the modal opened, so anything not
// made of digits and dots is left unmasked instead.
if (el.value && !/^[\d.]*$/.test(el.value)) {
return;
}
var octet = '(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)';
var octet4 = octet + '?';
var octet3 = '(' + octet + '(\\.' + octet4 + ')?)?';
var octet2 = '(' + octet + '(\\.' + octet3 + ')?)?';
IMask(el, {
mask: 'a.b.c.d',
blocks: {
a: { mask: IMask.MaskedRange, from: 0, to: 255 },
b: { mask: IMask.MaskedRange, from: 0, to: 255 },
c: { mask: IMask.MaskedRange, from: 0, to: 255 },
d: { mask: IMask.MaskedRange, from: 0, to: 255 }
},
lazy: true
mask: new RegExp('^(' + octet + '(\\.' + octet2 + ')?)?$')
});
} else if (spec.indexOf('mac') !== -1) {
IMask(el, {