From 44e95b3835c9e9f8ed309cdc31c048e8986da939 Mon Sep 17 00:00:00 2001 From: Daniel Apodaca Date: Mon, 23 Mar 2026 13:28:10 -0600 Subject: [PATCH 01/10] improve system administration settings hierarchy with grouped section headings --- .../admin/system-administration.html | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/enferno/admin/templates/admin/system-administration.html b/enferno/admin/templates/admin/system-administration.html index fb033a964..5f19a61f2 100644 --- a/enferno/admin/templates/admin/system-administration.html +++ b/enferno/admin/templates/admin/system-administration.html @@ -24,14 +24,16 @@

{{ _('Administration Dashboard') }}

-
+
- ${tabsMap[tab]?.text} +
+
${tabsMap[tab]?.text}
+
-
+
{{ _('Restore default settings') }} @@ -52,6 +54,8 @@

{{ _('Administration Dashboard') }}

+

{{ _('Interface defaults') }}

+

{{ _('Control default list behavior and media playback options.') }}

{{ _('Table settings') }}

@@ -70,6 +74,8 @@

{{ _('Media settings') }}

+

{{ _('Localization') }}

+

{{ _('Set the default interface language for new sessions.') }}

{{ _('Default language') }}

{{ _('Changes default interface language for all users. Users can still choose their own interface language.') }}

@@ -80,6 +86,8 @@

{{ _('Default language') }}

+

{{ _('Data quality and analysis') }}

+

{{ _('Configure record-matching behavior and advanced analysis capabilities.') }}

{{ _('Deduplication tool') }}

@@ -128,7 +136,7 @@

{{ _('Advanced analysis features') }}

-

{{ _('Settings') }}

+

{{ _('Storage backend') }}

{{ _('Storage options for media files uploaded to Bayanat. By default, Bayanat store these files locally on the server. It\'s also possible to use S3 compatible bucket using cloud providers like AWS, Azure, Google Cloud, or MinIO (which can be used in offline installations).') }}

@@ -138,6 +146,7 @@

{{ _('Settings') }}

+

{{ _('S3 connection details') }}

{{ _('Settings') }}
+

{{ _('Upload restrictions') }}

+

{{ _('Define which files are accepted and the maximum upload size.') }}

{{ _('Settings') }}
+

{{ _('Credential policies') }}

+

{{ _('Define password rules and authentication requirements for all users.') }}

{{ _('Password Policies') }}

@@ -232,7 +245,8 @@

{{ _('Disallow multiple concurrent sessions') }} -

{{ _('Additional Security Settings') }}

+

{{ _('Login protection and sign-in providers') }}

+

{{ _('Configure verification checks and optional third-party login methods.') }}

{{ _('Recaptcha enabled') }}

{{ _('Enable Google OAuth') }} +

{{ _('Re-authentication windows') }}

+

{{ _('Set how often users must re-authenticate on secure actions.') }}

{{ _('Enable Google OAuth') }} restrict access to certain items by assigning Access Group(s) to these items. Additionally, only administrators can restrict items. This default behaviour can be changed with the following settings.') }}

+

{{ _('Default access behavior') }}

@@ -434,6 +451,7 @@

{{ _('Authentication') }}

+

{{ _('Other actions') }}

{{ _('Search queries made') }}{{ _(' by users.') @@ -481,6 +499,8 @@

{{ _('Retention period') }}

+

{{ _('Ingestion pipelines') }}

+

{{ _('Enable and configure how media and structured data are imported into the platform.') }}

{{ _('Media Import tool') }}

{{ _('Export system') }}
+

{{ _('Map tiles provider') }}

+

{{ _('Choose the map tiles endpoint used throughout Bayanat.') }}

@@ -661,7 +683,7 @@

{{ _('Satellite Imagery') }}

hint="{{ _('API key for Google Maps. Adding a key enables satellite imagery in Bayanat\'s maps.') }}" v-model="eitem.GOOGLE_MAPS_API_KEY"> -

{{ _('Default Map Position') }}

+

{{ _('Default Map Position') }}

{{ _('Changes default position for all maps in all components.') }} @@ -924,6 +946,8 @@

{{ _('Bulk operations status') }}
+

{{ _('Mail transport') }}

+

{{ _('Configure SMTP delivery settings used by system emails and notifications.') }}

{{ _('Enable Mail System') }}

@@ -1423,4 +1447,4 @@

{{ _('Enable Mail System') }}

-{% endblock %} \ No newline at end of file +{% endblock %} From 47b33b08fc36c78e887f392813af860fe2570821 Mon Sep 17 00:00:00 2001 From: Daniel Apodaca Date: Mon, 23 Mar 2026 14:20:38 -0600 Subject: [PATCH 02/10] Allow searching organization settings via global search box; auto-highlight selected setting after navigation --- .../admin/system-administration.html | 396 +++++++++++++----- 1 file changed, 299 insertions(+), 97 deletions(-) diff --git a/enferno/admin/templates/admin/system-administration.html b/enferno/admin/templates/admin/system-administration.html index 5f19a61f2..1f31b8025 100644 --- a/enferno/admin/templates/admin/system-administration.html +++ b/enferno/admin/templates/admin/system-administration.html @@ -4,7 +4,38 @@
-

{{ _('Administration Dashboard') }}

+
+

{{ _('Administration Dashboard') }}

+ + + +
@@ -57,14 +88,14 @@

{{ _('Administration Dashboard') }}

{{ _('Interface defaults') }}

{{ _('Control default list behavior and media playback options.') }}

- +

{{ _('Table settings') }}

- +

{{ _('Media settings') }}

{{ _('Localization') }}

{{ _('Set the default interface language for new sessions.') }}

{{ _('Default language') }}

{{ _('Changes default interface language for all users. Users can still choose their own interface language.') }}

- - - ${name} - - +
+ + + ${name} + + +

{{ _('Data quality and analysis') }}

{{ _('Configure record-matching behavior and advanced analysis capabilities.') }}

{{ _('Deduplication tool') }}

- +
+ +
@@ -126,8 +161,10 @@

{{ _('Deduplication tool') }}

{{ _('Advanced analysis features') }}

- +
+ +
@@ -138,11 +175,13 @@

{{ _('Advanced analysis features') }}

{{ _('Storage backend') }}

{{ _('Storage options for media files uploaded to Bayanat. By default, Bayanat store these files locally on the server. It\'s also possible to use S3 compatible bucket using cloud providers like AWS, Azure, Google Cloud, or MinIO (which can be used in offline installations).') }}

- - {{ _('Local Filesystem') }} - {{ _('S3 Storage') }} - +
+ + {{ _('Local Filesystem') }} + {{ _('S3 Storage') }} + +
@@ -156,7 +195,7 @@

{{ _('S3 connection details') }}

- + @@ -170,15 +209,19 @@

{{ _('S3 connection details') }}

{{ _('Upload restrictions') }}

{{ _('Define which files are accepted and the maximum upload size.') }}

- - - +
+ +
+ +
+ +
@@ -190,13 +233,13 @@

{{ _('Upload restrictions') }}

{{ _('Credential policies') }}

{{ _('Define password rules and authentication requirements for all users.') }}

- +

{{ _('Password Policies') }}

- +

{{ _('Password Strength') }}

{{ _('Password Strength') }}

{{ _('Two Factor Authentication Policies') }}

- +

{{ _('Force 2FA enrollment') }}

@@ -228,14 +271,14 @@

{{ _('Force 2FA enrollment') }}

{{ _('Session policies') }}

- +

{{ _('Disallow multiple concurrent sessions') }}

- + @@ -248,9 +291,11 @@

{{ _('Disallow multiple concurrent sessions') }}{{ _('Login protection and sign-in providers') }}

{{ _('Configure verification checks and optional third-party login methods.') }}

{{ _('Recaptcha enabled') }}

- +
+ +
@@ -265,9 +310,11 @@

{{ _('Recaptcha enabled') }}

{{ _('Enable Google OAuth') }}

- +
+ +
@@ -287,7 +334,7 @@

{{ _('Enable Google OAuth') }}

{{ _('Re-authentication windows') }}

{{ _('Set how often users must re-authenticate on secure actions.') }}

- + @@ -316,13 +363,13 @@

{{ _('Re-authentication window

{{ _('Default access behavior') }}

- +

{{ _('Restrictive access control') }}

- +

{{ _('Allow non-admin users to restrict new items') }}

{{ _('Allow non-admin users to restrict new items')

{{ _('Set users\' actions to be logged in the Activity Monitor.') }}

-

{{ _('Items') }}

+
+

{{ _('Items') }}

+
{{ _('Items created') }}{{ _(' by users.') }} @@ -393,7 +442,9 @@

{{ _('Items') }}

-

{{ _('Export') }}

+
+

{{ _('Export') }}

+
{{ _('Export requests made') }}{{ _(' by @@ -431,7 +482,9 @@

{{ _('Export') }}

-

{{ _('Authentication') }}

+
+

{{ _('Authentication') }}

+
{{ _('Logins') }}{{ _(' by users.') }}
@@ -451,7 +504,9 @@

{{ _('Authentication') }}

-

{{ _('Other actions') }}

+
+

{{ _('Other actions') }}

+
{{ _('Search queries made') }}{{ _(' by users.') @@ -485,7 +540,7 @@

{{ _('Other actions') }}

{{ _('Retention period') }}

{{ _('Period after which all logged activities will be deleted.') }}

- + @@ -502,14 +557,16 @@

{{ _('Retention period') }}

{{ _('Ingestion pipelines') }}

{{ _('Enable and configure how media and structured data are imported into the platform.') }}

{{ _('Media Import tool') }}

- +
+ +
- +

{{ _('Media Import path scanning') }}

{{ _('Media Import path scanning') }} v-model="eitem.ETL_VID_EXT">
- +

{{ _('Tesseract OCR (Import)') }}

{{ _('Tesseract OCR (Import)') }} - +
+ +
- +

{{ _('Enable transcription') }}

{{ _('Enable transcription') }}

{{ _('Sheet Import') }}

- +
+ +
@@ -613,8 +674,10 @@

{{ _('Sheet Import') }}

{{ _('Web import') }}

- +
+ +
@@ -651,13 +714,17 @@

{{ _('Web import') }}

{{ _('Export system') }}

- +
+ +
- +
+ +
@@ -670,25 +737,31 @@

{{ _('Export system') }}

{{ _('Map tiles provider') }}

{{ _('Choose the map tiles endpoint used throughout Bayanat.') }}

- +
+ +

{{ _('Satellite Imagery') }}

{{ _('Bayanat uses OpenStreetMaps by default. Optionally, it is able to show satellite imagery using Google Maps, in addition to OSM. To enable, add a Google Maps API Key.') }}

- - -

{{ _('Default Map Position') }}

- {{ _('Changes default position for all maps in all components.') - }} - -
- +
+ +
+ +
+

{{ _('Default Map Position') }}

+ {{ _('Changes default position for all maps in all components.') + }} + +
+ +
@@ -697,7 +770,7 @@

{{ _('Default Map Position') }}

-
+

{{ _('Include postal code generation settings') }}

@@ -712,8 +785,10 @@

{{ _('Include postal code generation settings') }}< {{ _('Email is not configured, and email notifications are currently disabled. To enable them, set up the email service in the Mail tab.') }} -

{{ _('Notifications for users') }}

-

{{ _('These notifications are sent to users about important changes to their accounts and new task assignments.') }}

+
+

{{ _('Notifications for users') }}

+

{{ _('These notifications are sent to users about important changes to their accounts and new task assignments.') }}

+

{{ _('Login from new IP') }}

@@ -791,8 +866,10 @@

{{ _('Web Import status') }}

-

{{ _('Notifications for all administrators') }}

-

{{ _('Notifications sent to all administrators about important events.') }}

+
+

{{ _('Notifications for all administrators') }}

+

{{ _('Notifications sent to all administrators about important events.') }}

+

{{ _('Security') }}

@@ -915,8 +992,10 @@

{{ _('New batch') }}

-

{{ _('Notifications for administrators') }}

-

{{ _('Notifications sent to individual administrators about the results of actions they initiated.') }}

+
+

{{ _('Notifications for administrators') }}

+

{{ _('Notifications sent to individual administrators about the results of actions they initiated.') }}

+

{{ _('Import batch status') }}

@@ -949,19 +1028,21 @@

{{ _('Bulk operations status') }}{{ _('Mail transport') }}

{{ _('Configure SMTP delivery settings used by system emails and notifications.') }}

{{ _('Enable Mail System') }}

- - +
+ + +
- + - + @@ -986,12 +1067,12 @@

{{ _('Enable Mail System') }}

v-model="eitem.MAIL_PASSWORD">
- + - + {{ _('Enable Mail System') }} saveChangesDialog: false, loading: true, + settingsQuery: '', + settingSearchSelection: null, options: {}, @@ -1184,6 +1267,63 @@

{{ _('Enable Mail System') }}

notifications: { text: "{{ _('Notifications') }}" }, mail: { text: "{{ _('Mail') }}" }, }, + settingsSearchMap: [ + { id: 'items_per_page', tab: 'general', section: "{{ _('Interface defaults') }}", label: "{{ _('Items per page options') }}", anchorId: 'setting-items-per-page-options', keywords: ['table', 'pagination', 'list'] }, + { id: 'video_rate', tab: 'general', section: "{{ _('Interface defaults') }}", label: "{{ _('Video playback rate') }}", anchorId: 'setting-video-playback-rate', keywords: ['media', 'speed', 'video'] }, + { id: 'default_language', tab: 'general', section: "{{ _('Localization') }}", label: "{{ _('Default language') }}", anchorId: 'setting-default-language', keywords: ['locale', 'translation', 'language'] }, + { id: 'dedup_tool', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication tool') }}", anchorId: 'setting-dedup-tool', keywords: ['matching', 'duplicates'] }, + { id: 'adv_analysis', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Advanced analysis features') }}", anchorId: 'setting-advanced-analysis', keywords: ['analysis', 'features'] }, + + { id: 'storage_backend', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('Local Filesystem / S3 Storage') }}", anchorId: 'setting-storage-backend', keywords: ['files', 's3', 'bucket'] }, + { id: 's3_bucket', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('S3 Bucket Name') }}", anchorId: 'setting-s3-bucket', keywords: ['aws', 'storage', 'bucket'] }, + { id: 'media_extensions', tab: 'storage', section: "{{ _('Upload restrictions') }}", label: "{{ _('Allowed Media Extensions') }}", anchorId: 'setting-media-allowed-extensions', keywords: ['upload', 'extensions', 'files'] }, + { id: 'media_size', tab: 'storage', section: "{{ _('Upload restrictions') }}", label: "{{ _('Media Max Upload Size') }}", anchorId: 'setting-media-max-upload-size', keywords: ['upload', 'size', 'limit'] }, + + { id: 'password_min_len', tab: 'security', section: "{{ _('Credential policies') }}", label: "{{ _('Password Minimum Length') }}", anchorId: 'setting-password-min-length', keywords: ['password', 'security'] }, + { id: 'password_strength', tab: 'security', section: "{{ _('Credential policies') }}", label: "{{ _('Password Strength') }}", anchorId: 'setting-password-strength', keywords: ['zxcvbn', 'security'] }, + { id: 'force_2fa', tab: 'security', section: "{{ _('Two Factor Authentication Policies') }}", label: "{{ _('Force 2FA enrollment') }}", anchorId: 'setting-force-2fa', keywords: ['2fa', 'mfa', 'security'] }, + { id: 'disallow_sessions', tab: 'security', section: "{{ _('Session policies') }}", label: "{{ _('Disallow multiple concurrent sessions') }}", anchorId: 'setting-disallow-multiple-sessions', keywords: ['session', 'login', 'devices'] }, + { id: 'session_retention', tab: 'security', section: "{{ _('Session policies') }}", label: "{{ _('Session Data Retention Period') }}", anchorId: 'setting-session-retention', keywords: ['session', 'retention', 'days'] }, + { id: 'recaptcha_enabled', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Recaptcha enabled') }}", anchorId: 'setting-recaptcha-enabled', keywords: ['captcha', 'bot', 'login'] }, + { id: 'google_oauth_enabled', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Enable Google OAuth') }}", anchorId: 'setting-google-oauth-enabled', keywords: ['sso', 'oauth', 'google'] }, + { id: 'security_freshness', tab: 'security', section: "{{ _('Re-authentication windows') }}", label: "{{ _('Security freshness') }}", anchorId: 'setting-security-freshness', keywords: ['reauth', 'timeout', 'minutes'] }, + + { id: 'restrictive_access', tab: 'control', section: "{{ _('Default access behavior') }}", label: "{{ _('Restrictive access control') }}", anchorId: 'setting-restrictive-access-control', keywords: ['permissions', 'default access'] }, + { id: 'non_admin_restrict', tab: 'control', section: "{{ _('Default access behavior') }}", label: "{{ _('Allow non-admin users to restrict new items') }}", anchorId: 'setting-non-admin-restrict', keywords: ['permissions', 'item restriction'] }, + + { id: 'activity_items', tab: 'logging', section: "{{ _('Items') }}", label: "{{ _('Items activity logging') }}", anchorId: 'setting-activity-items', keywords: ['logging', 'audit', 'items'] }, + { id: 'activity_export', tab: 'logging', section: "{{ _('Export') }}", label: "{{ _('Export activity logging') }}", anchorId: 'setting-activity-export', keywords: ['logging', 'audit', 'export'] }, + { id: 'activity_auth', tab: 'logging', section: "{{ _('Authentication') }}", label: "{{ _('Authentication activity logging') }}", anchorId: 'setting-activity-auth', keywords: ['logging', 'login', 'logout'] }, + { id: 'activity_other', tab: 'logging', section: "{{ _('Other actions') }}", label: "{{ _('Other actions logging') }}", anchorId: 'setting-activity-other', keywords: ['search', 'upload', 'bulk'] }, + { id: 'activity_retention', tab: 'logging', section: "{{ _('Retention period') }}", label: "{{ _('Activity Retention Period') }}", anchorId: 'setting-activity-retention', keywords: ['retention', 'cleanup', 'days'] }, + + { id: 'media_import_tool', tab: 'import', section: "{{ _('Ingestion pipelines') }}", label: "{{ _('Media Import tool') }}", anchorId: 'setting-media-import-tool', keywords: ['etl', 'import', 'media'] }, + { id: 'import_path_scanning', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Media Import path scanning') }}", anchorId: 'setting-import-path-scanning', keywords: ['path', 'scan', 'security'] }, + { id: 'ocr_import', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Tesseract OCR (Import)') }}", anchorId: 'setting-import-ocr', keywords: ['ocr', 'tesseract', 'text extraction'] }, + { id: 'vision_api_key', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Google Cloud API Key') }}", anchorId: 'setting-google-vision-api-key', keywords: ['vision', 'ocr', 'translation'] }, + { id: 'transcription_enabled', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Enable transcription') }}", anchorId: 'setting-transcription-enabled', keywords: ['whisper', 'audio', 'transcript'] }, + { id: 'sheet_import', tab: 'import', section: "{{ _('Sheet Import') }}", label: "{{ _('Sheet Import') }}", anchorId: 'setting-sheet-import', keywords: ['spreadsheet', 'excel', 'import'] }, + { id: 'web_import', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Web import') }}", anchorId: 'setting-web-import', keywords: ['yt-dlp', 'url', 'media import'] }, + + { id: 'export_tool', tab: 'export', section: "{{ _('Export system') }}", label: "{{ _('Export system') }}", anchorId: 'setting-export-tool', keywords: ['exports', 'requests'] }, + { id: 'export_expiry', tab: 'export', section: "{{ _('Export system') }}", label: "{{ _('Export Expiry Time') }}", anchorId: 'setting-export-expiry-time', keywords: ['expiry', 'retention', 'hours'] }, + + { id: 'map_endpoint', tab: 'maps', section: "{{ _('Map tiles provider') }}", label: "{{ _('Map API endpoint') }}", anchorId: 'setting-map-api-endpoint', keywords: ['maps', 'osm', 'tiles'] }, + { id: 'google_maps_api', tab: 'maps', section: "{{ _('Satellite Imagery') }}", label: "{{ _('Google Maps API Key') }}", anchorId: 'setting-google-maps-api-key', keywords: ['maps', 'satellite', 'google'] }, + { id: 'map_default_position', tab: 'maps', section: "{{ _('Default Map Position') }}", label: "{{ _('Default Map Position') }}", anchorId: 'setting-map-default-position', keywords: ['coordinates', 'center', 'default map'] }, + + { id: 'postal_code_generation', tab: 'locations', section: "{{ _('Location') }}", label: "{{ _('Include postal code generation settings') }}", anchorId: 'setting-include-postal-code', keywords: ['location', 'postal code'] }, + + { id: 'notifications_users', tab: 'notifications', section: "{{ _('Notifications') }}", label: "{{ _('Notifications for users') }}", anchorId: 'setting-notifications-users', keywords: ['notification', 'users'] }, + { id: 'notifications_admins_all', tab: 'notifications', section: "{{ _('Notifications') }}", label: "{{ _('Notifications for all administrators') }}", anchorId: 'setting-notifications-admins-all', keywords: ['notification', 'admins'] }, + { id: 'notifications_admins', tab: 'notifications', section: "{{ _('Notifications') }}", label: "{{ _('Notifications for administrators') }}", anchorId: 'setting-notifications-admins', keywords: ['notification', 'admin'] }, + + { id: 'mail_enabled', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Enable Mail System') }}", anchorId: 'setting-mail-enabled', keywords: ['mail', 'smtp', 'email'] }, + { id: 'mail_server', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Server') }}", anchorId: 'setting-mail-server', keywords: ['smtp', 'host'] }, + { id: 'mail_port', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Port') }}", anchorId: 'setting-mail-port', keywords: ['smtp', 'port'] }, + { id: 'mail_default_sender', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Default Sender') }}", anchorId: 'setting-mail-default-sender', keywords: ['sender', 'from'] }, + { id: 'mail_allowed_domains', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Allowed Email Domains') }}", anchorId: 'setting-mail-allowed-domains', keywords: ['email', 'domains', 'allowlist'] }, + ], alHeaders: [ @@ -1243,6 +1383,31 @@

{{ _('Enable Mail System') }}

model_name: model.model_name })); }, + filteredSettings() { + const query = (this.settingsQuery || '').toLowerCase().trim(); + const items = this.settingsSearchMap.map(setting => ({ + ...setting, + tabText: this.tabsMap?.[setting.tab]?.text || setting.tab, + })); + + if (!query) { + return items.slice(0, 12); + } + + const terms = query.split(/\s+/).filter(Boolean); + return items + .filter(setting => { + const haystack = [ + setting.label, + setting.section, + setting.tabText, + ...(setting.keywords || []), + ].join(' ').toLowerCase(); + + return terms.every(term => haystack.includes(term)); + }) + .slice(0, 24); + }, hasChanges() { return DiffTool.hasDiff(this.exconfig, this.eitem); }, @@ -1257,6 +1422,43 @@

{{ _('Enable Mail System') }}

console.error(err); }) }, + async onSettingSelected(setting) { + if (!setting) return; + + if (this.tab !== setting.tab) { + this.tab = setting.tab; + } + + this.settingSearchSelection = null; + this.settingsQuery = ''; + + await this.$nextTick(); + await new Promise(resolve => requestAnimationFrame(resolve)); + + const target = document.getElementById(setting.anchorId); + if (!target) return; + + target.scrollIntoView({ behavior: 'smooth', block: 'center' }); + if (typeof target.animate === 'function') { + target.animate( + [ + { + backgroundColor: 'rgba(var(--v-theme-primary), 0.28)', + boxShadow: '0 0 0 2px rgba(var(--v-theme-primary), 0.55)', + }, + { + backgroundColor: 'rgba(var(--v-theme-primary), 0.12)', + boxShadow: '0 0 0 1px rgba(var(--v-theme-primary), 0.30)', + }, + { + backgroundColor: 'transparent', + boxShadow: '0 0 0 0 rgba(var(--v-theme-primary), 0)', + }, + ], + { duration: 1400, easing: 'ease-out' } + ); + } + }, loadDefaults() { api.get('/admin/api/configuration/defaults/').then(res => { From cf3c3a8219b2adff3dd91b5a20073463dc8ff4d7 Mon Sep 17 00:00:00 2001 From: Daniel Apodaca Date: Mon, 23 Mar 2026 15:31:01 -0600 Subject: [PATCH 03/10] translate keywords and normalize search so users can search in any language --- .../admin/system-administration.html | 144 ++++++++++-------- 1 file changed, 78 insertions(+), 66 deletions(-) diff --git a/enferno/admin/templates/admin/system-administration.html b/enferno/admin/templates/admin/system-administration.html index 1f31b8025..54123055e 100644 --- a/enferno/admin/templates/admin/system-administration.html +++ b/enferno/admin/templates/admin/system-administration.html @@ -1268,61 +1268,61 @@

{{ _('Enable Mail System') }}

mail: { text: "{{ _('Mail') }}" }, }, settingsSearchMap: [ - { id: 'items_per_page', tab: 'general', section: "{{ _('Interface defaults') }}", label: "{{ _('Items per page options') }}", anchorId: 'setting-items-per-page-options', keywords: ['table', 'pagination', 'list'] }, - { id: 'video_rate', tab: 'general', section: "{{ _('Interface defaults') }}", label: "{{ _('Video playback rate') }}", anchorId: 'setting-video-playback-rate', keywords: ['media', 'speed', 'video'] }, - { id: 'default_language', tab: 'general', section: "{{ _('Localization') }}", label: "{{ _('Default language') }}", anchorId: 'setting-default-language', keywords: ['locale', 'translation', 'language'] }, - { id: 'dedup_tool', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication tool') }}", anchorId: 'setting-dedup-tool', keywords: ['matching', 'duplicates'] }, - { id: 'adv_analysis', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Advanced analysis features') }}", anchorId: 'setting-advanced-analysis', keywords: ['analysis', 'features'] }, - - { id: 'storage_backend', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('Local Filesystem / S3 Storage') }}", anchorId: 'setting-storage-backend', keywords: ['files', 's3', 'bucket'] }, - { id: 's3_bucket', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('S3 Bucket Name') }}", anchorId: 'setting-s3-bucket', keywords: ['aws', 'storage', 'bucket'] }, - { id: 'media_extensions', tab: 'storage', section: "{{ _('Upload restrictions') }}", label: "{{ _('Allowed Media Extensions') }}", anchorId: 'setting-media-allowed-extensions', keywords: ['upload', 'extensions', 'files'] }, - { id: 'media_size', tab: 'storage', section: "{{ _('Upload restrictions') }}", label: "{{ _('Media Max Upload Size') }}", anchorId: 'setting-media-max-upload-size', keywords: ['upload', 'size', 'limit'] }, - - { id: 'password_min_len', tab: 'security', section: "{{ _('Credential policies') }}", label: "{{ _('Password Minimum Length') }}", anchorId: 'setting-password-min-length', keywords: ['password', 'security'] }, - { id: 'password_strength', tab: 'security', section: "{{ _('Credential policies') }}", label: "{{ _('Password Strength') }}", anchorId: 'setting-password-strength', keywords: ['zxcvbn', 'security'] }, - { id: 'force_2fa', tab: 'security', section: "{{ _('Two Factor Authentication Policies') }}", label: "{{ _('Force 2FA enrollment') }}", anchorId: 'setting-force-2fa', keywords: ['2fa', 'mfa', 'security'] }, - { id: 'disallow_sessions', tab: 'security', section: "{{ _('Session policies') }}", label: "{{ _('Disallow multiple concurrent sessions') }}", anchorId: 'setting-disallow-multiple-sessions', keywords: ['session', 'login', 'devices'] }, - { id: 'session_retention', tab: 'security', section: "{{ _('Session policies') }}", label: "{{ _('Session Data Retention Period') }}", anchorId: 'setting-session-retention', keywords: ['session', 'retention', 'days'] }, - { id: 'recaptcha_enabled', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Recaptcha enabled') }}", anchorId: 'setting-recaptcha-enabled', keywords: ['captcha', 'bot', 'login'] }, - { id: 'google_oauth_enabled', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Enable Google OAuth') }}", anchorId: 'setting-google-oauth-enabled', keywords: ['sso', 'oauth', 'google'] }, - { id: 'security_freshness', tab: 'security', section: "{{ _('Re-authentication windows') }}", label: "{{ _('Security freshness') }}", anchorId: 'setting-security-freshness', keywords: ['reauth', 'timeout', 'minutes'] }, - - { id: 'restrictive_access', tab: 'control', section: "{{ _('Default access behavior') }}", label: "{{ _('Restrictive access control') }}", anchorId: 'setting-restrictive-access-control', keywords: ['permissions', 'default access'] }, - { id: 'non_admin_restrict', tab: 'control', section: "{{ _('Default access behavior') }}", label: "{{ _('Allow non-admin users to restrict new items') }}", anchorId: 'setting-non-admin-restrict', keywords: ['permissions', 'item restriction'] }, - - { id: 'activity_items', tab: 'logging', section: "{{ _('Items') }}", label: "{{ _('Items activity logging') }}", anchorId: 'setting-activity-items', keywords: ['logging', 'audit', 'items'] }, - { id: 'activity_export', tab: 'logging', section: "{{ _('Export') }}", label: "{{ _('Export activity logging') }}", anchorId: 'setting-activity-export', keywords: ['logging', 'audit', 'export'] }, - { id: 'activity_auth', tab: 'logging', section: "{{ _('Authentication') }}", label: "{{ _('Authentication activity logging') }}", anchorId: 'setting-activity-auth', keywords: ['logging', 'login', 'logout'] }, - { id: 'activity_other', tab: 'logging', section: "{{ _('Other actions') }}", label: "{{ _('Other actions logging') }}", anchorId: 'setting-activity-other', keywords: ['search', 'upload', 'bulk'] }, - { id: 'activity_retention', tab: 'logging', section: "{{ _('Retention period') }}", label: "{{ _('Activity Retention Period') }}", anchorId: 'setting-activity-retention', keywords: ['retention', 'cleanup', 'days'] }, - - { id: 'media_import_tool', tab: 'import', section: "{{ _('Ingestion pipelines') }}", label: "{{ _('Media Import tool') }}", anchorId: 'setting-media-import-tool', keywords: ['etl', 'import', 'media'] }, - { id: 'import_path_scanning', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Media Import path scanning') }}", anchorId: 'setting-import-path-scanning', keywords: ['path', 'scan', 'security'] }, - { id: 'ocr_import', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Tesseract OCR (Import)') }}", anchorId: 'setting-import-ocr', keywords: ['ocr', 'tesseract', 'text extraction'] }, - { id: 'vision_api_key', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Google Cloud API Key') }}", anchorId: 'setting-google-vision-api-key', keywords: ['vision', 'ocr', 'translation'] }, - { id: 'transcription_enabled', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Enable transcription') }}", anchorId: 'setting-transcription-enabled', keywords: ['whisper', 'audio', 'transcript'] }, - { id: 'sheet_import', tab: 'import', section: "{{ _('Sheet Import') }}", label: "{{ _('Sheet Import') }}", anchorId: 'setting-sheet-import', keywords: ['spreadsheet', 'excel', 'import'] }, - { id: 'web_import', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Web import') }}", anchorId: 'setting-web-import', keywords: ['yt-dlp', 'url', 'media import'] }, - - { id: 'export_tool', tab: 'export', section: "{{ _('Export system') }}", label: "{{ _('Export system') }}", anchorId: 'setting-export-tool', keywords: ['exports', 'requests'] }, - { id: 'export_expiry', tab: 'export', section: "{{ _('Export system') }}", label: "{{ _('Export Expiry Time') }}", anchorId: 'setting-export-expiry-time', keywords: ['expiry', 'retention', 'hours'] }, - - { id: 'map_endpoint', tab: 'maps', section: "{{ _('Map tiles provider') }}", label: "{{ _('Map API endpoint') }}", anchorId: 'setting-map-api-endpoint', keywords: ['maps', 'osm', 'tiles'] }, - { id: 'google_maps_api', tab: 'maps', section: "{{ _('Satellite Imagery') }}", label: "{{ _('Google Maps API Key') }}", anchorId: 'setting-google-maps-api-key', keywords: ['maps', 'satellite', 'google'] }, - { id: 'map_default_position', tab: 'maps', section: "{{ _('Default Map Position') }}", label: "{{ _('Default Map Position') }}", anchorId: 'setting-map-default-position', keywords: ['coordinates', 'center', 'default map'] }, - - { id: 'postal_code_generation', tab: 'locations', section: "{{ _('Location') }}", label: "{{ _('Include postal code generation settings') }}", anchorId: 'setting-include-postal-code', keywords: ['location', 'postal code'] }, - - { id: 'notifications_users', tab: 'notifications', section: "{{ _('Notifications') }}", label: "{{ _('Notifications for users') }}", anchorId: 'setting-notifications-users', keywords: ['notification', 'users'] }, - { id: 'notifications_admins_all', tab: 'notifications', section: "{{ _('Notifications') }}", label: "{{ _('Notifications for all administrators') }}", anchorId: 'setting-notifications-admins-all', keywords: ['notification', 'admins'] }, - { id: 'notifications_admins', tab: 'notifications', section: "{{ _('Notifications') }}", label: "{{ _('Notifications for administrators') }}", anchorId: 'setting-notifications-admins', keywords: ['notification', 'admin'] }, - - { id: 'mail_enabled', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Enable Mail System') }}", anchorId: 'setting-mail-enabled', keywords: ['mail', 'smtp', 'email'] }, - { id: 'mail_server', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Server') }}", anchorId: 'setting-mail-server', keywords: ['smtp', 'host'] }, - { id: 'mail_port', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Port') }}", anchorId: 'setting-mail-port', keywords: ['smtp', 'port'] }, - { id: 'mail_default_sender', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Default Sender') }}", anchorId: 'setting-mail-default-sender', keywords: ['sender', 'from'] }, - { id: 'mail_allowed_domains', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Allowed Email Domains') }}", anchorId: 'setting-mail-allowed-domains', keywords: ['email', 'domains', 'allowlist'] }, + { id: 'items_per_page', tab: 'general', section: "{{ _('Interface defaults') }}", label: "{{ _('Items per page options') }}", anchorId: 'setting-items-per-page-options', keywords: ["{{ _('table') }}", "{{ _('pagination') }}", "{{ _('list') }}"] }, + { id: 'video_rate', tab: 'general', section: "{{ _('Interface defaults') }}", label: "{{ _('Video playback rate') }}", anchorId: 'setting-video-playback-rate', keywords: ["{{ _('media') }}", "{{ _('speed') }}", "{{ _('video') }}"] }, + { id: 'default_language', tab: 'general', section: "{{ _('Localization') }}", label: "{{ _('Default language') }}", anchorId: 'setting-default-language', keywords: ["{{ _('locale') }}", "{{ _('translation') }}", "{{ _('language') }}"] }, + { id: 'dedup_tool', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication tool') }}", anchorId: 'setting-dedup-tool', keywords: ["{{ _('matching') }}", "{{ _('duplicates') }}"] }, + { id: 'adv_analysis', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Advanced analysis features') }}", anchorId: 'setting-advanced-analysis', keywords: ["{{ _('analysis') }}", "{{ _('features') }}"] }, + + { id: 'storage_backend', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('Local Filesystem / S3 Storage') }}", anchorId: 'setting-storage-backend', keywords: ["{{ _('files') }}", "{{ _('s3') }}", "{{ _('bucket') }}"] }, + { id: 's3_bucket', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('S3 Bucket Name') }}", anchorId: 'setting-s3-bucket', keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('bucket') }}"] }, + { id: 'media_extensions', tab: 'storage', section: "{{ _('Upload restrictions') }}", label: "{{ _('Allowed Media Extensions') }}", anchorId: 'setting-media-allowed-extensions', keywords: ["{{ _('upload') }}", "{{ _('extensions') }}", "{{ _('files') }}"] }, + { id: 'media_size', tab: 'storage', section: "{{ _('Upload restrictions') }}", label: "{{ _('Media Max Upload Size') }}", anchorId: 'setting-media-max-upload-size', keywords: ["{{ _('upload') }}", "{{ _('size') }}", "{{ _('limit') }}"] }, + + { id: 'password_min_len', tab: 'security', section: "{{ _('Credential policies') }}", label: "{{ _('Password Minimum Length') }}", anchorId: 'setting-password-min-length', keywords: ["{{ _('password') }}", "{{ _('security') }}"] }, + { id: 'password_strength', tab: 'security', section: "{{ _('Credential policies') }}", label: "{{ _('Password Strength') }}", anchorId: 'setting-password-strength', keywords: ["{{ _('zxcvbn') }}", "{{ _('security') }}"] }, + { id: 'force_2fa', tab: 'security', section: "{{ _('Two Factor Authentication Policies') }}", label: "{{ _('Force 2FA enrollment') }}", anchorId: 'setting-force-2fa', keywords: ["{{ _('2fa') }}", "{{ _('mfa') }}", "{{ _('security') }}"] }, + { id: 'disallow_sessions', tab: 'security', section: "{{ _('Session policies') }}", label: "{{ _('Disallow multiple concurrent sessions') }}", anchorId: 'setting-disallow-multiple-sessions', keywords: ["{{ _('session') }}", "{{ _('login') }}", "{{ _('devices') }}"] }, + { id: 'session_retention', tab: 'security', section: "{{ _('Session policies') }}", label: "{{ _('Session Data Retention Period') }}", anchorId: 'setting-session-retention', keywords: ["{{ _('session') }}", "{{ _('retention') }}", "{{ _('days') }}"] }, + { id: 'recaptcha_enabled', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Recaptcha enabled') }}", anchorId: 'setting-recaptcha-enabled', keywords: ["{{ _('captcha') }}", "{{ _('bot') }}", "{{ _('login') }}"] }, + { id: 'google_oauth_enabled', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Enable Google OAuth') }}", anchorId: 'setting-google-oauth-enabled', keywords: ["{{ _('sso') }}", "{{ _('oauth') }}", "{{ _('google') }}"] }, + { id: 'security_freshness', tab: 'security', section: "{{ _('Re-authentication windows') }}", label: "{{ _('Security freshness') }}", anchorId: 'setting-security-freshness', keywords: ["{{ _('reauth') }}", "{{ _('timeout') }}", "{{ _('minutes') }}"] }, + + { id: 'restrictive_access', tab: 'control', section: "{{ _('Default access behavior') }}", label: "{{ _('Restrictive access control') }}", anchorId: 'setting-restrictive-access-control', keywords: ["{{ _('permissions') }}", "{{ _('default access') }}"] }, + { id: 'non_admin_restrict', tab: 'control', section: "{{ _('Default access behavior') }}", label: "{{ _('Allow non-admin users to restrict new items') }}", anchorId: 'setting-non-admin-restrict', keywords: ["{{ _('permissions') }}", "{{ _('item restriction') }}"] }, + + { id: 'activity_items', tab: 'logging', section: "{{ _('Items') }}", label: "{{ _('Items activity logging') }}", anchorId: 'setting-activity-items', keywords: ["{{ _('logging') }}", "{{ _('audit') }}", "{{ _('items') }}"] }, + { id: 'activity_export', tab: 'logging', section: "{{ _('Export') }}", label: "{{ _('Export activity logging') }}", anchorId: 'setting-activity-export', keywords: ["{{ _('logging') }}", "{{ _('audit') }}", "{{ _('export') }}"] }, + { id: 'activity_auth', tab: 'logging', section: "{{ _('Authentication') }}", label: "{{ _('Authentication activity logging') }}", anchorId: 'setting-activity-auth', keywords: ["{{ _('logging') }}", "{{ _('login') }}", "{{ _('logout') }}"] }, + { id: 'activity_other', tab: 'logging', section: "{{ _('Other actions') }}", label: "{{ _('Other actions logging') }}", anchorId: 'setting-activity-other', keywords: ["{{ _('search') }}", "{{ _('upload') }}", "{{ _('bulk') }}"] }, + { id: 'activity_retention', tab: 'logging', section: "{{ _('Retention period') }}", label: "{{ _('Activity Retention Period') }}", anchorId: 'setting-activity-retention', keywords: ["{{ _('retention') }}", "{{ _('cleanup') }}", "{{ _('days') }}"] }, + + { id: 'media_import_tool', tab: 'import', section: "{{ _('Ingestion pipelines') }}", label: "{{ _('Media Import tool') }}", anchorId: 'setting-media-import-tool', keywords: ["{{ _('etl') }}", "{{ _('import') }}", "{{ _('media') }}"] }, + { id: 'import_path_scanning', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Media Import path scanning') }}", anchorId: 'setting-import-path-scanning', keywords: ["{{ _('path') }}", "{{ _('scan') }}", "{{ _('security') }}"] }, + { id: 'ocr_import', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Tesseract OCR (Import)') }}", anchorId: 'setting-import-ocr', keywords: ["{{ _('ocr') }}", "{{ _('tesseract') }}", "{{ _('text extraction') }}"] }, + { id: 'vision_api_key', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Google Cloud API Key') }}", anchorId: 'setting-google-vision-api-key', keywords: ["{{ _('vision') }}", "{{ _('ocr') }}", "{{ _('translation') }}"] }, + { id: 'transcription_enabled', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Enable transcription') }}", anchorId: 'setting-transcription-enabled', keywords: ["{{ _('whisper') }}", "{{ _('audio') }}", "{{ _('transcript') }}"] }, + { id: 'sheet_import', tab: 'import', section: "{{ _('Sheet Import') }}", label: "{{ _('Sheet Import') }}", anchorId: 'setting-sheet-import', keywords: ["{{ _('spreadsheet') }}", "{{ _('excel') }}", "{{ _('import') }}"] }, + { id: 'web_import', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Web import') }}", anchorId: 'setting-web-import', keywords: ["{{ _('yt-dlp') }}", "{{ _('url') }}", "{{ _('media import') }}"] }, + + { id: 'export_tool', tab: 'export', section: "{{ _('Export system') }}", label: "{{ _('Export system') }}", anchorId: 'setting-export-tool', keywords: ["{{ _('exports') }}", "{{ _('requests') }}"] }, + { id: 'export_expiry', tab: 'export', section: "{{ _('Export system') }}", label: "{{ _('Export Expiry Time') }}", anchorId: 'setting-export-expiry-time', keywords: ["{{ _('expiry') }}", "{{ _('retention') }}", "{{ _('hours') }}"] }, + + { id: 'map_endpoint', tab: 'maps', section: "{{ _('Map tiles provider') }}", label: "{{ _('Map API endpoint') }}", anchorId: 'setting-map-api-endpoint', keywords: ["{{ _('maps') }}", "{{ _('osm') }}", "{{ _('tiles') }}"] }, + { id: 'google_maps_api', tab: 'maps', section: "{{ _('Satellite Imagery') }}", label: "{{ _('Google Maps API Key') }}", anchorId: 'setting-google-maps-api-key', keywords: ["{{ _('maps') }}", "{{ _('satellite') }}", "{{ _('google') }}"] }, + { id: 'map_default_position', tab: 'maps', section: "{{ _('Default Map Position') }}", label: "{{ _('Default Map Position') }}", anchorId: 'setting-map-default-position', keywords: ["{{ _('coordinates') }}", "{{ _('center') }}", "{{ _('default map') }}"] }, + + { id: 'postal_code_generation', tab: 'locations', section: "{{ _('Location') }}", label: "{{ _('Include postal code generation settings') }}", anchorId: 'setting-include-postal-code', keywords: ["{{ _('location') }}", "{{ _('postal code') }}"] }, + + { id: 'notifications_users', tab: 'notifications', section: "{{ _('Notifications') }}", label: "{{ _('Notifications for users') }}", anchorId: 'setting-notifications-users', keywords: ["{{ _('notification') }}", "{{ _('users') }}"] }, + { id: 'notifications_admins_all', tab: 'notifications', section: "{{ _('Notifications') }}", label: "{{ _('Notifications for all administrators') }}", anchorId: 'setting-notifications-admins-all', keywords: ["{{ _('notification') }}", "{{ _('admins') }}"] }, + { id: 'notifications_admins', tab: 'notifications', section: "{{ _('Notifications') }}", label: "{{ _('Notifications for administrators') }}", anchorId: 'setting-notifications-admins', keywords: ["{{ _('notification') }}", "{{ _('admin') }}"] }, + + { id: 'mail_enabled', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Enable Mail System') }}", anchorId: 'setting-mail-enabled', keywords: ["{{ _('mail') }}", "{{ _('smtp') }}", "{{ _('email') }}"] }, + { id: 'mail_server', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Server') }}", anchorId: 'setting-mail-server', keywords: ["{{ _('smtp') }}", "{{ _('host') }}"] }, + { id: 'mail_port', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Port') }}", anchorId: 'setting-mail-port', keywords: ["{{ _('smtp') }}", "{{ _('port') }}"] }, + { id: 'mail_default_sender', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Default Sender') }}", anchorId: 'setting-mail-default-sender', keywords: ["{{ _('sender') }}", "{{ _('from') }}"] }, + { id: 'mail_allowed_domains', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Allowed Email Domains') }}", anchorId: 'setting-mail-allowed-domains', keywords: ["{{ _('email') }}", "{{ _('domains') }}", "{{ _('allowlist') }}"] }, ], @@ -1384,10 +1384,16 @@

{{ _('Enable Mail System') }}

})); }, filteredSettings() { - const query = (this.settingsQuery || '').toLowerCase().trim(); + const query = this.normalizeForSearch(this.settingsQuery); const items = this.settingsSearchMap.map(setting => ({ ...setting, tabText: this.tabsMap?.[setting.tab]?.text || setting.tab, + normalizedHaystack: this.normalizeForSearch([ + setting.label, + setting.section, + this.tabsMap?.[setting.tab]?.text || setting.tab, + ...(setting.keywords || []), + ].join(' ')), })); if (!query) { @@ -1396,16 +1402,7 @@

{{ _('Enable Mail System') }}

const terms = query.split(/\s+/).filter(Boolean); return items - .filter(setting => { - const haystack = [ - setting.label, - setting.section, - setting.tabText, - ...(setting.keywords || []), - ].join(' ').toLowerCase(); - - return terms.every(term => haystack.includes(term)); - }) + .filter(setting => terms.every(term => setting.normalizedHaystack.includes(term))) .slice(0, 24); }, hasChanges() { @@ -1414,6 +1411,21 @@

{{ _('Enable Mail System') }}

}, methods: { + normalizeForSearch(value) { + return String(value || '') + .normalize('NFKD') + .replace(/[\u0300-\u036f]/g, '') + .replace(/[\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06ED]/g, '') + .replace(/\u0640/g, '') + .replace(/[أإآٱ]/g, 'ا') + .replace(/[ؤئ]/g, 'ء') + .replace(/ى/g, 'ي') + .replace(/ة/g, 'ه') + .replace(/[_./-]+/g, ' ') + .toLocaleLowerCase() + .replace(/\s+/g, ' ') + .trim(); + }, loadWhisperModels(){ api.get('/import/api/whisper/models/').then(res => { this.whisperModels = res.data.models; From 80438773b5a09ee6a086af60e258f6221d3833e4 Mon Sep 17 00:00:00 2001 From: Daniel Apodaca Date: Wed, 1 Apr 2026 07:51:15 -0600 Subject: [PATCH 04/10] add missing email settings to search --- .../admin/templates/admin/system-administration.html | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/enferno/admin/templates/admin/system-administration.html b/enferno/admin/templates/admin/system-administration.html index 9821d525b..36fd73c6d 100644 --- a/enferno/admin/templates/admin/system-administration.html +++ b/enferno/admin/templates/admin/system-administration.html @@ -1047,22 +1047,22 @@

{{ _('Enable Mail System') }}

hint="{{ _('Port for SMTP server.') }}" v-model.number="eitem.MAIL_PORT">
- + - + - + - + @@ -1323,6 +1323,10 @@

{{ _('Enable Mail System') }}

{ id: 'mail_port', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Port') }}", anchorId: 'setting-mail-port', keywords: ["{{ _('smtp') }}", "{{ _('port') }}"] }, { id: 'mail_default_sender', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Default Sender') }}", anchorId: 'setting-mail-default-sender', keywords: ["{{ _('sender') }}", "{{ _('from') }}"] }, { id: 'mail_allowed_domains', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Allowed Email Domains') }}", anchorId: 'setting-mail-allowed-domains', keywords: ["{{ _('email') }}", "{{ _('domains') }}", "{{ _('allowlist') }}"] }, + { id: 'mail_tls', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Use TLS') }}", anchorId: 'setting-mail-tls', keywords: ["{{ _('tls') }}", "{{ _('transport') }}", "{{ _('layer') }}", "{{ _('security') }}"] }, + { id: 'mail_ssl', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Use SSL') }}", anchorId: 'setting-mail-ssl', keywords: ["{{ _('ssl') }}", "{{ _('secure') }}", "{{ _('sockets') }}", "{{ _('layer') }}"] }, + { id: 'mail_user', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail User') }}", anchorId: 'setting-mail-user', keywords: ["{{ _('user') }}", "{{ _('account') }}", "{{ _('credentials') }}"] }, + { id: 'mail_password', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Password') }}", anchorId: 'setting-mail-password', keywords: ["{{ _('password') }}", "{{ _('account') }}", "{{ _('credentials') }}"] }, ], From ccc23dc7e50ed558ac9365cedab1f58b9caa93e1 Mon Sep 17 00:00:00 2001 From: Daniel Apodaca Date: Wed, 1 Apr 2026 08:12:11 -0600 Subject: [PATCH 05/10] move some id's directly to btn toggle and add aws settings to search --- .../admin/system-administration.html | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/enferno/admin/templates/admin/system-administration.html b/enferno/admin/templates/admin/system-administration.html index 36fd73c6d..88aa9499e 100644 --- a/enferno/admin/templates/admin/system-administration.html +++ b/enferno/admin/templates/admin/system-administration.html @@ -109,13 +109,11 @@

{{ _('Localization') }}

{{ _('Set the default interface language for new sessions.') }}

{{ _('Default language') }}

{{ _('Changes default interface language for all users. Users can still choose their own interface language.') }}

-
- - - ${name} - - -
+ + + ${name} + + @@ -175,23 +173,21 @@

{{ _('Advanced analysis features') }}

{{ _('Storage backend') }}

{{ _('Storage options for media files uploaded to Bayanat. By default, Bayanat store these files locally on the server. It\'s also possible to use S3 compatible bucket using cloud providers like AWS, Azure, Google Cloud, or MinIO (which can be used in offline installations).') }}

-
- - {{ _('Local Filesystem') }} - {{ _('S3 Storage') }} - -
+ + {{ _('Local Filesystem') }} + {{ _('S3 Storage') }} +

{{ _('S3 connection details') }}

- + - + @@ -199,7 +195,7 @@

{{ _('S3 connection details') }}

- + @@ -1276,6 +1272,9 @@

{{ _('Enable Mail System') }}

{ id: 'storage_backend', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('Local Filesystem / S3 Storage') }}", anchorId: 'setting-storage-backend', keywords: ["{{ _('files') }}", "{{ _('s3') }}", "{{ _('bucket') }}"] }, { id: 's3_bucket', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('S3 Bucket Name') }}", anchorId: 'setting-s3-bucket', keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('bucket') }}"] }, + { id: 'aws_access_key_id', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Access Key ID') }}", anchorId: 'setting-aws-access-key-id', keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('access') }}", "{{ _('key') }}", "{{ _('id') }}"] }, + { id: 'aws_secret_access_key', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Secret Access Key') }}", anchorId: 'setting-aws-secret-access-key', keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('secret') }}", "{{ _('key') }}"] }, + { id: 'aws_region', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Region') }}", anchorId: 'setting-aws-region', keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('region') }}"] }, { id: 'media_extensions', tab: 'storage', section: "{{ _('Upload restrictions') }}", label: "{{ _('Allowed Media Extensions') }}", anchorId: 'setting-media-allowed-extensions', keywords: ["{{ _('upload') }}", "{{ _('extensions') }}", "{{ _('files') }}"] }, { id: 'media_size', tab: 'storage', section: "{{ _('Upload restrictions') }}", label: "{{ _('Media Max Upload Size') }}", anchorId: 'setting-media-max-upload-size', keywords: ["{{ _('upload') }}", "{{ _('size') }}", "{{ _('limit') }}"] }, From 3848d8265396388f09763f03793ab768dd217e80 Mon Sep 17 00:00:00 2001 From: Daniel Apodaca Date: Wed, 1 Apr 2026 08:26:55 -0600 Subject: [PATCH 06/10] add remaining missing settings to search map --- .../admin/system-administration.html | 65 +++++++++++++++++-- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/enferno/admin/templates/admin/system-administration.html b/enferno/admin/templates/admin/system-administration.html index 88aa9499e..beb69420f 100644 --- a/enferno/admin/templates/admin/system-administration.html +++ b/enferno/admin/templates/admin/system-administration.html @@ -1268,6 +1268,10 @@

{{ _('Enable Mail System') }}

{ id: 'video_rate', tab: 'general', section: "{{ _('Interface defaults') }}", label: "{{ _('Video playback rate') }}", anchorId: 'setting-video-playback-rate', keywords: ["{{ _('media') }}", "{{ _('speed') }}", "{{ _('video') }}"] }, { id: 'default_language', tab: 'general', section: "{{ _('Localization') }}", label: "{{ _('Default language') }}", anchorId: 'setting-default-language', keywords: ["{{ _('locale') }}", "{{ _('translation') }}", "{{ _('language') }}"] }, { id: 'dedup_tool', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication tool') }}", anchorId: 'setting-dedup-tool', keywords: ["{{ _('matching') }}", "{{ _('duplicates') }}"] }, + { id: 'dedup_low_distance', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication low distance') }}", anchorId: 'setting-dedup-tool', keywords: ["{{ _('dedup') }}", "{{ _('distance') }}", "{{ _('threshold') }}"] }, + { id: 'dedup_max_distance', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication max distance') }}", anchorId: 'setting-dedup-tool', keywords: ["{{ _('dedup') }}", "{{ _('distance') }}", "{{ _('threshold') }}"] }, + { id: 'dedup_batch_size', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication batch size') }}", anchorId: 'setting-dedup-tool', keywords: ["{{ _('dedup') }}", "{{ _('batch') }}", "{{ _('performance') }}"] }, + { id: 'dedup_interval', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication interval') }}", anchorId: 'setting-dedup-tool', keywords: ["{{ _('dedup') }}", "{{ _('interval') }}", "{{ _('performance') }}"] }, { id: 'adv_analysis', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Advanced analysis features') }}", anchorId: 'setting-advanced-analysis', keywords: ["{{ _('analysis') }}", "{{ _('features') }}"] }, { id: 'storage_backend', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('Local Filesystem / S3 Storage') }}", anchorId: 'setting-storage-backend', keywords: ["{{ _('files') }}", "{{ _('s3') }}", "{{ _('bucket') }}"] }, @@ -1284,25 +1288,57 @@

{{ _('Enable Mail System') }}

{ id: 'disallow_sessions', tab: 'security', section: "{{ _('Session policies') }}", label: "{{ _('Disallow multiple concurrent sessions') }}", anchorId: 'setting-disallow-multiple-sessions', keywords: ["{{ _('session') }}", "{{ _('login') }}", "{{ _('devices') }}"] }, { id: 'session_retention', tab: 'security', section: "{{ _('Session policies') }}", label: "{{ _('Session Data Retention Period') }}", anchorId: 'setting-session-retention', keywords: ["{{ _('session') }}", "{{ _('retention') }}", "{{ _('days') }}"] }, { id: 'recaptcha_enabled', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Recaptcha enabled') }}", anchorId: 'setting-recaptcha-enabled', keywords: ["{{ _('captcha') }}", "{{ _('bot') }}", "{{ _('login') }}"] }, + { id: 'recaptcha_public_key', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Recaptcha Public Key') }}", anchorId: 'setting-recaptcha-enabled', keywords: ["{{ _('recaptcha') }}", "{{ _('site key') }}", "{{ _('captcha') }}"] }, + { id: 'recaptcha_private_key', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Recaptcha Private Key') }}", anchorId: 'setting-recaptcha-enabled', keywords: ["{{ _('recaptcha') }}", "{{ _('secret key') }}", "{{ _('captcha') }}"] }, { id: 'google_oauth_enabled', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Enable Google OAuth') }}", anchorId: 'setting-google-oauth-enabled', keywords: ["{{ _('sso') }}", "{{ _('oauth') }}", "{{ _('google') }}"] }, + { id: 'google_client_id', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Google Client ID') }}", anchorId: 'setting-google-oauth-enabled', keywords: ["{{ _('oauth') }}", "{{ _('google') }}", "{{ _('client') }}"] }, + { id: 'google_client_secret', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Google Client Secret') }}", anchorId: 'setting-google-oauth-enabled', keywords: ["{{ _('oauth') }}", "{{ _('google') }}", "{{ _('secret') }}"] }, + { id: 'google_discovery_url', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Google Discovery URL') }}", anchorId: 'setting-google-oauth-enabled', keywords: ["{{ _('oauth') }}", "{{ _('google') }}", "{{ _('oidc') }}"] }, { id: 'security_freshness', tab: 'security', section: "{{ _('Re-authentication windows') }}", label: "{{ _('Security freshness') }}", anchorId: 'setting-security-freshness', keywords: ["{{ _('reauth') }}", "{{ _('timeout') }}", "{{ _('minutes') }}"] }, + { id: 'security_freshness_grace', tab: 'security', section: "{{ _('Re-authentication windows') }}", label: "{{ _('Security freshness grace period') }}", anchorId: 'setting-security-freshness', keywords: ["{{ _('reauth') }}", "{{ _('grace') }}", "{{ _('2fa') }}"] }, { id: 'restrictive_access', tab: 'control', section: "{{ _('Default access behavior') }}", label: "{{ _('Restrictive access control') }}", anchorId: 'setting-restrictive-access-control', keywords: ["{{ _('permissions') }}", "{{ _('default access') }}"] }, { id: 'non_admin_restrict', tab: 'control', section: "{{ _('Default access behavior') }}", label: "{{ _('Allow non-admin users to restrict new items') }}", anchorId: 'setting-non-admin-restrict', keywords: ["{{ _('permissions') }}", "{{ _('item restriction') }}"] }, { id: 'activity_items', tab: 'logging', section: "{{ _('Items') }}", label: "{{ _('Items activity logging') }}", anchorId: 'setting-activity-items', keywords: ["{{ _('logging') }}", "{{ _('audit') }}", "{{ _('items') }}"] }, + { id: 'activity_create', tab: 'logging', section: "{{ _('Items') }}", label: "{{ _('Items created') }}", anchorId: 'setting-activity-items', keywords: ["{{ _('create') }}", "{{ _('logging') }}", "{{ _('audit') }}"] }, + { id: 'activity_view', tab: 'logging', section: "{{ _('Items') }}", label: "{{ _('Items viewed') }}", anchorId: 'setting-activity-items', keywords: ["{{ _('view') }}", "{{ _('logging') }}", "{{ _('audit') }}"] }, + { id: 'activity_update', tab: 'logging', section: "{{ _('Items') }}", label: "{{ _('Items edited') }}", anchorId: 'setting-activity-items', keywords: ["{{ _('edit') }}", "{{ _('update') }}", "{{ _('logging') }}"] }, + { id: 'activity_delete', tab: 'logging', section: "{{ _('Items') }}", label: "{{ _('Items deleted') }}", anchorId: 'setting-activity-items', keywords: ["{{ _('delete') }}", "{{ _('logging') }}", "{{ _('audit') }}"] }, + { id: 'activity_review', tab: 'logging', section: "{{ _('Items') }}", label: "{{ _('Items reviewed') }}", anchorId: 'setting-activity-items', keywords: ["{{ _('review') }}", "{{ _('peer') }}", "{{ _('logging') }}"] }, + { id: 'activity_self_assign', tab: 'logging', section: "{{ _('Items') }}", label: "{{ _('Items self-assigned') }}", anchorId: 'setting-activity-items', keywords: ["{{ _('assign') }}", "{{ _('self') }}", "{{ _('logging') }}"] }, + { id: 'activity_export', tab: 'logging', section: "{{ _('Export') }}", label: "{{ _('Export activity logging') }}", anchorId: 'setting-activity-export', keywords: ["{{ _('logging') }}", "{{ _('audit') }}", "{{ _('export') }}"] }, + { id: 'activity_request', tab: 'logging', section: "{{ _('Export') }}", label: "{{ _('Export requests made') }}", anchorId: 'setting-activity-export', keywords: ["{{ _('export') }}", "{{ _('request') }}", "{{ _('logging') }}"] }, + { id: 'activity_approve', tab: 'logging', section: "{{ _('Export') }}", label: "{{ _('Export requests approved') }}", anchorId: 'setting-activity-export', keywords: ["{{ _('export') }}", "{{ _('approve') }}", "{{ _('logging') }}"] }, + { id: 'activity_reject', tab: 'logging', section: "{{ _('Export') }}", label: "{{ _('Export requests rejected') }}", anchorId: 'setting-activity-export', keywords: ["{{ _('export') }}", "{{ _('reject') }}", "{{ _('logging') }}"] }, + { id: 'activity_download', tab: 'logging', section: "{{ _('Export') }}", label: "{{ _('Export requests downloaded') }}", anchorId: 'setting-activity-export', keywords: ["{{ _('export') }}", "{{ _('download') }}", "{{ _('logging') }}"] }, + { id: 'activity_auth', tab: 'logging', section: "{{ _('Authentication') }}", label: "{{ _('Authentication activity logging') }}", anchorId: 'setting-activity-auth', keywords: ["{{ _('logging') }}", "{{ _('login') }}", "{{ _('logout') }}"] }, + { id: 'activity_login', tab: 'logging', section: "{{ _('Authentication') }}", label: "{{ _('Logins') }}", anchorId: 'setting-activity-auth', keywords: ["{{ _('login') }}", "{{ _('sign in') }}", "{{ _('logging') }}"] }, + { id: 'activity_logout', tab: 'logging', section: "{{ _('Authentication') }}", label: "{{ _('Logouts') }}", anchorId: 'setting-activity-auth', keywords: ["{{ _('logout') }}", "{{ _('sign out') }}", "{{ _('logging') }}"] }, + { id: 'activity_other', tab: 'logging', section: "{{ _('Other actions') }}", label: "{{ _('Other actions logging') }}", anchorId: 'setting-activity-other', keywords: ["{{ _('search') }}", "{{ _('upload') }}", "{{ _('bulk') }}"] }, + { id: 'activity_search', tab: 'logging', section: "{{ _('Other actions') }}", label: "{{ _('Search queries made') }}", anchorId: 'setting-activity-other', keywords: ["{{ _('search') }}", "{{ _('query') }}", "{{ _('logging') }}"] }, + { id: 'activity_upload', tab: 'logging', section: "{{ _('Other actions') }}", label: "{{ _('Files uploaded') }}", anchorId: 'setting-activity-other', keywords: ["{{ _('upload') }}", "{{ _('files') }}", "{{ _('logging') }}"] }, + { id: 'activity_bulk', tab: 'logging', section: "{{ _('Other actions') }}", label: "{{ _('Bulk operations queued') }}", anchorId: 'setting-activity-other', keywords: ["{{ _('bulk') }}", "{{ _('batch') }}", "{{ _('logging') }}"] }, + { id: 'activity_retention', tab: 'logging', section: "{{ _('Retention period') }}", label: "{{ _('Activity Retention Period') }}", anchorId: 'setting-activity-retention', keywords: ["{{ _('retention') }}", "{{ _('cleanup') }}", "{{ _('days') }}"] }, { id: 'media_import_tool', tab: 'import', section: "{{ _('Ingestion pipelines') }}", label: "{{ _('Media Import tool') }}", anchorId: 'setting-media-import-tool', keywords: ["{{ _('etl') }}", "{{ _('import') }}", "{{ _('media') }}"] }, { id: 'import_path_scanning', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Media Import path scanning') }}", anchorId: 'setting-import-path-scanning', keywords: ["{{ _('path') }}", "{{ _('scan') }}", "{{ _('security') }}"] }, + { id: 'etl_vid_ext', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Allowed Media Import Extensions') }}", anchorId: 'setting-import-path-scanning', keywords: ["{{ _('extensions') }}", "{{ _('etl') }}", "{{ _('files') }}"] }, { id: 'ocr_import', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Tesseract OCR (Import)') }}", anchorId: 'setting-import-ocr', keywords: ["{{ _('ocr') }}", "{{ _('tesseract') }}", "{{ _('text extraction') }}"] }, + { id: 'ocr_extensions', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('OCR Extensions') }}", anchorId: 'setting-import-ocr', keywords: ["{{ _('ocr') }}", "{{ _('extensions') }}", "{{ _('tesseract') }}"] }, { id: 'vision_api_key', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Google Cloud API Key') }}", anchorId: 'setting-google-vision-api-key', keywords: ["{{ _('vision') }}", "{{ _('ocr') }}", "{{ _('translation') }}"] }, { id: 'transcription_enabled', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Enable transcription') }}", anchorId: 'setting-transcription-enabled', keywords: ["{{ _('whisper') }}", "{{ _('audio') }}", "{{ _('transcript') }}"] }, + { id: 'whisper_model', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Whisper Model') }}", anchorId: 'setting-transcription-enabled', keywords: ["{{ _('whisper') }}", "{{ _('model') }}", "{{ _('transcription') }}"] }, { id: 'sheet_import', tab: 'import', section: "{{ _('Sheet Import') }}", label: "{{ _('Sheet Import') }}", anchorId: 'setting-sheet-import', keywords: ["{{ _('spreadsheet') }}", "{{ _('excel') }}", "{{ _('import') }}"] }, + { id: 'sheets_allowed_extensions', tab: 'import', section: "{{ _('Sheet Import') }}", label: "{{ _('Allowed Sheets Extensions') }}", anchorId: 'setting-sheet-import', keywords: ["{{ _('spreadsheet') }}", "{{ _('extensions') }}", "{{ _('csv') }}"] }, { id: 'web_import', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Web import') }}", anchorId: 'setting-web-import', keywords: ["{{ _('yt-dlp') }}", "{{ _('url') }}", "{{ _('media import') }}"] }, + { id: 'web_import_proxy', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Web import proxy') }}", anchorId: 'setting-web-import', keywords: ["{{ _('proxy') }}", "{{ _('socks5') }}", "{{ _('yt-dlp') }}"] }, + { id: 'ytdlp_allowed_domains', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Allowed domains') }}", anchorId: 'setting-web-import', keywords: ["{{ _('domains') }}", "{{ _('allowlist') }}", "{{ _('yt-dlp') }}"] }, + { id: 'ytdlp_cookies', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Web import cookies') }}", anchorId: 'setting-web-import', keywords: ["{{ _('cookies') }}", "{{ _('auth') }}", "{{ _('yt-dlp') }}"] }, { id: 'export_tool', tab: 'export', section: "{{ _('Export system') }}", label: "{{ _('Export system') }}", anchorId: 'setting-export-tool', keywords: ["{{ _('exports') }}", "{{ _('requests') }}"] }, { id: 'export_expiry', tab: 'export', section: "{{ _('Export system') }}", label: "{{ _('Export Expiry Time') }}", anchorId: 'setting-export-expiry-time', keywords: ["{{ _('expiry') }}", "{{ _('retention') }}", "{{ _('hours') }}"] }, @@ -1313,9 +1349,30 @@

{{ _('Enable Mail System') }}

{ id: 'postal_code_generation', tab: 'locations', section: "{{ _('Location') }}", label: "{{ _('Include postal code generation settings') }}", anchorId: 'setting-include-postal-code', keywords: ["{{ _('location') }}", "{{ _('postal code') }}"] }, - { id: 'notifications_users', tab: 'notifications', section: "{{ _('Notifications') }}", label: "{{ _('Notifications for users') }}", anchorId: 'setting-notifications-users', keywords: ["{{ _('notification') }}", "{{ _('users') }}"] }, - { id: 'notifications_admins_all', tab: 'notifications', section: "{{ _('Notifications') }}", label: "{{ _('Notifications for all administrators') }}", anchorId: 'setting-notifications-admins-all', keywords: ["{{ _('notification') }}", "{{ _('admins') }}"] }, - { id: 'notifications_admins', tab: 'notifications', section: "{{ _('Notifications') }}", label: "{{ _('Notifications for administrators') }}", anchorId: 'setting-notifications-admins', keywords: ["{{ _('notification') }}", "{{ _('admin') }}"] }, + { id: 'notifications_users', tab: 'notifications', section: "{{ _('Notifications for users') }}", label: "{{ _('Notifications for users') }}", anchorId: 'setting-notifications-users', keywords: ["{{ _('notification') }}", "{{ _('users') }}"] }, + { id: 'notif_login_new_ip', tab: 'notifications', section: "{{ _('Notifications for users') }}", label: "{{ _('Login from new IP') }}", anchorId: 'setting-notifications-users', keywords: ["{{ _('ip') }}", "{{ _('login') }}", "{{ _('alert') }}"] }, + { id: 'notif_password', tab: 'notifications', section: "{{ _('Notifications for users') }}", label: "{{ _('Password') }}", anchorId: 'setting-notifications-users', keywords: ["{{ _('password') }}", "{{ _('change') }}", "{{ _('notification') }}"] }, + { id: 'notif_2fa', tab: 'notifications', section: "{{ _('Notifications for users') }}", label: "{{ _('Two-factor authentication') }}", anchorId: 'setting-notifications-users', keywords: ["{{ _('2fa') }}", "{{ _('mfa') }}", "{{ _('notification') }}"] }, + { id: 'notif_recovery_codes', tab: 'notifications', section: "{{ _('Notifications for users') }}", label: "{{ _('Recovery codes') }}", anchorId: 'setting-notifications-users', keywords: ["{{ _('recovery') }}", "{{ _('codes') }}", "{{ _('2fa') }}"] }, + { id: 'notif_new_assignment', tab: 'notifications', section: "{{ _('Notifications for users') }}", label: "{{ _('New assignment') }}", anchorId: 'setting-notifications-users', keywords: ["{{ _('task') }}", "{{ _('assign') }}", "{{ _('notification') }}"] }, + { id: 'notif_review_needed', tab: 'notifications', section: "{{ _('Notifications for users') }}", label: "{{ _('Review needed') }}", anchorId: 'setting-notifications-users', keywords: ["{{ _('review') }}", "{{ _('request') }}", "{{ _('notification') }}"] }, + { id: 'notif_web_import_status', tab: 'notifications', section: "{{ _('Notifications for users') }}", label: "{{ _('Web Import status') }}", anchorId: 'setting-notifications-users', keywords: ["{{ _('web import') }}", "{{ _('yt-dlp') }}", "{{ _('notification') }}"] }, + + { id: 'notifications_admins_all', tab: 'notifications', section: "{{ _('Notifications for all administrators') }}", label: "{{ _('Notifications for all administrators') }}", anchorId: 'setting-notifications-admins-all', keywords: ["{{ _('notification') }}", "{{ _('admins') }}"] }, + { id: 'notif_new_user', tab: 'notifications', section: "{{ _('Notifications for all administrators') }}", label: "{{ _('New user') }}", anchorId: 'setting-notifications-admins-all', keywords: ["{{ _('user') }}", "{{ _('account') }}", "{{ _('notification') }}"] }, + { id: 'notif_update_user', tab: 'notifications', section: "{{ _('Notifications for all administrators') }}", label: "{{ _('User updates') }}", anchorId: 'setting-notifications-admins-all', keywords: ["{{ _('user') }}", "{{ _('update') }}", "{{ _('notification') }}"] }, + { id: 'notif_new_group', tab: 'notifications', section: "{{ _('Notifications for all administrators') }}", label: "{{ _('New group') }}", anchorId: 'setting-notifications-admins-all', keywords: ["{{ _('group') }}", "{{ _('role') }}", "{{ _('notification') }}"] }, + { id: 'notif_system_settings_change', tab: 'notifications', section: "{{ _('Notifications for all administrators') }}", label: "{{ _('System settings change') }}", anchorId: 'setting-notifications-admins-all', keywords: ["{{ _('settings') }}", "{{ _('change') }}", "{{ _('notification') }}"] }, + { id: 'notif_unauthorized_action', tab: 'notifications', section: "{{ _('Notifications for all administrators') }}", label: "{{ _('Unauthorized action') }}", anchorId: 'setting-notifications-admins-all', keywords: ["{{ _('unauthorized') }}", "{{ _('security') }}", "{{ _('alert') }}"] }, + { id: 'notif_admin_credentials_change', tab: 'notifications', section: "{{ _('Notifications for all administrators') }}", label: "{{ _('Admin security credentials change') }}", anchorId: 'setting-notifications-admins-all', keywords: ["{{ _('admin') }}", "{{ _('credentials') }}", "{{ _('security') }}"] }, + { id: 'notif_item_deleted', tab: 'notifications', section: "{{ _('Notifications for all administrators') }}", label: "{{ _('Deleted items') }}", anchorId: 'setting-notifications-admins-all', keywords: ["{{ _('delete') }}", "{{ _('items') }}", "{{ _('notification') }}"] }, + { id: 'notif_new_export', tab: 'notifications', section: "{{ _('Notifications for all administrators') }}", label: "{{ _('New export request') }}", anchorId: 'setting-notifications-admins-all', keywords: ["{{ _('export') }}", "{{ _('request') }}", "{{ _('notification') }}"] }, + { id: 'notif_export_approved', tab: 'notifications', section: "{{ _('Notifications for all administrators') }}", label: "{{ _('Approved export request') }}", anchorId: 'setting-notifications-admins-all', keywords: ["{{ _('export') }}", "{{ _('approve') }}", "{{ _('notification') }}"] }, + { id: 'notif_new_batch', tab: 'notifications', section: "{{ _('Notifications for all administrators') }}", label: "{{ _('New import batch') }}", anchorId: 'setting-notifications-admins-all', keywords: ["{{ _('import') }}", "{{ _('batch') }}", "{{ _('notification') }}"] }, + + { id: 'notifications_admins', tab: 'notifications', section: "{{ _('Notifications for administrators') }}", label: "{{ _('Notifications for administrators') }}", anchorId: 'setting-notifications-admins', keywords: ["{{ _('notification') }}", "{{ _('admin') }}"] }, + { id: 'notif_batch_status', tab: 'notifications', section: "{{ _('Notifications for administrators') }}", label: "{{ _('Import batch status') }}", anchorId: 'setting-notifications-admins', keywords: ["{{ _('import') }}", "{{ _('batch') }}", "{{ _('status') }}"] }, + { id: 'notif_bulk_operation_status', tab: 'notifications', section: "{{ _('Notifications for administrators') }}", label: "{{ _('Bulk operations status') }}", anchorId: 'setting-notifications-admins', keywords: ["{{ _('bulk') }}", "{{ _('operations') }}", "{{ _('status') }}"] }, { id: 'mail_enabled', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Enable Mail System') }}", anchorId: 'setting-mail-enabled', keywords: ["{{ _('mail') }}", "{{ _('smtp') }}", "{{ _('email') }}"] }, { id: 'mail_server', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Server') }}", anchorId: 'setting-mail-server', keywords: ["{{ _('smtp') }}", "{{ _('host') }}"] }, @@ -1324,7 +1381,7 @@

{{ _('Enable Mail System') }}

{ id: 'mail_allowed_domains', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Allowed Email Domains') }}", anchorId: 'setting-mail-allowed-domains', keywords: ["{{ _('email') }}", "{{ _('domains') }}", "{{ _('allowlist') }}"] }, { id: 'mail_tls', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Use TLS') }}", anchorId: 'setting-mail-tls', keywords: ["{{ _('tls') }}", "{{ _('transport') }}", "{{ _('layer') }}", "{{ _('security') }}"] }, { id: 'mail_ssl', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Use SSL') }}", anchorId: 'setting-mail-ssl', keywords: ["{{ _('ssl') }}", "{{ _('secure') }}", "{{ _('sockets') }}", "{{ _('layer') }}"] }, - { id: 'mail_user', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail User') }}", anchorId: 'setting-mail-user', keywords: ["{{ _('user') }}", "{{ _('account') }}", "{{ _('credentials') }}"] }, + { id: 'mail_user', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail User') }}", anchorId: 'setting-mail-username', keywords: ["{{ _('user') }}", "{{ _('account') }}", "{{ _('credentials') }}"] }, { id: 'mail_password', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Password') }}", anchorId: 'setting-mail-password', keywords: ["{{ _('password') }}", "{{ _('account') }}", "{{ _('credentials') }}"] }, ], From 5506bc6cf083e0c4cc6c6d9d31fbb631b9548f3a Mon Sep 17 00:00:00 2001 From: Daniel Apodaca Date: Wed, 1 Apr 2026 08:55:12 -0600 Subject: [PATCH 07/10] add missing settings to search map; notify user when a searched setting is hidden behind a disabled parent feature --- enferno/admin/templates/admin/jsapi.jinja2 | 1 + .../admin/system-administration.html | 98 ++++++++++++------- 2 files changed, 66 insertions(+), 33 deletions(-) diff --git a/enferno/admin/templates/admin/jsapi.jinja2 b/enferno/admin/templates/admin/jsapi.jinja2 index 49fc98622..3f9b7de3d 100644 --- a/enferno/admin/templates/admin/jsapi.jinja2 +++ b/enferno/admin/templates/admin/jsapi.jinja2 @@ -635,6 +635,7 @@ updated_: "{{ _('Updated') }}", unset_: "{{ _('UNSET') }}", on_: "{{ _('On') }}", off_: "{{ _('Off') }}", +settingHiddenRequires_: "{{ _('{label} is only visible when {requires} is enabled.') }}", // Component Data include_postal_code_ : "{{ _('Include Postal Code') }}", diff --git a/enferno/admin/templates/admin/system-administration.html b/enferno/admin/templates/admin/system-administration.html index beb69420f..9f5049b90 100644 --- a/enferno/admin/templates/admin/system-administration.html +++ b/enferno/admin/templates/admin/system-administration.html @@ -1268,17 +1268,17 @@

{{ _('Enable Mail System') }}

{ id: 'video_rate', tab: 'general', section: "{{ _('Interface defaults') }}", label: "{{ _('Video playback rate') }}", anchorId: 'setting-video-playback-rate', keywords: ["{{ _('media') }}", "{{ _('speed') }}", "{{ _('video') }}"] }, { id: 'default_language', tab: 'general', section: "{{ _('Localization') }}", label: "{{ _('Default language') }}", anchorId: 'setting-default-language', keywords: ["{{ _('locale') }}", "{{ _('translation') }}", "{{ _('language') }}"] }, { id: 'dedup_tool', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication tool') }}", anchorId: 'setting-dedup-tool', keywords: ["{{ _('matching') }}", "{{ _('duplicates') }}"] }, - { id: 'dedup_low_distance', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication low distance') }}", anchorId: 'setting-dedup-tool', keywords: ["{{ _('dedup') }}", "{{ _('distance') }}", "{{ _('threshold') }}"] }, - { id: 'dedup_max_distance', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication max distance') }}", anchorId: 'setting-dedup-tool', keywords: ["{{ _('dedup') }}", "{{ _('distance') }}", "{{ _('threshold') }}"] }, - { id: 'dedup_batch_size', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication batch size') }}", anchorId: 'setting-dedup-tool', keywords: ["{{ _('dedup') }}", "{{ _('batch') }}", "{{ _('performance') }}"] }, - { id: 'dedup_interval', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication interval') }}", anchorId: 'setting-dedup-tool', keywords: ["{{ _('dedup') }}", "{{ _('interval') }}", "{{ _('performance') }}"] }, + { id: 'dedup_low_distance', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication low distance') }}", anchorId: 'setting-dedup-tool', requires: { label: "{{ _('Deduplication tool') }}", anchorId: 'setting-dedup-tool' }, keywords: ["{{ _('dedup') }}", "{{ _('distance') }}", "{{ _('threshold') }}"] }, + { id: 'dedup_max_distance', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication max distance') }}", anchorId: 'setting-dedup-tool', requires: { label: "{{ _('Deduplication tool') }}", anchorId: 'setting-dedup-tool' }, keywords: ["{{ _('dedup') }}", "{{ _('distance') }}", "{{ _('threshold') }}"] }, + { id: 'dedup_batch_size', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication batch size') }}", anchorId: 'setting-dedup-tool', requires: { label: "{{ _('Deduplication tool') }}", anchorId: 'setting-dedup-tool' }, keywords: ["{{ _('dedup') }}", "{{ _('batch') }}", "{{ _('performance') }}"] }, + { id: 'dedup_interval', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Deduplication interval') }}", anchorId: 'setting-dedup-tool', requires: { label: "{{ _('Deduplication tool') }}", anchorId: 'setting-dedup-tool' }, keywords: ["{{ _('dedup') }}", "{{ _('interval') }}", "{{ _('performance') }}"] }, { id: 'adv_analysis', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Advanced analysis features') }}", anchorId: 'setting-advanced-analysis', keywords: ["{{ _('analysis') }}", "{{ _('features') }}"] }, { id: 'storage_backend', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('Local Filesystem / S3 Storage') }}", anchorId: 'setting-storage-backend', keywords: ["{{ _('files') }}", "{{ _('s3') }}", "{{ _('bucket') }}"] }, - { id: 's3_bucket', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('S3 Bucket Name') }}", anchorId: 'setting-s3-bucket', keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('bucket') }}"] }, - { id: 'aws_access_key_id', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Access Key ID') }}", anchorId: 'setting-aws-access-key-id', keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('access') }}", "{{ _('key') }}", "{{ _('id') }}"] }, - { id: 'aws_secret_access_key', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Secret Access Key') }}", anchorId: 'setting-aws-secret-access-key', keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('secret') }}", "{{ _('key') }}"] }, - { id: 'aws_region', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Region') }}", anchorId: 'setting-aws-region', keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('region') }}"] }, + { id: 's3_bucket', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('S3 Bucket Name') }}", anchorId: 'setting-s3-bucket', requires: { label: "{{ _('S3 Storage') }}", anchorId: 'setting-storage-backend' }, keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('bucket') }}"] }, + { id: 'aws_access_key_id', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Access Key ID') }}", anchorId: 'setting-aws-access-key-id', requires: { label: "{{ _('S3 Storage') }}", anchorId: 'setting-storage-backend' }, keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('access') }}", "{{ _('key') }}", "{{ _('id') }}"] }, + { id: 'aws_secret_access_key', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Secret Access Key') }}", anchorId: 'setting-aws-secret-access-key', requires: { label: "{{ _('S3 Storage') }}", anchorId: 'setting-storage-backend' }, keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('secret') }}", "{{ _('key') }}"] }, + { id: 'aws_region', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Region') }}", anchorId: 'setting-aws-region', requires: { label: "{{ _('S3 Storage') }}", anchorId: 'setting-storage-backend' }, keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('region') }}"] }, { id: 'media_extensions', tab: 'storage', section: "{{ _('Upload restrictions') }}", label: "{{ _('Allowed Media Extensions') }}", anchorId: 'setting-media-allowed-extensions', keywords: ["{{ _('upload') }}", "{{ _('extensions') }}", "{{ _('files') }}"] }, { id: 'media_size', tab: 'storage', section: "{{ _('Upload restrictions') }}", label: "{{ _('Media Max Upload Size') }}", anchorId: 'setting-media-max-upload-size', keywords: ["{{ _('upload') }}", "{{ _('size') }}", "{{ _('limit') }}"] }, @@ -1288,12 +1288,12 @@

{{ _('Enable Mail System') }}

{ id: 'disallow_sessions', tab: 'security', section: "{{ _('Session policies') }}", label: "{{ _('Disallow multiple concurrent sessions') }}", anchorId: 'setting-disallow-multiple-sessions', keywords: ["{{ _('session') }}", "{{ _('login') }}", "{{ _('devices') }}"] }, { id: 'session_retention', tab: 'security', section: "{{ _('Session policies') }}", label: "{{ _('Session Data Retention Period') }}", anchorId: 'setting-session-retention', keywords: ["{{ _('session') }}", "{{ _('retention') }}", "{{ _('days') }}"] }, { id: 'recaptcha_enabled', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Recaptcha enabled') }}", anchorId: 'setting-recaptcha-enabled', keywords: ["{{ _('captcha') }}", "{{ _('bot') }}", "{{ _('login') }}"] }, - { id: 'recaptcha_public_key', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Recaptcha Public Key') }}", anchorId: 'setting-recaptcha-enabled', keywords: ["{{ _('recaptcha') }}", "{{ _('site key') }}", "{{ _('captcha') }}"] }, - { id: 'recaptcha_private_key', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Recaptcha Private Key') }}", anchorId: 'setting-recaptcha-enabled', keywords: ["{{ _('recaptcha') }}", "{{ _('secret key') }}", "{{ _('captcha') }}"] }, + { id: 'recaptcha_public_key', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Recaptcha Public Key') }}", anchorId: 'setting-recaptcha-enabled', requires: { label: "{{ _('Recaptcha') }}", anchorId: 'setting-recaptcha-enabled' }, keywords: ["{{ _('recaptcha') }}", "{{ _('site key') }}", "{{ _('captcha') }}"] }, + { id: 'recaptcha_private_key', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Recaptcha Private Key') }}", anchorId: 'setting-recaptcha-enabled', requires: { label: "{{ _('Recaptcha') }}", anchorId: 'setting-recaptcha-enabled' }, keywords: ["{{ _('recaptcha') }}", "{{ _('secret key') }}", "{{ _('captcha') }}"] }, { id: 'google_oauth_enabled', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Enable Google OAuth') }}", anchorId: 'setting-google-oauth-enabled', keywords: ["{{ _('sso') }}", "{{ _('oauth') }}", "{{ _('google') }}"] }, - { id: 'google_client_id', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Google Client ID') }}", anchorId: 'setting-google-oauth-enabled', keywords: ["{{ _('oauth') }}", "{{ _('google') }}", "{{ _('client') }}"] }, - { id: 'google_client_secret', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Google Client Secret') }}", anchorId: 'setting-google-oauth-enabled', keywords: ["{{ _('oauth') }}", "{{ _('google') }}", "{{ _('secret') }}"] }, - { id: 'google_discovery_url', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Google Discovery URL') }}", anchorId: 'setting-google-oauth-enabled', keywords: ["{{ _('oauth') }}", "{{ _('google') }}", "{{ _('oidc') }}"] }, + { id: 'google_client_id', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Google Client ID') }}", anchorId: 'setting-google-oauth-enabled', requires: { label: "{{ _('Google OAuth') }}", anchorId: 'setting-google-oauth-enabled' }, keywords: ["{{ _('oauth') }}", "{{ _('google') }}", "{{ _('client') }}"] }, + { id: 'google_client_secret', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Google Client Secret') }}", anchorId: 'setting-google-oauth-enabled', requires: { label: "{{ _('Google OAuth') }}", anchorId: 'setting-google-oauth-enabled' }, keywords: ["{{ _('oauth') }}", "{{ _('google') }}", "{{ _('secret') }}"] }, + { id: 'google_discovery_url', tab: 'security', section: "{{ _('Login protection and sign-in providers') }}", label: "{{ _('Google Discovery URL') }}", anchorId: 'setting-google-oauth-enabled', requires: { label: "{{ _('Google OAuth') }}", anchorId: 'setting-google-oauth-enabled' }, keywords: ["{{ _('oauth') }}", "{{ _('google') }}", "{{ _('oidc') }}"] }, { id: 'security_freshness', tab: 'security', section: "{{ _('Re-authentication windows') }}", label: "{{ _('Security freshness') }}", anchorId: 'setting-security-freshness', keywords: ["{{ _('reauth') }}", "{{ _('timeout') }}", "{{ _('minutes') }}"] }, { id: 'security_freshness_grace', tab: 'security', section: "{{ _('Re-authentication windows') }}", label: "{{ _('Security freshness grace period') }}", anchorId: 'setting-security-freshness', keywords: ["{{ _('reauth') }}", "{{ _('grace') }}", "{{ _('2fa') }}"] }, @@ -1326,22 +1326,22 @@

{{ _('Enable Mail System') }}

{ id: 'activity_retention', tab: 'logging', section: "{{ _('Retention period') }}", label: "{{ _('Activity Retention Period') }}", anchorId: 'setting-activity-retention', keywords: ["{{ _('retention') }}", "{{ _('cleanup') }}", "{{ _('days') }}"] }, { id: 'media_import_tool', tab: 'import', section: "{{ _('Ingestion pipelines') }}", label: "{{ _('Media Import tool') }}", anchorId: 'setting-media-import-tool', keywords: ["{{ _('etl') }}", "{{ _('import') }}", "{{ _('media') }}"] }, - { id: 'import_path_scanning', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Media Import path scanning') }}", anchorId: 'setting-import-path-scanning', keywords: ["{{ _('path') }}", "{{ _('scan') }}", "{{ _('security') }}"] }, - { id: 'etl_vid_ext', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Allowed Media Import Extensions') }}", anchorId: 'setting-import-path-scanning', keywords: ["{{ _('extensions') }}", "{{ _('etl') }}", "{{ _('files') }}"] }, - { id: 'ocr_import', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Tesseract OCR (Import)') }}", anchorId: 'setting-import-ocr', keywords: ["{{ _('ocr') }}", "{{ _('tesseract') }}", "{{ _('text extraction') }}"] }, - { id: 'ocr_extensions', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('OCR Extensions') }}", anchorId: 'setting-import-ocr', keywords: ["{{ _('ocr') }}", "{{ _('extensions') }}", "{{ _('tesseract') }}"] }, - { id: 'vision_api_key', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Google Cloud API Key') }}", anchorId: 'setting-google-vision-api-key', keywords: ["{{ _('vision') }}", "{{ _('ocr') }}", "{{ _('translation') }}"] }, - { id: 'transcription_enabled', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Enable transcription') }}", anchorId: 'setting-transcription-enabled', keywords: ["{{ _('whisper') }}", "{{ _('audio') }}", "{{ _('transcript') }}"] }, - { id: 'whisper_model', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Whisper Model') }}", anchorId: 'setting-transcription-enabled', keywords: ["{{ _('whisper') }}", "{{ _('model') }}", "{{ _('transcription') }}"] }, + { id: 'import_path_scanning', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Media Import path scanning') }}", anchorId: 'setting-import-path-scanning', requires: { label: "{{ _('Media Import tool') }}", anchorId: 'setting-media-import-tool' }, keywords: ["{{ _('path') }}", "{{ _('scan') }}", "{{ _('security') }}"] }, + { id: 'etl_vid_ext', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Allowed Media Import Extensions') }}", anchorId: 'setting-import-path-scanning', requires: { label: "{{ _('Media Import path scanning') }}", anchorId: 'setting-import-path-scanning' }, keywords: ["{{ _('extensions') }}", "{{ _('etl') }}", "{{ _('files') }}"] }, + { id: 'ocr_import', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Tesseract OCR (Import)') }}", anchorId: 'setting-import-ocr', requires: { label: "{{ _('Media Import tool') }}", anchorId: 'setting-media-import-tool' }, keywords: ["{{ _('ocr') }}", "{{ _('tesseract') }}", "{{ _('text extraction') }}"] }, + { id: 'ocr_extensions', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('OCR Extensions') }}", anchorId: 'setting-import-ocr', requires: { label: "{{ _('Tesseract OCR') }}", anchorId: 'setting-import-ocr' }, keywords: ["{{ _('ocr') }}", "{{ _('extensions') }}", "{{ _('tesseract') }}"] }, + { id: 'vision_api_key', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Google Cloud API Key') }}", anchorId: 'setting-google-vision-api-key', requires: { label: "{{ _('Media Import tool') }}", anchorId: 'setting-media-import-tool' }, keywords: ["{{ _('vision') }}", "{{ _('ocr') }}", "{{ _('translation') }}"] }, + { id: 'transcription_enabled', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Enable transcription') }}", anchorId: 'setting-transcription-enabled', requires: { label: "{{ _('Media Import tool') }}", anchorId: 'setting-media-import-tool' }, keywords: ["{{ _('whisper') }}", "{{ _('audio') }}", "{{ _('transcript') }}"] }, + { id: 'whisper_model', tab: 'import', section: "{{ _('Media Import tool') }}", label: "{{ _('Whisper Model') }}", anchorId: 'setting-transcription-enabled', requires: { label: "{{ _('Transcription') }}", anchorId: 'setting-transcription-enabled' }, keywords: ["{{ _('whisper') }}", "{{ _('model') }}", "{{ _('transcription') }}"] }, { id: 'sheet_import', tab: 'import', section: "{{ _('Sheet Import') }}", label: "{{ _('Sheet Import') }}", anchorId: 'setting-sheet-import', keywords: ["{{ _('spreadsheet') }}", "{{ _('excel') }}", "{{ _('import') }}"] }, - { id: 'sheets_allowed_extensions', tab: 'import', section: "{{ _('Sheet Import') }}", label: "{{ _('Allowed Sheets Extensions') }}", anchorId: 'setting-sheet-import', keywords: ["{{ _('spreadsheet') }}", "{{ _('extensions') }}", "{{ _('csv') }}"] }, + { id: 'sheets_allowed_extensions', tab: 'import', section: "{{ _('Sheet Import') }}", label: "{{ _('Allowed Sheets Extensions') }}", anchorId: 'setting-sheet-import', requires: { label: "{{ _('Sheet Import') }}", anchorId: 'setting-sheet-import' }, keywords: ["{{ _('spreadsheet') }}", "{{ _('extensions') }}", "{{ _('csv') }}"] }, { id: 'web_import', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Web import') }}", anchorId: 'setting-web-import', keywords: ["{{ _('yt-dlp') }}", "{{ _('url') }}", "{{ _('media import') }}"] }, - { id: 'web_import_proxy', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Web import proxy') }}", anchorId: 'setting-web-import', keywords: ["{{ _('proxy') }}", "{{ _('socks5') }}", "{{ _('yt-dlp') }}"] }, - { id: 'ytdlp_allowed_domains', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Allowed domains') }}", anchorId: 'setting-web-import', keywords: ["{{ _('domains') }}", "{{ _('allowlist') }}", "{{ _('yt-dlp') }}"] }, - { id: 'ytdlp_cookies', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Web import cookies') }}", anchorId: 'setting-web-import', keywords: ["{{ _('cookies') }}", "{{ _('auth') }}", "{{ _('yt-dlp') }}"] }, + { id: 'web_import_proxy', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Web import proxy') }}", anchorId: 'setting-web-import', requires: { label: "{{ _('Web Import') }}", anchorId: 'setting-web-import' }, keywords: ["{{ _('proxy') }}", "{{ _('socks5') }}", "{{ _('yt-dlp') }}"] }, + { id: 'ytdlp_allowed_domains', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Allowed domains') }}", anchorId: 'setting-web-import', requires: { label: "{{ _('Web Import') }}", anchorId: 'setting-web-import' }, keywords: ["{{ _('domains') }}", "{{ _('allowlist') }}", "{{ _('yt-dlp') }}"] }, + { id: 'ytdlp_cookies', tab: 'import', section: "{{ _('Web import') }}", label: "{{ _('Web import cookies') }}", anchorId: 'setting-web-import', requires: { label: "{{ _('Web Import') }}", anchorId: 'setting-web-import' }, keywords: ["{{ _('cookies') }}", "{{ _('auth') }}", "{{ _('yt-dlp') }}"] }, { id: 'export_tool', tab: 'export', section: "{{ _('Export system') }}", label: "{{ _('Export system') }}", anchorId: 'setting-export-tool', keywords: ["{{ _('exports') }}", "{{ _('requests') }}"] }, - { id: 'export_expiry', tab: 'export', section: "{{ _('Export system') }}", label: "{{ _('Export Expiry Time') }}", anchorId: 'setting-export-expiry-time', keywords: ["{{ _('expiry') }}", "{{ _('retention') }}", "{{ _('hours') }}"] }, + { id: 'export_expiry', tab: 'export', section: "{{ _('Export system') }}", label: "{{ _('Export Expiry Time') }}", anchorId: 'setting-export-expiry-time', requires: { label: "{{ _('Export system') }}", anchorId: 'setting-export-tool' }, keywords: ["{{ _('expiry') }}", "{{ _('retention') }}", "{{ _('hours') }}"] }, { id: 'map_endpoint', tab: 'maps', section: "{{ _('Map tiles provider') }}", label: "{{ _('Map API endpoint') }}", anchorId: 'setting-map-api-endpoint', keywords: ["{{ _('maps') }}", "{{ _('osm') }}", "{{ _('tiles') }}"] }, { id: 'google_maps_api', tab: 'maps', section: "{{ _('Satellite Imagery') }}", label: "{{ _('Google Maps API Key') }}", anchorId: 'setting-google-maps-api-key', keywords: ["{{ _('maps') }}", "{{ _('satellite') }}", "{{ _('google') }}"] }, @@ -1375,14 +1375,14 @@

{{ _('Enable Mail System') }}

{ id: 'notif_bulk_operation_status', tab: 'notifications', section: "{{ _('Notifications for administrators') }}", label: "{{ _('Bulk operations status') }}", anchorId: 'setting-notifications-admins', keywords: ["{{ _('bulk') }}", "{{ _('operations') }}", "{{ _('status') }}"] }, { id: 'mail_enabled', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Enable Mail System') }}", anchorId: 'setting-mail-enabled', keywords: ["{{ _('mail') }}", "{{ _('smtp') }}", "{{ _('email') }}"] }, - { id: 'mail_server', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Server') }}", anchorId: 'setting-mail-server', keywords: ["{{ _('smtp') }}", "{{ _('host') }}"] }, - { id: 'mail_port', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Port') }}", anchorId: 'setting-mail-port', keywords: ["{{ _('smtp') }}", "{{ _('port') }}"] }, - { id: 'mail_default_sender', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Default Sender') }}", anchorId: 'setting-mail-default-sender', keywords: ["{{ _('sender') }}", "{{ _('from') }}"] }, - { id: 'mail_allowed_domains', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Allowed Email Domains') }}", anchorId: 'setting-mail-allowed-domains', keywords: ["{{ _('email') }}", "{{ _('domains') }}", "{{ _('allowlist') }}"] }, - { id: 'mail_tls', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Use TLS') }}", anchorId: 'setting-mail-tls', keywords: ["{{ _('tls') }}", "{{ _('transport') }}", "{{ _('layer') }}", "{{ _('security') }}"] }, - { id: 'mail_ssl', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Use SSL') }}", anchorId: 'setting-mail-ssl', keywords: ["{{ _('ssl') }}", "{{ _('secure') }}", "{{ _('sockets') }}", "{{ _('layer') }}"] }, - { id: 'mail_user', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail User') }}", anchorId: 'setting-mail-username', keywords: ["{{ _('user') }}", "{{ _('account') }}", "{{ _('credentials') }}"] }, - { id: 'mail_password', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Password') }}", anchorId: 'setting-mail-password', keywords: ["{{ _('password') }}", "{{ _('account') }}", "{{ _('credentials') }}"] }, + { id: 'mail_server', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Server') }}", anchorId: 'setting-mail-server', requires: { label: "{{ _('Mail System') }}", anchorId: 'setting-mail-enabled' }, keywords: ["{{ _('smtp') }}", "{{ _('host') }}"] }, + { id: 'mail_port', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Port') }}", anchorId: 'setting-mail-port', requires: { label: "{{ _('Mail System') }}", anchorId: 'setting-mail-enabled' }, keywords: ["{{ _('smtp') }}", "{{ _('port') }}"] }, + { id: 'mail_default_sender', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Default Sender') }}", anchorId: 'setting-mail-default-sender', requires: { label: "{{ _('Mail System') }}", anchorId: 'setting-mail-enabled' }, keywords: ["{{ _('sender') }}", "{{ _('from') }}"] }, + { id: 'mail_allowed_domains', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Allowed Email Domains') }}", anchorId: 'setting-mail-allowed-domains', requires: { label: "{{ _('Mail System') }}", anchorId: 'setting-mail-enabled' }, keywords: ["{{ _('email') }}", "{{ _('domains') }}", "{{ _('allowlist') }}"] }, + { id: 'mail_tls', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Use TLS') }}", anchorId: 'setting-mail-tls', requires: { label: "{{ _('Mail System') }}", anchorId: 'setting-mail-enabled' }, keywords: ["{{ _('tls') }}", "{{ _('transport') }}", "{{ _('layer') }}", "{{ _('security') }}"] }, + { id: 'mail_ssl', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Use SSL') }}", anchorId: 'setting-mail-ssl', requires: { label: "{{ _('Mail System') }}", anchorId: 'setting-mail-enabled' }, keywords: ["{{ _('ssl') }}", "{{ _('secure') }}", "{{ _('sockets') }}", "{{ _('layer') }}"] }, + { id: 'mail_user', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail User') }}", anchorId: 'setting-mail-username', requires: { label: "{{ _('Mail System') }}", anchorId: 'setting-mail-enabled' }, keywords: ["{{ _('user') }}", "{{ _('account') }}", "{{ _('credentials') }}"] }, + { id: 'mail_password', tab: 'mail', section: "{{ _('Mail transport') }}", label: "{{ _('Mail Password') }}", anchorId: 'setting-mail-password', requires: { label: "{{ _('Mail System') }}", anchorId: 'setting-mail-enabled' }, keywords: ["{{ _('password') }}", "{{ _('account') }}", "{{ _('credentials') }}"] }, ], @@ -1510,6 +1510,38 @@

{{ _('Enable Mail System') }}

const target = document.getElementById(setting.anchorId); if (!target) return; + // Check if the target or any ancestor is hidden (e.g. behind a v-show) + let isHidden = false; + let node = target; + while (node && node !== document.body) { + if (window.getComputedStyle(node).display === 'none') { isHidden = true; break; } + node = node.parentElement; + } + + if (isHidden) { + if (setting.requires) { + const requiresTarget = document.getElementById(setting.requires.anchorId); + if (requiresTarget) { + requiresTarget.scrollIntoView({ behavior: 'smooth', block: 'center' }); + if (typeof requiresTarget.animate === 'function') { + requiresTarget.animate( + [ + { backgroundColor: 'rgba(var(--v-theme-primary), 0.28)', boxShadow: '0 0 0 2px rgba(var(--v-theme-primary), 0.55)' }, + { backgroundColor: 'rgba(var(--v-theme-primary), 0.12)', boxShadow: '0 0 0 1px rgba(var(--v-theme-primary), 0.30)' }, + { backgroundColor: 'transparent', boxShadow: '0 0 0 0 rgba(var(--v-theme-primary), 0)' }, + ], + { duration: 1400, easing: 'ease-out' } + ); + } + } + this.$root.showSnack(this.translations.settingHiddenRequires_.replace('{label}', setting.label).replace('{requires}', setting.requires.label)); + } else { + target.scrollIntoView({ behavior: 'smooth', block: 'center' }); + this.$root.showSnack("{{ _('This setting is currently hidden. Enable the parent feature to reveal it.') }}"); + } + return; + } + target.scrollIntoView({ behavior: 'smooth', block: 'center' }); if (typeof target.animate === 'function') { target.animate( From f4c1e79240bf1d621ae537928bc70ccecca65d6c Mon Sep 17 00:00:00 2001 From: Daniel Apodaca Date: Wed, 1 Apr 2026 09:00:02 -0600 Subject: [PATCH 08/10] remove while loop for simpler approach --- enferno/admin/templates/admin/system-administration.html | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/enferno/admin/templates/admin/system-administration.html b/enferno/admin/templates/admin/system-administration.html index 9f5049b90..29504dc99 100644 --- a/enferno/admin/templates/admin/system-administration.html +++ b/enferno/admin/templates/admin/system-administration.html @@ -1511,12 +1511,7 @@

{{ _('Enable Mail System') }}

if (!target) return; // Check if the target or any ancestor is hidden (e.g. behind a v-show) - let isHidden = false; - let node = target; - while (node && node !== document.body) { - if (window.getComputedStyle(node).display === 'none') { isHidden = true; break; } - node = node.parentElement; - } + const isHidden = !target.offsetParent; if (isHidden) { if (setting.requires) { From 1f2f288a681eeab7e2de0d34ab1a4b71cda655a8 Mon Sep 17 00:00:00 2001 From: Daniel Apodaca Date: Wed, 1 Apr 2026 09:14:55 -0600 Subject: [PATCH 09/10] add s3 keyword --- enferno/admin/templates/admin/system-administration.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/enferno/admin/templates/admin/system-administration.html b/enferno/admin/templates/admin/system-administration.html index 29504dc99..acf5aefaf 100644 --- a/enferno/admin/templates/admin/system-administration.html +++ b/enferno/admin/templates/admin/system-administration.html @@ -1275,10 +1275,10 @@

{{ _('Enable Mail System') }}

{ id: 'adv_analysis', tab: 'general', section: "{{ _('Data quality and analysis') }}", label: "{{ _('Advanced analysis features') }}", anchorId: 'setting-advanced-analysis', keywords: ["{{ _('analysis') }}", "{{ _('features') }}"] }, { id: 'storage_backend', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('Local Filesystem / S3 Storage') }}", anchorId: 'setting-storage-backend', keywords: ["{{ _('files') }}", "{{ _('s3') }}", "{{ _('bucket') }}"] }, - { id: 's3_bucket', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('S3 Bucket Name') }}", anchorId: 'setting-s3-bucket', requires: { label: "{{ _('S3 Storage') }}", anchorId: 'setting-storage-backend' }, keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('bucket') }}"] }, - { id: 'aws_access_key_id', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Access Key ID') }}", anchorId: 'setting-aws-access-key-id', requires: { label: "{{ _('S3 Storage') }}", anchorId: 'setting-storage-backend' }, keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('access') }}", "{{ _('key') }}", "{{ _('id') }}"] }, - { id: 'aws_secret_access_key', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Secret Access Key') }}", anchorId: 'setting-aws-secret-access-key', requires: { label: "{{ _('S3 Storage') }}", anchorId: 'setting-storage-backend' }, keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('secret') }}", "{{ _('key') }}"] }, - { id: 'aws_region', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Region') }}", anchorId: 'setting-aws-region', requires: { label: "{{ _('S3 Storage') }}", anchorId: 'setting-storage-backend' }, keywords: ["{{ _('aws') }}", "{{ _('storage') }}", "{{ _('region') }}"] }, + { id: 's3_bucket', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('S3 Bucket Name') }}", anchorId: 'setting-s3-bucket', requires: { label: "{{ _('S3 Storage') }}", anchorId: 'setting-storage-backend' }, keywords: ["{{ _('s3') }}", "{{ _('aws') }}", "{{ _('storage') }}", "{{ _('bucket') }}"] }, + { id: 'aws_access_key_id', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Access Key ID') }}", anchorId: 'setting-aws-access-key-id', requires: { label: "{{ _('S3 Storage') }}", anchorId: 'setting-storage-backend' }, keywords: ["{{ _('s3') }}", "{{ _('aws') }}", "{{ _('storage') }}", "{{ _('access') }}", "{{ _('key') }}", "{{ _('id') }}"] }, + { id: 'aws_secret_access_key', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Secret Access Key') }}", anchorId: 'setting-aws-secret-access-key', requires: { label: "{{ _('S3 Storage') }}", anchorId: 'setting-storage-backend' }, keywords: ["{{ _('s3') }}", "{{ _('aws') }}", "{{ _('storage') }}", "{{ _('secret') }}", "{{ _('key') }}"] }, + { id: 'aws_region', tab: 'storage', section: "{{ _('Storage backend') }}", label: "{{ _('AWS Region') }}", anchorId: 'setting-aws-region', requires: { label: "{{ _('S3 Storage') }}", anchorId: 'setting-storage-backend' }, keywords: ["{{ _('s3') }}", "{{ _('aws') }}", "{{ _('storage') }}", "{{ _('region') }}"] }, { id: 'media_extensions', tab: 'storage', section: "{{ _('Upload restrictions') }}", label: "{{ _('Allowed Media Extensions') }}", anchorId: 'setting-media-allowed-extensions', keywords: ["{{ _('upload') }}", "{{ _('extensions') }}", "{{ _('files') }}"] }, { id: 'media_size', tab: 'storage', section: "{{ _('Upload restrictions') }}", label: "{{ _('Media Max Upload Size') }}", anchorId: 'setting-media-max-upload-size', keywords: ["{{ _('upload') }}", "{{ _('size') }}", "{{ _('limit') }}"] }, From d79b1d412d2f52a5862dfed26a8cbb20b51a69b3 Mon Sep 17 00:00:00 2001 From: Daniel Apodaca Date: Wed, 1 Apr 2026 09:19:17 -0600 Subject: [PATCH 10/10] move id to root h4 component --- .../templates/admin/system-administration.html | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/enferno/admin/templates/admin/system-administration.html b/enferno/admin/templates/admin/system-administration.html index acf5aefaf..58a7a2fbf 100644 --- a/enferno/admin/templates/admin/system-administration.html +++ b/enferno/admin/templates/admin/system-administration.html @@ -382,9 +382,7 @@

{{ _('Allow non-admin users to restrict new items')

{{ _('Set users\' actions to be logged in the Activity Monitor.') }}

-
-

{{ _('Items') }}

-
+

{{ _('Items') }}

{{ _('Items created') }}{{ _(' by users.') }} @@ -438,9 +436,7 @@

{{ _('Items') }}

-
-

{{ _('Export') }}

-
+

{{ _('Export') }}

{{ _('Export requests made') }}{{ _(' by @@ -478,9 +474,7 @@

{{ _('Export') }}

-
-

{{ _('Authentication') }}

-
+

{{ _('Authentication') }}

{{ _('Logins') }}{{ _(' by users.') }}
@@ -500,9 +494,7 @@

{{ _('Authentication') }}

-
-

{{ _('Other actions') }}

-
+

{{ _('Other actions') }}

{{ _('Search queries made') }}{{ _(' by users.')