semantic update
This commit is contained in:
@@ -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">
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<!-- [DEF:DebugPage:Component] -->
|
||||
<!--
|
||||
@TIER: TRIVIAL
|
||||
@SEMANTICS: debug, page, tool
|
||||
@PURPOSE: Page for system diagnostics and debugging.
|
||||
@LAYER: UI
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<!-- [DEF:MapperPage:Component] -->
|
||||
<!--
|
||||
@TIER: TRIVIAL
|
||||
@SEMANTICS: mapper, page, tool
|
||||
@PURPOSE: Page for the dataset column mapper tool.
|
||||
@LAYER: UI
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user