The card was fixed to the 25 seeded rows, so a new site such as IXcellerate MOS7 (34 MW, under construction) could only be shoehorned in by overwriting an existing row. Add create and delete (cascading to incidents), make position an insert that shifts the rest, and keep positions dense. More than 25 rows are allowed: the card shows the first 25 and the rest wait in reserve. "Sort by MW" re-ranks by the parsed power figure, unknown last. Assisted-by: Claude:opus-5
68 lines
4.9 KiB
Text
68 lines
4.9 KiB
Text
<% fresh = @dc.new? %>
|
||
<div class="header">
|
||
<h1><%= fresh ? 'New datacenter' : "##{@dc.position} #{@dc.name_ru}" %></h1>
|
||
<p class="tagline"><a href="/admin/bingo">← bingo</a><% if !fresh && @dc.position > Bingo::SIZE**2 %> · off card (reserve)<% end %></p>
|
||
</div>
|
||
|
||
<% if @flash %><div class="form-error-base"><div><%= @flash %></div></div><% end %>
|
||
|
||
<% unless fresh %>
|
||
<section class="section">
|
||
<h2>Photo</h2>
|
||
<% if @dc.photo_file %>
|
||
<p><img src="/admin/bingo/p/<%= @dc.photo_file %>" alt="" style="max-width: 100%; max-height: 280px" /></p>
|
||
<form method="post" action="/admin/bingo/dc/<%= @dc.id %>/photo/delete">
|
||
<input type="hidden" name="authenticity_token" value="<%= csrf_token %>" />
|
||
<button type="submit" class="link-button">remove from card</button>
|
||
</form>
|
||
<% end %>
|
||
<form class="invoice-form" method="post" action="/admin/bingo/dc/<%= @dc.id %>/photo" enctype="multipart/form-data">
|
||
<input type="hidden" name="authenticity_token" value="<%= csrf_token %>" />
|
||
<div class="field"><label for="photo">Upload <span class="optional">(JPEG/PNG/WebP, ≤ 8 MB)</span></label><input type="file" id="photo" name="photo" accept="image/jpeg,image/png,image/webp" /></div>
|
||
<div class="field"><label for="photo_url">…or import from URL <span class="optional">(blank = saved source URL)</span></label><input type="url" id="photo_url" name="url" placeholder="<%= @dc.photo_source_url %>" /></div>
|
||
<button type="submit" class="download-button">Store photo</button>
|
||
</form>
|
||
</section>
|
||
<% end %>
|
||
|
||
<section class="section">
|
||
<h2>Details</h2>
|
||
<form class="invoice-form" method="post" action="<%= fresh ? '/admin/bingo/dc' : "/admin/bingo/dc/#{@dc.id}" %>" autocomplete="off">
|
||
<input type="hidden" name="authenticity_token" value="<%= csrf_token %>" />
|
||
<% if fresh %>
|
||
<div class="field"><label for="slug">Slug <span class="optional">(permanent; used in photo names, e.g. ix-mos7)</span></label><input type="text" id="slug" name="slug" value="<%= @dc.slug %>" required pattern="[a-z0-9]+(-[a-z0-9]+)*" /></div>
|
||
<% end %>
|
||
<div class="invoice-grid">
|
||
<% %w[ru en uk].each do |l| %>
|
||
<div class="field"><label for="name_<%= l %>">Name (<%= l %>)</label><input type="text" id="name_<%= l %>" name="name_<%= l %>" value="<%= @dc[:"name_#{l}"] %>" <%= 'required' if l == 'ru' %> /></div>
|
||
<% end %>
|
||
<% %w[ru en uk].each do |l| %>
|
||
<div class="field"><label for="city_<%= l %>">City (<%= l %>)</label><input type="text" id="city_<%= l %>" name="city_<%= l %>" value="<%= @dc[:"city_#{l}"] %>" <%= 'required' if l == 'ru' %> /></div>
|
||
<% end %>
|
||
<div class="field"><label for="operator">Operator</label><input type="text" id="operator" name="operator" value="<%= @dc.operator %>" required /></div>
|
||
<div class="field"><label for="mw">MW <span class="optional">(number or range)</span></label><input type="text" id="mw" name="mw" value="<%= @dc.mw %>" /></div>
|
||
<div class="field">
|
||
<label for="status">Status</label>
|
||
<select id="status" name="status">
|
||
<% %w[operational building].each do |s| %><option <%= 'selected' if @dc.status == s %>><%= s %></option><% end %>
|
||
</select>
|
||
</div>
|
||
<div class="field"><label for="year">Year</label><input type="text" id="year" name="year" value="<%= @dc.year %>" inputmode="numeric" /></div>
|
||
<div class="field"><label for="position">Position <span class="optional">(inserts here; 1–<%= Bingo::SIZE**2 %> are on the card<%= ', blank = last' if fresh %>)</span></label><input type="text" id="position" name="position" value="<%= @dc.position %>" inputmode="numeric" /></div>
|
||
</div>
|
||
<div class="field"><label for="photo_credit">Photo credit</label><input type="text" id="photo_credit" name="photo_credit" value="<%= @dc.photo_credit %>" /></div>
|
||
<div class="field"><label for="photo_source_url">Photo source URL</label><input type="url" id="photo_source_url" name="photo_source_url" value="<%= @dc.photo_source_url %>" /></div>
|
||
<div class="field"><label for="info_url">Info / fact source URL</label><input type="url" id="info_url" name="info_url" value="<%= @dc.info_url %>" /></div>
|
||
<button type="submit" class="download-button"><%= fresh ? 'Add datacenter' : 'Save' %></button>
|
||
</form>
|
||
</section>
|
||
|
||
<% unless fresh %>
|
||
<section class="section">
|
||
<h2>Danger zone</h2>
|
||
<form method="post" action="/admin/bingo/dc/<%= @dc.id %>/delete" onsubmit="return confirm('Delete this datacenter and all its incidents? This cannot be undone.')">
|
||
<input type="hidden" name="authenticity_token" value="<%= csrf_token %>" />
|
||
<button type="submit" class="link-button">delete this datacenter<%= " (and #{@dc.incidents.size} incident(s))" if @dc.incidents.any? %></button>
|
||
</form>
|
||
</section>
|
||
<% end %>
|