chore: stage changes before history rewrite
This commit is contained in:
@@ -170,31 +170,63 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<form method="post" action="/settings/apikeys/create" style="display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-bottom:1rem">
|
||||
<input type="text" name="name" placeholder="{{ 'apikey.name_ph'|t(user.language) }}" style="max-width:200px">
|
||||
<button type="submit" class="btn btn-primary btn-sm">{{ 'apikey.create'|t(user.language) }}</button>
|
||||
<form method="post" action="/settings/apikeys/create" style="margin-bottom:1rem">
|
||||
<div style="display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin-bottom:.75rem">
|
||||
<input type="text" name="name" placeholder="{{ 'apikey.name_ph'|t(user.language) }}" style="max-width:200px">
|
||||
<button type="submit" class="btn btn-primary btn-sm">{{ 'apikey.create'|t(user.language) }}</button>
|
||||
</div>
|
||||
<details>
|
||||
<summary style="font-size:.85rem;color:var(--text-muted);cursor:pointer;margin-bottom:.5rem">{{ 'apikey.permissions'|t(user.language) }}</summary>
|
||||
<div style="display:flex;flex-wrap:wrap;gap:.75rem 1.5rem">
|
||||
{% for scope, label in [
|
||||
('profiles:read', 'apikey.perm.profiles_read'),
|
||||
('profiles:write', 'apikey.perm.profiles_write'),
|
||||
('postcards:read', 'apikey.perm.postcards_read'),
|
||||
('postcards:write', 'apikey.perm.postcards_write'),
|
||||
('images:upload', 'apikey.perm.images_upload')
|
||||
] %}
|
||||
<label style="display:flex;align-items:center;gap:.3rem;font-size:.85rem;white-space:nowrap">
|
||||
<input type="checkbox" name="permissions" value="{{ scope }}">
|
||||
{{ label|t(user.language) }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<p style="font-size:.78rem;color:var(--text-muted);margin-top:.5rem">{{ 'apikey.perm.hint'|t(user.language) }}</p>
|
||||
</details>
|
||||
</form>
|
||||
|
||||
{% if api_keys %}
|
||||
<div class="table-wrap">
|
||||
<table class="table">
|
||||
<div style="overflow-x:auto;-webkit-overflow-scrolling:touch">
|
||||
<table class="table" style="min-width:700px;white-space:nowrap">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ 'apikey.name'|t(user.language) }}</th>
|
||||
<th>{{ 'apikey.key'|t(user.language) }}</th>
|
||||
<th>{{ 'apikey.permissions'|t(user.language) }}</th>
|
||||
<th>{{ 'apikey.created_at'|t(user.language) }}</th>
|
||||
<th>{{ 'apikey.last_used'|t(user.language) }}</th>
|
||||
<th></th>
|
||||
<th style="white-space:nowrap"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for ak in api_keys %}
|
||||
{% set perms = ak.permissions|default('[]', true)|json_loads %}
|
||||
<tr>
|
||||
<td>{{ ak.name or '—' }}</td>
|
||||
<td><code style="font-size:.8rem">{{ ak.key[:8] }}****</code></td>
|
||||
<td>{{ ak.created_at|to_local|strftime('%Y-%m-%d') }}</td>
|
||||
<td>{% if ak.last_used_at %}{{ ak.last_used_at|to_local|strftime('%Y-%m-%d') }}{% else %}—{% endif %}</td>
|
||||
<td>
|
||||
<td style="white-space:nowrap"><strong>{{ ak.name or '—' }}</strong></td>
|
||||
<td><code style="font-size:.78rem">{{ ak.key[:8] }}****</code></td>
|
||||
<td style="white-space:nowrap">
|
||||
{% if not perms %}
|
||||
<span class="badge" style="background:var(--sent);font-size:.75rem">{{ 'apikey.perm_full_access'|t(user.language) }}</span>
|
||||
{% else %}
|
||||
{% for p in perms %}
|
||||
<span class="badge" style="font-size:.7rem;margin:1px">{{ p }}</span>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</td>
|
||||
<td style="white-space:nowrap;font-size:.82rem">{{ ak.created_at|to_local|strftime('%Y-%m-%d %H:%M:%S') }}</td>
|
||||
<td style="white-space:nowrap;font-size:.82rem">{% if ak.last_used_at %}{{ ak.last_used_at|to_local|strftime('%Y-%m-%d %H:%M:%S') }}{% else %}—{% endif %}</td>
|
||||
<td style="white-space:nowrap">
|
||||
<button type="button" class="btn btn-sm" onclick="toggleAkEdit({{ ak.id }})">{{ 'apikey.edit'|t(user.language) }}</button>
|
||||
<form method="post" action="/settings/apikeys/{{ ak.id }}/delete" style="display:inline" onsubmit="return confirm('{{ 'apikey.confirm_delete'|t(user.language) }}')">
|
||||
<button type="submit" class="btn btn-danger btn-sm">{{ 'apikey.delete'|t(user.language) }}</button>
|
||||
</form>
|
||||
@@ -204,6 +236,38 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% for ak in api_keys %}
|
||||
{% set perms = ak.permissions|default('[]', true)|json_loads %}
|
||||
<div id="ak-edit-{{ ak.id }}" style="display:none;margin-top:.5rem;background:var(--card-bg);border:1px solid var(--border);border-radius:8px;padding:1rem">
|
||||
<h4 style="font-size:.85rem;margin-bottom:.75rem;color:var(--text-muted)">{{ 'apikey.edit'|t(user.language) }}: {{ ak.name or '—' }}</h4>
|
||||
<form method="post" action="/settings/apikeys/{{ ak.id }}/edit" style="display:flex;flex-direction:column;gap:.5rem">
|
||||
<div style="display:flex;align-items:center;gap:.5rem;flex-wrap:wrap">
|
||||
<label style="font-size:.85rem;white-space:nowrap">{{ 'apikey.name'|t(user.language) }}</label>
|
||||
<input type="text" name="name" value="{{ ak.name }}" style="max-width:200px">
|
||||
</div>
|
||||
<div style="display:flex;flex-wrap:wrap;gap:.6rem 1.25rem">
|
||||
{% for scope, label in [
|
||||
('profiles:read', 'apikey.perm.profiles_read'),
|
||||
('profiles:write', 'apikey.perm.profiles_write'),
|
||||
('postcards:read', 'apikey.perm.postcards_read'),
|
||||
('postcards:write', 'apikey.perm.postcards_write'),
|
||||
('images:upload', 'apikey.perm.images_upload')
|
||||
] %}
|
||||
<label style="display:flex;align-items:center;gap:.3rem;font-size:.85rem;white-space:nowrap">
|
||||
<input type="checkbox" name="permissions" value="{{ scope }}" {% if scope in perms %}checked{% endif %}>
|
||||
{{ label|t(user.language) }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div style="display:flex;gap:.5rem;margin-top:.25rem">
|
||||
<button type="submit" class="btn btn-primary btn-sm">{{ 'apikey.save'|t(user.language) }}</button>
|
||||
<button type="button" class="btn btn-sm" onclick="toggleAkEdit({{ ak.id }})">{{ 'apikey.cancel'|t(user.language) }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
{% else %}
|
||||
<div class="empty-state">
|
||||
<p>{{ 'apikey.empty'|t(user.language) }}</p>
|
||||
@@ -219,5 +283,9 @@ function switchTab(name) {
|
||||
event.currentTarget.classList.add('active');
|
||||
document.getElementById('tab-' + name).style.display = '';
|
||||
}
|
||||
function toggleAkEdit(id) {
|
||||
var el = document.getElementById('ak-edit-' + id);
|
||||
if (el) el.style.display = el.style.display === 'none' ? '' : 'none';
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user