forked from xziino/ff14-mitigator
Planner: Info-Panel + Fight-Namen Fix
- Info-Panel in Sidebar: Farbschema-Legende + prägnante Hinweise bei fehlenden Jobs/Zuordnungen - fight.php: immer englischen Endpoint nutzen damit Fight-Namen sprachunabhängig stabil sind Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
86d2a106bb
commit
9a2c1490de
@ -75,8 +75,9 @@ function localized_graphql_uri(string $language): string {
|
|||||||
return preg_replace('#https://[^/]+#', 'https://' . $host, GRAPHQL_URI);
|
return preg_replace('#https://[^/]+#', 'https://' . $host, GRAPHQL_URI);
|
||||||
}
|
}
|
||||||
|
|
||||||
$acceptLanguage = $language === 'jp' ? 'ja' : $language;
|
// Fight names must be stable regardless of language — always use the English endpoint.
|
||||||
$ch = curl_init(localized_graphql_uri($language));
|
// Localization only matters for ability/player names in analysis.php.
|
||||||
|
$ch = curl_init(GRAPHQL_URI);
|
||||||
curl_setopt_array($ch, [
|
curl_setopt_array($ch, [
|
||||||
CURLOPT_POST => true,
|
CURLOPT_POST => true,
|
||||||
CURLOPT_POSTFIELDS => $payload,
|
CURLOPT_POSTFIELDS => $payload,
|
||||||
@ -84,7 +85,6 @@ curl_setopt_array($ch, [
|
|||||||
CURLOPT_HTTPHEADER => [
|
CURLOPT_HTTPHEADER => [
|
||||||
'Content-Type: application/json',
|
'Content-Type: application/json',
|
||||||
'Authorization: Bearer ' . $_SESSION['access_token'],
|
'Authorization: Bearer ' . $_SESSION['access_token'],
|
||||||
'Accept-Language: ' . $acceptLanguage,
|
|
||||||
],
|
],
|
||||||
CURLOPT_SSL_VERIFYPEER => !DEV_MODE,
|
CURLOPT_SSL_VERIFYPEER => !DEV_MODE,
|
||||||
]);
|
]);
|
||||||
|
|||||||
@ -451,6 +451,60 @@
|
|||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Info Panel ──────────────────────────────────────────────────────────────── */
|
||||||
|
.planner-info-panel {
|
||||||
|
margin-top: 14px;
|
||||||
|
padding-top: 14px;
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-section { margin-bottom: 12px; }
|
||||||
|
.info-section:last-child { margin-bottom: 0; }
|
||||||
|
|
||||||
|
.info-section-title {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--t3);
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.06em;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-legend-items {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-legend-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-legend-dot {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border-radius: 2px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.info-legend-dot--buff { background: rgba(200,168,75,.8); }
|
||||||
|
.info-legend-dot--debuff { background: var(--red); }
|
||||||
|
.info-legend-dot--shield { background: var(--blue); }
|
||||||
|
|
||||||
|
.info-legend-label {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--t2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-section--warnings { margin-top: 12px; }
|
||||||
|
|
||||||
|
.info-warning {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 3px 0;
|
||||||
|
}
|
||||||
|
.info-warning--job { color: var(--t2); }
|
||||||
|
.info-warning--missing { color: var(--red); }
|
||||||
|
|
||||||
/* ── Folder Sidebar ──────────────────────────────────────────────────────────── */
|
/* ── Folder Sidebar ──────────────────────────────────────────────────────────── */
|
||||||
.folder-section { margin-bottom: 2px; }
|
.folder-section { margin-bottom: 2px; }
|
||||||
|
|
||||||
|
|||||||
@ -286,6 +286,7 @@ function renderPlanDetail(plan) {
|
|||||||
if (!plan) {
|
if (!plan) {
|
||||||
noplan.style.display = '';
|
noplan.style.display = '';
|
||||||
content.style.display = 'none';
|
content.style.display = 'none';
|
||||||
|
renderInfoPanel(null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,6 +326,7 @@ function renderPlanDetail(plan) {
|
|||||||
});
|
});
|
||||||
initJobSlots(plan.id);
|
initJobSlots(plan.id);
|
||||||
initMechanicClicks(plan.id);
|
initMechanicClicks(plan.id);
|
||||||
|
renderInfoPanel(plan);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderMechanicListHtml(plan) {
|
function renderMechanicListHtml(plan) {
|
||||||
@ -438,6 +440,52 @@ function refreshMechanicList(planId) {
|
|||||||
if (!plan) return;
|
if (!plan) return;
|
||||||
const el = document.getElementById('mechanic-list');
|
const el = document.getElementById('mechanic-list');
|
||||||
if (el) el.innerHTML = renderMechanicListHtml(plan);
|
if (el) el.innerHTML = renderMechanicListHtml(plan);
|
||||||
|
renderInfoPanel(plan);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderInfoPanel(plan) {
|
||||||
|
const el = document.getElementById('planner-info-panel');
|
||||||
|
if (!el) return;
|
||||||
|
|
||||||
|
const legendHtml = `
|
||||||
|
<div class="info-section">
|
||||||
|
<div class="info-section-title">Farbschema</div>
|
||||||
|
<div class="info-legend-items">
|
||||||
|
<div class="info-legend-row"><span class="info-legend-dot info-legend-dot--buff"></span><span class="info-legend-label">Mitigation</span></div>
|
||||||
|
<div class="info-legend-row"><span class="info-legend-dot info-legend-dot--debuff"></span><span class="info-legend-label">Debuff</span></div>
|
||||||
|
<div class="info-legend-row"><span class="info-legend-dot info-legend-dot--shield"></span><span class="info-legend-label">Schild</span></div>
|
||||||
|
</div>
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
if (!plan) { el.innerHTML = legendHtml; return; }
|
||||||
|
|
||||||
|
const activeJobSet = new Set(plan.jobComposition.filter(j => j));
|
||||||
|
const noJobAbilities = new Set();
|
||||||
|
const missingJobPairs = new Set();
|
||||||
|
|
||||||
|
for (const m of plan.mechanics) {
|
||||||
|
for (const a of m.assignments) {
|
||||||
|
if (!a.job) {
|
||||||
|
noJobAbilities.add(a.ability);
|
||||||
|
} else if (!activeJobSet.has(a.job)) {
|
||||||
|
missingJobPairs.add(`${a.job} · ${a.ability}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let warningsHtml = '';
|
||||||
|
if (noJobAbilities.size > 0 || missingJobPairs.size > 0) {
|
||||||
|
warningsHtml = `<div class="info-section info-section--warnings"><div class="info-section-title">Hinweise</div>`;
|
||||||
|
if (noJobAbilities.size > 0) {
|
||||||
|
warningsHtml += `<div class="info-warning info-warning--job">Fähigkeiten ohne Job-Zuordnung</div>`;
|
||||||
|
}
|
||||||
|
if (missingJobPairs.size > 0) {
|
||||||
|
warningsHtml += `<div class="info-warning info-warning--missing">Fähigkeiten mit fehlendem Job</div>`;
|
||||||
|
}
|
||||||
|
warningsHtml += '</div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
el.innerHTML = legendHtml + warningsHtml;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeAssignment(planId, mechanicId, abilityName) {
|
function removeAssignment(planId, mechanicId, abilityName) {
|
||||||
|
|||||||
@ -25,6 +25,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="plan-list"></div>
|
<div id="plan-list"></div>
|
||||||
|
|
||||||
|
<div id="planner-info-panel" class="planner-info-panel"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Right: Plan detail -->
|
<!-- Right: Plan detail -->
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user