445 lines
22 KiB
HTML
445 lines
22 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||
<title>All Assets | AMS</title>
|
||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
|
||
<link rel="stylesheet" href="css/styles.css">
|
||
</head>
|
||
<body>
|
||
<div class="app-layout">
|
||
|
||
<!-- SIDEBAR -->
|
||
<aside class="sidebar" id="appSidebar"></aside>
|
||
|
||
<!-- MAIN -->
|
||
<div class="main-wrapper">
|
||
<header class="topbar">
|
||
<div class="topbar-left"><div class="topbar-title">All Assets <span class="topbar-sub" id="totalCount"></span></div></div>
|
||
<div class="topbar-search"><span style="color:var(--text-muted)"><i data-lucide="search" style="width:14px;height:14px"></i></span><input type="text" placeholder="Search assets…" id="assetSearch" data-search-table="assetTable"></div>
|
||
<div class="topbar-actions">
|
||
<a href="asset-create.html" class="btn btn-primary btn-sm">+ Add Asset</a>
|
||
<button class="btn btn-secondary btn-sm" onclick="exportAssets()">📥 Export</button>
|
||
<a href="index.html" class="icon-btn" title="Logout"><i data-lucide="log-out"></i></a>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="content">
|
||
<!-- Stat Mini Cards -->
|
||
<div class="grid-4 mb-4" id="assetStats"></div>
|
||
|
||
<!-- Filters -->
|
||
<div class="filters-row" id="filtersRow">
|
||
<div class="search-wrap" style="max-width:240px">
|
||
<span style="color:var(--text-muted);font-size:13px">🔍</span>
|
||
<input type="text" id="tableSearch" placeholder="Filter list…">
|
||
</div>
|
||
<select class="filter-sel" id="typeFilter">
|
||
<option value="">All Types</option>
|
||
<option value="physical">Physical Assets</option>
|
||
<option value="digital">Digital Assets</option>
|
||
<option value="other">Other Assets</option>
|
||
</select>
|
||
<select class="filter-sel" id="assignFilter">
|
||
<option value="">All Assignments</option>
|
||
<option value="user">Assigned to User</option>
|
||
<option value="project">Assigned to Project</option>
|
||
<option value="unassigned">Unassigned</option>
|
||
</select>
|
||
<select class="filter-sel" id="statusFilter">
|
||
<option value="">All Statuses</option>
|
||
<option>Active</option><option>Idle</option>
|
||
<option>Under Maintenance</option><option>Disposed</option>
|
||
</select>
|
||
<select class="filter-sel" id="catFilter">
|
||
<option value="">All Categories</option>
|
||
<option>Laptops</option><option>Desktops</option><option>Servers</option>
|
||
<option>Printers</option><option>Networking</option><option>Mobile Devices</option>
|
||
<option>AV Equipment</option><option>Displays</option><option>Furniture</option>
|
||
<option>Vehicles</option><option>HVAC</option><option>Power Equipment</option>
|
||
<option>Software Licenses</option><option>Cloud Subscriptions</option>
|
||
</select>
|
||
<select class="filter-sel" id="deptFilter">
|
||
<option value="">All Departments</option>
|
||
<option>IT</option><option>Finance</option><option>HR</option>
|
||
<option>Operations</option><option>Marketing</option><option>Admin</option>
|
||
</select>
|
||
<button class="btn btn-ghost btn-sm" onclick="clearFilters()">✕ Clear</button>
|
||
<div style="margin-left:auto;font-size:12.5px;color:var(--text-muted)">Showing <strong id="visCount" style="color:var(--text-primary)">0</strong> assets</div>
|
||
</div>
|
||
|
||
<!-- Bulk Bar -->
|
||
<div class="bulk-bar" id="assetTableBulk">
|
||
<span class="bulk-count">0 items selected</span>
|
||
<button class="btn btn-secondary btn-sm" onclick="bulkAction('transfer')">↔ Transfer</button>
|
||
<button class="btn btn-secondary btn-sm" onclick="bulkAction('assign')">👤 Assign</button>
|
||
<button class="btn btn-secondary btn-sm" onclick="bulkAction('export')">📥 Export</button>
|
||
<button class="btn btn-danger btn-sm" onclick="bulkAction('dispose')">🗑️ Dispose</button>
|
||
</div>
|
||
|
||
<!-- Table -->
|
||
<div class="table-wrapper">
|
||
<table class="data-table" id="assetTable" data-table-checkboxes>
|
||
<thead>
|
||
<tr>
|
||
<th style="width:40px"><input type="checkbox" class="select-all"></th>
|
||
<th onclick="sortTable(1)">Asset ↕</th>
|
||
<th onclick="sortTable(2)">Category ↕</th>
|
||
<th onclick="sortTable(3)">Status ↕</th>
|
||
<th onclick="sortTable(4)">Department ↕</th>
|
||
<th onclick="sortTable(5)">Assigned To ↕</th>
|
||
<th onclick="sortTable(6)">Purchase Cost ↕</th>
|
||
<th onclick="sortTable(7)">Net Value ↕</th>
|
||
<th>Warranty</th>
|
||
<th style="width:110px">Actions</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="assetTbody"></tbody>
|
||
</table>
|
||
<div class="pagination" id="assetPagination"></div>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── Assign Modal ── -->
|
||
<div class="modal-overlay" id="assignModal">
|
||
<div class="modal">
|
||
<div class="modal-header"><span class="modal-title">Assign Asset</span><button class="modal-close">✕</button></div>
|
||
<div class="modal-body">
|
||
<div class="alert alert-info mb-4"><div class="alert-icon">ℹ️</div><div><div class="alert-title" id="assignAssetName">Asset Name</div><div class="alert-text">Current assignee will receive a handover notification</div></div></div>
|
||
<div class="form-group">
|
||
<label class="form-label">Assign To (Employee) <span class="req">*</span></label>
|
||
<select class="form-select" id="assignEmployee">
|
||
<option value="">Select employee…</option>
|
||
<option>Priya Kumar – IT</option><option>Rahul Mehta – Finance</option>
|
||
<option>Anita Singh – HR</option><option>Vikram Reddy – Operations</option>
|
||
<option>Sneha Patel – Marketing</option><option>Deepak Joshi – Admin</option>
|
||
<option>Kavya Nair – IT</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-row">
|
||
<div class="form-group">
|
||
<label class="form-label">Effective From</label>
|
||
<input type="date" class="form-input" id="assignFrom" value="2025-05-28">
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Expected Return (if temp)</label>
|
||
<input type="date" class="form-input" id="assignTo">
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Acknowledgment Required?</label>
|
||
<select class="form-select">
|
||
<option>Yes – Send email to employee for confirmation</option>
|
||
<option>No – Direct assignment</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Notes</label>
|
||
<textarea class="form-textarea" placeholder="Any notes about this assignment…" rows="2"></textarea>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn btn-ghost" onclick="closeModal('assignModal')">Cancel</button>
|
||
<button class="btn btn-primary" onclick="saveAssignment()">Assign Asset</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── QR Modal ── -->
|
||
<div class="modal-overlay" id="qrModal">
|
||
<div class="modal" style="max-width:380px">
|
||
<div class="modal-header"><span class="modal-title">QR Code Label</span><button class="modal-close">✕</button></div>
|
||
<div class="modal-body" style="text-align:center">
|
||
<div id="qrDisplay" style="margin:0 auto 16px;display:inline-block"></div>
|
||
<div id="qrAssetInfo" style="font-size:12.5px;color:var(--text-muted);margin-bottom:16px"></div>
|
||
<button class="btn btn-primary" onclick="printQR()">🖨️ Print Label</button>
|
||
<button class="btn btn-secondary" onclick="downloadQR()">📥 Download PNG</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ── Transfer Modal ── -->
|
||
<div class="modal-overlay" id="transferModal">
|
||
<div class="modal">
|
||
<div class="modal-header"><span class="modal-title">Transfer Asset</span><button class="modal-close">✕</button></div>
|
||
<div class="modal-body">
|
||
<div class="form-group">
|
||
<label class="form-label">Transfer From (Current Location)</label>
|
||
<input type="text" class="form-input" id="transferFrom" disabled>
|
||
</div>
|
||
<div class="form-row">
|
||
<div class="form-group">
|
||
<label class="form-label">To Department <span class="req">*</span></label>
|
||
<select class="form-select">
|
||
<option>IT</option><option>Finance</option><option>HR</option>
|
||
<option>Operations</option><option>Marketing</option><option>Admin</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">To Location <span class="req">*</span></label>
|
||
<select class="form-select">
|
||
<option>IT Dept – Floor 2</option><option>Finance – Floor 1</option>
|
||
<option>HR – Floor 2</option><option>Server Room – B1</option>
|
||
<option>Marketing – Floor 3</option><option>Conference Room A</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Reason for Transfer <span class="req">*</span></label>
|
||
<select class="form-select">
|
||
<option>Department Restructuring</option><option>Employee Transfer</option>
|
||
<option>Better Utilization</option><option>Location Upgrade</option><option>Other</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-group">
|
||
<label class="form-label">Approval Required?</label>
|
||
<select class="form-select"><option>Yes – Send for Department Head approval</option><option>No (Self-authorized)</option></select>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button class="btn btn-ghost" onclick="closeModal('transferModal')">Cancel</button>
|
||
<button class="btn btn-primary" onclick="saveTransfer()">Initiate Transfer</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Confirm Modal -->
|
||
<div class="modal-overlay" id="confirmModal">
|
||
<div class="modal" style="max-width:400px">
|
||
<div class="modal-header"><span class="modal-title confirm-title">Confirm</span><button class="modal-close">✕</button></div>
|
||
<div class="modal-body"><p class="confirm-message" style="color:var(--text-secondary);font-size:13.5px"></p></div>
|
||
<div class="modal-footer"><button class="btn btn-ghost" onclick="closeModal('confirmModal')">Cancel</button><button class="btn btn-danger confirm-ok">Confirm</button></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="toast-container" id="toastContainer"></div>
|
||
<script src="https://unpkg.com/lucide@latest"></script>
|
||
<script src="js/data.js"></script>
|
||
<script src="js/sidebar.js"></script>
|
||
<script src="js/app.js"></script>
|
||
<script>
|
||
let currentPage = 1;
|
||
const perPage = 10;
|
||
let sortCol = -1, sortDir = 1;
|
||
let filteredAssets = [];
|
||
|
||
document.addEventListener('DOMContentLoaded', () => {
|
||
renderStats();
|
||
applyFilters();
|
||
initCheckboxes('assetTable','assetTableBulk');
|
||
document.getElementById('tableSearch').addEventListener('input', applyFilters);
|
||
document.getElementById('typeFilter').addEventListener('change', applyFilters);
|
||
document.getElementById('assignFilter').addEventListener('change', applyFilters);
|
||
document.getElementById('statusFilter').addEventListener('change', applyFilters);
|
||
document.getElementById('catFilter').addEventListener('change', applyFilters);
|
||
document.getElementById('deptFilter').addEventListener('change', applyFilters);
|
||
});
|
||
|
||
function renderStats() {
|
||
const s = AMS.stats;
|
||
document.getElementById('totalCount').textContent = `— ${s.total.toLocaleString()} total`;
|
||
document.getElementById('assetStats').innerHTML = [
|
||
{label:'Total',icon:'📦',val:s.total,color:'var(--primary)',link:'?status='},
|
||
{label:'Active',icon:'✅',val:s.active,color:'var(--success)',link:'?status=active'},
|
||
{label:'Maintenance',icon:'🔧',val:s.maintenance,color:'var(--info)',link:'?status=maintenance'},
|
||
{label:'Idle',icon:'😴',val:s.idle,color:'var(--warning)',link:'?status=idle'}
|
||
].map(k=>`
|
||
<div class="stat-card" style="--sc-color:${k.color};cursor:pointer" onclick="filterByStatus('${k.label}')">
|
||
<div class="stat-icon" style="background:${k.color}18;color:${k.color}">${k.icon}</div>
|
||
<div class="stat-label">${k.label}</div>
|
||
<div class="stat-value" style="color:${k.color}">${k.val.toLocaleString('en-IN')}</div>
|
||
</div>`).join('');
|
||
}
|
||
|
||
function filterByStatus(s) {
|
||
if(s==='Total') { document.getElementById('statusFilter').value=''; }
|
||
else if(s==='Active') document.getElementById('statusFilter').value='Active';
|
||
else if(s==='Maintenance') document.getElementById('statusFilter').value='Under Maintenance';
|
||
else if(s==='Idle') document.getElementById('statusFilter').value='Idle';
|
||
applyFilters();
|
||
}
|
||
|
||
function applyFilters() {
|
||
const q = document.getElementById('tableSearch').value.toLowerCase();
|
||
const ty = document.getElementById('typeFilter').value.toLowerCase();
|
||
const as = document.getElementById('assignFilter').value.toLowerCase();
|
||
const st = document.getElementById('statusFilter').value.toLowerCase();
|
||
const ct = document.getElementById('catFilter').value.toLowerCase();
|
||
const dt = document.getElementById('deptFilter').value.toLowerCase();
|
||
|
||
filteredAssets = AMS.assets.filter(a => {
|
||
const matchesSearch = !q || a.name.toLowerCase().includes(q) || a.id.toLowerCase().includes(q) || (a.serial && a.serial.toLowerCase().includes(q));
|
||
const matchesType = !ty || (a.type && a.type.toLowerCase() === ty);
|
||
const matchesStatus = !st || a.status.toLowerCase() === st;
|
||
const matchesCat = !ct || a.cat.toLowerCase() === ct;
|
||
const matchesDept = !dt || a.dept.toLowerCase() === dt;
|
||
|
||
let matchesAssign = true;
|
||
if (as === 'user') {
|
||
matchesAssign = a.assignee && a.assignee !== 'Unassigned' && (!a.project || a.project === 'N/A' || a.project === 'Unassigned / No Project');
|
||
} else if (as === 'project') {
|
||
matchesAssign = a.project && a.project !== 'N/A' && a.project !== 'Unassigned / No Project';
|
||
} else if (as === 'unassigned') {
|
||
matchesAssign = !a.assignee || a.assignee === 'Unassigned';
|
||
}
|
||
|
||
// Role-based restrictions: Employees can only view assets assigned to them
|
||
const isEmployee = AMS.currentUser.role === 'Employee';
|
||
const matchesRole = !isEmployee || a.assignee === AMS.currentUser.name;
|
||
|
||
return matchesSearch && matchesType && matchesAssign && matchesStatus && matchesCat && matchesDept && matchesRole;
|
||
});
|
||
|
||
currentPage = 1;
|
||
renderTable();
|
||
}
|
||
|
||
function clearFilters() {
|
||
document.getElementById('tableSearch').value = '';
|
||
document.getElementById('typeFilter').value = '';
|
||
document.getElementById('assignFilter').value = '';
|
||
document.getElementById('statusFilter').value = '';
|
||
document.getElementById('catFilter').value = '';
|
||
document.getElementById('deptFilter').value = '';
|
||
applyFilters();
|
||
}
|
||
|
||
function renderTable() {
|
||
if (!filteredAssets.length && !document.getElementById('tableSearch').value && !document.getElementById('typeFilter').value && !document.getElementById('assignFilter').value && !document.getElementById('statusFilter').value && !document.getElementById('catFilter').value && !document.getElementById('deptFilter').value) {
|
||
// If no filters are active and no search, check employee role list
|
||
const isEmployee = AMS.currentUser.role === 'Employee';
|
||
filteredAssets = isEmployee ? AMS.assets.filter(a => a.assignee === AMS.currentUser.name) : [...AMS.assets];
|
||
}
|
||
document.getElementById('visCount').textContent = filteredAssets.length;
|
||
const start = (currentPage-1)*perPage;
|
||
const page = filteredAssets.slice(start, start+perPage);
|
||
const tbody = document.getElementById('assetTbody');
|
||
if (!page.length) {
|
||
tbody.innerHTML = `<tr><td colspan="10"><div class="empty-state"><div class="empty-icon">📦</div><div class="empty-title">No assets found</div><div class="empty-text">Try adjusting your filters</div></div></td></tr>`;
|
||
return;
|
||
}
|
||
const warningDate = new Date(); warningDate.setDate(warningDate.getDate()+90);
|
||
tbody.innerHTML = page.map(a => {
|
||
const isDigital = a.type === 'digital';
|
||
const warrantyExpiring = a.warranty !== 'N/A' && new Date(a.warranty) < warningDate;
|
||
const depPct = isDigital ? 100 : Math.round((a.cost - a.value)/a.cost*100);
|
||
|
||
const assigneeText = (a.project && a.project !== 'N/A' && a.project !== 'Unassigned / No Project')
|
||
? `<span class="badge badge-primary" style="font-size:10.5px;padding:3px 6px">📁 ${escapeHtml(a.project)}</span>`
|
||
: escapeHtml(a.assignee || 'Unassigned');
|
||
|
||
const valueText = isDigital
|
||
? `<div style="font-weight:600;color:var(--primary-light)">${a.seatsAlloc}/${a.seatsTotal} seats</div><div style="font-size:10px;color:var(--text-muted)">allocated</div>`
|
||
: `<div style="font-weight:600;color:${depPct>60?'var(--warning)':'var(--text-primary)'}">${fmt(a.value)}</div><div style="font-size:10px;color:var(--text-muted)">${depPct}% depreciated</div>`;
|
||
|
||
return `<tr onclick="goToDetail('${a.id}')">
|
||
<td onclick="event.stopPropagation()"><input type="checkbox" class="row-check"></td>
|
||
<td><div class="asset-cell">
|
||
<div class="asset-ic">${a.icon || '📦'}</div>
|
||
<div><div class="asset-n">${escapeHtml(a.name)}</div><div class="asset-id">${escapeHtml(a.id)} · ${isDigital ? 'Software License' : escapeHtml(a.serial)}</div></div>
|
||
</div></td>
|
||
<td><span class="badge badge-neutral" style="font-size:10px">${escapeHtml(a.cat)}</span></td>
|
||
<td><span class="badge ${statusBadge(a.status)}"><span class="badge-dot-ind" style="background:${statusDot(a.status)}"></span>${a.status}</span></td>
|
||
<td>${escapeHtml(a.dept)}</td>
|
||
<td>${assigneeText}</td>
|
||
<td style="font-weight:600">${fmt(a.cost)}</td>
|
||
<td>${valueText}</td>
|
||
<td><span style="color:${warrantyExpiring?'var(--warning)':'var(--text-muted)'};font-size:12px">${a.warranty==='N/A'?'—':fmtDate(a.warranty)}</span></td>
|
||
<td onclick="event.stopPropagation()">
|
||
<div class="flex gap-1">
|
||
<button class="btn btn-icon btn-ghost" title="View" onclick="goToDetail('${a.id}')"><i data-lucide="eye" style="width:14px;height:14px"></i></button>
|
||
<button class="btn btn-icon btn-ghost" title="QR Code" onclick="showQR('${a.id}')"><i data-lucide="qr-code" style="width:14px;height:14px"></i></button>
|
||
<button class="btn btn-icon btn-ghost" title="Assign" onclick="openAssignModal('${escapeJs(a.id)}','${escapeJs(a.name)}','${escapeJs(a.dept)}')"><i data-lucide="user-check" style="width:14px;height:14px"></i></button>
|
||
<button class="btn btn-icon btn-ghost" title="Transfer" onclick="openTransferModal('${a.id}','${a.loc}')"><i data-lucide="arrow-left-right" style="width:14px;height:14px"></i></button>
|
||
</div>
|
||
</td>
|
||
</tr>`;
|
||
}).join('');
|
||
renderPagBtn();
|
||
}
|
||
|
||
function renderPagBtn() {
|
||
const total = filteredAssets.length;
|
||
const pages = Math.max(1,Math.ceil(total/perPage));
|
||
let html = `<button class="page-btn" onclick="goPage(${currentPage-1})" ${currentPage===1?'disabled':''}>‹</button>`;
|
||
for(let i=1;i<=pages;i++) html+=`<button class="page-btn${i===currentPage?' active':''}" onclick="goPage(${i})">${i}</button>`;
|
||
html+=`<button class="page-btn" onclick="goPage(${currentPage+1})" ${currentPage===pages?'disabled':''}>›</button>`;
|
||
document.getElementById('assetPagination').innerHTML = html;
|
||
}
|
||
function goPage(p) { if(p<1||p>Math.ceil(filteredAssets.length/perPage))return; currentPage=p; renderTable(); window.scrollTo(0,0); }
|
||
|
||
function sortTable(col) {
|
||
if(sortCol===col) sortDir*=-1; else { sortCol=col; sortDir=1; }
|
||
const keys=['','name','cat','status','dept','assignee','cost','value','warranty'];
|
||
filteredAssets.sort((a,b)=>{
|
||
const av=a[keys[col]]||''; const bv=b[keys[col]]||'';
|
||
if(typeof av==='number') return (av-bv)*sortDir;
|
||
return av.localeCompare(bv)*sortDir;
|
||
});
|
||
renderTable();
|
||
}
|
||
|
||
function goToDetail(id) { window.location.href = `asset-detail.html?id=${encodeURIComponent(id)}`; }
|
||
|
||
function openAssignModal(id, name, dept) {
|
||
document.getElementById('assignAssetName').textContent = name;
|
||
openModal('assignModal');
|
||
}
|
||
function saveAssignment() {
|
||
const emp = document.getElementById('assignEmployee').value;
|
||
if(!emp) { showToast('Error','Please select an employee','error'); return; }
|
||
closeModal('assignModal');
|
||
showToast('Asset Assigned','Acknowledgment email sent to employee','success');
|
||
}
|
||
|
||
function openTransferModal(id, loc) {
|
||
document.getElementById('transferFrom').value = loc;
|
||
openModal('transferModal');
|
||
}
|
||
function saveTransfer() { closeModal('transferModal'); showToast('Transfer Initiated','Approval request sent to Department Head','info'); }
|
||
|
||
function showQR(id) {
|
||
const a = AMS.assets.find(x=>x.id===id);
|
||
if(!a) return;
|
||
const cells = generateQRPattern(id);
|
||
const qrHTML = `<div class="qr-box">
|
||
<div style="display:grid;grid-template-columns:repeat(7,12px);grid-template-rows:repeat(7,12px);gap:2px;background:#fff;padding:10px">
|
||
${cells.map(c=>`<div style="background:${c?'#000':'#fff'};border-radius:1px"></div>`).join('')}
|
||
</div>
|
||
<div style="font-size:9px;color:#333;font-weight:700;font-family:monospace">${a.id}</div>
|
||
<div style="font-size:8px;color:#555;max-width:120px;text-align:center">${a.name}</div>
|
||
</div>`;
|
||
document.getElementById('qrDisplay').innerHTML = qrHTML;
|
||
document.getElementById('qrAssetInfo').innerHTML = `<strong>${a.name}</strong><br>Serial: ${a.serial}<br>Category: ${a.cat}`;
|
||
openModal('qrModal');
|
||
}
|
||
function printQR() { window.print(); }
|
||
function downloadQR() { showToast('Download','QR code image downloaded','success'); }
|
||
|
||
function bulkAction(action) {
|
||
const checked = document.querySelectorAll('#assetTable .row-check:checked').length;
|
||
if(!checked) { showToast('No selection','Please select assets first','warning'); return; }
|
||
if(action==='dispose') {
|
||
confirmAction('Dispose Assets',`Mark ${checked} asset(s) as disposed? This action cannot be undone.`,()=>{
|
||
showToast('Assets Disposed',`${checked} asset(s) marked for disposal`,'success');
|
||
});
|
||
} else if(action==='transfer') {
|
||
openModal('transferModal');
|
||
} else if(action==='export') {
|
||
showToast('Export','Exporting selected assets to CSV…','info');
|
||
setTimeout(()=>{ downloadCSV(AMS.assets.slice(0,checked),'selected_assets.csv'); },600);
|
||
} else if(action==='assign') {
|
||
openModal('assignModal');
|
||
}
|
||
}
|
||
|
||
function exportAssets() {
|
||
showToast('Export','Preparing CSV export…','info');
|
||
setTimeout(()=>{ downloadCSV(AMS.assets.map(a=>({ID:a.id,Name:a.name,Category:a.cat,Status:a.status,Dept:a.dept,Assignee:a.assignee,Cost:a.cost,Value:a.value,Serial:a.serial,Vendor:a.vendor,Warranty:a.warranty})),'all_assets_export.csv'); },800);
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|