forked from snxraven/p2ns
Updates
This commit is contained in:
@@ -39,15 +39,17 @@ async function handleDomainsRoutes(req, res) {
|
||||
for (const domain of domains) {
|
||||
const hash = await getHashForDomain(domain) || 'none';
|
||||
const isLocal = localWriter ? domainClaimants.get(domain)?.has(localWriter) || false : false;
|
||||
// Check if local writer is the resolved claimant (owner)
|
||||
|
||||
let isOwner = false;
|
||||
let consensusState = null;
|
||||
try {
|
||||
const consensusState = await getConsensusState(domain);
|
||||
consensusState = await getConsensusState(domain);
|
||||
isOwner = localWriter ? consensusState.resolvedClaimant === localWriter : false;
|
||||
} catch (err) {
|
||||
logDebug('Admin', `Error checking ownership for ${domain}: ${err.message}`);
|
||||
logDebug('Admin', `Error checking ownership/consensus for ${domain}: ${err.message}`);
|
||||
}
|
||||
resolved.push({ domain, hash, isLocal, isOwner });
|
||||
|
||||
resolved.push({ domain, hash, isLocal, isOwner, consensusState });
|
||||
}
|
||||
let internalDomains = ['p2ns.admin'];
|
||||
try {
|
||||
@@ -59,7 +61,7 @@ async function handleDomainsRoutes(req, res) {
|
||||
// Only add internal domains that aren't already in the resolved list
|
||||
for (const d of internalDomains) {
|
||||
if (!resolved.some(r => r.domain === d)) {
|
||||
resolved.push({ domain: d, hash: 'internal', isLocal: true, isOwner: true });
|
||||
resolved.push({ domain: d, hash: 'internal', isLocal: true, isOwner: true, consensusStatus: 'internal' });
|
||||
}
|
||||
}
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
|
||||
@@ -107,24 +107,17 @@ window.tabs = {
|
||||
<td class="p-3">${item.isLocal && item.hash !== 'internal' ? `<button onclick="removeDomain('${item.domain}')" class="px-2 py-1 bg-red-500 text-white rounded hover:bg-red-600">Remove</button>` : ''}</td>`;
|
||||
return tr;
|
||||
},
|
||||
postFetch: async (data) => {
|
||||
// Fetch consensus states for all domains
|
||||
const domainsWithConsensus = await Promise.all(data.map(async (item) => {
|
||||
if (item.hash === 'internal' || item.hash === 'none') {
|
||||
postFetch: (data) => {
|
||||
// Data already contains consensusState from backend
|
||||
return data.map(item => {
|
||||
if (item.consensusStatus === 'internal' || item.hash === 'internal' || item.hash === 'none') {
|
||||
return { ...item, consensusStatus: 'internal' };
|
||||
}
|
||||
try {
|
||||
const consensusRes = await fetch(`/api/consensus/${encodeURIComponent(item.domain)}`);
|
||||
if (consensusRes.ok) {
|
||||
const consensusState = await consensusRes.json();
|
||||
return { ...item, consensusStatus: consensusState.status, consensusState };
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(`Failed to fetch consensus for ${item.domain}:`, err);
|
||||
}
|
||||
return { ...item, consensusStatus: 'unknown' };
|
||||
}));
|
||||
return domainsWithConsensus;
|
||||
return {
|
||||
...item,
|
||||
consensusStatus: item.consensusState?.status || 'unknown'
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
entries: {
|
||||
|
||||
@@ -25,7 +25,7 @@ async function genericFetch(tabId, shouldRender = true) {
|
||||
window[config.dataKey] = data;
|
||||
|
||||
// Reset infinite scroll state when fetching fresh data
|
||||
if (window.infiniteScrollState && window.infiniteScrollState[tabId]) {
|
||||
if (shouldRender && window.infiniteScrollState && window.infiniteScrollState[tabId]) {
|
||||
window.infiniteScrollState[tabId].loadedCount = 0;
|
||||
window.infiniteScrollState[tabId].lastQuery = '';
|
||||
// Disconnect existing observer
|
||||
|
||||
@@ -148,8 +148,9 @@ function connectWebSocket() {
|
||||
window.updateMap[data.type]();
|
||||
} else {
|
||||
window.updateMap[data.type].forEach(tab => {
|
||||
if (window.activeTab === 'host' || window.activeTab === tab) {
|
||||
if (window.genericFetch) window.genericFetch(tab, true);
|
||||
// Always fetch data in background, but only render if tab is active
|
||||
if (window.genericFetch) {
|
||||
window.genericFetch(tab, window.activeTab === 'host' || window.activeTab === tab);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -39,7 +39,17 @@ async function handleDomainsRoutes(req, res) {
|
||||
for (const domain of domains) {
|
||||
const hash = await getHashForDomain(domain) || 'none';
|
||||
const isLocal = localWriter ? domainClaimants.get(domain)?.has(localWriter) || false : false;
|
||||
resolved.push({ domain, hash, isLocal });
|
||||
|
||||
let isOwner = false;
|
||||
let consensusState = null;
|
||||
try {
|
||||
consensusState = await getConsensusState(domain);
|
||||
isOwner = localWriter ? consensusState.resolvedClaimant === localWriter : false;
|
||||
} catch (err) {
|
||||
logDebug('Admin', `Error checking ownership/consensus for ${domain}: ${err.message}`);
|
||||
}
|
||||
|
||||
resolved.push({ domain, hash, isLocal, isOwner, consensusState });
|
||||
}
|
||||
let internalDomains = ['p2ns.admin'];
|
||||
try {
|
||||
@@ -51,7 +61,7 @@ async function handleDomainsRoutes(req, res) {
|
||||
// Only add internal domains that aren't already in the resolved list
|
||||
for (const d of internalDomains) {
|
||||
if (!resolved.some(r => r.domain === d)) {
|
||||
resolved.push({ domain: d, hash: 'internal', isLocal: true });
|
||||
resolved.push({ domain: d, hash: 'internal', isLocal: true, isOwner: true, consensusStatus: 'internal' });
|
||||
}
|
||||
}
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
|
||||
@@ -22,9 +22,26 @@ window.paginationState = {
|
||||
'dns-conflicts': { current: 1, size: 10 },
|
||||
'host-servers': { current: 1, size: 10 },
|
||||
'host-clients': { current: 1, size: 10 },
|
||||
settings: { current: 1, size: 20 }
|
||||
plugins: { current: 1, size: 10 }
|
||||
};
|
||||
|
||||
// Helper function to get consensus status badge
|
||||
function getConsensusStatusBadge(status) {
|
||||
const badges = {
|
||||
'resolved': '<span class="px-2 py-1 bg-green-500 text-white rounded text-xs">Resolved</span>',
|
||||
'tie': '<span class="px-2 py-1 bg-yellow-500 text-white rounded text-xs">Tie</span>',
|
||||
'insufficient_quorum': '<span class="px-2 py-1 bg-orange-500 text-white rounded text-xs">No Quorum</span>',
|
||||
'no_claims': '<span class="px-2 py-1 bg-gray-500 text-white rounded text-xs">No Claims</span>',
|
||||
'error': '<span class="px-2 py-1 bg-red-500 text-white rounded text-xs">Error</span>',
|
||||
'internal': '<span class="px-2 py-1 bg-blue-500 text-white rounded text-xs">Internal</span>',
|
||||
'unknown': '<span class="px-2 py-1 bg-gray-400 text-white rounded text-xs">Unknown</span>'
|
||||
};
|
||||
return badges[status] || badges['unknown'];
|
||||
}
|
||||
|
||||
// Make function globally available
|
||||
window.getConsensusStatusBadge = getConsensusStatusBadge;
|
||||
|
||||
window.chartColors = {
|
||||
primary: 'rgb(59, 130, 246)',
|
||||
success: 'rgb(34, 197, 94)',
|
||||
@@ -59,10 +76,33 @@ window.tabs = {
|
||||
renderItem: (item) => {
|
||||
const tr = document.createElement('tr');
|
||||
tr.className = 'border-b hover:bg-gray-50 dark:hover:bg-gray-700';
|
||||
|
||||
let consensusInfo = '';
|
||||
if (item.consensusState) {
|
||||
const statusBadge = getConsensusStatusBadge(item.consensusStatus);
|
||||
consensusInfo = `<td class="p-3">${statusBadge}</td>`;
|
||||
} else if (item.consensusStatus === 'internal') {
|
||||
consensusInfo = `<td class="p-3">${getConsensusStatusBadge('internal')}</td>`;
|
||||
} else {
|
||||
consensusInfo = `<td class="p-3">${getConsensusStatusBadge('unknown')}</td>`;
|
||||
}
|
||||
|
||||
tr.innerHTML = `<td class="p-3">${item.domain}${item.isLocal ? '🏠' : ''}</td>
|
||||
<td class="p-3 break-all">${item.hash}</td>
|
||||
${consensusInfo}
|
||||
<td class="p-3">${item.isLocal && item.hash !== 'internal' ? `<button onclick="removeDomain('${item.domain}')" class="px-2 py-1 bg-red-500 text-white rounded hover:bg-red-600">Remove</button>` : ''}</td>`;
|
||||
return tr;
|
||||
},
|
||||
postFetch: (data) => {
|
||||
return data.map(item => {
|
||||
if (item.consensusStatus === 'internal' || item.hash === 'internal' || item.hash === 'none') {
|
||||
return { ...item, consensusStatus: 'internal' };
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
consensusStatus: item.consensusState?.status || 'unknown'
|
||||
};
|
||||
});
|
||||
}
|
||||
},
|
||||
entries: {
|
||||
|
||||
@@ -148,8 +148,9 @@ function connectWebSocket() {
|
||||
window.updateMap[data.type]();
|
||||
} else {
|
||||
window.updateMap[data.type].forEach(tab => {
|
||||
if (window.activeTab === 'host' || window.activeTab === tab) {
|
||||
if (window.genericFetch) window.genericFetch(tab, true);
|
||||
// Always fetch data in background, but only render if tab is active
|
||||
if (window.genericFetch) {
|
||||
window.genericFetch(tab, window.activeTab === 'host' || window.activeTab === tab);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user