150 lines
5.9 KiB
Plaintext
150 lines
5.9 KiB
Plaintext
@{
|
|
ViewData["Title"] = "Overtime Status";
|
|
Layout = "~/Views/Shared/_Layout.cshtml";
|
|
}
|
|
|
|
<style>
|
|
.white-box {
|
|
background-color: white;
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
margin-top: 20px;
|
|
}
|
|
</style>
|
|
|
|
<div id="app" style="max-width: 1300px; margin: auto; font-size: 13px;">
|
|
<div class="table-layer">
|
|
<div class="white-box">
|
|
<div class="table-container table-responsive">
|
|
<table id="otStatusTable" class="table table-bordered table-sm table-striped">
|
|
<thead>
|
|
<tr>
|
|
<th>Month/Year</th>
|
|
<th>Submit Date</th>
|
|
<th v-if="includeHou">HoU Status</th>
|
|
<th v-if="includeHod">HoD Status</th>
|
|
<th v-if="includeManager">Manager Status</th>
|
|
<th v-if="includeHr">HR Status</th>
|
|
<th>Updated</th>
|
|
<th>File</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr v-for="(item, index) in otRecords" :key="index">
|
|
<td>{{ formatMonthYear(item.month, item.year) }}</td>
|
|
<td>{{ formatDate(item.submitDate) }}</td>
|
|
<td v-if="includeHou">{{ item.houStatus ?? '-' }}</td>
|
|
<td v-if="includeHod">{{ item.hodStatus ?? '-' }}</td>
|
|
<td v-if="includeManager">{{ item.managerStatus ?? '-' }}</td>
|
|
<td v-if="includeHr">{{ item.hrStatus ?? '-' }}</td>
|
|
<td>{{ item.updated ? 'Yes' : 'No' }}</td>
|
|
<td>
|
|
<button v-if="item.filePath" class="btn btn-sm btn-primary" v-on:click ="previewFile(item.filePath)">
|
|
View
|
|
</button>
|
|
<span v-else>-</span>
|
|
</td>
|
|
</tr>
|
|
<tr v-if="otRecords.length === 0">
|
|
<td :colspan="columnCount" class="text-center">No records found.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div v-if="showPreview" class="modal-backdrop">
|
|
<div class="modal-dialog-box">
|
|
<div class="modal-header" style="background-color: white;">
|
|
<h5 class="modal-title">File Preview</h5>
|
|
<button type="button" class="btn-close" aria-label="Close Preview" v-on:click ="closePreview"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<iframe :src="previewUrl" width="100%" height="650px" style="border: none;"></iframe>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@section Scripts {
|
|
<script>
|
|
const app = Vue.createApp({
|
|
data() {
|
|
return {
|
|
otRecords: [],
|
|
includeHou: false,
|
|
includeHod: false,
|
|
includeManager: false,
|
|
includeHr: false,
|
|
showPreview: false,
|
|
previewUrl: ''
|
|
};
|
|
},
|
|
computed: {
|
|
columnCount() {
|
|
let count = 3; // Month/Year, SubmitDate, Updated
|
|
if (this.includeHou) count++;
|
|
if (this.includeHod) count++;
|
|
if (this.includeManager) count++;
|
|
if (this.includeHr) count++;
|
|
return count + 1; // File column
|
|
}
|
|
},
|
|
mounted() {
|
|
fetch('/OvertimeAPI/GetUserOtStatus')
|
|
.then(res => res.json())
|
|
.then(data => {
|
|
this.includeHou = data.includeHou;
|
|
this.includeHod = data.includeHod;
|
|
this.includeManager = data.includeManager;
|
|
this.includeHr = data.includeHr;
|
|
this.otRecords = (data.otStatuses || []).sort((a, b) => {
|
|
// Sort in descending order of SubmitDate (latest first)
|
|
return new Date(b.submitDate) - new Date(a.submitDate);
|
|
});
|
|
|
|
this.$nextTick(() => {
|
|
// Delay to ensure table is rendered
|
|
if ($.fn.dataTable.isDataTable('#otStatusTable')) {
|
|
$('#otStatusTable').DataTable().destroy();
|
|
}
|
|
$('#otStatusTable').DataTable({
|
|
responsive: true,
|
|
pageLength: 10,
|
|
order: []
|
|
});
|
|
});
|
|
})
|
|
.catch(err => {
|
|
console.error("Error fetching OT records:", err);
|
|
});
|
|
},
|
|
methods: {
|
|
formatDate(dateStr) {
|
|
const date = new Date(dateStr);
|
|
return date.toLocaleDateString();
|
|
},
|
|
formatMonthYear(month, year) {
|
|
if (!month || !year) return '-';
|
|
return `${month.toString().padStart(2, '0')}/${year}`;
|
|
},
|
|
previewFile(path) {
|
|
this.previewUrl = '/' + path.replace(/^\/+/, '');
|
|
this.showPreview = true;
|
|
document.body.style.overflow = 'hidden';
|
|
},
|
|
closePreview() {
|
|
this.previewUrl = '';
|
|
this.showPreview = false;
|
|
document.body.style.overflow = '';
|
|
}
|
|
}
|
|
});
|
|
|
|
app.mount('#app');
|
|
</script>
|
|
}
|