364 lines
13 KiB
PHP
364 lines
13 KiB
PHP
<?php
|
||
/**
|
||
* @api-readonly
|
||
* Returns column history comments
|
||
*/
|
||
use App\Models\ColumnComment;
|
||
use App\Models\User;
|
||
use Carbon\Carbon;
|
||
use Carbon\CarbonInterval;
|
||
|
||
$id = get("id");
|
||
$table = get("table");
|
||
$columnName = get("column");
|
||
|
||
// Get comments from our new table
|
||
$users = User::all();
|
||
$comments = ColumnComment::where('table_name', $table)
|
||
->where('record_id', $id)
|
||
->where('column_name', $columnName)
|
||
->orderBy('created_at', 'DESC')
|
||
->get();
|
||
|
||
$weldLogEditInfo = null;
|
||
$weldLogInfoMessages = [];
|
||
$showWeldLogTimer = ($table === 'weld_logs' && $columnName === 'welding_date');
|
||
|
||
if ($showWeldLogTimer) {
|
||
$latestWeldingDateComment = $comments->first(function ($comment) {
|
||
return stripos($comment->comment ?? '', 'welding date set') !== false;
|
||
});
|
||
|
||
$limitHours = (float) setting('weld_log_edit_time_limit');
|
||
$exceptLevelsRaw = setting('weld_log_edit_time_limit_except_levels');
|
||
$exceptLevels = $exceptLevelsRaw ? j($exceptLevelsRaw) : [];
|
||
if (!is_array($exceptLevels)) {
|
||
$exceptLevels = [];
|
||
}
|
||
|
||
$currentUserLevel = optional(u())->level;
|
||
$isExcept = $currentUserLevel && in_array($currentUserLevel, $exceptLevels);
|
||
if ($isExcept) {
|
||
$weldLogInfoMessages[] = "Your level is excluded from the weld log edit time limit.";
|
||
}
|
||
|
||
if ($latestWeldingDateComment && $limitHours > 0) {
|
||
$commentTime = Carbon::parse($latestWeldingDateComment->created_at);
|
||
$expiresAt = $commentTime->copy()->addHours($limitHours);
|
||
$now = Carbon::now();
|
||
$totalSeconds = (int) ($limitHours * 3600);
|
||
$secondsLeft = $now->diffInSeconds($expiresAt, false);
|
||
$isEditable = $secondsLeft > 0;
|
||
$secondsLeft = max(0, $secondsLeft);
|
||
$elapsedSeconds = max(0, $totalSeconds - $secondsLeft);
|
||
$percent = $totalSeconds > 0 ? round(($elapsedSeconds / $totalSeconds) * 100, 1) : 100;
|
||
$interval = CarbonInterval::seconds($secondsLeft)->cascade();
|
||
|
||
$weldLogEditInfo = [
|
||
'isEditable' => $isEditable,
|
||
'secondsLeft' => $secondsLeft,
|
||
'humanLeft' => $isEditable ? $interval->forHumans(['short' => true, 'parts' => 2]) : '0 minutes',
|
||
'limitHours' => $limitHours,
|
||
'percent' => min(100, max(0, $percent)),
|
||
'expiresAt' => $expiresAt,
|
||
'commentTime' => $commentTime,
|
||
'exceptLevels' => $exceptLevels,
|
||
];
|
||
} elseif ($limitHours > 0) {
|
||
$weldLogInfoMessages[] = "No recent welding date change was found to calculate the countdown.";
|
||
}
|
||
}
|
||
|
||
// Convert comments to JSON for DataGrid
|
||
$commentsJson = json_encode($comments);
|
||
// Convert users to a lookup object for DataGrid
|
||
$usersLookup = [];
|
||
foreach ($users as $user) {
|
||
$usersLookup[$user->id] = $user->name;
|
||
}
|
||
$usersJson = json_encode($usersLookup);
|
||
|
||
if($comments->count() > 0 || true)
|
||
{
|
||
?>
|
||
<?php if ($showWeldLogTimer): ?>
|
||
<div class="alert alert-info">
|
||
<?php if ($weldLogEditInfo): ?>
|
||
<div class="d-flex flex-column flex-md-row align-items-md-center justify-content-between">
|
||
<div>
|
||
<div><strong>Status:</strong> <?php echo $weldLogEditInfo['isEditable'] ? 'Currently editable' : 'Currently not editable'; ?></div>
|
||
<div><strong>Remaining Time:</strong> <?php echo $weldLogEditInfo['isEditable'] ? $weldLogEditInfo['humanLeft'] : 'Expired'; ?> (limit: <?php echo $weldLogEditInfo['limitHours']; ?> hours)</div>
|
||
<div><strong>Expires At:</strong> <?php echo $weldLogEditInfo['expiresAt']->format('d.m.Y H:i'); ?></div>
|
||
<?php if (!empty($weldLogEditInfo['exceptLevels'])): ?>
|
||
<div><small>Except Levels: <?php echo implode(', ', $weldLogEditInfo['exceptLevels']); ?></small></div>
|
||
<?php endif; ?>
|
||
</div>
|
||
<div class="flex-grow-1 w-100 w-md-auto mt-3 mt-md-0">
|
||
<div class="progress" style="height: 20px;">
|
||
<div
|
||
class="progress-bar <?php echo $weldLogEditInfo['isEditable'] ? 'bg-success' : 'bg-danger'; ?>"
|
||
role="progressbar"
|
||
style="width: <?php echo $weldLogEditInfo['percent']; ?>%;"
|
||
aria-valuenow="<?php echo $weldLogEditInfo['percent']; ?>"
|
||
aria-valuemin="0"
|
||
aria-valuemax="100">
|
||
<?php echo $weldLogEditInfo['percent']; ?>%
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php endif; ?>
|
||
<?php
|
||
if (!$weldLogEditInfo && empty($weldLogInfoMessages)) {
|
||
$weldLogInfoMessages[] = 'Weld log edit time limit is not configured.';
|
||
}
|
||
?>
|
||
<?php if (!empty($weldLogInfoMessages)): ?>
|
||
<div class="mt-3">
|
||
<?php foreach ($weldLogInfoMessages as $infoMessage): ?>
|
||
<div><strong>Info:</strong> <?php echo $infoMessage; ?></div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
<div class="card mb-3">
|
||
<div class="card-header">
|
||
<h5>
|
||
<span class="badge badge-primary">{{e2($table)}}</span> /
|
||
<span class="badge badge-secondary">{{e2($id)}}</span> /
|
||
<span class="badge badge-success">{{e2($columnName)}}</span>
|
||
<span class="badge badge-default">{{e2("Add Comment")}}</span>
|
||
</h5>
|
||
</div>
|
||
<div class="card-body">
|
||
<form id="columnCommentForm" method="post">
|
||
@csrf
|
||
<input type="hidden" name="table_name" value="<?php echo $table; ?>">
|
||
<input type="hidden" name="record_id" value="<?php echo $id; ?>">
|
||
<input type="hidden" name="column_name" value="<?php echo $columnName; ?>">
|
||
<input type="hidden" name="column_value" value="">
|
||
|
||
<div class="form-group">
|
||
<label for="comment">{{e2("Your Comment")}}</label>
|
||
<textarea class="form-control" id="comment" name="comment" rows="3" required></textarea>
|
||
</div>
|
||
|
||
<button type="submit" class="btn btn-primary">{{e2("Submit Comment")}}</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card fullsize-grid">
|
||
<div class="card-header">
|
||
<h5>{{e2("Comments History")}}</h5>
|
||
</div>
|
||
<div class="card-body p-0">
|
||
<!-- DevExtreme DataGrid container -->
|
||
<div id="commentsDataGrid" style="width: 100%;"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<?php
|
||
|
||
} else {
|
||
?>
|
||
<div class="alert alert-info">{{e2("No Comments Found")}}</div>
|
||
<?php
|
||
}
|
||
|
||
// Add JS for form submission
|
||
?>
|
||
|
||
<style>
|
||
/* DataGrid için stil ayarları */
|
||
.dx-datagrid {
|
||
min-height: 500px;
|
||
}
|
||
|
||
/* Card gövdesi padding kaldırma */
|
||
.card-body.p-0 {
|
||
padding: 0 !important;
|
||
}
|
||
|
||
/* Card kendisi için margin ayarları */
|
||
.card.fullsize-grid {
|
||
margin-bottom: 0 !important;
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
$(function() {
|
||
// Format date for DataGrid
|
||
function formatDate(dateString) {
|
||
const date = new Date(dateString);
|
||
return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
|
||
}
|
||
|
||
// Users lookup table from server
|
||
const usersLookup = <?php echo $usersJson; ?>;
|
||
|
||
// Format user information
|
||
function formatUser(userId) {
|
||
return usersLookup[userId] || 'Unknown';
|
||
}
|
||
|
||
// Calculate grid height - responsive approach
|
||
function calculateGridHeight() {
|
||
// Minimum yükseklik 500px, aksi takdirde pencere yüksekliğinin %70'i
|
||
return Math.max(500, window.innerHeight * 0.7);
|
||
}
|
||
|
||
// Initialize DataGrid with comments data
|
||
const comments = <?php echo $commentsJson; ?>;
|
||
|
||
const dataGrid = $("#commentsDataGrid").dxDataGrid({
|
||
dataSource: comments,
|
||
showBorders: true,
|
||
height: calculateGridHeight(),
|
||
width: "100%",
|
||
filterRow: {
|
||
visible: true,
|
||
applyFilter: "auto"
|
||
},
|
||
searchPanel: {
|
||
visible: true,
|
||
width: 240,
|
||
placeholder: "Search..."
|
||
},
|
||
headerFilter: {
|
||
visible: true
|
||
},
|
||
grouping: {
|
||
autoExpandAll: false
|
||
},
|
||
paging: {
|
||
pageSize: 10
|
||
},
|
||
pager: {
|
||
showPageSizeSelector: true,
|
||
allowedPageSizes: [5, 10, 20, 50],
|
||
showInfo: true
|
||
},
|
||
columnAutoWidth: true,
|
||
columns: [
|
||
{
|
||
dataField: "created_at",
|
||
caption: "Date",
|
||
dataType: "datetime",
|
||
format: "dd.MM.yyyy HH:mm",
|
||
sortOrder: "desc",
|
||
width: 160
|
||
},
|
||
{
|
||
dataField: "comment",
|
||
caption: "Comment",
|
||
dataType: "string",
|
||
width: 350
|
||
},
|
||
{
|
||
dataField: "column_value",
|
||
caption: "Value at Comment Time",
|
||
dataType: "string",
|
||
width: 200
|
||
},
|
||
{
|
||
dataField: "user_id",
|
||
caption: "User",
|
||
lookup: {
|
||
dataSource: Object.entries(usersLookup).map(([id, name]) => ({ id: parseInt(id), name: name })),
|
||
displayExpr: "name",
|
||
valueExpr: "id"
|
||
},
|
||
width: 150
|
||
},
|
||
{
|
||
dataField: "ip_address",
|
||
caption: "IP Address",
|
||
dataType: "string",
|
||
width: 120
|
||
}
|
||
],
|
||
export: {
|
||
enabled: true,
|
||
allowExportSelectedData: true
|
||
},
|
||
onContentReady: function(e) {
|
||
if(comments.length === 0) {
|
||
e.component.option("noDataText", "No comments found");
|
||
}
|
||
}
|
||
}).dxDataGrid("instance");
|
||
|
||
// Pencere yeniden boyutlandırıldığında grid yüksekliğini güncelle
|
||
$(window).on("resize", function() {
|
||
dataGrid.option("height", calculateGridHeight());
|
||
});
|
||
|
||
// Form submission handler
|
||
$('#columnCommentForm').submit(function(e) {
|
||
e.preventDefault();
|
||
|
||
$.ajax({
|
||
url: '<?php echo url('api/column-comment'); ?>',
|
||
type: 'POST',
|
||
data: $(this).serialize(),
|
||
success: function(response) {
|
||
if(response.success) {
|
||
// Show success message with SweetAlert
|
||
Swal.fire({
|
||
icon: 'success',
|
||
title: 'Success!',
|
||
text: 'Your comment has been added successfully.',
|
||
confirmButtonText: 'OK'
|
||
}).then((result) => {
|
||
// After alert is closed, refresh the content
|
||
refreshComments();
|
||
});
|
||
|
||
// Clear the form
|
||
$('#comment').val('');
|
||
} else {
|
||
Swal.fire({
|
||
icon: 'error',
|
||
title: 'Error!',
|
||
text: response.message || 'Failed to add comment.',
|
||
confirmButtonText: 'OK'
|
||
});
|
||
}
|
||
},
|
||
error: function(xhr) {
|
||
Swal.fire({
|
||
icon: 'error',
|
||
title: 'Error!',
|
||
text: 'An error occurred while processing your request.',
|
||
confirmButtonText: 'OK'
|
||
});
|
||
}
|
||
});
|
||
});
|
||
|
||
// Function to refresh comments
|
||
function refreshComments() {
|
||
$.ajax({
|
||
url: '<?php echo url('admin-ajax/column-history?column=' . $columnName . '&id=' . $id . '&table=' . $table); ?>',
|
||
type: 'GET',
|
||
success: function(data) {
|
||
// Use a simple approach: replace the entire container contents
|
||
const currentContainer = $('#commentsDataGrid').closest('.card').parent();
|
||
currentContainer.html(data);
|
||
},
|
||
error: function() {
|
||
console.error('Failed to refresh comments');
|
||
}
|
||
});
|
||
}
|
||
|
||
// Modal size adjustment if needed
|
||
if ($("#modal-popin").length) {
|
||
$("#modal-popin .modal-dialog").addClass("modal-lg");
|
||
}
|
||
});
|
||
</script>
|
||
|