feat(ui): i18n-translate credentials and audit_logs templates
Replace all hardcoded English text in credentials.html and audit_logs.html
with {{ _("key") }} translation function calls.
New keys added:
credentials.*: page_title, title, subtitle, total_credentials, configured,
not_configured, legend_title, legend_db, legend_env_before, legend_env_after,
legend_missing, legend_restart, col_credential, col_source, col_action,
table_for, restart_title, status_missing, source_db_title, source_env_title,
edit_in_settings, manage_settings, raw_json
audit.*: page_title, title, subtitle, siem_enabled_title, siem_off,
siem_disabled_title, refresh_label, filter_action, filter_all_actions,
filter_user, filter_all_users, filter_severity, filter_resource_type,
filter_resource_placeholder, filters_section_label, col_timestamp,
col_resource, col_ip, table_label, no_events, no_events_hint,
pagination_label, prev_label, prev, next_label, next, critical
Reused existing keys: common.description, common.status, common.actions,
common.edit, common.all, common.info, common.warning, common.error,
common.refresh, common.details, common.loading
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block title %}Audit Logs - DocuElevate{% endblock %}
|
||||
{% block title %}{{ _("audit.page_title") }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div x-data="auditLogs()" x-init="fetchLogs()" class="container mx-auto px-4 py-8 max-w-7xl">
|
||||
@@ -9,69 +9,69 @@
|
||||
<div class="flex flex-col md:flex-row md:items-center md:justify-between mb-6">
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">
|
||||
<i class="fas fa-shield-halved mr-2 text-indigo-600" aria-hidden="true"></i>Audit Logs
|
||||
<i class="fas fa-shield-halved mr-2 text-indigo-600" aria-hidden="true"></i>{{ _("audit.title") }}
|
||||
</h1>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">
|
||||
Comprehensive, append-only record of all significant actions.
|
||||
{{ _("audit.subtitle") }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="mt-3 md:mt-0 flex items-center gap-3">
|
||||
{% if siem_enabled %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-800 dark:text-green-100"
|
||||
title="Events are being forwarded to {{ siem_transport|upper }}">
|
||||
title="{{ _('audit.siem_enabled_title') ~ (siem_transport|upper) }}">
|
||||
<i class="fas fa-tower-broadcast mr-1" aria-hidden="true"></i>SIEM: {{ siem_transport|upper }}
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-300"
|
||||
title="SIEM forwarding is disabled">
|
||||
<i class="fas fa-tower-broadcast mr-1" aria-hidden="true"></i>SIEM: Off
|
||||
title="{{ _('audit.siem_disabled_title') }}">
|
||||
<i class="fas fa-tower-broadcast mr-1" aria-hidden="true"></i>{{ _("audit.siem_off") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
<button @click="fetchLogs()" class="inline-flex items-center px-3 py-1.5 border border-gray-300 rounded-md text-sm font-medium text-gray-700 bg-white hover:bg-gray-50 dark:bg-gray-700 dark:text-gray-200 dark:border-gray-600 dark:hover:bg-gray-600 min-h-[44px] min-w-[44px]"
|
||||
aria-label="Refresh audit logs">
|
||||
<i class="fas fa-arrows-rotate mr-1" aria-hidden="true"></i>Refresh
|
||||
aria-label="{{ _('audit.refresh_label') }}">
|
||||
<i class="fas fa-arrows-rotate mr-1" aria-hidden="true"></i>{{ _("common.refresh") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filters -->
|
||||
<section class="bg-white dark:bg-gray-800 shadow rounded-lg p-4 mb-6" aria-label="Audit log filters">
|
||||
<section class="bg-white dark:bg-gray-800 shadow rounded-lg p-4 mb-6" aria-label="{{ _('audit.filters_section_label') }}">
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
|
||||
<div>
|
||||
<label for="filter-action" class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Action</label>
|
||||
<label for="filter-action" class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">{{ _("audit.filter_action") }}</label>
|
||||
<select id="filter-action" x-model="filters.action" @change="fetchLogs()"
|
||||
class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white text-sm">
|
||||
<option value="">All actions</option>
|
||||
<option value="">{{ _("audit.filter_all_actions") }}</option>
|
||||
<template x-for="a in distinctActions" :key="a">
|
||||
<option :value="a" x-text="a"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="filter-user" class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">User</label>
|
||||
<label for="filter-user" class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">{{ _("audit.filter_user") }}</label>
|
||||
<select id="filter-user" x-model="filters.user" @change="fetchLogs()"
|
||||
class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white text-sm">
|
||||
<option value="">All users</option>
|
||||
<option value="">{{ _("audit.filter_all_users") }}</option>
|
||||
<template x-for="u in distinctUsers" :key="u">
|
||||
<option :value="u" x-text="u"></option>
|
||||
</template>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="filter-severity" class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Severity</label>
|
||||
<label for="filter-severity" class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">{{ _("audit.filter_severity") }}</label>
|
||||
<select id="filter-severity" x-model="filters.severity" @change="fetchLogs()"
|
||||
class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white text-sm">
|
||||
<option value="">All</option>
|
||||
<option value="info">Info</option>
|
||||
<option value="warning">Warning</option>
|
||||
<option value="error">Error</option>
|
||||
<option value="critical">Critical</option>
|
||||
<option value="">{{ _("common.all") }}</option>
|
||||
<option value="info">{{ _("common.info") }}</option>
|
||||
<option value="warning">{{ _("common.warning") }}</option>
|
||||
<option value="error">{{ _("common.error") }}</option>
|
||||
<option value="critical">{{ _("audit.critical") }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="filter-resource" class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">Resource Type</label>
|
||||
<label for="filter-resource" class="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">{{ _("audit.filter_resource_type") }}</label>
|
||||
<input id="filter-resource" type="text" x-model.debounce.300ms="filters.resource_type" @input="fetchLogs()"
|
||||
placeholder="e.g. document, user"
|
||||
placeholder="{{ _('audit.filter_resource_placeholder') }}"
|
||||
class="w-full rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white text-sm min-h-[44px]">
|
||||
</div>
|
||||
</div>
|
||||
@@ -80,22 +80,22 @@
|
||||
<!-- Results summary -->
|
||||
<div class="flex items-center justify-between mb-3 text-sm text-gray-500 dark:text-gray-400" aria-live="polite">
|
||||
<span x-show="!loading" x-text="total + ' event' + (total !== 1 ? 's' : '') + ' found'"></span>
|
||||
<span x-show="loading"><i class="fas fa-spinner fa-spin mr-1" aria-hidden="true"></i>Loading…</span>
|
||||
<span x-show="loading"><i class="fas fa-spinner fa-spin mr-1" aria-hidden="true"></i>{{ _("common.loading") }}</span>
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
<div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700" aria-label="Audit log events">
|
||||
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700" aria-label="{{ _('audit.table_label') }}">
|
||||
<thead class="bg-gray-50 dark:bg-gray-700">
|
||||
<tr>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Timestamp</th>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Severity</th>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">User</th>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Action</th>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Resource</th>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">IP</th>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">Details</th>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">{{ _("audit.col_timestamp") }}</th>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">{{ _("audit.filter_severity") }}</th>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">{{ _("audit.filter_user") }}</th>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">{{ _("audit.filter_action") }}</th>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">{{ _("audit.col_resource") }}</th>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">{{ _("audit.col_ip") }}</th>
|
||||
<th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">{{ _("common.details") }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 dark:divide-gray-700">
|
||||
@@ -118,8 +118,8 @@
|
||||
<tr x-show="!loading && entries.length === 0">
|
||||
<td colspan="7" class="px-4 py-8 text-center text-gray-400 dark:text-gray-500">
|
||||
<i class="fas fa-inbox text-3xl mb-2" aria-hidden="true"></i>
|
||||
<p class="text-lg">No audit events recorded yet.</p>
|
||||
<p class="text-sm mt-1">Significant actions (logins, document operations, settings changes) will appear here.</p>
|
||||
<p class="text-lg">{{ _("audit.no_events") }}</p>
|
||||
<p class="text-sm mt-1">{{ _("audit.no_events_hint") }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -128,17 +128,17 @@
|
||||
</div>
|
||||
|
||||
<!-- Pagination -->
|
||||
<nav class="flex items-center justify-between mt-4" aria-label="Audit log pagination" x-show="total > filters.limit">
|
||||
<nav class="flex items-center justify-between mt-4" aria-label="{{ _('audit.pagination_label') }}" x-show="total > filters.limit">
|
||||
<button @click="prevPage()" :disabled="filters.offset === 0"
|
||||
class="px-3 py-1.5 rounded-md text-sm border border-gray-300 dark:border-gray-600 disabled:opacity-50 min-h-[44px] min-w-[44px]"
|
||||
aria-label="Previous page">
|
||||
<i class="fas fa-chevron-left mr-1" aria-hidden="true"></i>Prev
|
||||
aria-label="{{ _('audit.prev_label') }}">
|
||||
<i class="fas fa-chevron-left mr-1" aria-hidden="true"></i>{{ _("audit.prev") }}
|
||||
</button>
|
||||
<span class="text-sm text-gray-500 dark:text-gray-400" x-text="'Page ' + currentPage + ' of ' + totalPages"></span>
|
||||
<button @click="nextPage()" :disabled="filters.offset + filters.limit >= total"
|
||||
class="px-3 py-1.5 rounded-md text-sm border border-gray-300 dark:border-gray-600 disabled:opacity-50 min-h-[44px] min-w-[44px]"
|
||||
aria-label="Next page">
|
||||
Next<i class="fas fa-chevron-right ml-1" aria-hidden="true"></i>
|
||||
aria-label="{{ _('audit.next_label') }}">
|
||||
{{ _("audit.next") }}<i class="fas fa-chevron-right ml-1" aria-hidden="true"></i>
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% block title %}Credential Audit - DocuElevate{% endblock %}
|
||||
{% block title %}{{ _("credentials.page_title") }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
@@ -8,11 +8,10 @@
|
||||
<div class="mb-8">
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<i class="fas fa-key text-yellow-500 text-2xl" aria-hidden="true"></i>
|
||||
<h1 class="text-3xl font-bold">Credential Audit</h1>
|
||||
<h1 class="text-3xl font-bold">{{ _("credentials.title") }}</h1>
|
||||
</div>
|
||||
<p class="text-gray-600">
|
||||
Overview of all sensitive credentials used by DocuElevate. No secret values are shown here — only
|
||||
whether each credential is configured and where it comes from.
|
||||
{{ _("credentials.subtitle") }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -24,7 +23,7 @@
|
||||
</span>
|
||||
<div>
|
||||
<div class="text-2xl font-bold text-gray-800">{{ total }}</div>
|
||||
<div class="text-sm text-gray-500">Total Credentials</div>
|
||||
<div class="text-sm text-gray-500">{{ _("credentials.total_credentials") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-lg shadow p-5 flex items-center gap-4">
|
||||
@@ -33,7 +32,7 @@
|
||||
</span>
|
||||
<div>
|
||||
<div class="text-2xl font-bold text-green-700">{{ configured_count }}</div>
|
||||
<div class="text-sm text-gray-500">Configured</div>
|
||||
<div class="text-sm text-gray-500">{{ _("credentials.configured") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white rounded-lg shadow p-5 flex items-center gap-4">
|
||||
@@ -42,32 +41,32 @@
|
||||
</span>
|
||||
<div>
|
||||
<div class="text-2xl font-bold text-gray-600">{{ unconfigured_count }}</div>
|
||||
<div class="text-sm text-gray-500">Not Configured</div>
|
||||
<div class="text-sm text-gray-500">{{ _("credentials.not_configured") }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Legend -->
|
||||
<div class="bg-blue-50 border-l-4 border-blue-500 text-blue-800 p-4 mb-6 rounded-r-md">
|
||||
<p class="font-semibold mb-2"><i class="fas fa-circle-info mr-1" aria-hidden="true"></i> Legend</p>
|
||||
<p class="font-semibold mb-2"><i class="fas fa-circle-info mr-1" aria-hidden="true"></i> {{ _("credentials.legend_title") }}</p>
|
||||
<div class="flex flex-wrap gap-4 text-sm">
|
||||
<span>
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-green-100 text-green-800 mr-1">DB</span>
|
||||
Value stored in the database (encrypted at rest; overrides environment variable)
|
||||
{{ _("credentials.legend_db") }}
|
||||
</span>
|
||||
<span>
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800 mr-1">ENV</span>
|
||||
Value from environment variable or <code>.env</code> file
|
||||
{{ _("credentials.legend_env_before") }}<code>.env</code>{{ _("credentials.legend_env_after") }}
|
||||
</span>
|
||||
<span>
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-700 mr-1">
|
||||
<i class="fas fa-circle-exclamation mr-0.5 text-xs"></i> Missing
|
||||
<i class="fas fa-circle-exclamation mr-0.5 text-xs"></i> {{ _("credentials.status_missing") }}
|
||||
</span>
|
||||
Credential not set — integration will not work
|
||||
{{ _("credentials.legend_missing") }}
|
||||
</span>
|
||||
<span>
|
||||
<span class="text-orange-500 mr-1"><i class="fas fa-rotate"></i></span>
|
||||
Restart required when this credential is rotated
|
||||
{{ _("credentials.legend_restart") }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -79,29 +78,29 @@
|
||||
<div class="bg-gray-100 px-6 py-3 border-b border-gray-200 flex items-center justify-between">
|
||||
<h2 class="text-lg font-semibold text-gray-800">{{ category }}</h2>
|
||||
<span class="text-sm text-gray-500">
|
||||
{{ creds | selectattr('configured') | list | length }} / {{ creds | length }} configured
|
||||
{{ creds | selectattr('configured') | list | length }} / {{ creds | length }} {{ _("credentials.configured") }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Credentials Table -->
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-gray-200" aria-label="Credentials for {{ category }}">
|
||||
<table class="min-w-full divide-y divide-gray-200" aria-label="{{ _('credentials.table_for') ~ ' ' ~ category }}">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider w-56">
|
||||
Credential
|
||||
{{ _("credentials.col_credential") }}
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
Description
|
||||
{{ _("common.description") }}
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider w-32">
|
||||
Status
|
||||
{{ _("common.status") }}
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider w-24">
|
||||
Source
|
||||
{{ _("credentials.col_source") }}
|
||||
</th>
|
||||
<th scope="col" class="px-6 py-3 text-center text-xs font-medium text-gray-500 uppercase tracking-wider w-20">
|
||||
Action
|
||||
{{ _("credentials.col_action") }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -114,7 +113,7 @@
|
||||
<div class="flex items-center gap-1">
|
||||
<code class="text-sm font-mono text-gray-800">{{ cred.key }}</code>
|
||||
{% if cred.restart_required %}
|
||||
<span title="Restart required after rotating this credential">
|
||||
<span title="{{ _('credentials.restart_title') }}">
|
||||
<i class="fas fa-rotate text-orange-400 text-xs"></i>
|
||||
</span>
|
||||
{% endif %}
|
||||
@@ -130,11 +129,11 @@
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
{% if cred.configured %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-semibold bg-green-100 text-green-800">
|
||||
<i class="fas fa-check mr-1" aria-hidden="true"></i> Configured
|
||||
<i class="fas fa-check mr-1" aria-hidden="true"></i> {{ _("credentials.configured") }}
|
||||
</span>
|
||||
{% else %}
|
||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-semibold bg-red-100 text-red-700">
|
||||
<i class="fas fa-circle-exclamation mr-1" aria-hidden="true"></i> Missing
|
||||
<i class="fas fa-circle-exclamation mr-1" aria-hidden="true"></i> {{ _("credentials.status_missing") }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
@@ -142,11 +141,11 @@
|
||||
<!-- Source badge -->
|
||||
<td class="px-6 py-4 whitespace-nowrap">
|
||||
{% if cred.source == 'db' %}
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-green-100 text-green-800" title="Stored in database (encrypted)">
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-green-100 text-green-800" title="{{ _('credentials.source_db_title') }}">
|
||||
<i class="fas fa-database mr-1 text-xs" aria-hidden="true"></i> DB
|
||||
</span>
|
||||
{% elif cred.source == 'env' %}
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800" title="From environment variable">
|
||||
<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800" title="{{ _('credentials.source_env_title') }}">
|
||||
<i class="fas fa-terminal mr-1 text-xs" aria-hidden="true"></i> ENV
|
||||
</span>
|
||||
{% else %}
|
||||
@@ -157,8 +156,8 @@
|
||||
<!-- Quick-edit link -->
|
||||
<td class="px-6 py-4 whitespace-nowrap text-center">
|
||||
<a href="/settings#{{ cred.key }}"
|
||||
title="Edit in Settings"
|
||||
aria-label="Edit {{ cred.key }}"
|
||||
title="{{ _('credentials.edit_in_settings') }}"
|
||||
aria-label="{{ _('common.edit') ~ ' ' ~ cred.key }}"
|
||||
class="inline-flex items-center justify-center w-7 h-7 rounded text-gray-400 hover:text-blue-600 hover:bg-blue-50 transition-colors"
|
||||
>
|
||||
<i class="fas fa-pen-to-square text-sm" aria-hidden="true"></i>
|
||||
@@ -178,13 +177,13 @@
|
||||
<a href="/settings"
|
||||
class="inline-flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 text-sm font-medium"
|
||||
>
|
||||
<i class="fas fa-cog" aria-hidden="true"></i> Manage Settings
|
||||
<i class="fas fa-cog" aria-hidden="true"></i> {{ _("credentials.manage_settings") }}
|
||||
</a>
|
||||
<a href="/api/settings/credentials"
|
||||
target="_blank"
|
||||
class="inline-flex items-center gap-2 px-4 py-2 border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50 text-sm font-medium"
|
||||
>
|
||||
<i class="fas fa-code" aria-hidden="true"></i> Raw JSON (API)
|
||||
<i class="fas fa-code" aria-hidden="true"></i> {{ _("credentials.raw_json") }}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user