279 lines
11 KiB
HTML
279 lines
11 KiB
HTML
{{define "instance-detail.html"}}
|
|
<!doctype html>
|
|
<html lang="{{.Language}}">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>
|
|
{{.InstanceDetail.Instance.Preview.DisplayName}}
|
|
· DoGaMa
|
|
</title>
|
|
<link rel="stylesheet" href="/static/app.v2.css">
|
|
<link rel="stylesheet" href="/static/theme.v2.css">
|
|
</head>
|
|
<body class="app-body">
|
|
{{template "sidebar" .}}
|
|
<main class="app-main">
|
|
<a class="back-link" href="/">
|
|
←
|
|
{{.Msg "instance.back"}}
|
|
</a>
|
|
{{if .InstanceDetail.Message}}
|
|
<p class="{{if .InstanceDetail.MessageError}}error{{else}}notice{{end}}">
|
|
{{.InstanceDetail.Message}}
|
|
</p>
|
|
{{end}}
|
|
<section class="instance-detail">
|
|
<aside>
|
|
<div class="game-cover">
|
|
{{if .InstanceDetail.Instance.Preview.Game.ArtworkURL}}
|
|
<img src="{{.InstanceDetail.Instance.Preview.Game.ArtworkURL}}" alt="{{.InstanceDetail.Instance.Preview.Game.Name}}">
|
|
{{else}}
|
|
<span>
|
|
◈
|
|
</span>
|
|
{{end}}
|
|
</div>
|
|
</aside>
|
|
<article>
|
|
<div class="detail-actions">
|
|
<form method="post" action="/instances/{{.InstanceDetail.Instance.ID}}/start">
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
<button class="action-start" {{if not .InstanceDetail.CanStart}}disabled{{end}}>
|
|
{{.Msg "instance.start"}}
|
|
</button>
|
|
</form>
|
|
<form method="post" action="/instances/{{.InstanceDetail.Instance.ID}}/stop">
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
<button class="action-stop" {{if not .InstanceDetail.CanStop}}disabled{{end}}>
|
|
{{.Msg "instance.stop"}}
|
|
</button>
|
|
</form>
|
|
<form method="post" action="/instances/{{.InstanceDetail.Instance.ID}}/backup">
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
<button class="action-backup" {{if not .InstanceDetail.CanBackup}}disabled{{end}}>
|
|
{{.Msg "instance.backup"}}
|
|
</button>
|
|
</form>
|
|
<form method="post" action="/instances/{{.InstanceDetail.Instance.ID}}/update">
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
<button class="action-update" {{if not .InstanceDetail.CanUpdate}}disabled{{end}} title="{{if eq .InstanceDetail.UpdateStatus "available"}}{{.Msg "instance.update_available"}}{{else if eq .InstanceDetail.UpdateStatus "up_to_date"}}{{.Msg "instance.update_current"}}{{else}}{{.Msg "instance.update_unknown"}}{{end}}">
|
|
{{.Msg "instance.update"}}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
<p class="eyebrow">
|
|
{{.InstanceDetail.Instance.Preview.Game.Name}}
|
|
</p>
|
|
<h1>
|
|
{{.InstanceDetail.Instance.Preview.DisplayName}}
|
|
</h1>
|
|
<p class="game-description">
|
|
{{.InstanceDetail.Instance.Preview.Description}}
|
|
</p>
|
|
<p class="status-badge status-{{statusClass .InstanceDetail.Instance.LifecycleState}}">
|
|
<i>
|
|
</i>
|
|
{{statusLabel .InstanceDetail.Instance.LifecycleState}}
|
|
</p>
|
|
<dl class="instance-info">
|
|
<div>
|
|
<dt>
|
|
♙
|
|
{{.Msg "instance.players"}}
|
|
</dt>
|
|
<dd>
|
|
{{if .InstanceDetail.Live.Metrics}}
|
|
{{.InstanceDetail.Live.Metrics.CurrentPlayers}}
|
|
/
|
|
{{.InstanceDetail.Live.Metrics.MaxPlayers}}
|
|
live
|
|
{{else}}
|
|
{{.Msg "instance.unavailable"}}
|
|
{{if .InstanceDetail.MaxPlayers}}
|
|
/
|
|
{{.InstanceDetail.MaxPlayers}}
|
|
configured
|
|
{{end}}
|
|
{{end}}
|
|
</dd>
|
|
</div>
|
|
<div>
|
|
<dt>
|
|
⚿
|
|
{{.Msg "instance.password"}}
|
|
</dt>
|
|
<dd>
|
|
{{if .InstanceDetail.PasswordSet}}
|
|
••••••••
|
|
{{if .IsAdmin}}
|
|
<form method="post" action="/instances/{{.InstanceDetail.Instance.ID}}/password/reveal">
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
<button type="submit">
|
|
Reveal
|
|
</button>
|
|
</form>
|
|
{{end}}
|
|
{{else}}
|
|
{{.Msg "instance.unavailable"}}
|
|
{{end}}
|
|
</dd>
|
|
</div>
|
|
</dl>
|
|
{{if .InstanceDetail.Live.ServerInfo}}
|
|
<p>
|
|
{{.InstanceDetail.Live.ServerInfo.Name}}
|
|
·
|
|
{{.InstanceDetail.Live.ServerInfo.GameVersion}}
|
|
</p>
|
|
{{end}}
|
|
</article>
|
|
</section>
|
|
<div class="instance-detail-lower">
|
|
<section class="panel">
|
|
<div class="section-heading">
|
|
<h2>
|
|
{{.Msg "instance.backups"}}
|
|
</h2>
|
|
</div>
|
|
{{if .InstanceDetail.Backups}}
|
|
<ul class="backup-list">
|
|
{{range .InstanceDetail.Backups}}
|
|
<li>
|
|
<div>
|
|
<strong>
|
|
{{.CreatedAt}}
|
|
</strong>
|
|
<small>
|
|
{{.Origin}}
|
|
·
|
|
{{.Status}}
|
|
·
|
|
{{formatBytes .SizeBytes}}
|
|
</small>
|
|
</div>
|
|
{{if $.InstanceDetail.CanRestore}}
|
|
<form method="post" action="/instances/{{$.InstanceDetail.Instance.ID}}/backups/{{.ID}}/restore">
|
|
<input type="hidden" name="csrf_token" value="{{$.CSRFToken}}">
|
|
<input type="hidden" name="confirm" value="restore">
|
|
<button class="action-restore">
|
|
{{$.Msg "instance.restore"}}
|
|
</button>
|
|
</form>
|
|
{{end}}
|
|
</li>
|
|
{{end}}
|
|
</ul>
|
|
{{else}}
|
|
<p class="muted">
|
|
{{.Msg "instance.no_backups"}}
|
|
</p>
|
|
{{end}}
|
|
</section>
|
|
<section class="panel">
|
|
<div class="section-heading">
|
|
<h2>
|
|
{{.Msg "instance.server_functions"}}
|
|
</h2>
|
|
</div>
|
|
{{if .InstanceDetail.ModuleAvailable}}
|
|
{{if .InstanceDetail.CanAnnounce}}
|
|
<form method="post" action="/instances/{{.InstanceDetail.Instance.ID}}/module/announcement">
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
<label>
|
|
Announcement
|
|
<input name="message" maxlength="1000" required>
|
|
</label>
|
|
<button>
|
|
Send
|
|
</button>
|
|
</form>
|
|
{{end}}
|
|
{{if .InstanceDetail.Live.Players}}
|
|
<ul>
|
|
{{range .InstanceDetail.Live.Players}}
|
|
<li>
|
|
{{.DisplayName}}
|
|
<code>
|
|
{{.PlayerID}}
|
|
</code>
|
|
{{if $.InstanceDetail.CanKick}}
|
|
<form method="post" action="/instances/{{$.InstanceDetail.Instance.ID}}/module/kick">
|
|
<input type="hidden" name="csrf_token" value="{{$.CSRFToken}}">
|
|
<input type="hidden" name="player_id" value="{{.PlayerID}}">
|
|
<input name="reason" maxlength="1000">
|
|
<button>
|
|
Kick
|
|
</button>
|
|
</form>
|
|
{{end}}
|
|
{{if $.InstanceDetail.CanBan}}
|
|
<form method="post" action="/instances/{{$.InstanceDetail.Instance.ID}}/module/ban">
|
|
<input type="hidden" name="csrf_token" value="{{$.CSRFToken}}">
|
|
<input type="hidden" name="player_id" value="{{.PlayerID}}">
|
|
<input name="reason" maxlength="1000">
|
|
<button>
|
|
Ban
|
|
</button>
|
|
</form>
|
|
{{end}}
|
|
</li>
|
|
{{end}}
|
|
</ul>
|
|
{{end}}
|
|
{{if .InstanceDetail.BansAvailable}}
|
|
{{if .InstanceDetail.Live.Bans}}
|
|
<form method="post" action="/instances/{{.InstanceDetail.Instance.ID}}/module/unban">
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
<label>
|
|
{{.Msg "instance.banned_players"}}
|
|
<select name="player_id" required>
|
|
{{range .InstanceDetail.Live.Bans}}
|
|
<option value="{{.PlayerID}}">
|
|
{{.DisplayName}}
|
|
</option>
|
|
{{end}}
|
|
</select>
|
|
</label>
|
|
<button>
|
|
Unban
|
|
</button>
|
|
</form>
|
|
{{else}}
|
|
<p class="muted">
|
|
{{.Msg "instance.no_banned_players"}}
|
|
</p>
|
|
{{end}}
|
|
{{else if .InstanceDetail.BansUnavailable}}
|
|
<p class="muted">
|
|
{{.Msg "instance.unavailable"}}
|
|
</p>
|
|
{{else if and .InstanceDetail.CanUnban (not .InstanceDetail.Live.Capabilities.list_bans)}}
|
|
<form method="post" action="/instances/{{.InstanceDetail.Instance.ID}}/module/unban">
|
|
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
|
|
<label>
|
|
{{.Msg "instance.player_identifier"}}
|
|
<input name="player_id" maxlength="256" required>
|
|
</label>
|
|
<p class="muted">
|
|
{{.Msg "instance.bans_not_supported"}}
|
|
</p>
|
|
<button>
|
|
Unban
|
|
</button>
|
|
</form>
|
|
{{end}}
|
|
{{else}}
|
|
<p class="muted">
|
|
{{.Msg "instance.module_unavailable"}}
|
|
</p>
|
|
{{end}}
|
|
</section>
|
|
</div>
|
|
</main>
|
|
<script src="/static/app.v2.js">
|
|
</script>
|
|
</body>
|
|
</html>
|
|
{{end}}
|