fix(a11y): switches, icon buttons, selects and number inputs in Admin Settings have names (#33145)

This commit is contained in:
G30 2026-10-25 00:14:38 -04:00 • committed by GitHub
parent 17065714bc
commit caae0be19b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 92 additions and 10 deletions

View file

@ -408,8 +408,13 @@
<AdminSettingRow
label={$i18n.t('settings.admin.audio.speechToTextEngine.label')}
description={$i18n.t('settings.admin.audio.speechToTextEngine.description')}
let:labelId
>
<SettingsSelect bind:value={STT_ENGINE} placeholder={$i18n.t('Select an engine')}>
<SettingsSelect
id={`${labelId}-control`}
bind:value={STT_ENGINE}
placeholder={$i18n.t('Select an engine')}
>
<option value="" disabled={$config?.features?.slim === true}
>{$i18n.t('Whisper (Local)')}</option
>
@ -456,8 +461,9 @@
<AdminSettingRow
label={$i18n.t('settings.admin.audio.requestFormat.label')}
description={$i18n.t('settings.admin.audio.requestFormat.description')}
let:labelId
>
<SettingsSelect bind:value={STT_OPENAI_API_REQUEST_FORMAT}>
<SettingsSelect id={`${labelId}-control`} bind:value={STT_OPENAI_API_REQUEST_FORMAT}>
<option value="multipart">{$i18n.t('Multipart Upload')}</option>
<option value="json">{$i18n.t('JSON Base64')}</option>
</SettingsSelect>
@ -633,8 +639,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.audio.textToSpeechEngine.label')}
description={$i18n.t('settings.admin.audio.textToSpeechEngine.description')}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={TTS_ENGINE}
placeholder={$i18n.t('Select a mode')}
on:change={async (e) => {
@ -745,8 +753,8 @@
{/if}
{#if TTS_ENGINE === ''}
<AdminSettingField label={$i18n.t('settings.admin.audio.ttsVoice.label')}>
<SettingsSelect bind:value={TTS_VOICE} className="w-full">
<AdminSettingField label={$i18n.t('settings.admin.audio.ttsVoice.label')} forId="tts-voice">
<SettingsSelect id="tts-voice" bind:value={TTS_VOICE} className="w-full">
<option value="" selected={TTS_VOICE !== ''}>{$i18n.t('Default')}</option>
{#each voices as voice}
<option

View file

@ -154,8 +154,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.authentication.defaultUserRole.label')}
description={$i18n.t('settings.admin.authentication.defaultUserRole.description')}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={adminConfig.DEFAULT_USER_ROLE}
placeholder={$i18n.t('Select a role')}
>
@ -168,8 +170,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.authentication.defaultGroup.label')}
description={$i18n.t('settings.admin.authentication.defaultGroup.description')}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={adminConfig.DEFAULT_GROUP_ID}
placeholder={$i18n.t('Select a group')}
>

View file

@ -69,8 +69,10 @@
'Warning: Jupyter execution enables arbitrary code execution, posing severe security risks\u2014proceed with extreme caution.'
)
: $i18n.t('settings.admin.codeExecution.codeExecutionEngine.description')}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={config.CODE_EXECUTION_ENGINE}
placeholder={$i18n.t('Select a engine')}
required
@ -106,8 +108,10 @@
description={$i18n.t(
'settings.admin.codeExecution.codeExecutionJupyterAuth.description'
)}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={config.CODE_EXECUTION_JUPYTER_AUTH}
placeholder={$i18n.t('Select an auth method')}
>
@ -183,8 +187,10 @@
'Warning: Jupyter execution enables arbitrary code execution, posing severe security risks\u2014proceed with extreme caution.'
)
: $i18n.t('settings.admin.codeExecution.codeInterpreterEngine.description')}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={config.CODE_INTERPRETER_ENGINE}
placeholder={$i18n.t('Select a engine')}
required
@ -220,8 +226,10 @@
description={$i18n.t(
'settings.admin.codeExecution.codeInterpreterJupyterAuth.description'
)}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={config.CODE_INTERPRETER_JUPYTER_AUTH}
placeholder={$i18n.t('Select an auth method')}
>

View file

@ -259,6 +259,7 @@
<Tooltip content={$i18n.t('settings.admin.connections.addConnection.label')}>
<button
aria-label={$i18n.t('settings.admin.connections.addConnection.label')}
class="flex size-6 items-center justify-center rounded-lg text-gray-400 transition-colors hover:bg-black/5 hover:text-gray-700 dark:text-gray-600 dark:hover:bg-white/5 dark:hover:text-gray-300"
on:click={() => {
showAddOpenAIConnectionModal = true;
@ -318,6 +319,7 @@
<Tooltip content={$i18n.t('settings.admin.connections.addConnection.label')}>
<button
aria-label={$i18n.t('settings.admin.connections.addConnection.label')}
class="flex size-6 items-center justify-center rounded-lg text-gray-400 transition-colors hover:bg-black/5 hover:text-gray-700 dark:text-gray-600 dark:hover:bg-white/5 dark:hover:text-gray-300"
on:click={() => {
showAddOllamaConnectionModal = true;

View file

@ -70,6 +70,7 @@
<div class="flex gap-1 items-center">
<Tooltip content={$i18n.t('Manage')} className="self-start">
<button
aria-label={$i18n.t('Manage')}
class="self-center p-1 bg-transparent hover:bg-gray-100 dark:hover:bg-gray-850 rounded-lg transition"
on:click={() => {
showManageModal = true;
@ -82,6 +83,7 @@
<Tooltip content={$i18n.t('Configure')} className="self-start">
<button
aria-label={$i18n.t('Configure')}
class="self-center p-1 bg-transparent hover:bg-gray-100 dark:hover:bg-gray-850 rounded-lg transition"
on:click={() => {
showConfigModal = true;
@ -95,6 +97,7 @@
<Tooltip content={(config?.enable ?? true) ? $i18n.t('Enabled') : $i18n.t('Disabled')}>
<Switch
bind:state={config.enable}
ariaLabel={$i18n.t('Enabled')}
on:change={() => {
config.enable = config.enable ?? false;
onSubmit({ url, key: config?.key ?? '', config });

View file

@ -96,6 +96,7 @@
<div class="flex gap-1 items-center">
<Tooltip content={$i18n.t('Configure')} className="self-start">
<button
aria-label={$i18n.t('Configure')}
class="self-center p-1 bg-transparent hover:bg-gray-100 dark:hover:bg-gray-850 rounded-lg transition"
on:click={() => {
showConfigModal = true;
@ -109,6 +110,7 @@
<Tooltip content={(config?.enable ?? true) ? $i18n.t('Enabled') : $i18n.t('Disabled')}>
<Switch
bind:state={config.enable}
ariaLabel={$i18n.t('Enabled')}
on:change={() => {
config.enable = config.enable ?? false;
onSubmit({ url, key, config });

View file

@ -438,8 +438,12 @@
<AdminSettingRow
label={$i18n.t('settings.admin.documents.contentExtractionEngine.label')}
description={$i18n.t('settings.admin.documents.contentExtractionEngine.description')}
let:labelId
>
<SettingsSelect bind:value={RAGConfig.CONTENT_EXTRACTION_ENGINE}>
<SettingsSelect
id={`${labelId}-control`}
bind:value={RAGConfig.CONTENT_EXTRACTION_ENGINE}
>
<option value=""
>{$config?.features?.slim === true
? $i18n.t('Basic text only')
@ -479,8 +483,9 @@
<AdminSettingRow
label={$i18n.t('settings.admin.documents.pdfLoaderMode.label')}
description={$i18n.t('settings.admin.documents.pdfLoaderMode.description')}
let:labelId
>
<SettingsSelect bind:value={RAGConfig.PDF_LOADER_MODE}>
<SettingsSelect id={`${labelId}-control`} bind:value={RAGConfig.PDF_LOADER_MODE}>
<option value="page">{$i18n.t('Page')}</option>
<option value="single">{$i18n.t('Single')}</option>
</SettingsSelect>
@ -586,8 +591,12 @@
<AdminSettingRow
label={$i18n.t('settings.admin.documents.outputFormat.label')}
description={$i18n.t('settings.admin.documents.outputFormat.description')}
let:labelId
>
<SettingsSelect bind:value={RAGConfig.DATALAB_MARKER_OUTPUT_FORMAT}>
<SettingsSelect
id={`${labelId}-control`}
bind:value={RAGConfig.DATALAB_MARKER_OUTPUT_FORMAT}
>
<option value="markdown">{$i18n.t('Markdown')}</option>
<option value="json">{$i18n.t('JSON')}</option>
<option value="html">{$i18n.t('HTML')}</option>
@ -813,8 +822,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.documents.apiMode.label')}
description={$i18n.t('settings.admin.documents.apiMode.description')}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={RAGConfig.MINERU_API_MODE}
on:change={() => {
const cloudUrl = 'https://mineru.net/api/v4';
@ -864,8 +875,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.documents.apiTimeout.label')}
description={$i18n.t('settings.admin.documents.apiTimeout.description')}
let:labelId
>
<input
id={`${labelId}-control`}
class="w-16 rounded-lg border border-gray-100/50 bg-gray-50/40 px-2 text-right text-xs text-gray-700 outline-hidden transition-colors focus:border-blue-400 dark:border-white/[0.04] dark:bg-white/[0.03] dark:text-gray-300 dark:focus:border-blue-500"
type="number"
min="1"
@ -915,8 +928,9 @@
<AdminSettingRow
label={$i18n.t('settings.admin.documents.textSplitter.label')}
description={$i18n.t('settings.admin.documents.textSplitter.description')}
let:labelId
>
<SettingsSelect bind:value={RAGConfig.TEXT_SPLITTER}>
<SettingsSelect id={`${labelId}-control`} bind:value={RAGConfig.TEXT_SPLITTER}>
<option value="">{$i18n.t('Default')} ({$i18n.t('Character')})</option>
<option value="token">{$i18n.t('Token')} ({$i18n.t('Tiktoken')})</option>
<option value="token_transformers" disabled={$config?.features?.slim === true}>
@ -1003,8 +1017,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.documents.embeddingModelEngine.label')}
description={$i18n.t('settings.admin.documents.embeddingModelEngine.description')}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={RAG_EMBEDDING_ENGINE}
placeholder={$i18n.t('Select an embedding model engine')}
on:change={(e) => {
@ -1171,8 +1187,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.documents.embeddingBatchSize.label')}
description={$i18n.t('settings.admin.documents.embeddingBatchSize.description')}
let:labelId
>
<input
id={`${labelId}-control`}
bind:value={RAG_EMBEDDING_BATCH_SIZE}
type="number"
class="w-14 bg-transparent text-center text-xs outline-none"
@ -1195,8 +1213,10 @@
description={$i18n.t(
'settings.admin.documents.embeddingConcurrentRequests.description'
)}
let:labelId
>
<input
id={`${labelId}-control`}
bind:value={RAG_EMBEDDING_CONCURRENT_REQUESTS}
type="number"
class="w-14 bg-transparent text-center text-xs outline-none"
@ -1244,8 +1264,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.documents.rerankingEngine.label')}
description={$i18n.t('settings.admin.documents.rerankingEngine.description')}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={RAGConfig.RAG_RERANKING_ENGINE}
placeholder={$i18n.t('Select a reranking model engine')}
on:change={(e) => {
@ -1313,8 +1335,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.documents.rerankingBatchSize.label')}
description={$i18n.t('settings.admin.documents.rerankingBatchSize.description')}
let:labelId
>
<input
id={`${labelId}-control`}
bind:value={RAGConfig.RAG_RERANKING_BATCH_SIZE}
type="number"
class="w-14 bg-transparent text-center text-xs outline-none"

View file

@ -121,6 +121,7 @@
<Tooltip content={$i18n.t('settings.admin.evaluations.addArenaModel.label')}>
<button
aria-label={$i18n.t('settings.admin.evaluations.addArenaModel.label')}
class="flex size-6 items-center justify-center rounded-lg text-gray-400 transition-colors hover:bg-black/5 hover:text-gray-900 dark:text-gray-600 dark:hover:bg-white/5 dark:hover:text-white"
type="button"
on:click={() => {

View file

@ -706,6 +706,7 @@
</div>
<Tooltip content={$i18n.t('Add webhook')}>
<button
aria-label={$i18n.t('Add webhook')}
class="flex size-6 items-center justify-center rounded-lg text-gray-400 transition-colors hover:bg-black/5 hover:text-gray-900 dark:text-gray-600 dark:hover:bg-white/5 dark:hover:text-white"
on:click={newWebhook}
type="button"

View file

@ -803,6 +803,7 @@
<Tooltip content={$i18n.t('settings.admin.integrations.externalKnowledge.addConnection.label')}>
<button
aria-label={$i18n.t('settings.admin.integrations.externalKnowledge.addConnection.label')}
class="flex size-6 items-center justify-center rounded-lg text-gray-400 transition-colors hover:bg-black/5 hover:text-gray-900 dark:text-gray-600 dark:hover:bg-white/5 dark:hover:text-white"
on:click={openCreateSource}
type="button"

View file

@ -341,8 +341,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.images.imageGenerationEngine.label')}
description={$i18n.t('settings.admin.images.imageGenerationEngine.description')}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={config.IMAGE_GENERATION_ENGINE}
placeholder={$i18n.t('Select Engine')}
>
@ -739,8 +741,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.images.geminiEndpointMethod.label')}
description={$i18n.t('settings.admin.images.geminiEndpointMethod.description')}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={config.IMAGES_GEMINI_ENDPOINT_METHOD}
placeholder={$i18n.t('Select Method')}
>
@ -763,8 +767,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.images.imageEditEngine.label')}
description={$i18n.t('settings.admin.images.imageEditEngine.description')}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={config.IMAGE_EDIT_ENGINE}
placeholder={$i18n.t('Select Engine')}
>

View file

@ -200,6 +200,7 @@
<Tooltip content={$i18n.t('settings.admin.integrations.addConnection.label')}>
<button
aria-label={$i18n.t('settings.admin.integrations.addConnection.label')}
class="flex size-6 items-center justify-center rounded-lg text-gray-400 transition-colors hover:bg-black/5 hover:text-gray-900 dark:text-gray-600 dark:hover:bg-white/5 dark:hover:text-white"
on:click={() => {
showConnectionModal = true;
@ -247,6 +248,7 @@
<Tooltip content={$i18n.t('settings.admin.integrations.addConnection.label')}>
<button
aria-label={$i18n.t('settings.admin.integrations.addConnection.label')}
class="flex size-6 items-center justify-center rounded-lg text-gray-400 transition-colors hover:bg-black/5 hover:text-gray-900 dark:text-gray-600 dark:hover:bg-white/5 dark:hover:text-white"
on:click={() => {
editTerminalIdx = null;

View file

@ -205,8 +205,12 @@
</div>
<div class="grid w-full grid-cols-1 gap-2.5 sm:grid-cols-2">
<AdminSettingField label={$i18n.t('settings.admin.interface.localTaskModel.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.interface.localTaskModel.label')}
forId="task-model"
>
<SettingsSelect
id="task-model"
bind:value={taskConfig.TASK_MODEL}
className="w-full"
placeholder={$i18n.t('Select a model')}
@ -224,8 +228,12 @@
</SettingsSelect>
</AdminSettingField>
<AdminSettingField label={$i18n.t('settings.admin.interface.externalTaskModel.label')}>
<AdminSettingField
label={$i18n.t('settings.admin.interface.externalTaskModel.label')}
forId="task-model-external"
>
<SettingsSelect
id="task-model-external"
bind:value={taskConfig.TASK_MODEL_EXTERNAL}
className="w-full"
placeholder={$i18n.t('Select a model')}
@ -300,8 +308,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.interface.contextCompactionModel.label')}
description={$i18n.t('settings.admin.interface.contextCompactionModel.description')}
forId="context-compaction-model"
>
<SettingsSelect
id="context-compaction-model"
bind:value={chatConfig.CONTEXT_COMPACTION_MODEL}
className="w-full"
placeholder={$i18n.t('Select a model')}

View file

@ -1278,6 +1278,7 @@
<button
class="self-center w-fit text-sm p-1.5 dark:text-gray-300 dark:hover:text-white hover:bg-black/5 dark:hover:bg-white/5 rounded-xl"
type="button"
aria-label={$i18n.t('More Options')}
>
<EllipsisHorizontal className="size-3.5" />
</button>
@ -1291,6 +1292,7 @@
>
<Switch
bind:state={model.is_active}
ariaLabel={$i18n.t('Enabled')}
on:change={async () => {
toggleModelHandler(model);
}}

View file

@ -276,8 +276,10 @@
<AdminSettingField
label={$i18n.t('settings.admin.pipelines.pipelineUrl.label')}
description={$i18n.t('settings.admin.pipelines.pipelineUrl.description')}
forId="pipelines-url"
>
<SettingsSelect
id="pipelines-url"
bind:value={selectedPipelinesUrlIdx}
className="w-full"
placeholder={$i18n.t('Select a pipeline url')}
@ -364,9 +366,11 @@
<AdminSettingField
label={$i18n.t('settings.admin.pipelines.pipeline.label')}
description={$i18n.t('settings.admin.pipelines.pipeline.description')}
forId="pipeline"
>
<div class="flex gap-2">
<SettingsSelect
id="pipeline"
bind:value={selectedPipelineIdx}
className="w-full"
placeholder={$i18n.t('Select a pipeline')}

View file

@ -216,8 +216,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.web.webSearchEngine.label')}
description={$i18n.t('settings.admin.web.webSearchEngine.description')}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={webConfig.WEB_SEARCH_ENGINE}
placeholder={$i18n.t('Select a engine')}
required
@ -1258,8 +1260,10 @@
<AdminSettingRow
label={$i18n.t('settings.admin.web.webLoaderEngine.label')}
description={$i18n.t('settings.admin.web.webLoaderEngine.description')}
let:labelId
>
<SettingsSelect
id={`${labelId}-control`}
bind:value={webConfig.WEB_LOADER_ENGINE}
placeholder={$i18n.t('Select a engine')}
>