mirror of
https://github.com/perstarkse/minne.git
synced 2026-03-18 15:34:16 +01:00
207 lines
8.5 KiB
HTML
207 lines
8.5 KiB
HTML
{% extends 'body_base.html' %}
|
|
|
|
{% block title %}Minne - Account{% endblock %}
|
|
|
|
{% block main %}
|
|
<main class="container flex-grow flex flex-col mx-auto mt-4 space-y-6">
|
|
<h1 class="text-2xl font-bold mb-2">Admin Dashboard</h1>
|
|
|
|
<div class="stats stats-vertical md:stats-horizontal shadow">
|
|
<div class="stat">
|
|
<div class="stat-title font-bold">Page loads</div>
|
|
<div class="stat-value text-secondary">{{analytics.page_loads}}</div>
|
|
<div class="stat-desc">Amount of page loads</div>
|
|
</div>
|
|
|
|
<div class="stat">
|
|
<div class="stat-title font-bold">Unique visitors</div>
|
|
<div class="stat-value text-primary">{{analytics.visitors}}</div>
|
|
<div class="stat-desc">Amount of unique visitors</div>
|
|
</div>
|
|
|
|
<div class="stat">
|
|
<div class="stat-title font-bold">Users</div>
|
|
<div class="stat-value text-accent">{{users}}</div>
|
|
<div class="stat-desc">Amount of registered users</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Settings in Fieldset -->
|
|
<div class="grid grid-cols-1 xl:grid-cols-2 gap-6">
|
|
{% block system_prompt_section %}
|
|
<div id="system_prompt_section">
|
|
<fieldset class="fieldset p-4 shadow rounded-box">
|
|
<legend class="fieldset-legend">System Prompts</legend>
|
|
<div class="flex gap-2 flex-col sm:flex-row">
|
|
<button type="button" class="btn btn-primary btn-sm" hx-get="/edit-query-prompt" hx-target="#modal"
|
|
hx-swap="innerHTML">
|
|
Edit Query Prompt
|
|
</button>
|
|
<button type="button" class="btn btn-primary btn-sm" hx-get="/edit-ingestion-prompt" hx-target="#modal"
|
|
hx-swap="innerHTML">
|
|
Edit Ingestion Prompt
|
|
</button>
|
|
<button type="button" class="btn btn-primary btn-sm" hx-get="/edit-image-prompt" hx-target="#modal"
|
|
hx-swap="innerHTML">
|
|
Edit Image Prompt
|
|
</button>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
<fieldset class="fieldset p-4 shadow rounded-box">
|
|
<legend class="fieldset-legend">AI Models</legend>
|
|
{% block model_settings_form %}
|
|
<form hx-patch="/update-model-settings" hx-swap="outerHTML">
|
|
<!-- Query Model -->
|
|
<div class="form-control mb-4">
|
|
<label class="label">
|
|
<span class="label-text">Query Model</span>
|
|
</label>
|
|
<select name="query_model" class="select select-bordered w-full">
|
|
{% for model in available_models.data %}
|
|
<option value="{{model.id}}" {% if settings.query_model==model.id %} selected {% endif %}>{{model.id}}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
|
|
<p class="text-xs text-gray-500 mt-1">
|
|
Current used:
|
|
<span class="font-mono">{{settings.query_model}}</span>
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Processing Model -->
|
|
<div class="form-control mb-4">
|
|
<label class="label">
|
|
<span class="label-text">Processing Model</span>
|
|
</label>
|
|
<select name="processing_model" class="select select-bordered w-full">
|
|
{% for model in available_models.data %}
|
|
<option value="{{model.id}}" {% if settings.processing_model==model.id %} selected {% endif %}>{{model.id}}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<p class="text-xs text-gray-500 mt-1">
|
|
Current used:
|
|
<span class="font-mono">{{settings.processing_model}}</span>
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Image Processing Model -->
|
|
<div class="form-control mb-4">
|
|
<label class="label">
|
|
<span class="label-text">Image Processing Model</span>
|
|
</label>
|
|
<select name="image_processing_model" class="select select-bordered w-full">
|
|
{% for model in available_models.data %}
|
|
<option value="{{model.id}}" {% if settings.image_processing_model==model.id %} selected {% endif %}>
|
|
{{model.id}}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<p class="text-xs text-gray-500 mt-1">
|
|
Current used:
|
|
<span class="font-mono">{{settings.image_processing_model}}</span>
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Voice Processing Model -->
|
|
<div class="form-control mb-4">
|
|
<label class="label">
|
|
<span class="label-text">Voice Processing Model</span>
|
|
</label>
|
|
<select name="voice_processing_model" class="select select-bordered w-full">
|
|
{% for model in available_models.data %}
|
|
<option value="{{model.id}}" {% if settings.voice_processing_model==model.id %} selected {% endif %}>{{model.id}}</option>
|
|
{% endfor %}
|
|
</select>
|
|
<p class="text-xs text-gray-500 mt-1">
|
|
Current used:
|
|
<span class="font-mono">{{settings.voice_processing_model}}</span>
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Embedding Model -->
|
|
<div class="form-control mb-4">
|
|
<label class="label">
|
|
<span class="label-text">Embedding Model</span>
|
|
</label>
|
|
<select name="embedding_model" class="select select-bordered w-full">
|
|
{% for model in available_models.data %}
|
|
<option value="{{model.id}}" {% if settings.embedding_model==model.id %} selected {% endif %}>{{model.id}}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
<p class="text-xs text-gray-500 mt-1">
|
|
Current used:
|
|
<span class="font-mono">{{settings.embedding_model}} ({{settings.embedding_dimensions}} dims)</span>
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Embedding Dimensions (Always Visible) -->
|
|
<div class="form-control mb-4">
|
|
<label class="label" for="embedding_dimensions">
|
|
<span class="label-text">Embedding Dimensions</span>
|
|
</label>
|
|
<input type="number" id="embedding_dimensions" name="embedding_dimensions" class="input input-bordered w-full"
|
|
value="{{ settings.embedding_dimensions }}" required />
|
|
</div>
|
|
|
|
<!-- Conditional Alert -->
|
|
<div id="embedding-change-alert" role="alert" class="alert alert-warning mt-2 hidden">
|
|
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none"
|
|
viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
|
|
d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
|
|
</svg>
|
|
<span><strong>Warning:</strong> Changing dimensions will require re-creating all embeddings. Make sure you
|
|
look up what dimensions the model uses or use a model that allows specifying embedding dimensions</span>
|
|
</div>
|
|
|
|
<button type="submit" class="btn btn-primary btn-sm mt-4">Save Model Settings</button>
|
|
</form>
|
|
|
|
<script>
|
|
// Use a self-executing function to avoid polluting the global scope
|
|
// and to ensure it runs correctly after an HTMX swap.
|
|
(() => {
|
|
const dimensionInput = document.getElementById('embedding_dimensions');
|
|
const alertElement = document.getElementById('embedding-change-alert');
|
|
// The initial value is read directly from the template each time this script runs.
|
|
const initialDimensions = '{{ settings.embedding_dimensions }}';
|
|
|
|
if (dimensionInput && alertElement) {
|
|
// Use the 'input' event for immediate feedback as the user types.
|
|
dimensionInput.addEventListener('input', (event) => {
|
|
// Show alert if the current value is not the initial value. Hide it otherwise.
|
|
if (event.target.value !== initialDimensions) {
|
|
alertElement.classList.remove('hidden');
|
|
} else {
|
|
alertElement.classList.add('hidden');
|
|
}
|
|
});
|
|
}
|
|
})();
|
|
</script>
|
|
{% endblock %}
|
|
</fieldset>
|
|
|
|
<fieldset class="fieldset p-4 shadow rounded-box">
|
|
<legend class="fieldset-legend">Registration</legend>
|
|
<label class="flex gap-4 text-center">
|
|
{% block registration_status_input %}
|
|
<form hx-patch="/toggle-registrations" hx-swap="outerHTML" hx-trigger="change">
|
|
<input name="registration_open" type="checkbox" class="checkbox" {% if settings.registrations_enabled
|
|
%}checked{% endif %} />
|
|
</form>
|
|
{% endblock %}
|
|
Enable Registrations
|
|
</label>
|
|
<div id="registration-status" class="text-sm mt-2"></div>
|
|
</fieldset>
|
|
|
|
</div>
|
|
</main>
|
|
{% endblock %} |