added 'time' column, fix image sorting generation based on naming format

This commit is contained in:
misya 2025-06-05 16:18:11 +08:00
parent 416b283341
commit 9958a4b1d1
3 changed files with 69 additions and 44 deletions

View File

@ -55,16 +55,17 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
return View(); return View();
} }
public IActionResult TarBallForm()//Queries the database and returns a view with tarball data public IActionResult TarBallForm()
{ {
try try
{ {
var marineTarballs = _context.MarineTarballs //ERRORRRRRRR====================================== var marineTarballs = _context.MarineTarballs
.Select(t => new .Select(t => new
{ {
t.Id, id = t.Id,
Date = t.DateSample.ToString("yyyy/MM/dd"), date = t.DateSample.ToString("yyyy/MM/dd"),
Station = t.StationID station = t.StationID,
time = t.TimeSample.ToString("hh\\:mm\\:ss")
}) })
.ToList(); .ToList();
@ -73,10 +74,8 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
} }
catch (Exception ex) catch (Exception ex)
{ {
// Show the real error in the browser (for debugging only)
return Content($"Error: {ex.Message}<br/>{ex.StackTrace}", "text/html"); return Content($"Error: {ex.Message}<br/>{ex.StackTrace}", "text/html");
} }
} }
[HttpGet] // Explicitly mark as a GET endpoint [HttpGet] // Explicitly mark as a GET endpoint

View File

@ -308,11 +308,11 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
// Row 2: Captions // Row 2: Captions
table.Cell().Element(CellStyle) table.Cell().Element(CellStyle)
.Text(string.IsNullOrEmpty(_photoPath5) ? "" : $"Figure 5: {_optionalName1}") .Text($"Figure 5: {(_optionalName1 ?? "")}")
.FontSize(12).AlignLeft(); .FontSize(12).AlignLeft();
table.Cell().Element(CellStyle) table.Cell().Element(CellStyle)
.Text(string.IsNullOrEmpty(_photoPath6) ? "" : $"Figure 6: {_optionalName2}") .Text($"Figure 6: {(_optionalName2 ?? "")}")
.FontSize(12).AlignLeft(); .FontSize(12).AlignLeft();
// Row 3: Optional images 7 & 8 // Row 3: Optional images 7 & 8
@ -321,11 +321,11 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
// Row 4: Captions // Row 4: Captions
table.Cell().Element(CellStyle) table.Cell().Element(CellStyle)
.Text(string.IsNullOrEmpty(_photoPath7) ? "" : $"Figure 7: {_optionalName3}") .Text($"Figure 7: {(_optionalName3 ?? "")}")
.FontSize(12).AlignLeft(); .FontSize(12).AlignLeft();
table.Cell().Element(CellStyle) table.Cell().Element(CellStyle)
.Text(string.IsNullOrEmpty(_photoPath8) ? "" : $"Figure 8: {_optionalName4}") .Text($"Figure 8: {(_optionalName4 ?? "")}")
.FontSize(12).AlignLeft(); .FontSize(12).AlignLeft();
}); });
@ -360,7 +360,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
table.Cell().Element(CellStyle).Text("Signature").FontSize(12); table.Cell().Element(CellStyle).Text("Signature").FontSize(12);
table.Cell().Element(CellStyle).Text(""); table.Cell().Element(CellStyle).Text("");
table.Cell().Element(CellStyle).Text("Date").FontSize(12); table.Cell().Element(CellStyle).Text("Date").FontSize(12);
table.Cell().Element(CellStyle).Text($"{_dateSample:yyyyMMdd}").FontSize(12); table.Cell().Element(CellStyle).Text($"{_dateSample:dd/MM/yyyy}").FontSize(12);
table.Cell().Element(CellStyle).Text("Designation").FontSize(12); table.Cell().Element(CellStyle).Text("Designation").FontSize(12);
table.Cell().ColumnSpan(3).Element(CellStyle).Text(_levelName).FontSize(12); table.Cell().ColumnSpan(3).Element(CellStyle).Text(_levelName).FontSize(12);

View File

@ -69,6 +69,7 @@
<th>No.</th> <th>No.</th>
<th>Date</th> <th>Date</th>
<th>Station</th> <th>Station</th>
<th>Time</th>
<th>Status</th> <th>Status</th>
<th>PDF</th> <th>PDF</th>
</tr> </tr>
@ -86,16 +87,26 @@
<script> <script>
new Vue({ new Vue({
el: '#app', el: '#app',
data: { data: {
selectedMonth: '', selectedMonth: '',
selectedYear: '', selectedYear: '',
months: [ months: [
'January', 'February', 'March', 'April', 'May', 'January', 'February', 'March', 'April', 'May',
'June', 'July', 'August', 'September', 'June', 'July', 'August', 'September',
'October', 'November', 'December' 'October', 'November', 'December'
], ],
dataFromServer: @Html.Raw(Json.Serialize(Model ?? new List<object>())) dataFromServer: @Json.Serialize(Model ?? new List<object>()),
}, dataTable: null
},
mounted() {
if (this.dataFromServer && this.dataFromServer.length > 0) {
this.$nextTick(() => {
this.initializeDataTable();
});
} else {
console.log("No data received from server");
}
},
computed: { computed: {
years() { years() {
if (!this.dataFromServer || this.dataFromServer.length === 0) { if (!this.dataFromServer || this.dataFromServer.length === 0) {
@ -138,31 +149,27 @@
clearFilters() { clearFilters() {
this.selectedMonth = ''; this.selectedMonth = '';
this.selectedYear = ''; this.selectedYear = '';
} },
}, initializeDataTable() {
mounted() { // Initialize DataTables
// Initialize DataTables after Vue has rendered the table const self = this; // Store the Vue instance context
this.$nextTick(() => { this.dataTable = $('#tarballTable').DataTable({
const table = $('#tarballTable').DataTable({
"pageLength": 10, "pageLength": 10,
"lengthMenu": [5, 10, 15, 20], "lengthMenu": [5, 10, 15, 20],
"responsive": true, "responsive": true,
"order": [[1, "desc"]], // Default sorting by Date column (descending) "order": [[1, "desc"]], // Default sorting by Date column (descending)
"orderMulti": false, // Disable multi-column sorting "orderMulti": false, // Disable multi-column sorting
"columns": [ "columns": [
{ { "data": null,"render": (data, type, row, meta) => meta.row + 1},
"data": null,
"render": (data, type, row, meta) => meta.row + 1 // Dynamically generate "No."
},
{ "data": "date", "render": (data) => new Date(data).toLocaleDateString('en-GB') }, { "data": "date", "render": (data) => new Date(data).toLocaleDateString('en-GB') },
{ "data": "station" }, { "data": "station" },
{ "data": "time" }, // Removed the incorrect toLocaleDateString()
{ {
"data": null, "data": null,
"render": () => ` "render": () => `
<button class="btn btn-success">Approve</button> <button class="btn btn-success" disabled>Approve</button>
<button class="btn btn-danger">Reject</button> <button class="btn btn-danger" disabled>Reject</button>
` `
}, },
{ {
"data": null, "data": null,
@ -174,22 +181,41 @@
], ],
"rowCallback": function(row, data, index) { "rowCallback": function(row, data, index) {
// Update the "No." column to start from 1 for the current page // Update the "No." column to start from 1 for the current page
const pageInfo = table.page.info(); const pageInfo = this.api().page.info();
$('td:first', row).html(pageInfo.start + index + 1); $('td:first', row).html(pageInfo.start + index + 1);
} }
}); });
// Populate the table with all data on initial load // Populate the table with initial data
table.rows.add(this.dataFromServer).draw(); this.updateDataTable(this.sortedFilteredData);
//auto-filtering
$('#tarballTable_filter input').on('keyup', function () {
self.dataTable.search(this.value).draw();
});
},
updateDataTable(data) {
if (this.dataTable) {
this.dataTable.clear();
this.dataTable.rows.add(data);
this.dataTable.draw();
}
}
},
mounted() {
// Initialize DataTables after Vue has rendered the table
this.$nextTick(() => {
this.initializeDataTable();
}); });
}, },
watch: { watch: {
sortedFilteredData() { sortedFilteredData(newData) {
// Automatically update DataTables whenever the filtered data changes // Automatically update DataTables whenever the filtered data changes
const table = $('#tarballTable').DataTable(); this.updateDataTable(newData);
table.clear(); //trigger search function after updating data(?)
table.rows.add(this.sortedFilteredData); if(this.dataTable) {
table.draw(); this.dataTable.search('').draw();//clear existing search
}
} }
} }
}); });