119 lines
4.3 KiB
JavaScript
119 lines
4.3 KiB
JavaScript
const API_BASE = window.location.origin;
|
|
|
|
function getTrackingUri() {
|
|
return document.getElementById('trackingUri').value.trim() || null;
|
|
}
|
|
|
|
function formatTime(ts) {
|
|
if (!ts) return '';
|
|
const d = new Date(ts);
|
|
return d.toLocaleDateString('ko-KR') + ' ' + d.toLocaleTimeString('ko-KR', {hour: '2-digit', minute: '2-digit'});
|
|
}
|
|
|
|
async function loadExperiments() {
|
|
const container = document.getElementById('content');
|
|
container.innerHTML = '<div class="loading">Loading...</div>';
|
|
|
|
const uri = getTrackingUri();
|
|
const params = uri ? '?tracking_uri=' + encodeURIComponent(uri) : '';
|
|
|
|
try {
|
|
const res = await fetch(API_BASE + '/api/experiments' + params);
|
|
if (!res.ok) throw new Error('Failed: ' + res.status);
|
|
const experiments = await res.json();
|
|
|
|
if (experiments.length === 0) {
|
|
container.innerHTML = '<div class="loading">No experiments found.</div>';
|
|
return;
|
|
}
|
|
|
|
container.innerHTML = '';
|
|
experiments.forEach(function(exp) {
|
|
const card = document.createElement('div');
|
|
card.className = 'exp-card';
|
|
card.innerHTML =
|
|
'<div class="exp-header" onclick="toggleExp(this, \'' + exp.experiment_id + '\')">' +
|
|
'<span class="exp-arrow">▶</span>' +
|
|
'<span class="exp-name">' + exp.name + '</span>' +
|
|
'<span class="exp-badge">' + exp.run_count + ' runs</span>' +
|
|
'</div>' +
|
|
'<div class="run-list" id="runs-' + exp.experiment_id + '">' +
|
|
'<div class="loading">Loading runs...</div>' +
|
|
'</div>';
|
|
container.appendChild(card);
|
|
});
|
|
} catch (e) {
|
|
container.innerHTML = '<div class="error">Connection failed: ' + e.message + '</div>';
|
|
}
|
|
}
|
|
|
|
async function toggleExp(header, expId) {
|
|
const arrow = header.querySelector('.exp-arrow');
|
|
const runList = document.getElementById('runs-' + expId);
|
|
|
|
if (runList.classList.contains('open')) {
|
|
runList.classList.remove('open');
|
|
arrow.classList.remove('open');
|
|
return;
|
|
}
|
|
|
|
arrow.classList.add('open');
|
|
runList.classList.add('open');
|
|
runList.innerHTML = '<div class="loading">Loading runs...</div>';
|
|
|
|
const uri = getTrackingUri();
|
|
const params = uri ? '?tracking_uri=' + encodeURIComponent(uri) : '';
|
|
|
|
try {
|
|
const res = await fetch(API_BASE + '/api/experiments/' + expId + '/runs' + params);
|
|
const runs = await res.json();
|
|
|
|
if (runs.length === 0) {
|
|
runList.innerHTML = '<div class="run-row" style="color:#888;">No runs</div>';
|
|
return;
|
|
}
|
|
|
|
runList.innerHTML = '';
|
|
runs.forEach(function(run) {
|
|
const row = document.createElement('div');
|
|
row.className = 'run-row';
|
|
row.innerHTML =
|
|
'<span class="run-name">' + (run.run_name || run.run_id.substring(0, 8)) + '</span>' +
|
|
'<span class="status ' + run.status + '">' + run.status + '</span>' +
|
|
'<span class="run-time">' + formatTime(run.start_time) + '</span>' +
|
|
'<div class="btn-group">' +
|
|
'<button class="btn btn-view" onclick="viewRun(\'' + run.run_id + '\')">View</button>' +
|
|
'<button class="btn btn-train" onclick="trainRun(\'' + run.run_id + '\')">Train</button>' +
|
|
'<button class="btn btn-serve" onclick="serveRun(\'' + run.run_id + '\')">Serve</button>' +
|
|
'</div>';
|
|
runList.appendChild(row);
|
|
});
|
|
} catch (e) {
|
|
runList.innerHTML = '<div class="error">Failed to load runs</div>';
|
|
}
|
|
}
|
|
|
|
async function viewRun(runId) {
|
|
const uri = getTrackingUri();
|
|
const params = uri ? '?tracking_uri=' + encodeURIComponent(uri) : '';
|
|
try {
|
|
const res = await fetch(API_BASE + '/api/runs/' + runId + '/mlflow-link' + params);
|
|
const data = await res.json();
|
|
window.open(data.url, '_blank');
|
|
} catch (e) {
|
|
alert('Failed to get MLflow link');
|
|
}
|
|
}
|
|
|
|
function trainRun(runId) {
|
|
alert('Train is not implemented yet.');
|
|
}
|
|
|
|
function serveRun(runId) {
|
|
alert('Serve: model_uri required. Use Swagger UI (/docs) for now.');
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
loadExperiments();
|
|
});
|