semantic update

This commit is contained in:
2026-02-08 22:53:54 +03:00
parent e6087bd3c1
commit 235b0e3c9f
71 changed files with 68034 additions and 62417 deletions

View File

@@ -1,7 +1,8 @@
<!-- [DEF:AdminSettingsPage:Component] -->
<!--
@SEMANTICS: admin, adfs, mappings, configuration
@PURPOSE: UI for configuring Active Directory Group to local Role mappings for ADFS SSO.
@TIER: STANDARD
@SEMANTICS: admin, adfs, mappings, configuration, logging
@PURPOSE: UI for configuring Active Directory Group to local Role mappings for ADFS SSO and logging settings.
@LAYER: Feature
@RELATION: DEPENDS_ON -> frontend.src.services.adminService
@RELATION: DEPENDS_ON -> frontend.src.components.auth.ProtectedRoute
@@ -28,6 +29,19 @@
role_id: ''
};
// [SECTION: LOGGING_CONFIG]
let loggingConfig = {
level: 'INFO',
task_log_level: 'INFO',
enable_belief_state: true
};
let loggingConfigLoading = false;
let loggingConfigSaving = false;
let loggingConfigSaved = false;
// [/SECTION]
const LOG_LEVELS = ['DEBUG', 'INFO', 'WARNING', 'ERROR'];
// [DEF:loadData:Function]
/**
* @purpose Fetches AD mappings and roles from the backend to populate the UI.
@@ -93,7 +107,64 @@
}
// [/DEF:handleCreateMapping:Function]
onMount(loadData);
// [DEF:loadLoggingConfig:Function]
/**
* @purpose Fetches current logging configuration from the backend.
* @pre Component is mounted and user has active session.
* @post loggingConfig variable is updated with backend data.
* @returns {Promise<void>}
* @relation CALLS -> adminService.getLoggingConfig
*/
async function loadLoggingConfig() {
console.log('[AdminSettingsPage][loadLoggingConfig][Entry]');
loggingConfigLoading = true;
try {
const config = await adminService.getLoggingConfig();
loggingConfig = {
level: config.level || 'INFO',
task_log_level: config.task_log_level || 'INFO',
enable_belief_state: config.enable_belief_state ?? true
};
console.log('[AdminSettingsPage][loadLoggingConfig][Coherence:OK]');
} catch (e) {
console.error('[AdminSettingsPage][loadLoggingConfig][Coherence:Failed]', e);
} finally {
loggingConfigLoading = false;
}
}
// [/DEF:loadLoggingConfig:Function]
// [DEF:saveLoggingConfig:Function]
/**
* @purpose Saves logging configuration to the backend.
* @pre loggingConfig contains valid values.
* @post Configuration is saved and feedback is shown.
* @returns {Promise<void>}
* @relation CALLS -> adminService.updateLoggingConfig
*/
async function saveLoggingConfig() {
console.log('[AdminSettingsPage][saveLoggingConfig][Entry]');
loggingConfigSaving = true;
loggingConfigSaved = false;
try {
await adminService.updateLoggingConfig(loggingConfig);
loggingConfigSaved = true;
console.log('[AdminSettingsPage][saveLoggingConfig][Coherence:OK]');
// Reset saved indicator after 2 seconds
setTimeout(() => { loggingConfigSaved = false; }, 2000);
} catch (e) {
alert("Failed to save logging configuration: " + (e.message || "Unknown error"));
console.error('[AdminSettingsPage][saveLoggingConfig][Coherence:Failed]', e);
} finally {
loggingConfigSaving = false;
}
}
// [/DEF:saveLoggingConfig:Function]
onMount(() => {
loadData();
loadLoggingConfig();
});
</script>
<ProtectedRoute requiredPermission="admin:settings">
@@ -155,6 +226,74 @@
</div>
{/if}
<!-- [SECTION: LOGGING_CONFIG_UI] -->
<div class="mt-8 bg-white shadow rounded-lg border border-gray-200 p-6">
<h2 class="text-xl font-bold mb-4 text-gray-800">Logging Configuration</h2>
{#if loggingConfigLoading}
<div class="flex justify-center py-4">
<p class="text-gray-500 animate-pulse">Loading logging configuration...</p>
</div>
{:else}
<div class="space-y-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Application Log Level</label>
<select
bind:value={loggingConfig.level}
class="w-full border border-gray-300 p-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
{#each LOG_LEVELS as level}
<option value={level}>{level}</option>
{/each}
</select>
<p class="text-xs text-gray-500 mt-1">Controls the verbosity of application logs.</p>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-1">Task Log Level</label>
<select
bind:value={loggingConfig.task_log_level}
class="w-full border border-gray-300 p-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
>
{#each LOG_LEVELS as level}
<option value={level}>{level}</option>
{/each}
</select>
<p class="text-xs text-gray-500 mt-1">Minimum level for logs stored in task history. DEBUG shows all logs.</p>
</div>
</div>
<div class="flex items-center">
<input
type="checkbox"
id="enable_belief_state"
bind:checked={loggingConfig.enable_belief_state}
class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
/>
<label for="enable_belief_state" class="ml-2 block text-sm text-gray-700">
Enable Belief State Logging (Entry/Exit/Coherence logs)
</label>
</div>
<p class="text-xs text-gray-500 -mt-2">When disabled, belief scope logs are hidden. Requires DEBUG level to see in task logs.</p>
<div class="flex items-center gap-3 pt-2">
<button
on:click={saveLoggingConfig}
disabled={loggingConfigSaving}
class="px-4 py-2 bg-blue-600 text-white rounded font-medium hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors"
>
{loggingConfigSaving ? 'Saving...' : 'Save Configuration'}
</button>
{#if loggingConfigSaved}
<span class="text-green-600 text-sm font-medium">✓ Saved</span>
{/if}
</div>
</div>
{/if}
</div>
<!-- [/SECTION: LOGGING_CONFIG_UI] -->
{#if showCreateModal}
<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50">
<div class="bg-white rounded-lg shadow-xl p-6 max-w-md w-full">

View File

@@ -1,6 +1,7 @@
<!-- [DEF:LLMSettingsPage:Component] -->
<!--
<!--
@TIER: STANDARD
@SEMANTICS: admin, llm, settings, provider, configuration
@PURPOSE: Admin settings page for LLM provider configuration.
@LAYER: UI
@RELATION: CALLS -> frontend/src/components/llm/ProviderConfig.svelte

View File

@@ -1,5 +1,6 @@
<!-- [DEF:DebugPage:Component] -->
<!--
@TIER: TRIVIAL
@SEMANTICS: debug, page, tool
@PURPOSE: Page for system diagnostics and debugging.
@LAYER: UI

View File

@@ -1,5 +1,6 @@
<!-- [DEF:MapperPage:Component] -->
<!--
@TIER: TRIVIAL
@SEMANTICS: mapper, page, tool
@PURPOSE: Page for the dataset column mapper tool.
@LAYER: UI

View File

@@ -25,6 +25,7 @@
// [DEF:loadFiles:Function]
/**
* @purpose Fetches the list of files from the server.
* @pre The activeTab is set to a valid category.
* @post Updates the `files` array with the latest data.
*/
let files = [];
@@ -33,6 +34,7 @@
let currentPath = 'backups'; // Relative to storage root
async function loadFiles() {
console.log('[STORAGE-PAGE][LOAD_START] category=%s path=%s', activeTab, currentPath);
isLoading = true;
try {
const category = activeTab;
@@ -51,7 +53,9 @@
: effectivePath;
files = await listFiles(category, subpath);
console.log('[STORAGE-PAGE][LOAD_OK] count=%d', files.length);
} catch (error) {
console.log('[STORAGE-PAGE][LOAD_ERR] error=%s', error.message);
addToast($t.storage.messages.load_failed.replace('{error}', error.message), 'error');
} finally {
isLoading = false;
@@ -62,17 +66,22 @@
// [DEF:handleDelete:Function]
/**
* @purpose Handles the file deletion process.
* @pre The event contains valid category and path.
* @post File is deleted and file list is refreshed.
* @param {CustomEvent} event - The delete event containing category and path.
*/
async function handleDelete(event) {
const { category, path, name } = event.detail;
console.log('[STORAGE-PAGE][DELETE_START] category=%s path=%s', category, path);
if (!confirm($t.storage.messages.delete_confirm.replace('{name}', name))) return;
try {
await deleteFile(category, path);
console.log('[STORAGE-PAGE][DELETE_OK] name=%s', name);
addToast($t.storage.messages.delete_success.replace('{name}', name), 'success');
await loadFiles();
} catch (error) {
console.log('[STORAGE-PAGE][DELETE_ERR] error=%s', error.message);
addToast($t.storage.messages.delete_failed.replace('{error}', error.message), 'error');
}
}
@@ -81,9 +90,12 @@
// [DEF:handleNavigate:Function]
/**
* @purpose Updates the current path and reloads files when navigating into a directory.
* @pre The event contains a valid path string.
* @post currentPath is updated and files are reloaded.
* @param {CustomEvent} event - The navigation event containing the new path.
*/
function handleNavigate(event) {
console.log('[STORAGE-PAGE][NAVIGATE] path=%s', event.detail);
currentPath = event.detail;
loadFiles();
}