feat: indicateurs de statut et configuration des endpoints SubSquid/Cesium+
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Dots de statut en temps réel dans le StatsPanel (ok/slow/error + latence) - Bannière d'alerte si un service est inaccessible - EndpointPopover : sélection parmi nœuds connus, test de latence live, URL custom - Rechargement automatique des données après changement d'endpoint - SubsquidAdapter et CesiumAdapter lisent l'URL active depuis EndpointConfig - InfoPanel mis à jour (overlay DU + statut des services) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
const STORAGE_KEY = {
|
||||
subsquid: 'geoflux-ep-subsquid',
|
||||
cesium: 'geoflux-ep-cesium',
|
||||
} as const;
|
||||
|
||||
export const DEFAULT_ENDPOINTS = {
|
||||
subsquid: 'https://squidv2s.syoul.fr/v1/graphql',
|
||||
cesium: 'https://g1.data.e-is.pro',
|
||||
} as const;
|
||||
|
||||
export const KNOWN_SUBSQUID_NODES: { label: string; url: string }[] = [
|
||||
{ label: 'squidv2s.syoul.fr (défaut)', url: 'https://squidv2s.syoul.fr/v1/graphql' },
|
||||
];
|
||||
|
||||
export const KNOWN_CESIUM_NODES: { label: string; url: string }[] = [
|
||||
{ label: 'g1.data.e-is.pro (défaut)', url: 'https://g1.data.e-is.pro' },
|
||||
];
|
||||
|
||||
export function getSubsquidUrl(): string {
|
||||
return localStorage.getItem(STORAGE_KEY.subsquid) ?? DEFAULT_ENDPOINTS.subsquid;
|
||||
}
|
||||
|
||||
export function getCesiumUrl(): string {
|
||||
return localStorage.getItem(STORAGE_KEY.cesium) ?? DEFAULT_ENDPOINTS.cesium;
|
||||
}
|
||||
|
||||
export function setSubsquidUrl(url: string): void {
|
||||
if (url === DEFAULT_ENDPOINTS.subsquid) localStorage.removeItem(STORAGE_KEY.subsquid);
|
||||
else localStorage.setItem(STORAGE_KEY.subsquid, url);
|
||||
}
|
||||
|
||||
export function setCesiumUrl(url: string): void {
|
||||
if (url === DEFAULT_ENDPOINTS.cesium) localStorage.removeItem(STORAGE_KEY.cesium);
|
||||
else localStorage.setItem(STORAGE_KEY.cesium, url);
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
import { getCesiumUrl } from '../EndpointConfig';
|
||||
|
||||
export const CESIUM_ENDPOINT = 'https://g1.data.e-is.pro';
|
||||
|
||||
@@ -136,7 +137,7 @@ export async function resolveGeoByKeys(
|
||||
_source: ['title', 'city', 'geoPoint'],
|
||||
};
|
||||
|
||||
const response = await fetch(`${CESIUM_ENDPOINT}/user/profile/_search`, {
|
||||
const response = await fetch(`${getCesiumUrl()}/user/profile/_search`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(query),
|
||||
@@ -210,7 +211,7 @@ export async function resolveGeoByNames(
|
||||
_source: ['title', 'city', 'geoPoint'],
|
||||
};
|
||||
|
||||
const response = await fetch(`${CESIUM_ENDPOINT}/user/profile/_search`, {
|
||||
const response = await fetch(`${getCesiumUrl()}/user/profile/_search`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(query),
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
import { z } from 'zod';
|
||||
import { getSubsquidUrl } from '../EndpointConfig';
|
||||
|
||||
export const SUBSQUID_ENDPOINT = 'https://squidv2s.syoul.fr/v1/graphql';
|
||||
|
||||
@@ -136,7 +137,7 @@ const IDENTITY_KEY_MAP_QUERY = `
|
||||
* car previousId = clé génesis = clé Ed25519 v1 = _id dans Cesium+
|
||||
*/
|
||||
export async function buildIdentityKeyMap(): Promise<Map<string, string>> {
|
||||
const response = await fetch(SUBSQUID_ENDPOINT, {
|
||||
const response = await fetch(getSubsquidUrl(), {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ query: IDENTITY_KEY_MAP_QUERY }),
|
||||
@@ -157,7 +158,7 @@ export async function buildIdentityKeyMap(): Promise<Map<string, string>> {
|
||||
export async function fetchCurrentUD(): Promise<number> {
|
||||
const UD_FALLBACK = 11.78; // valeur au bloc 225874 — mis à jour si la requête échoue
|
||||
try {
|
||||
const response = await fetch(SUBSQUID_ENDPOINT, {
|
||||
const response = await fetch(getSubsquidUrl(), {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
@@ -193,7 +194,7 @@ const ACTIVE_MEMBERS_QUERY = `
|
||||
|
||||
/** Retourne la liste des clés SS58 de tous les membres WoT actifs. */
|
||||
export async function fetchActiveMemberKeys(): Promise<string[]> {
|
||||
const res = await fetch(SUBSQUID_ENDPOINT, {
|
||||
const res = await fetch(getSubsquidUrl(), {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ query: ACTIVE_MEMBERS_QUERY }),
|
||||
@@ -222,7 +223,7 @@ export async function fetchTransfers(
|
||||
Date.now() - periodDays * 24 * 60 * 60 * 1000
|
||||
).toISOString();
|
||||
|
||||
const response = await fetch(SUBSQUID_ENDPOINT, {
|
||||
const response = await fetch(getSubsquidUrl(), {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
|
||||
Reference in New Issue
Block a user