Add per-profile AI comment action limits
This commit is contained in:
@@ -1145,6 +1145,14 @@
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="form-label">Tageslimit pro Profil für den AI-Kommentar-Button</label>
|
||||
<p class="form-help">
|
||||
Gilt nur für die Aktion <code>AI - generiere automatisch einen passenden Kommentar</code> im Tracker. <code>0</code> bedeutet kein Limit.
|
||||
</p>
|
||||
<div id="aiProfileCommentLimits"></div>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="button" class="btn btn-secondary" id="testBtn">
|
||||
🧪 Kommentar testen
|
||||
|
||||
103
web/settings.js
103
web/settings.js
@@ -41,6 +41,7 @@ const PROVIDER_INFO = {
|
||||
apiKeyHelp: 'Für lokale OpenAI-kompatible Server (z.B. Ollama) kannst du den Schlüssel leer lassen.'
|
||||
}
|
||||
};
|
||||
const AI_AUTO_COMMENT_DAILY_LIMIT_MAX = 500;
|
||||
|
||||
let credentials = [];
|
||||
let currentSettings = null;
|
||||
@@ -173,6 +174,7 @@ async function loadSettings() {
|
||||
document.getElementById('activeCredential').value = currentSettings.active_credential_id || '';
|
||||
document.getElementById('aiPromptPrefix').value = currentSettings.prompt_prefix ||
|
||||
'Schreibe einen freundlichen, authentischen Kommentar auf Deutsch zu folgendem Facebook-Post. Der Kommentar soll natürlich wirken und maximal 2-3 Sätze lang sein:\n\n';
|
||||
renderAIProfileLimitInputs();
|
||||
}
|
||||
|
||||
async function loadHiddenSettings() {
|
||||
@@ -425,6 +427,94 @@ function normalizeSimilarityImageThresholdInput(value) {
|
||||
return Math.min(64, Math.max(0, parsed));
|
||||
}
|
||||
|
||||
function normalizeAIProfileDailyLimitInput(value) {
|
||||
const parsed = parseInt(value, 10);
|
||||
if (Number.isNaN(parsed) || parsed < 0) {
|
||||
return 0;
|
||||
}
|
||||
return Math.min(AI_AUTO_COMMENT_DAILY_LIMIT_MAX, parsed);
|
||||
}
|
||||
|
||||
function getDefaultAIProfileLimitEntry(profileNumber) {
|
||||
return {
|
||||
profile_number: profileNumber,
|
||||
profile_name: `Profil ${profileNumber}`,
|
||||
daily_limit: 0,
|
||||
used_today: 0,
|
||||
remaining_today: null
|
||||
};
|
||||
}
|
||||
|
||||
function getAIProfileLimitEntries() {
|
||||
const rows = Array.isArray(currentSettings?.profile_limits)
|
||||
? currentSettings.profile_limits
|
||||
: [];
|
||||
const byProfile = new Map();
|
||||
rows.forEach((row) => {
|
||||
const profileNumber = parseInt(row?.profile_number, 10);
|
||||
if (!Number.isNaN(profileNumber) && profileNumber >= 1 && profileNumber <= 5) {
|
||||
byProfile.set(profileNumber, {
|
||||
...getDefaultAIProfileLimitEntry(profileNumber),
|
||||
...row,
|
||||
daily_limit: normalizeAIProfileDailyLimitInput(row?.daily_limit),
|
||||
used_today: Math.max(0, parseInt(row?.used_today, 10) || 0)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return Array.from({ length: 5 }, (_unused, index) => {
|
||||
const profileNumber = index + 1;
|
||||
return byProfile.get(profileNumber) || getDefaultAIProfileLimitEntry(profileNumber);
|
||||
});
|
||||
}
|
||||
|
||||
function renderAIProfileLimitInputs() {
|
||||
const container = document.getElementById('aiProfileCommentLimits');
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
const entries = getAIProfileLimitEntries();
|
||||
container.innerHTML = '';
|
||||
|
||||
entries.forEach((entry) => {
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'form-group';
|
||||
wrapper.style.marginBottom = '12px';
|
||||
|
||||
const label = document.createElement('label');
|
||||
label.className = 'form-label';
|
||||
label.setAttribute('for', `aiProfileLimit${entry.profile_number}`);
|
||||
label.textContent = entry.profile_name || `Profil ${entry.profile_number}`;
|
||||
|
||||
const input = document.createElement('input');
|
||||
input.type = 'number';
|
||||
input.min = '0';
|
||||
input.max = String(AI_AUTO_COMMENT_DAILY_LIMIT_MAX);
|
||||
input.step = '1';
|
||||
input.id = `aiProfileLimit${entry.profile_number}`;
|
||||
input.className = 'form-input';
|
||||
input.value = String(normalizeAIProfileDailyLimitInput(entry.daily_limit));
|
||||
input.placeholder = '0 = kein Limit';
|
||||
input.addEventListener('blur', () => {
|
||||
input.value = String(normalizeAIProfileDailyLimitInput(input.value));
|
||||
});
|
||||
|
||||
const help = document.createElement('p');
|
||||
help.className = 'form-help';
|
||||
const dailyLimit = normalizeAIProfileDailyLimitInput(entry.daily_limit);
|
||||
const usedToday = Math.max(0, parseInt(entry.used_today, 10) || 0);
|
||||
help.textContent = dailyLimit > 0
|
||||
? `Heute verwendet: ${usedToday} / ${dailyLimit}`
|
||||
: `Heute verwendet: ${usedToday} · aktuell kein Limit aktiv`;
|
||||
|
||||
wrapper.appendChild(label);
|
||||
wrapper.appendChild(input);
|
||||
wrapper.appendChild(help);
|
||||
container.appendChild(wrapper);
|
||||
});
|
||||
}
|
||||
|
||||
function applySimilaritySettingsUI() {
|
||||
const textInput = document.getElementById('similarityTextThreshold');
|
||||
const imageInput = document.getElementById('similarityImageThreshold');
|
||||
@@ -998,7 +1088,15 @@ async function saveSettings(e, { silent = false } = {}) {
|
||||
const data = {
|
||||
enabled: document.getElementById('aiEnabled').checked,
|
||||
active_credential_id: parseInt(document.getElementById('activeCredential').value) || null,
|
||||
prompt_prefix: document.getElementById('aiPromptPrefix').value
|
||||
prompt_prefix: document.getElementById('aiPromptPrefix').value,
|
||||
profile_limits: Array.from({ length: 5 }, (_unused, index) => {
|
||||
const profileNumber = index + 1;
|
||||
const input = document.getElementById(`aiProfileLimit${profileNumber}`);
|
||||
return {
|
||||
profile_number: profileNumber,
|
||||
daily_limit: normalizeAIProfileDailyLimitInput(input ? input.value : 0)
|
||||
};
|
||||
})
|
||||
};
|
||||
|
||||
const res = await apiFetch(`${API_URL}/ai-settings`, {
|
||||
@@ -1013,6 +1111,7 @@ async function saveSettings(e, { silent = false } = {}) {
|
||||
}
|
||||
|
||||
currentSettings = await res.json();
|
||||
renderAIProfileLimitInputs();
|
||||
if (!silent) {
|
||||
showSuccess('✅ Einstellungen erfolgreich gespeichert');
|
||||
}
|
||||
@@ -1058,7 +1157,7 @@ async function generateTest() {
|
||||
const res = await apiFetch(`${API_URL}/ai/generate-comment`, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({postText: text, profileNumber})
|
||||
body: JSON.stringify({postText: text, profileNumber, traceSource: 'settings-test'})
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
|
||||
Reference in New Issue
Block a user