feat(database): integrate wizard into settings page, improve accessibility and test coverage
- Add "DB Wizard" link button to settings page header - Add help_link to database_url SETTING_METADATA pointing to /database-wizard - Add help_link rendering in settings template for any setting with a help_link - Fix SQLite whitespace path handling in build_connection_string - Add dark mode CSS overrides for wizard template - Add aria-describedby for all form inputs with help text - Add prefers-reduced-motion media query for smooth scrolling - Expand test coverage: 106 tests (up from 49) - db_wizard.py: 100% coverage - db_wizard view: 100% coverage - database.py API: 97.37% coverage - db_migrate.py: 96.60% coverage Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -13,6 +13,14 @@
|
||||
.migration-table th, .migration-table td { padding: 0.5rem 1rem; text-align: left; }
|
||||
@keyframes pulse-bar { 0%,100%{opacity:1} 50%{opacity:.5} }
|
||||
.animate-pulse-bar { animation: pulse-bar 1.5s ease-in-out infinite; }
|
||||
/* Dark mode overrides for db-wizard specific styles */
|
||||
html.dark .from-blue-50 { --tw-gradient-from: #1e3a5f; }
|
||||
html.dark .to-indigo-100 { --tw-gradient-to: #1e1b4b; }
|
||||
html.dark .db-card { background-color: #1f2937; border-color: #374151; }
|
||||
html.dark .db-card:hover { border-color: #818cf8; }
|
||||
html.dark .db-card.selected { border-color: #818cf8; box-shadow: 0 0 0 3px rgba(129,140,248,0.3); }
|
||||
/* Ensure smooth scroll only when user permits */
|
||||
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
@@ -124,8 +132,9 @@
|
||||
<label for="sqlite_path" class="block text-sm font-medium text-gray-700">Database File Path</label>
|
||||
<input id="sqlite_path" x-model="form.sqlite_path" type="text"
|
||||
class="mono-input w-full px-4 py-3 border border-gray-300 rounded-md shadow-sm focus:ring-2 focus:ring-indigo-500 focus:border-transparent"
|
||||
placeholder="./app/database.db" />
|
||||
<p class="text-xs text-gray-500">Leave blank to use the default path <code>./app/database.db</code>.</p>
|
||||
placeholder="./app/database.db"
|
||||
aria-describedby="sqlite_path_help" />
|
||||
<p id="sqlite_path_help" class="text-xs text-gray-500">Leave blank to use the default path <code>./app/database.db</code>.</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -169,13 +178,14 @@
|
||||
<div x-show="form.backend==='postgresql'">
|
||||
<label for="ssl_mode" class="block text-sm font-medium text-gray-700">SSL Mode</label>
|
||||
<select id="ssl_mode" x-model="form.ssl_mode"
|
||||
class="w-full px-4 py-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-indigo-500">
|
||||
class="w-full px-4 py-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-indigo-500"
|
||||
aria-describedby="ssl_mode_help">
|
||||
<option value="">None (disable)</option>
|
||||
<option value="require">require</option>
|
||||
<option value="verify-ca">verify-ca</option>
|
||||
<option value="verify-full">verify-full</option>
|
||||
</select>
|
||||
<p class="text-xs text-gray-500 mt-1">Use <code>require</code> for managed cloud databases (AWS RDS, Supabase, etc.).</p>
|
||||
<p id="ssl_mode_help" class="text-xs text-gray-500 mt-1">Use <code>require</code> for managed cloud databases (AWS RDS, Supabase, etc.).</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -238,7 +248,7 @@
|
||||
</div>
|
||||
|
||||
<div class="p-4 border rounded-lg bg-gray-50">
|
||||
<label for="env_snippet" class="block text-sm font-medium text-gray-700 mb-2">
|
||||
<label for="env_snippet" id="env_snippet_label" class="block text-sm font-medium text-gray-700 mb-2">
|
||||
Copy this into your <code>.env</code> file:
|
||||
</label>
|
||||
<div class="flex items-center">
|
||||
@@ -297,8 +307,9 @@
|
||||
</label>
|
||||
<input id="mig_source" x-model="migrate.source" type="text"
|
||||
class="mono-input w-full px-4 py-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-indigo-500"
|
||||
:placeholder="currentDbUrl || 'sqlite:///./app/database.db'" />
|
||||
<p class="text-xs text-gray-500 mt-1">
|
||||
:placeholder="currentDbUrl || 'sqlite:///./app/database.db'"
|
||||
aria-describedby="mig_source_help" />
|
||||
<p id="mig_source_help" class="text-xs text-gray-500 mt-1">
|
||||
This is your current database. Pre-filled with the running configuration.
|
||||
</p>
|
||||
<button @click="migrate.source = currentDbUrl"
|
||||
@@ -315,8 +326,9 @@
|
||||
</label>
|
||||
<input id="mig_target" x-model="migrate.target" type="text"
|
||||
class="mono-input w-full px-4 py-3 border border-gray-300 rounded-md focus:ring-2 focus:ring-indigo-500"
|
||||
placeholder="postgresql://user:pass@host:5432/docuelevate" />
|
||||
<p class="text-xs text-gray-500 mt-1">
|
||||
placeholder="postgresql://user:pass@host:5432/docuelevate"
|
||||
aria-describedby="mig_target_help" />
|
||||
<p id="mig_target_help" class="text-xs text-gray-500 mt-1">
|
||||
The new database to copy data into. Must be empty (schema will be created automatically).
|
||||
</p>
|
||||
<button @click="if(builtUrl) migrate.target = builtUrl"
|
||||
|
||||
@@ -60,6 +60,10 @@
|
||||
class="inline-flex items-center px-3 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
|
||||
<i class="fas fa-magic mr-1.5" aria-hidden="true"></i> Wizard
|
||||
</a>
|
||||
<a href="/database-wizard"
|
||||
class="inline-flex items-center px-3 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
|
||||
<i class="fas fa-database mr-1.5" aria-hidden="true"></i> DB Wizard
|
||||
</a>
|
||||
<div class="relative" x-data="{ exportOpen: false }">
|
||||
<button @click="exportOpen = !exportOpen"
|
||||
class="inline-flex items-center px-3 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
|
||||
@@ -236,6 +240,14 @@
|
||||
</div>
|
||||
|
||||
<p class="text-xs text-gray-500 mb-2">{{ setting.metadata.description }}</p>
|
||||
{% if setting.metadata.get('help_link') %}
|
||||
<p class="text-xs mb-2">
|
||||
<a href="{{ setting.metadata.help_link }}"
|
||||
class="text-indigo-600 hover:underline focus:outline-none focus:ring-2 focus:ring-indigo-500 rounded">
|
||||
<i class="fas fa-external-link-alt mr-1" aria-hidden="true"></i>{{ setting.metadata.get('help_link_label', 'More info') }}
|
||||
</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
{% if setting.metadata.type == 'boolean' %}
|
||||
<!-- Boolean/Checkbox Input -->
|
||||
|
||||
Reference in New Issue
Block a user