margins for table
This commit is contained in:
@@ -9,6 +9,8 @@
|
||||
let error = null;
|
||||
let filter = 'all'; // all, worked, confirmed, unworked
|
||||
let sort = 'name'; // name, status
|
||||
let groupedData = [];
|
||||
let bands = [];
|
||||
|
||||
onMount(async () => {
|
||||
await loadAwardData();
|
||||
@@ -40,6 +42,9 @@
|
||||
|
||||
award = data.award;
|
||||
entities = data.entities || [];
|
||||
|
||||
// Group data for table display
|
||||
groupDataForTable();
|
||||
} catch (e) {
|
||||
error = e.message;
|
||||
} finally {
|
||||
@@ -47,6 +52,93 @@
|
||||
}
|
||||
}
|
||||
|
||||
function groupDataForTable() {
|
||||
// Group by entity name, then create band columns
|
||||
const entityMap = new Map();
|
||||
const bandsSet = new Set();
|
||||
|
||||
entities.forEach((entity) => {
|
||||
const entityName = entity.entityName || entity.entity || 'Unknown';
|
||||
|
||||
if (!entityMap.has(entityName)) {
|
||||
entityMap.set(entityName, {
|
||||
entityName,
|
||||
bands: new Map(),
|
||||
worked: entity.worked,
|
||||
confirmed: entity.confirmed,
|
||||
});
|
||||
}
|
||||
|
||||
const entityData = entityMap.get(entityName);
|
||||
|
||||
if (entity.band) {
|
||||
bandsSet.add(entity.band);
|
||||
|
||||
if (!entityData.bands.has(entity.band)) {
|
||||
entityData.bands.set(entity.band, []);
|
||||
}
|
||||
|
||||
// Add QSO info to this band
|
||||
entityData.bands.get(entity.band).push({
|
||||
callsign: entity.callsign,
|
||||
mode: entity.mode,
|
||||
confirmed: entity.confirmed,
|
||||
qsoDate: entity.qsoDate,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Convert bands Set to sorted array
|
||||
bands = Array.from(bandsSet).sort();
|
||||
|
||||
// Convert Map to array
|
||||
groupedData = Array.from(entityMap.values());
|
||||
|
||||
// Apply filtering
|
||||
applyFilter();
|
||||
}
|
||||
|
||||
function applyFilter() {
|
||||
// Re-group from original entities with filter applied
|
||||
const filteredEntities = getFilteredEntities();
|
||||
|
||||
const entityMap = new Map();
|
||||
const bandsSet = new Set();
|
||||
|
||||
filteredEntities.forEach((entity) => {
|
||||
const entityName = entity.entityName || entity.entity || 'Unknown';
|
||||
|
||||
if (!entityMap.has(entityName)) {
|
||||
entityMap.set(entityName, {
|
||||
entityName,
|
||||
bands: new Map(),
|
||||
worked: entity.worked,
|
||||
confirmed: entity.confirmed,
|
||||
});
|
||||
}
|
||||
|
||||
const entityData = entityMap.get(entityName);
|
||||
|
||||
if (entity.band) {
|
||||
bandsSet.add(entity.band);
|
||||
|
||||
if (!entityData.bands.has(entity.band)) {
|
||||
entityData.bands.set(entity.band, []);
|
||||
}
|
||||
|
||||
entityData.bands.get(entity.band).push({
|
||||
callsign: entity.callsign,
|
||||
mode: entity.mode,
|
||||
confirmed: entity.confirmed,
|
||||
qsoDate: entity.qsoDate,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
bands = Array.from(bandsSet).sort();
|
||||
groupedData = Array.from(entityMap.values());
|
||||
}
|
||||
|
||||
function getFilteredEntities() {
|
||||
let filtered = [...entities];
|
||||
|
||||
@@ -88,16 +180,9 @@
|
||||
return filtered;
|
||||
}
|
||||
|
||||
function getStatusClass(entity) {
|
||||
if (entity.confirmed) return 'confirmed';
|
||||
if (entity.worked) return 'worked';
|
||||
return 'unworked';
|
||||
}
|
||||
|
||||
function getStatusText(entity) {
|
||||
if (entity.confirmed) return 'Confirmed';
|
||||
if (entity.worked) return 'Worked';
|
||||
return 'Not Worked';
|
||||
// Re-apply filter when filter/sort changes
|
||||
$: if (entities.length > 0) {
|
||||
applyFilter();
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -187,44 +272,46 @@
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div class="entities-list">
|
||||
{#if getFilteredEntities().length === 0}
|
||||
<div class="table-container">
|
||||
{#if groupedData.length === 0}
|
||||
<div class="empty">No entities match the current filter.</div>
|
||||
{:else}
|
||||
{#each getFilteredEntities() as entity (entity.entity)}
|
||||
<div class="entity-card {getStatusClass(entity)}">
|
||||
<div class="entity-info">
|
||||
<div class="entity-name">
|
||||
{entity.entityName || entity.entity || 'Unknown'}
|
||||
{#if entity.points}
|
||||
<span class="points-badge">{entity.points} pts</span>
|
||||
{/if}
|
||||
{#if entity.entityId && entity.entityId !== entity.entityName}
|
||||
<span class="entity-id">({entity.entityId})</span>
|
||||
{/if}
|
||||
</div>
|
||||
<div class="entity-details">
|
||||
{#if entity.callsign}
|
||||
<span class="callsign">{entity.callsign}</span>
|
||||
{/if}
|
||||
{#if entity.band}
|
||||
<span class="band">{entity.band}</span>
|
||||
{/if}
|
||||
{#if entity.mode}
|
||||
<span class="mode">{entity.mode}</span>
|
||||
{/if}
|
||||
{#if entity.qsoDate}
|
||||
<span class="date">{entity.qsoDate}</span>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<div class="entity-status">
|
||||
<span class="status-badge {getStatusClass(entity)}">
|
||||
{getStatusText(entity)}
|
||||
</span>
|
||||
</div>
|
||||
<table class="award-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="entity-column">Entity</th>
|
||||
{#each bands as band}
|
||||
<th class="band-column">{band}</th>
|
||||
{/each}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each groupedData as row}
|
||||
<tr class="{row.confirmed ? 'confirmed' : row.worked ? 'worked' : 'unworked'}">
|
||||
<td class="entity-cell">
|
||||
<div class="entity-name">{row.entityName}</div>
|
||||
</td>
|
||||
{#each bands as band}
|
||||
{@const qsos = row.bands.get(band) || []}
|
||||
<td class="band-cell">
|
||||
{#if qsos.length > 0}
|
||||
<div class="qso-list">
|
||||
{#each qsos as qso}
|
||||
<div class="qso-entry {qso.confirmed ? 'qso-confirmed' : 'qso-worked'}">
|
||||
<span class="callsign">{qso.callsign}</span>
|
||||
<span class="mode">{qso.mode}</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="no-qso">-</div>
|
||||
{/if}
|
||||
</td>
|
||||
{/each}
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
@@ -250,6 +337,16 @@
|
||||
color: #d32f2f;
|
||||
}
|
||||
|
||||
.award-table {
|
||||
border: 1px solid #000;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.award-table td {
|
||||
border: 1px solid #000;
|
||||
padding: 0px 3px 0px 3px;
|
||||
}
|
||||
|
||||
.award-header {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user