Use htmx to switch between settings tabs
This commit is contained in:
@@ -5,12 +5,12 @@
|
|||||||
<!-- Settings Navigation -->
|
<!-- Settings Navigation -->
|
||||||
<div class="mb-6 border-b border-gray-200 dark:border-gray-700">
|
<div class="mb-6 border-b border-gray-200 dark:border-gray-700">
|
||||||
<nav class="-mb-px flex space-x-8">
|
<nav class="-mb-px flex space-x-8">
|
||||||
<a href="{{ url_for('settings.api_keys') }}"
|
<a hx-get="{{ url_for('settings.api_keys') }}" hx-target="#container" hx-swap="innerHTML" hx-push-url="true"
|
||||||
class="border-b-2 border-blue-500 text-blue-600 dark:text-blue-400 py-4 px-1 text-sm font-medium">
|
class="border-b-2 border-blue-500 text-blue-600 dark:text-blue-400 py-4 px-1 text-sm font-medium cursor-pointer">
|
||||||
API Keys
|
API Keys
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ url_for('settings.export') }}"
|
<a hx-get="{{ url_for('settings.export') }}" hx-target="#container" hx-swap="innerHTML" hx-push-url="true"
|
||||||
class="border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300 py-4 px-1 text-sm font-medium">
|
class="border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300 py-4 px-1 text-sm font-medium cursor-pointer">
|
||||||
Export Data
|
Export Data
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
@@ -53,37 +53,30 @@
|
|||||||
<tr id="key-row-{{ key.id }}">
|
<tr id="key-row-{{ key.id }}">
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">{{
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">{{
|
||||||
key.name }}</td>
|
key.name }}</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">{{ key.key[:8]
|
||||||
{{ key.key[:8] }}...
|
}}...</td>
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 text-sm text-gray-500 dark:text-gray-400">
|
<td class="px-6 py-4 text-sm text-gray-500 dark:text-gray-400">
|
||||||
{% for scope in key.scopes %}
|
{% for scope in key.scopes %}
|
||||||
<span
|
<span
|
||||||
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 mr-1">
|
class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200 mr-1">{{
|
||||||
{{ scope }}
|
scope }}</span>
|
||||||
</span>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">{{
|
||||||
{{ key.created_at.strftime('%Y-%m-%d') }}
|
key.created_at.strftime('%Y-%m-%d') }}</td>
|
||||||
</td>
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">{{
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
|
key.last_used_at.strftime('%Y-%m-%d %H:%M') if key.last_used_at else 'Never' }}</td>
|
||||||
{{ key.last_used_at.strftime('%Y-%m-%d %H:%M') if key.last_used_at else 'Never' }}
|
|
||||||
</td>
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
|
||||||
<button hx-delete="{{ url_for('settings.delete_api_key', key_id=key.id) }}"
|
<button hx-delete="{{ url_for('settings.delete_api_key', key_id=key.id) }}"
|
||||||
hx-target="#key-row-{{ key.id }}" hx-swap="outerHTML"
|
hx-target="#key-row-{{ key.id }}" hx-swap="outerHTML"
|
||||||
hx-confirm="Are you sure you want to revoke this key?"
|
hx-confirm="Are you sure you want to revoke this key?"
|
||||||
class="text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300">
|
class="text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300">Revoke</button>
|
||||||
Revoke
|
|
||||||
</button>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% else %}
|
{% else %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="6" class="px-6 py-4 text-center text-sm text-gray-500 dark:text-gray-400">
|
<td colspan="6" class="px-6 py-4 text-center text-sm text-gray-500 dark:text-gray-400">No API keys
|
||||||
No API keys found. Generate one to get started.
|
found. Generate one to get started.</td>
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
@@ -101,7 +94,6 @@
|
|||||||
<input type="text" name="name" required placeholder="e.g., CI/CD Pipeline"
|
<input type="text" name="name" required placeholder="e.g., CI/CD Pipeline"
|
||||||
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:text-white">
|
class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:text-white">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Scopes</label>
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1">Scopes</label>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
@@ -110,7 +102,6 @@
|
|||||||
class="rounded border-gray-300 text-blue-600 focus:ring-blue-500">
|
class="rounded border-gray-300 text-blue-600 focus:ring-blue-500">
|
||||||
<span class="ml-2 text-sm text-gray-600 dark:text-gray-400">Full Access (*)</span>
|
<span class="ml-2 text-sm text-gray-600 dark:text-gray-400">Full Access (*)</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="mt-3 border-t pt-3">
|
<div class="mt-3 border-t pt-3">
|
||||||
<p class="text-xs font-medium text-gray-500 mb-2">Or limit to specific functions:</p>
|
<p class="text-xs font-medium text-gray-500 mb-2">Or limit to specific functions:</p>
|
||||||
<div class="max-h-40 overflow-y-auto space-y-2 pl-1">
|
<div class="max-h-40 overflow-y-auto space-y-2 pl-1">
|
||||||
@@ -126,16 +117,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<p class="mt-1 text-xs text-gray-500">Select "Full Access" or specific functions.</p>
|
<p class="mt-1 text-xs text-gray-500">Select "Full Access" or specific functions.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end space-x-3">
|
<div class="flex justify-end space-x-3">
|
||||||
<button type="button" onclick="document.getElementById('create-key-modal').close()"
|
<button type="button" onclick="document.getElementById('create-key-modal').close()"
|
||||||
class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-600 dark:hover:bg-gray-600">
|
class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-600 dark:hover:bg-gray-600">Cancel</button>
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
<button type="submit"
|
<button type="submit"
|
||||||
class="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
class="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">Generate</button>
|
||||||
Generate
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,12 +5,12 @@
|
|||||||
<!-- Settings Navigation -->
|
<!-- Settings Navigation -->
|
||||||
<div class="mb-6 border-b border-gray-200 dark:border-gray-700">
|
<div class="mb-6 border-b border-gray-200 dark:border-gray-700">
|
||||||
<nav class="-mb-px flex space-x-8">
|
<nav class="-mb-px flex space-x-8">
|
||||||
<a href="{{ url_for('settings.api_keys') }}"
|
<a hx-get="{{ url_for('settings.api_keys') }}" hx-target="#container" hx-swap="innerHTML" hx-push-url="true"
|
||||||
class="border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300 py-4 px-1 text-sm font-medium">
|
class="border-b-2 border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300 py-4 px-1 text-sm font-medium cursor-pointer">
|
||||||
API Keys
|
API Keys
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ url_for('settings.export') }}"
|
<a hx-get="{{ url_for('settings.export') }}" hx-target="#container" hx-swap="innerHTML" hx-push-url="true"
|
||||||
class="border-b-2 border-blue-500 text-blue-600 dark:text-blue-400 py-4 px-1 text-sm font-medium">
|
class="border-b-2 border-blue-500 text-blue-600 dark:text-blue-400 py-4 px-1 text-sm font-medium cursor-pointer">
|
||||||
Export Data
|
Export Data
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
@@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6 mb-6">
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow p-6 mb-6">
|
||||||
<h2 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">What's Included</h2>
|
<h2 class="text-lg font-semibold text-gray-900 dark:text-white mb-4">What's Included</h2>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
|
||||||
<div class="flex items-start space-x-3">
|
<div class="flex items-start space-x-3">
|
||||||
<svg class="w-5 h-5 text-green-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
<svg class="w-5 h-5 text-green-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
@@ -38,7 +37,6 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-start space-x-3">
|
<div class="flex items-start space-x-3">
|
||||||
<svg class="w-5 h-5 text-green-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
<svg class="w-5 h-5 text-green-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
<path fill-rule="evenodd"
|
<path fill-rule="evenodd"
|
||||||
@@ -51,7 +49,6 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-start space-x-3">
|
<div class="flex items-start space-x-3">
|
||||||
<svg class="w-5 h-5 text-green-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
<svg class="w-5 h-5 text-green-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
<path fill-rule="evenodd"
|
<path fill-rule="evenodd"
|
||||||
@@ -63,7 +60,6 @@
|
|||||||
<p class="text-sm text-gray-600 dark:text-gray-400">Environment variables and configurations</p>
|
<p class="text-sm text-gray-600 dark:text-gray-400">Environment variables and configurations</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-start space-x-3">
|
<div class="flex items-start space-x-3">
|
||||||
<svg class="w-5 h-5 text-green-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
<svg class="w-5 h-5 text-green-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
<path fill-rule="evenodd"
|
<path fill-rule="evenodd"
|
||||||
@@ -75,7 +71,6 @@
|
|||||||
<p class="text-sm text-gray-600 dark:text-gray-400">API key names and scopes (keys are masked)</p>
|
<p class="text-sm text-gray-600 dark:text-gray-400">API key names and scopes (keys are masked)</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-start space-x-3">
|
<div class="flex items-start space-x-3">
|
||||||
<svg class="w-5 h-5 text-green-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
<svg class="w-5 h-5 text-green-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
<path fill-rule="evenodd"
|
<path fill-rule="evenodd"
|
||||||
@@ -87,7 +82,6 @@
|
|||||||
<p class="text-sm text-gray-600 dark:text-gray-400">Last 100 invocations per function</p>
|
<p class="text-sm text-gray-600 dark:text-gray-400">Last 100 invocations per function</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex items-start space-x-3">
|
<div class="flex items-start space-x-3">
|
||||||
<svg class="w-5 h-5 text-green-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
<svg class="w-5 h-5 text-green-500 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
<path fill-rule="evenodd"
|
<path fill-rule="evenodd"
|
||||||
@@ -100,7 +94,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4 mb-6">
|
class="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4 mb-6">
|
||||||
<div class="flex items-start space-x-3">
|
<div class="flex items-start space-x-3">
|
||||||
@@ -121,7 +114,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-center">
|
<div class="flex justify-center">
|
||||||
<a href="{{ url_for('settings.export', download='true') }}"
|
<a href="{{ url_for('settings.export', download='true') }}"
|
||||||
class="px-6 py-3 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 transition-colors flex items-center space-x-2">
|
class="px-6 py-3 bg-blue-600 text-white font-medium rounded-lg hover:bg-blue-700 transition-colors flex items-center space-x-2">
|
||||||
@@ -133,7 +125,6 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bg-gray-50 dark:bg-gray-900 rounded-lg p-4">
|
<div class="bg-gray-50 dark:bg-gray-900 rounded-lg p-4">
|
||||||
<h3 class="font-medium text-gray-900 dark:text-white mb-2">What to Do With Your Export</h3>
|
<h3 class="font-medium text-gray-900 dark:text-white mb-2">What to Do With Your Export</h3>
|
||||||
<ul class="text-sm text-gray-600 dark:text-gray-400 space-y-1">
|
<ul class="text-sm text-gray-600 dark:text-gray-400 space-y-1">
|
||||||
|
|||||||
Reference in New Issue
Block a user