Skip to content

Improve Pending Match UX Attribute Display (CO-2233) #48

Merged
merged 3 commits into from
Oct 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/resources/locales/en_US/default.po
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,18 @@ msgstr "Filter"
msgid "match.op.go"
msgstr "Go"

msgid "match.op.highlight"
msgstr "Highlight:"

msgid "match.op.highlight.both"
msgstr "both"

msgid "match.op.highlight.differences"
msgstr "differences"

msgid "match.op.highlight.matches"
msgstr "matches"

msgid "match.op.last"
msgstr "Last"

Expand Down
111 changes: 88 additions & 23 deletions app/templates/Matchgrids/reconcile.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,40 @@

use \App\Lib\Util\ArrayUtil;

// extract the attribute field names into a simple array
// Ensure that the candidates array is sorted by referenceid so we can easily match up identical adjacent referenceids.
// Note that this will retain the "New" record in first position (because the referenceid is empty).
array_multisort(array_column($vv_candidates, 'referenceid'), SORT_ASC, $vv_candidates);

// Generate the referenceid label output by creating a simple array that contains the unique referenceid values
// along with the count of how many occurrences each has in the $vv_candidates structure (for colspan).
// Note that we must assign an empty string when encountering a NULL referenceid because array_count_values
// can only work on integers or strings.
$refIds = array();
foreach ($vv_candidates as $candidate) {
$refIds[] = !empty($candidate['referenceid']) ? $candidate['referenceid'] : '';
}
$refIds = array_count_values($refIds);

// Extract the attribute field names into a simple array.
$fieldNames = array();
foreach ($vv_candidates as $candidate) {
$fieldNames = array_keys($candidate);
break;
}

// remove "referenceid" - it is given special treatment and should not be included in our structure
// Remove "referenceid" from the field names - it is given special treatment and should not be included in our
// attributes structure.
array_splice($fieldNames, array_search('referenceid',$fieldNames), 1);

// build the data for the candidates into a structure for generating the view:
// Build the data for the candidates into a structure for generating the view:
// attribute field name | attribute values | do the values match?
$canAttr = array();
for($i = 0; $i < count($fieldNames); $i++) {

// put the field name in the first column
// Put the field name in the first column.
$canAttr[$i][0] = $fieldNames[$i];

// put all the values for the current attribute into the second column
// Put all the values for the current attribute into the second column.
$canAttr[$i][1] = array();
foreach($vv_candidates as $c) {
foreach($c as $key => $val) {
Expand All @@ -60,25 +75,48 @@
// Test for content and equality between the row's attribute values and
// set the third "match?" column to true (1) if non-empty equality found
$canAttr[$i][2] = !empty($canAttr[$i][1][0]) && count(ArrayUtil::array_iunique($canAttr[$i][1])) === 1 ? 1 : 0;

}

// Move request_time and resolution_time to the bottom
$tempArr = [];
foreach ($canAttr as $key => $val) {
if($val[0] == 'request_time' || $val[0] == 'resolution_time') {
$tempArr[] = $val;
unset($canAttr[$key]);
}
}
$canAttr = array_merge($canAttr, $tempArr);
?>

<div class="titleNavContainer">
<div class="pageTitle">
<h1><?= __('match.op.reconcile.requests'); ?></h1>
</div>
</div>

<div class="view-controls">
<span class="view-controls-title"><?= __('match.op.highlight'); ?></span>
<div class="form-check form-check-inline">
<input id="view-mode-diff" class="form-check-input" name="view-mode" type="radio" checked>
<label for="view-mode-diff" class="form-check-label"><?= __('match.op.highlight.differences'); ?></label>
</div>
<div class="form-check form-check-inline">
<input id="view-mode-match" class="form-check-input" name="view-mode" type="radio">
<label for="view-mode-match" class="form-check-label"><?= __('match.op.highlight.matches'); ?></label>
</div>
<div class="form-check form-check-inline">
<input id="view-mode-both" class="form-check-input" name="view-mode" type="radio">
<label for="view-mode-both" class="form-check-label"><?= __('match.op.highlight.both'); ?></label>
</div>
</div>
<div id="reconcile-table-container" class="table-container">
<table id="reconcile-table" class="side-by-side">
<table id="reconcile-table" class="side-by-side view-mode-diff">
<thead>
<tr>
<td class="empty"></td>
<?php $i = 0; // note that we'll skip the first, "new" record. ?>
<?php foreach($vv_candidates as $c): ?>
<th class="col-names" scope="col">
<?= !empty($c['referenceid']) ? __('match.fd.suggestion.a',[$i]) : __('match.fd.new_record'); ?>
<?php $i = 0; // used to print the suggestion number in the output. ?>
<?php foreach($refIds as $refId => $refIdCount): ?>
<th class="col-names" scope="col" colspan="<?= $refIdCount; ?>">
<?= !empty($refId) ? __('match.fd.suggestion.a',[$i]) : __('match.fd.new_record'); ?>
<?php $i++; ?>
</th>
<?php endforeach; ?>
Expand All @@ -90,9 +128,9 @@
<th class="attr-title" scope="row">
<?= __('match.fd.referenceid', [99]); ?>
</th>
<?php foreach($vv_candidates as $c): ?>
<td class="reference-ids">
<?= !empty($c['referenceid']) ? $c['referenceid'] : __('match.op.new'); ?>
<?php foreach($refIds as $refId => $refIdCount): ?>
<td class="reference-ids" colspan="<?= $refIdCount; ?>">
<?= !empty($refId) ? $refId : __('match.op.new'); ?>
</td>
<?php endforeach; ?>
</tr>
Expand All @@ -101,16 +139,16 @@
<th class="attr-title" scope="row">
<?= __('match.fd.action'); ?>
</th>
<?php foreach($vv_candidates as $c): ?>
<td class="reconcile-actions">
<?php foreach($refIds as $refId => $refIdCount): ?>
<td class="reconcile-actions" colspan="<?= $refIdCount; ?>">
<?=
$this->Form->postLink(__('match.op.reconcile.' . (!empty($c['referenceid']) ? 'assign' : 'generate')),
$this->Form->postLink(__('match.op.reconcile.' . (!empty($refId) ? 'assign' : 'generate')),
['action' => 'reconcile',
$vv_cur_mg->id],
['data' => [
'rowid' => $vv_request['id'],
// Default value needs to be the literal string "new" and not a localized text string
'referenceid' => (!empty($c['referenceid']) ? $c['referenceid'] : 'new')
'referenceid' => (!empty($refId) ? $refId : 'new')
],
'confirm' => __('match.op.assign.confirm'),
'class' => 'btn btn-primary nospin']);
Expand All @@ -120,12 +158,29 @@
</tr>
<!-- All other attributes -->
<?php for($i = 0; $i < count($canAttr); $i++): ?>
<?php $matchClass = $canAttr[$i][2] ? ' class="match"' : ''; ?>
<tr<?= $matchClass ?>>
<?php
$atr = $canAttr[$i][0];
// set the row css class
// (attribute name + standard, diff, or match)
$matchClass = 'matr-' . $atr;
if(
$atr == 'id'
|| $atr == 'sor'
|| $atr == 'sorid'
|| $atr == 'request_time'
|| $atr == 'resolution_time'
) {
$matchClass .= ' standard';
} else {
$matchClass .= ' defined-attr';
$matchClass .= ($canAttr[$i][2] ? ' match' : ' diff');
}
?>
<tr class="<?= $matchClass ?>">
<th class="attr-title" scope="row"><?= $canAttr[$i][0] ?></th>
<?php foreach($canAttr[$i][1] as $key => $val): ?>
<td>
<?php if($canAttr[$i][0] == 'id'): ?>
<?php if($atr == 'id'): ?>
<?= $this->Html->link(
$val,
['controller' => 'matchgrid-records',
Expand All @@ -141,4 +196,14 @@
<?php endfor; ?>
</tbody>
</table>
</div>
</div>

<script>
function js_local_onload() {
// Handle display-mode switching
$('.view-controls input').click(function () {
// Remove existing view-mode classes and add the new class equal to the view-controls switch ID
$('#reconcile-table').removeClass('view-mode-diff view-mode-match view-mode-both').addClass($(this).attr('id'));
});
}
</script>
26 changes: 25 additions & 1 deletion app/webroot/css/co-base.css
Original file line number Diff line number Diff line change
Expand Up @@ -694,9 +694,33 @@ body.logged-in #top-menu {
#reconcile-table tr:nth-child(2n+1) td {
background-color: var(--cmg-color-white);
}
#reconcile-table tr.match td {
#reconcile-table.view-mode-match tr.match td,
#reconcile-table.view-mode-both tr.match td {
background-color: var(--cmg-color-green-003);
}
#reconcile-table.view-mode-diff tr.diff td,
#reconcile-table.view-mode-both tr.diff td {
background-color: var(--cmg-color-yellow-003);
}
#reconcile-table tr.defined-attr th {
background-color: var(--cmg-color-lightgray-001);
border-left: 4px solid var(--cmg-color-lightgray-007);
}
#reconcile-table tr.defined-attr td:last-child {
border-right: 2px solid var(--cmg-color-lightgray-007);
}
#reconcile-table tr.matr-sorid th,
#reconcile-table tr.matr-sorid td {
border-bottom: 2px solid var(--cmg-color-lightgray-007);
}
#reconcile-table tr.matr-request_time th,
#reconcile-table tr.matr-request_time td {
border-top: 2px solid var(--cmg-color-lightgray-007);
}
/* view-controls */
.view-controls-title {
margin-right: 1em;
}
/* MATCHGRID MANAGEMENT */
#matchgrid-management {
padding: 0;
Expand Down
2 changes: 1 addition & 1 deletion app/webroot/css/co-color.css
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@

--cmg-color-yellow-001: #f5f5bb; /* yellow warning */
--cmg-color-yellow-002: #fbec88; /* infobox informational area */
--cmg-color-yellow-003: #ffd; /* forms: focused input */
--cmg-color-yellow-003: #ffd; /* forms: focused input; diffing fields for reconciliation */

--cmg-color-red-001: #fcc; /* red warning */
--cmg-color-red-002: #c00; /* forms: error icons */
Expand Down