standardise table format
This commit is contained in:
parent
7e80ca5ef9
commit
5ae31cd21b
@ -21,7 +21,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
_networkAccessService = networkAccessService;
|
_networkAccessService = networkAccessService;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryAccessNetworkPath()
|
private bool TryAccessNetworkPath() //check if the path is accessible
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -71,6 +71,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
Console.WriteLine($"Marine Tarballs Count: {marineTarballs.Count}");
|
||||||
return View(marineTarballs);
|
return View(marineTarballs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +110,12 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
TarBallNo = marine.ClassifyID == "NO",
|
TarBallNo = marine.ClassifyID == "NO",
|
||||||
IsSand = marine.ClassifyID == "SD",
|
IsSand = marine.ClassifyID == "SD",
|
||||||
IsNonSandy = marine.ClassifyID == "NS",
|
IsNonSandy = marine.ClassifyID == "NS",
|
||||||
IsCoquina = marine.ClassifyID == "CO"
|
IsCoquina = marine.ClassifyID == "CO",
|
||||||
|
marine.OptionalName1,
|
||||||
|
marine.OptionalName2,
|
||||||
|
marine.OptionalName3,
|
||||||
|
marine.OptionalName4,
|
||||||
|
marine.FirstSampler
|
||||||
}).FirstOrDefault();
|
}).FirstOrDefault();
|
||||||
|
|
||||||
if (tarballData == null)
|
if (tarballData == null)
|
||||||
@ -118,7 +124,7 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
// 2. Get photos from station folder (with date matching)
|
// 2. Get photos from station folder (with date matching)
|
||||||
var sampleDateString = tarballData.DateSample.ToString("yyyyMMdd");
|
var sampleDateString = tarballData.DateSample.ToString("yyyyMMdd");
|
||||||
var stationFolder = Path.Combine(PhotoBasePath, tarballData.StationID);
|
var stationFolder = Path.Combine(PhotoBasePath, tarballData.StationID);
|
||||||
var stationImages = new List<string>();
|
var stationImages = new Dictionary<string, string>();
|
||||||
|
|
||||||
if (Directory.Exists(stationFolder))
|
if (Directory.Exists(stationFolder))
|
||||||
{
|
{
|
||||||
@ -150,37 +156,33 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
"OPTIONAL04"
|
"OPTIONAL04"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sort logic
|
// Match images to their types
|
||||||
bool hasValidFormat = allImages.Any(f =>
|
foreach (var imageType in imageTypesInOrder)
|
||||||
imageTypesInOrder.Any(t => Path.GetFileNameWithoutExtension(f).ToUpper().Contains(t)));
|
|
||||||
|
|
||||||
if (hasValidFormat)
|
|
||||||
{
|
{
|
||||||
stationImages = allImages
|
var matchedImage = allImages.FirstOrDefault(f =>
|
||||||
.OrderBy(f =>
|
Path.GetFileNameWithoutExtension(f).ToUpper().Contains(imageType));
|
||||||
|
if (matchedImage != null)
|
||||||
{
|
{
|
||||||
var fileName = Path.GetFileNameWithoutExtension(f).ToUpper();
|
stationImages[imageType] = matchedImage;
|
||||||
var typeIndex = imageTypesInOrder.FindIndex(t => fileName.Contains(t));
|
|
||||||
return typeIndex >= 0 ? typeIndex : int.MaxValue;
|
|
||||||
})
|
|
||||||
.ThenBy(f => f)
|
|
||||||
.Take(8)
|
|
||||||
.ToList();
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
stationImages = allImages
|
|
||||||
.OrderBy(f => f)
|
|
||||||
.Take(8)
|
|
||||||
.ToList();
|
|
||||||
Console.WriteLine($"WARNING: No images matched keywords. Sorted alphabetically.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate minimum images
|
// Validate mandatory images
|
||||||
if (stationImages.Count < 4)
|
var mandatoryImages = new List<string>
|
||||||
{
|
{
|
||||||
return StatusCode(400, $"Minimum 4 images required for {tarballData.DateSample:yyyy/MM/dd}. Found: {stationImages.Count}");
|
"LEFTSIDECOASTALVIEW",
|
||||||
|
"RIGHTSIDECOASTALVIEW",
|
||||||
|
"DRAWINGVERTICALLINES",
|
||||||
|
"DRAWINGHORIZONTALLINES"
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var mandatoryImage in mandatoryImages)
|
||||||
|
{
|
||||||
|
if (!stationImages.ContainsKey(mandatoryImage))
|
||||||
|
{
|
||||||
|
return StatusCode(400, $"Missing mandatory image: {mandatoryImage}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Generate PDF
|
// 3. Generate PDF
|
||||||
@ -198,14 +200,19 @@ namespace PSTW_CentralSystem.Areas.MMS.Controllers
|
|||||||
tarballData.IsSand,
|
tarballData.IsSand,
|
||||||
tarballData.IsNonSandy,
|
tarballData.IsNonSandy,
|
||||||
tarballData.IsCoquina,
|
tarballData.IsCoquina,
|
||||||
stationImages.Count > 0 ? stationImages[0] : null,
|
stationImages.ContainsKey("LEFTSIDECOASTALVIEW") ? stationImages["LEFTSIDECOASTALVIEW"] : null,
|
||||||
stationImages.Count > 1 ? stationImages[1] : null,
|
stationImages.ContainsKey("RIGHTSIDECOASTALVIEW") ? stationImages["RIGHTSIDECOASTALVIEW"] : null,
|
||||||
stationImages.Count > 2 ? stationImages[2] : null,
|
stationImages.ContainsKey("DRAWINGVERTICALLINES") ? stationImages["DRAWINGVERTICALLINES"] : null,
|
||||||
stationImages.Count > 3 ? stationImages[3] : null,
|
stationImages.ContainsKey("DRAWINGHORIZONTALLINES") ? stationImages["DRAWINGHORIZONTALLINES"] : null,
|
||||||
stationImages.Count > 4 ? stationImages[4] : null,
|
stationImages.ContainsKey("OPTIONAL01") ? stationImages["OPTIONAL01"] : null,
|
||||||
stationImages.Count > 5 ? stationImages[5] : null,
|
stationImages.ContainsKey("OPTIONAL02") ? stationImages["OPTIONAL02"] : null,
|
||||||
stationImages.Count > 6 ? stationImages[6] : null,
|
stationImages.ContainsKey("OPTIONAL03") ? stationImages["OPTIONAL03"] : null,
|
||||||
stationImages.Count > 7 ? stationImages[7] : null
|
stationImages.ContainsKey("OPTIONAL04") ? stationImages["OPTIONAL04"] : null,
|
||||||
|
tarballData.OptionalName1,
|
||||||
|
tarballData.OptionalName2,
|
||||||
|
tarballData.OptionalName3,
|
||||||
|
tarballData.OptionalName4,
|
||||||
|
tarballData.FirstSampler
|
||||||
).GeneratePdf();
|
).GeneratePdf();
|
||||||
|
|
||||||
// 4. Return file
|
// 4. Return file
|
||||||
|
|||||||
@ -10,7 +10,9 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
|
|||||||
string longitude, string latitude, DateTime dateSample, TimeSpan timeSample,
|
string longitude, string latitude, DateTime dateSample, TimeSpan timeSample,
|
||||||
string classifyID, bool tarBallYes, bool tarBallNo, bool isSand, bool isNonSandy,
|
string classifyID, bool tarBallYes, bool tarBallNo, bool isSand, bool isNonSandy,
|
||||||
bool isCoquina, string photoPath1, string photoPath2, string photoPath3, string photoPath4,
|
bool isCoquina, string photoPath1, string photoPath2, string photoPath3, string photoPath4,
|
||||||
string photoPath5, string photoPath6, string photoPath7, string photoPath8
|
string photoPath5, string photoPath6, string photoPath7, string photoPath8,
|
||||||
|
string optionalName1, string optionalName2, string optionalName3, string optionalName4,
|
||||||
|
string firstSampler
|
||||||
)
|
)
|
||||||
: IDocument
|
: IDocument
|
||||||
{
|
{
|
||||||
@ -27,14 +29,19 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
|
|||||||
private readonly bool _isSand = isSand;
|
private readonly bool _isSand = isSand;
|
||||||
private readonly bool _isNonSandy = isNonSandy;
|
private readonly bool _isNonSandy = isNonSandy;
|
||||||
private readonly bool _isCoquina = isCoquina;
|
private readonly bool _isCoquina = isCoquina;
|
||||||
private readonly string? _photoPath1 = photoPath1; //having '?' makes it nullable, ELSE the string must always have a value
|
private readonly string _photoPath1 = photoPath1;
|
||||||
private readonly string? _photoPath2 = photoPath2; //"but why keep '?' for photopath 1 to 4?
|
private readonly string _photoPath2 = photoPath2;
|
||||||
private readonly string? _photoPath3 = photoPath3; //A: to make
|
private readonly string _photoPath3 = photoPath3;
|
||||||
private readonly string? _photoPath4 = photoPath4;
|
private readonly string _photoPath4 = photoPath4;
|
||||||
private readonly string? _photoPath5 = photoPath5;
|
private readonly string? _photoPath5 = photoPath5;
|
||||||
private readonly string? _photoPath6 = photoPath6;
|
private readonly string? _photoPath6 = photoPath6;
|
||||||
private readonly string? _photoPath7 = photoPath7;
|
private readonly string? _photoPath7 = photoPath7;
|
||||||
private readonly string? _photoPath8 = photoPath8;
|
private readonly string? _photoPath8 = photoPath8;
|
||||||
|
private readonly string? _optionalName1 = optionalName1;
|
||||||
|
private readonly string? _optionalName2 = optionalName2;
|
||||||
|
private readonly string? _optionalName3 = optionalName3;
|
||||||
|
private readonly string? _optionalName4 = optionalName4;
|
||||||
|
private readonly string _firstSampler = firstSampler;
|
||||||
|
|
||||||
private Image? LoadImage(string? imagePath)
|
private Image? LoadImage(string? imagePath)
|
||||||
{
|
{
|
||||||
@ -286,8 +293,10 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
|
|||||||
.Image(LoadImage(_photoPath6) ?? null) // Just pass null if no image
|
.Image(LoadImage(_photoPath6) ?? null) // Just pass null if no image
|
||||||
.FitArea();
|
.FitArea();
|
||||||
|
|
||||||
table.Cell().Element(CellStyle).Text("Figure 5:").FontSize(12).AlignLeft();
|
table.Cell().Element(CellStyle).Text($"Figure 5: {_optionalName1}")
|
||||||
table.Cell().Element(CellStyle).Text("Figure 6:").FontSize(12).AlignLeft();
|
.FontSize(12).AlignLeft();
|
||||||
|
table.Cell().Element(CellStyle).Text($"Figure 6: {_optionalName2}")
|
||||||
|
.FontSize(12).AlignLeft();
|
||||||
|
|
||||||
table.Cell().Element(CellStyle).Height(150)
|
table.Cell().Element(CellStyle).Height(150)
|
||||||
.Image(LoadImage(_photoPath7) ?? null) // Just pass null if no image
|
.Image(LoadImage(_photoPath7) ?? null) // Just pass null if no image
|
||||||
@ -296,8 +305,10 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
|
|||||||
.Image(LoadImage(_photoPath8) ?? null) // Just pass null if no image
|
.Image(LoadImage(_photoPath8) ?? null) // Just pass null if no image
|
||||||
.FitArea();
|
.FitArea();
|
||||||
|
|
||||||
table.Cell().Element(CellStyle).Text("Figure 7:").FontSize(12).AlignLeft();
|
table.Cell().Element(CellStyle).Text($"Figure 7: {_optionalName3}")
|
||||||
table.Cell().Element(CellStyle).Text("Figure 8:").FontSize(12).AlignLeft();
|
.FontSize(12).AlignLeft();
|
||||||
|
table.Cell().Element(CellStyle).Text($"Figure 8: {_optionalName4}")
|
||||||
|
.FontSize(12).AlignLeft();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Note Section
|
// Note Section
|
||||||
@ -322,7 +333,12 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
|
|||||||
columns.RelativeColumn(1);
|
columns.RelativeColumn(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
table.Cell().RowSpan(2).Element(CellStyle).Text("REPORTED BY :").Bold().FontSize(12);
|
table.Cell().RowSpan(2).Element(CellStyle)
|
||||||
|
.Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("REPORTED BY: ").Bold().FontSize(12);
|
||||||
|
text.Span(_firstSampler).FontSize(10);
|
||||||
|
});
|
||||||
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);
|
||||||
@ -331,7 +347,12 @@ namespace PSTW_CentralSystem.Areas.MMS.Models.PDFGenerator
|
|||||||
table.Cell().Element(CellStyle).Text("Designation").FontSize(12);
|
table.Cell().Element(CellStyle).Text("Designation").FontSize(12);
|
||||||
table.Cell().ColumnSpan(3).Element(CellStyle).Text("");
|
table.Cell().ColumnSpan(3).Element(CellStyle).Text("");
|
||||||
|
|
||||||
table.Cell().RowSpan(2).Element(CellStyle).Text("CHECKED BY :").Bold().FontSize(12);
|
table.Cell().RowSpan(2).Element(CellStyle)
|
||||||
|
.Text(text =>
|
||||||
|
{
|
||||||
|
text.Span("CHECKED BY: ").Bold().FontSize(12);
|
||||||
|
text.Span("Rifaie Azhari").FontSize(10);
|
||||||
|
});
|
||||||
table.Cell().Element(CellStyle).Text("Signature").FontSize(12);
|
table.Cell().Element(CellStyle).Text("Signature").FontSize(12);
|
||||||
table.Cell().ColumnSpan(2).Element(CellStyle).Text("");
|
table.Cell().ColumnSpan(2).Element(CellStyle).Text("");
|
||||||
//table.Cell().Element(CellStyle).Text("Date").FontSize(12);
|
//table.Cell().Element(CellStyle).Text("Date").FontSize(12);
|
||||||
|
|||||||
@ -20,8 +20,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
div {
|
div {
|
||||||
padding-top: 10px;
|
padding-top: 5px;
|
||||||
padding-bottom: 10px;
|
padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
@ -38,39 +38,22 @@
|
|||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tbhead {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Default arrow style (grey) */
|
|
||||||
.sort-arrow {
|
|
||||||
color: #aaa; /* Light grey for default state */
|
|
||||||
font-size: 12px; /* Adjust size for better visibility */
|
|
||||||
line-height: 1; /* Ensure proper spacing */
|
|
||||||
display: inline-block; /* Stack arrows vertically */
|
|
||||||
margin: 0; /* Remove extra spacing */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Active arrow style (darker grey) */
|
|
||||||
.sort-arrow.active {
|
|
||||||
color: #333; /* Dark grey for active state */
|
|
||||||
font-weight: bold; /* Optional: Make it bold for emphasis */
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
<!-- DataTables CSS -->
|
||||||
|
<link href="~/lib/datatables/datatables.css" rel="stylesheet" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app" class="container">
|
<div id="app" class="container">
|
||||||
<div>
|
<div>
|
||||||
<h4>Month</h4>
|
<h4>Month</h4>
|
||||||
<select v-model="selectedMonth" style="width: 100%; padding: 5px;">
|
<select v-model="selectedMonth" style="width: 100%; padding: 5px;">
|
||||||
<option value="default" selected disabled>Filter by Month</option>
|
<option value="" selected>Filter by Month</option>
|
||||||
<option v-for="month in months" :value="month">{{ month }}</option>
|
<option v-for="month in months" :value="month">{{ month }}</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<h4>Year</h4>
|
<h4>Year</h4>
|
||||||
<select v-model="selectedYear" style="width: 100%; padding: 5px;">
|
<select v-model="selectedYear" style="width: 100%; padding: 5px;">
|
||||||
<option value="default" selected disabled>Filter by Year</option>
|
<option value="" selected>Filter by Year</option>
|
||||||
<option v-for="year in years" :value="year">{{ year }}</option>
|
<option v-for="year in years" :value="year">{{ year }}</option>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
@ -80,40 +63,17 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="datatable">
|
<div class="datatable">
|
||||||
<table>
|
<table id="tarballTable" class="table table-bordered table-hover table-striped" style="width:100%;">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>No.</th>
|
<th>No.</th>
|
||||||
<th v-on:click="sortBy('date')">
|
<th>Date</th>
|
||||||
Date
|
<th>Station</th>
|
||||||
<span :class="['sort-arrow', { active: sortKey === 'date' && sortOrder === 'asc' }]">▲</span>
|
|
||||||
<span :class="['sort-arrow', { active: sortKey === 'date' && sortOrder === 'desc' }]">▼</span>
|
|
||||||
</th>
|
|
||||||
<th v-on:click="sortBy('station')">
|
|
||||||
Station
|
|
||||||
<span :class="['sort-arrow', { active: sortKey === 'station' && sortOrder === 'asc' }]">▲</span>
|
|
||||||
<span :class="['sort-arrow', { active: sortKey === 'station' && sortOrder === 'desc' }]">▼</span>
|
|
||||||
</th>
|
|
||||||
|
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th>PDF</th>
|
<th>PDF</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody></tbody>
|
||||||
<tr v-for="(data, index) in numberedData" :key="data.id">
|
|
||||||
<td>{{ index + 1 }}</td>
|
|
||||||
<td>{{ new Date(data.date).toLocaleDateString('en-GB') }}</td>
|
|
||||||
<td>{{ data.station }}</td>
|
|
||||||
<td>
|
|
||||||
<button class="btn btn-success">Approve</button>
|
|
||||||
<button class="btn btn-danger">Reject</button>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<a :href="`/MMS/Marine/ViewPDF?id=${data.id}`" class="btn btn-primary" target="_blank">View PDF</a>
|
|
||||||
<a :href="`/MMS/Marine/GenerateReport?id=${data.id}`" class="btn btn-primary">Download PDF</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -121,14 +81,14 @@
|
|||||||
</html>
|
</html>
|
||||||
|
|
||||||
@section Scripts {
|
@section Scripts {
|
||||||
|
<!-- DataTables JS -->
|
||||||
|
<script src="~/lib/datatables/datatables.js"></script>
|
||||||
<script>
|
<script>
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
data: {
|
data: {
|
||||||
selectedMonth: '',
|
selectedMonth: '',
|
||||||
selectedYear: '',
|
selectedYear: '',
|
||||||
sortKey: 'date',
|
|
||||||
sortOrder: 'desc',
|
|
||||||
months: [
|
months: [
|
||||||
'January', 'February', 'March', 'April', 'May',
|
'January', 'February', 'March', 'April', 'May',
|
||||||
'June', 'July', 'August', 'September',
|
'June', 'July', 'August', 'September',
|
||||||
@ -138,13 +98,28 @@
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
years() {
|
years() {
|
||||||
|
if (!this.dataFromServer || this.dataFromServer.length === 0) {
|
||||||
|
return []; // Return an empty array if no data is available
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract all years from the data
|
||||||
const allYears = this.dataFromServer.map(data => new Date(data.date).getFullYear());
|
const allYears = this.dataFromServer.map(data => new Date(data.date).getFullYear());
|
||||||
|
|
||||||
|
// Find the minimum and maximum years
|
||||||
const minYear = Math.min(...allYears);
|
const minYear = Math.min(...allYears);
|
||||||
const maxYear = Math.max(...allYears);
|
const maxYear = Math.max(...allYears);
|
||||||
|
|
||||||
|
// Generate a range of years from minYear to maxYear
|
||||||
return Array.from({ length: maxYear - minYear + 1 }, (_, i) => (minYear + i).toString());
|
return Array.from({ length: maxYear - minYear + 1 }, (_, i) => (minYear + i).toString());
|
||||||
},
|
},
|
||||||
filteredData() {
|
sortedFilteredData() {
|
||||||
return this.dataFromServer.filter(data => {
|
// If no filters are applied, return all data sorted by descending date
|
||||||
|
if (!this.selectedMonth && !this.selectedYear) {
|
||||||
|
return this.dataFromServer.sort((a, b) => new Date(b.date) - new Date(a.date));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter data by selected month and year
|
||||||
|
const filtered = this.dataFromServer.filter(data => {
|
||||||
const date = new Date(data.date);
|
const date = new Date(data.date);
|
||||||
const monthMatches = this.selectedMonth
|
const monthMatches = this.selectedMonth
|
||||||
? date.toLocaleString('default', { month: 'long' }) === this.selectedMonth
|
? date.toLocaleString('default', { month: 'long' }) === this.selectedMonth
|
||||||
@ -154,33 +129,66 @@
|
|||||||
: true;
|
: true;
|
||||||
return monthMatches && yearMatches;
|
return monthMatches && yearMatches;
|
||||||
});
|
});
|
||||||
},
|
|
||||||
numberedData() {
|
// Sort data by date in descending order
|
||||||
return this.filteredData
|
return filtered.sort((a, b) => new Date(b.date) - new Date(a.date));
|
||||||
.slice()
|
|
||||||
.sort((a, b) => {
|
|
||||||
const dateA = new Date(a.date);
|
|
||||||
const dateB = new Date(b.date);
|
|
||||||
return this.sortOrder === 'asc' ? dateA - dateB : dateB - dateA;
|
|
||||||
})
|
|
||||||
.map((data, index) => ({
|
|
||||||
no: index + 1,
|
|
||||||
...data
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
clearFilters() {
|
clearFilters() {
|
||||||
this.selectedMonth = '';
|
this.selectedMonth = '';
|
||||||
this.selectedYear = '';
|
this.selectedYear = '';
|
||||||
},
|
|
||||||
sortBy(key) {
|
|
||||||
if (this.sortKey === key) {
|
|
||||||
this.sortOrder = this.sortOrder === 'asc' ? 'desc' : 'asc';
|
|
||||||
} else {
|
|
||||||
this.sortKey = key;
|
|
||||||
this.sortOrder = 'asc';
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// Initialize DataTables after Vue has rendered the table
|
||||||
|
this.$nextTick(() => {
|
||||||
|
const table = $('#tarballTable').DataTable({
|
||||||
|
"pageLength": 10,
|
||||||
|
"lengthMenu": [5, 10, 15, 20],
|
||||||
|
"responsive": true,
|
||||||
|
"order": [[1, "desc"]], // Default sorting by Date column (descending)
|
||||||
|
"orderMulti": false, // Disable multi-column sorting
|
||||||
|
"columns": [
|
||||||
|
{
|
||||||
|
"data": null,
|
||||||
|
"render": (data, type, row, meta) => meta.row + 1 // Dynamically generate "No."
|
||||||
|
},
|
||||||
|
{ "data": "date", "render": (data) => new Date(data).toLocaleDateString('en-GB') },
|
||||||
|
{ "data": "station" },
|
||||||
|
{
|
||||||
|
"data": null,
|
||||||
|
"render": () => `
|
||||||
|
<button class="btn btn-success">Approve</button>
|
||||||
|
<button class="btn btn-danger">Reject</button>
|
||||||
|
`
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": null,
|
||||||
|
"render": (data) => `
|
||||||
|
<a href="/MMS/Marine/ViewPDF?id=${data.id}" class="btn btn-primary" target="_blank">View PDF</a>
|
||||||
|
<a href="/MMS/Marine/GenerateReport?id=${data.id}" class="btn btn-primary">Download PDF</a>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rowCallback": function(row, data, index) {
|
||||||
|
// Update the "No." column to start from 1 for the current page
|
||||||
|
const pageInfo = table.page.info();
|
||||||
|
$('td:first', row).html(pageInfo.start + index + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Populate the table with all data on initial load
|
||||||
|
table.rows.add(this.dataFromServer).draw();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
sortedFilteredData() {
|
||||||
|
// Automatically update DataTables whenever the filtered data changes
|
||||||
|
const table = $('#tarballTable').DataTable();
|
||||||
|
table.clear();
|
||||||
|
table.rows.add(this.sortedFilteredData);
|
||||||
|
table.draw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -38,6 +38,10 @@ namespace PSTW_CentralSystem.DBContext
|
|||||||
entity.Property(e => e.Longitude).HasColumnName("longitude");
|
entity.Property(e => e.Longitude).HasColumnName("longitude");
|
||||||
entity.Property(e => e.GetLatitude).HasColumnName("getLatitude");
|
entity.Property(e => e.GetLatitude).HasColumnName("getLatitude");
|
||||||
entity.Property(e => e.GetLongitude).HasColumnName("getLongitude");
|
entity.Property(e => e.GetLongitude).HasColumnName("getLongitude");
|
||||||
|
entity.Property(e => e.OptionalName1).HasColumnName("optionalName1");
|
||||||
|
entity.Property(e => e.OptionalName2).HasColumnName("optionalName2");
|
||||||
|
entity.Property(e => e.OptionalName3).HasColumnName("optionalName3");
|
||||||
|
entity.Property(e => e.OptionalName4).HasColumnName("optionalName4");
|
||||||
entity.Property(e => e.Timestamp).HasColumnName("timestamp");
|
entity.Property(e => e.Timestamp).HasColumnName("timestamp");
|
||||||
|
|
||||||
//Configure relationship with TarballStation
|
//Configure relationship with TarballStation
|
||||||
|
|||||||
@ -17,15 +17,19 @@ namespace PSTW_CentralSystem.Models
|
|||||||
public double GetLatitude { get; set; } // Maps to 'getLatitude'
|
public double GetLatitude { get; set; } // Maps to 'getLatitude'
|
||||||
public double GetLongitude { get; set; } // Maps to 'getLongitude'
|
public double GetLongitude { get; set; } // Maps to 'getLongitude'
|
||||||
public DateTime Timestamp { get; set; } // Maps to 'timestamp'
|
public DateTime Timestamp { get; set; } // Maps to 'timestamp'
|
||||||
|
public string? OptionalName1 { get; set; }
|
||||||
|
public string? OptionalName2 { get; set; }
|
||||||
|
public string? OptionalName3 { get; set; }
|
||||||
|
public string? OptionalName4 { get; set; }
|
||||||
|
|
||||||
public required string PhotoPath1 { get; set; } // Left Side Coastal View
|
public required string PhotoPath1 { get; set; } // Left Side Coastal View
|
||||||
public required string PhotoPath2 { get; set; } // Right Side Coastal View
|
public required string PhotoPath2 { get; set; } // Right Side Coastal View
|
||||||
public required string PhotoPath3 { get; set; } // Vertical Lines
|
public required string PhotoPath3 { get; set; } // Vertical Lines
|
||||||
public required string PhotoPath4 { get; set; } // Horizontal Lines
|
public required string PhotoPath4 { get; set; } // Horizontal Lines
|
||||||
public required string PhotoPath5 { get; set; } // optional
|
public string? PhotoPath5 { get; set; } // optional
|
||||||
public required string PhotoPath6 { get; set; } // optional
|
public string? PhotoPath6 { get; set; } // optional
|
||||||
public required string PhotoPath7 { get; set; } // optional
|
public string? PhotoPath7 { get; set; } // optional
|
||||||
public required string PhotoPath8 { get; set; } // optional
|
public string? PhotoPath8 { get; set; } // optional
|
||||||
|
|
||||||
[ForeignKey("StationID")]
|
[ForeignKey("StationID")]
|
||||||
public required MarineStation MarineStation { get; set; }
|
public required MarineStation MarineStation { get; set; }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user