- Plus de dépendance aux fichiers externes HTML - Utilise sessionStorage pour éviter les boucles - document.write() pour remplacer complètement la page
204 lines
13 KiB
JavaScript
204 lines
13 KiB
JavaScript
// SCRIPT ÉQUIPE - Affichage direct dans iframe
|
|
(function() {
|
|
'use strict';
|
|
|
|
var path = window.location.pathname;
|
|
var isTeamRoute = path === '/team' || path === '/team/' || path.startsWith('/team/');
|
|
|
|
if (!isTeamRoute) {
|
|
console.log('Page normale - team-block-script inactif');
|
|
return;
|
|
}
|
|
|
|
console.log('ÉQUIPE: Page team détectée');
|
|
|
|
// Éviter les boucles avec sessionStorage
|
|
var loadKey = 'team_page_loaded_' + Date.now().toString().slice(0,-3);
|
|
if (sessionStorage.getItem('team_loading')) {
|
|
console.log('ÉQUIPE: Chargement déjà en cours, abandon');
|
|
return;
|
|
}
|
|
sessionStorage.setItem('team_loading', 'true');
|
|
|
|
// Nettoyer après 2 secondes
|
|
setTimeout(function() {
|
|
sessionStorage.removeItem('team_loading');
|
|
}, 2000);
|
|
|
|
// Stopper le chargement Next.js
|
|
window.stop();
|
|
|
|
// Créer la page directement
|
|
var teamHTML = '<!DOCTYPE html><html lang="fr"><head>' +
|
|
'<meta charset="UTF-8">' +
|
|
'<meta name="viewport" content="width=device-width, initial-scale=1.0">' +
|
|
'<title>Equipe - Laplank</title>' +
|
|
'<script src="https://cdn.jsdelivr.net/npm/cytoscape@3.26.0/dist/cytoscape.min.js"><\/script>' +
|
|
'<script src="https://cdn.jsdelivr.net/npm/cytoscape-cose-bilkent@4.1.0/cytoscape-cose-bilkent.min.js"><\/script>' +
|
|
'<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"><\/script>' +
|
|
'<style>' +
|
|
'*{margin:0;padding:0;box-sizing:border-box}' +
|
|
'body{font-family:system-ui,sans-serif;background:#1a4d3a;color:#e0e0e0;padding:20px}' +
|
|
'.container{max-width:1400px;margin:0 auto}' +
|
|
'header{text-align:center;margin-bottom:30px;padding:20px;background:rgba(26,77,58,0.5);border-radius:8px}' +
|
|
'h1{color:#4ade80;margin-bottom:10px}' +
|
|
'.tabs{display:flex;gap:10px;margin-bottom:20px;flex-wrap:wrap}' +
|
|
'.tab-btn{padding:12px 24px;background:rgba(74,222,128,0.2);border:2px solid #4ade80;color:#4ade80;border-radius:6px;cursor:pointer;font-size:14px;font-weight:600}' +
|
|
'.tab-btn:hover{background:rgba(74,222,128,0.3)}' +
|
|
'.tab-btn.active{background:#4ade80;color:#1a4d3a}' +
|
|
'.tab-content{display:none;background:rgba(26,77,58,0.3);border-radius:8px;padding:20px;margin-bottom:20px}' +
|
|
'.tab-content.active{display:block}' +
|
|
'#network-graph{width:100%;height:700px;background:rgba(0,0,0,0.2);border-radius:8px;border:1px solid rgba(74,222,128,0.3)}' +
|
|
'#congestion-matrix{width:100%;height:600px;background:rgba(0,0,0,0.2);border-radius:8px}' +
|
|
'.genesis-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:15px;margin-bottom:30px}' +
|
|
'.stat-card{background:rgba(74,222,128,0.1);border:1px solid rgba(74,222,128,0.3);border-radius:6px;padding:15px}' +
|
|
'.stat-value{font-size:32px;font-weight:bold;color:#4ade80}' +
|
|
'.stat-label{font-size:14px;color:#a0a0a0;margin-top:5px}' +
|
|
'.member-card{background:rgba(26,77,58,0.5);border:1px solid rgba(74,222,128,0.3);border-radius:6px;padding:15px;margin-bottom:15px}' +
|
|
'.member-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px}' +
|
|
'.member-name{font-size:18px;font-weight:bold;color:#4ade80}' +
|
|
'.member-avail{background:rgba(74,222,128,0.2);padding:5px 12px;border-radius:4px;font-size:14px}' +
|
|
'.tech-list{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}' +
|
|
'.tech-tag{background:rgba(74,222,128,0.2);border:1px solid rgba(74,222,128,0.4);padding:4px 10px;border-radius:4px;font-size:12px}' +
|
|
'.warning-box{background:rgba(255,68,68,0.2);border:1px solid rgba(255,68,68,0.5);border-radius:6px;padding:15px;margin-top:20px}' +
|
|
'.warning-title{color:#ff6b6b;font-weight:bold;margin-bottom:10px}' +
|
|
'.uncovered{background:rgba(255,68,68,0.1);border-left:3px solid #ff6b6b;padding:10px;margin:8px 0;border-radius:4px}' +
|
|
'.legend{display:flex;gap:20px;margin:20px 0;flex-wrap:wrap}' +
|
|
'.legend-item{display:flex;align-items:center;gap:8px}' +
|
|
'.legend-color{width:20px;height:20px;border-radius:4px}' +
|
|
'.loading{text-align:center;padding:40px;color:#4ade80}' +
|
|
'</style>' +
|
|
'</head><body>' +
|
|
'<div class="container">' +
|
|
'<header>' +
|
|
'<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px">' +
|
|
'<a href="/" style="color:#4ade80;text-decoration:none;font-size:18px;font-weight:bold">← Retour au Radar</a>' +
|
|
'<div></div>' +
|
|
'</div>' +
|
|
'<h1>Equipe & Technologies</h1>' +
|
|
'<p>Visualisation des competences et identification de l\'equipe de genese MVP</p>' +
|
|
'</header>' +
|
|
'<div class="tabs">' +
|
|
'<button class="tab-btn active" onclick="showTab(\'network\')">Graphe Reseau</button>' +
|
|
'<button class="tab-btn" onclick="showTab(\'congestion\')">Matrice Congestion</button>' +
|
|
'<button class="tab-btn" onclick="showTab(\'genesis\')">Equipe Genese MVP</button>' +
|
|
'</div>' +
|
|
'<div id="network-tab" class="tab-content active">' +
|
|
'<div class="legend">' +
|
|
'<div class="legend-item"><div class="legend-color" style="background:#4ade80"></div><span>Adopt</span></div>' +
|
|
'<div class="legend-item"><div class="legend-color" style="background:#3997d4"></div><span>Trial</span></div>' +
|
|
'<div class="legend-item"><div class="legend-color" style="background:#f5b336"></div><span>Assess</span></div>' +
|
|
'<div class="legend-item"><div class="legend-color" style="background:#e5695e"></div><span>Hold</span></div>' +
|
|
'<div class="legend-item"><div class="legend-color" style="background:#88ff88"></div><span>Membres</span></div>' +
|
|
'</div>' +
|
|
'<div id="network-graph"></div>' +
|
|
'</div>' +
|
|
'<div id="congestion-tab" class="tab-content">' +
|
|
'<h2 style="margin-bottom:20px">Matrice de Congestion - Technologies Adopt</h2>' +
|
|
'<div id="congestion-matrix"></div>' +
|
|
'</div>' +
|
|
'<div id="genesis-tab" class="tab-content">' +
|
|
'<div id="genesis-team"><div class="loading">Chargement des donnees...</div></div>' +
|
|
'</div>' +
|
|
'</div>' +
|
|
'<script>' +
|
|
'var data=null,networkCy=null,congestionChart=null;' +
|
|
'async function loadData(){' +
|
|
'try{' +
|
|
'var r=await fetch("/team-visualization-data.json");' +
|
|
'if(!r.ok)throw new Error("HTTP "+r.status);' +
|
|
'data=await r.json();' +
|
|
'console.log("Donnees chargees:",Object.keys(data));' +
|
|
'initVis();' +
|
|
'}catch(e){' +
|
|
'console.error("Erreur:",e);' +
|
|
'var msg="<div style=\\"padding:20px;background:rgba(255,152,0,0.1);border:1px solid #ff9800;border-radius:8px;margin:20px\\"><h3 style=\\"color:#ff9800\\">Chargement...</h3><p>Erreur: "+e.message+"</p></div>";' +
|
|
'document.getElementById("network-graph").innerHTML=msg;' +
|
|
'document.getElementById("congestion-matrix").innerHTML=msg;' +
|
|
'document.getElementById("genesis-team").innerHTML=msg;' +
|
|
'}' +
|
|
'}' +
|
|
'function initVis(){initNetwork();initCongestion();initGenesis()}' +
|
|
'function initNetwork(){' +
|
|
'if(!data||!data.network)return;' +
|
|
'networkCy=cytoscape({' +
|
|
'container:document.getElementById("network-graph"),' +
|
|
'elements:data.network,' +
|
|
'style:[' +
|
|
'{selector:"node[type=\\"technology\\"]",style:{"background-color":"data(color)","label":"data(label)","width":function(e){return 30+(e.data("coverage")||0)*8},"height":function(e){return 30+(e.data("coverage")||0)*8},"color":"#fff","font-size":"12px","text-outline-width":2,"text-outline-color":"#000","text-wrap":"wrap","text-max-width":100}},' +
|
|
'{selector:"node[type=\\"member\\"]",style:{"background-color":"#88ff88","label":"data(label)","width":function(e){return 25+(e.data("availability")||0)/3},"height":function(e){return 25+(e.data("availability")||0)/3},"color":"#1a4d3a","font-size":"11px","font-weight":"bold","shape":"ellipse"}},' +
|
|
'{selector:"edge",style:{"width":function(e){return 1+(e.data("weight")||0.5)},"line-color":"#999","opacity":0.6,"curve-style":"bezier"}}' +
|
|
'],' +
|
|
'layout:{name:"cose-bilkent",nodeDimensionsIncludeLabels:true,idealEdgeLength:100,nodeRepulsion:4500,nestingFactor:0.1,gravity:0.25,numIter:2500,tile:true,animate:true,animationDuration:1000}' +
|
|
'});' +
|
|
'}' +
|
|
'function initCongestion(){' +
|
|
'if(!data||!data.congestionMatrix)return;' +
|
|
'var c=echarts.init(document.getElementById("congestion-matrix"));' +
|
|
'congestionChart=c;' +
|
|
'var techs=data.congestionMatrix.map(function(r){return r.technology});' +
|
|
'var members=data.congestionMatrix[0]?data.congestionMatrix[0].members.map(function(m){return m.fullName||m.member}):[];' +
|
|
'var scatter=[];' +
|
|
'data.congestionMatrix.forEach(function(row,i){row.members.forEach(function(m,j){if(m.hasSkill)scatter.push({value:[j,i],member:m.fullName||m.member,tech:row.technology,availability:m.availability})})});' +
|
|
'c.setOption({' +
|
|
'title:{text:"Disponibilite des membres sur les technologies Adopt",left:"center",textStyle:{color:"#e0e0e0"}},' +
|
|
'tooltip:{formatter:function(p){return p.data.member+"<br/>Tech: "+p.data.tech+"<br/>Dispo: "+p.data.availability+"%"}},' +
|
|
'grid:{height:"60%",top:"15%"},' +
|
|
'xAxis:{type:"category",data:members,axisLabel:{rotate:45,color:"#e0e0e0"},axisLine:{lineStyle:{color:"#4ade80"}}},' +
|
|
'yAxis:{type:"category",data:techs,axisLabel:{color:"#e0e0e0"},axisLine:{lineStyle:{color:"#4ade80"}}},' +
|
|
'visualMap:{min:0,max:100,calculable:true,orient:"horizontal",left:"center",bottom:"5%",inRange:{color:["#1a4d3a","#4ade80","#86efac"]},textStyle:{color:"#e0e0e0"}},' +
|
|
'series:[{type:"scatter",data:scatter,symbolSize:function(d){return 15+(d[2]||0)/2},itemStyle:{color:"#4ade80",borderColor:"#1a4d3a",borderWidth:2},label:{show:true,formatter:function(p){return p.data.availability+"%"},color:"#1a4d3a"}}]' +
|
|
'});' +
|
|
'window.addEventListener("resize",function(){c.resize()});' +
|
|
'}' +
|
|
'function initGenesis(){' +
|
|
'if(!data||!data.genesisTeam)return;' +
|
|
'var g=data.genesisTeam;' +
|
|
'var h="<div class=\\"genesis-stats\\">"' +
|
|
'+"<div class=\\"stat-card\\"><div class=\\"stat-value\\">"+g.totalMembers+"</div><div class=\\"stat-label\\">Membres selectionnes</div></div>"' +
|
|
'+"<div class=\\"stat-card\\"><div class=\\"stat-value\\">"+g.totalCapacity+"%</div><div class=\\"stat-label\\">Capacite totale</div></div>"' +
|
|
'+"<div class=\\"stat-card\\"><div class=\\"stat-value\\">"+g.averageAvailability+"%</div><div class=\\"stat-label\\">Disponibilite moyenne</div></div>"' +
|
|
'+"<div class=\\"stat-card\\"><div class=\\"stat-value\\">"+g.coveredTechnologies+"/"+g.totalCoreTechnologies+"</div><div class=\\"stat-label\\">Technologies couvertes</div></div>"' +
|
|
'+"</div>"' +
|
|
'+"<h2 style=\\"margin-bottom:20px;color:#4ade80\\">Membres de l\'equipe de genese</h2>";' +
|
|
'if(g.team.length>0){g.team.forEach(function(m){' +
|
|
'h+="<div class=\\"member-card\\">"' +
|
|
'+"<div class=\\"member-header\\">"' +
|
|
'+"<div><div class=\\"member-name\\">"+(m.fullName||m.member)+"</div>"' +
|
|
'+"<div style=\\"font-size:12px;color:#a0a0a0;margin-top:4px\\">"+(m.role||"")+" - "+m.seniority+" - "+m.coverage+" technologie(s)</div>"' +
|
|
'+"</div>"' +
|
|
'+"<div class=\\"member-avail\\">"+m.availability+"% dispo</div>"' +
|
|
'+"</div>"' +
|
|
'+"<div class=\\"tech-list\\">";' +
|
|
'm.technologies.forEach(function(t){h+="<span class=\\"tech-tag\\">"+t.title+"</span>"});' +
|
|
'h+="</div></div>"' +
|
|
'})}else{h+="<p style=\\"color:#a0a0a0\\">Aucun membre ne repond aux criteres.</p>"}' +
|
|
'if(g.uncoveredTechnologies.length>0){' +
|
|
'h+="<div class=\\"warning-box\\"><div class=\\"warning-title\\">Technologies Adopt non couvertes</div><p style=\\"margin-bottom:10px\\">Ces technologies critiques ne sont pas maitrisees :</p>";' +
|
|
'g.uncoveredTechnologies.forEach(function(t){' +
|
|
'h+="<div class=\\"uncovered\\"><strong>"+t.title+"</strong><div style=\\"font-size:12px;color:#a0a0a0;margin-top:4px\\">Impact: "+t.businessImpact+" - Gap: "+t.skillGap+" - Couverture: "+t.teamCoverage+" personne(s)</div></div>"' +
|
|
'});' +
|
|
'h+="</div>"' +
|
|
'}' +
|
|
'document.getElementById("genesis-team").innerHTML=h;' +
|
|
'}' +
|
|
'function showTab(n){' +
|
|
'document.querySelectorAll(".tab-content").forEach(function(t){t.classList.remove("active")});' +
|
|
'document.querySelectorAll(".tab-btn").forEach(function(b){b.classList.remove("active")});' +
|
|
'document.getElementById(n+"-tab").classList.add("active");' +
|
|
'event.target.classList.add("active");' +
|
|
'if(n==="congestion"&&congestionChart)setTimeout(function(){congestionChart.resize()},100);' +
|
|
'if(n==="network"&&networkCy)setTimeout(function(){networkCy.resize()},100);' +
|
|
'}' +
|
|
'loadData();' +
|
|
'<\/script>' +
|
|
'</body></html>';
|
|
|
|
// Remplacer le document
|
|
document.open();
|
|
document.write(teamHTML);
|
|
document.close();
|
|
|
|
console.log('ÉQUIPE: Page team injectée');
|
|
})();
|