Merge pull request #14959 from itk-dev/feature/accessibility-edit-connection-modal
Feature/accessibility edit connection modal
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
import { getContext, onMount } from 'svelte';
|
import { getContext, onMount } from 'svelte';
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
import { models } from '$lib/stores';
|
import { settings } from '$lib/stores';
|
||||||
import { verifyOpenAIConnection } from '$lib/apis/openai';
|
import { verifyOpenAIConnection } from '$lib/apis/openai';
|
||||||
import { verifyOllamaConnection } from '$lib/apis/ollama';
|
import { verifyOllamaConnection } from '$lib/apis/ollama';
|
||||||
|
|
||||||
@@ -258,11 +258,17 @@
|
|||||||
|
|
||||||
<div class="flex gap-2 mt-1.5">
|
<div class="flex gap-2 mt-1.5">
|
||||||
<div class="flex flex-col w-full">
|
<div class="flex flex-col w-full">
|
||||||
<div class=" mb-0.5 text-xs text-gray-500">{$i18n.t('URL')}</div>
|
<label
|
||||||
|
for="url-input"
|
||||||
|
class={`mb-0.5 text-xs text-gray-500
|
||||||
|
${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100' : ''}`}
|
||||||
|
>{$i18n.t('URL')}</label
|
||||||
|
>
|
||||||
|
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<input
|
<input
|
||||||
class="w-full text-sm bg-transparent placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden"
|
id="url-input"
|
||||||
|
class={`w-full text-sm bg-transparent ${($settings?.highContrastMode ?? false) ? 'placeholder:text-gray-700 dark:placeholder:text-gray-100' : 'outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'}`}
|
||||||
type="text"
|
type="text"
|
||||||
bind:value={url}
|
bind:value={url}
|
||||||
placeholder={$i18n.t('API Base URL')}
|
placeholder={$i18n.t('API Base URL')}
|
||||||
@@ -279,11 +285,13 @@
|
|||||||
verifyHandler();
|
verifyHandler();
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
|
aria-label={$i18n.t('Verify Connection')}
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 20 20"
|
viewBox="0 0 20 20"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
|
aria-hidden="true"
|
||||||
class="w-4 h-4"
|
class="w-4 h-4"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
@@ -296,19 +304,27 @@
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
<div class="flex flex-col shrink-0 self-end">
|
<div class="flex flex-col shrink-0 self-end">
|
||||||
|
<label class="sr-only" for="toggle-connection"
|
||||||
|
>{$i18n.t('Toggle whether current connection is active.')}</label
|
||||||
|
>
|
||||||
<Tooltip content={enable ? $i18n.t('Enabled') : $i18n.t('Disabled')}>
|
<Tooltip content={enable ? $i18n.t('Enabled') : $i18n.t('Disabled')}>
|
||||||
<Switch bind:state={enable} />
|
<Switch id="toggle-connection" bind:state={enable} />
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex gap-2 mt-2">
|
<div class="flex gap-2 mt-2">
|
||||||
<div class="flex flex-col w-full">
|
<div class="flex flex-col w-full">
|
||||||
<div class=" mb-0.5 text-xs text-gray-500">{$i18n.t('Key')}</div>
|
<div
|
||||||
|
class={`mb-0.5 text-xs text-gray-500
|
||||||
|
${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100' : ''}`}
|
||||||
|
>
|
||||||
|
{$i18n.t('Key')}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<SensitiveInput
|
<SensitiveInput
|
||||||
className="w-full text-sm bg-transparent placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden"
|
inputClassName={`w-full text-sm bg-transparent ${($settings?.highContrastMode ?? false) ? 'placeholder:text-gray-700 dark:placeholder:text-gray-100' : 'outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'}`}
|
||||||
bind:value={key}
|
bind:value={key}
|
||||||
placeholder={$i18n.t('API Key')}
|
placeholder={$i18n.t('API Key')}
|
||||||
required={false}
|
required={false}
|
||||||
@@ -317,7 +333,12 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col w-full">
|
<div class="flex flex-col w-full">
|
||||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('Prefix ID')}</div>
|
<label
|
||||||
|
for="prefix-id-input"
|
||||||
|
class={`mb-0.5 text-xs text-gray-500
|
||||||
|
${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100' : ''}`}
|
||||||
|
>{$i18n.t('Prefix ID')}</label
|
||||||
|
>
|
||||||
|
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<Tooltip
|
<Tooltip
|
||||||
@@ -326,8 +347,9 @@
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
class="w-full text-sm bg-transparent placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden"
|
class={`w-full text-sm bg-transparent ${($settings?.highContrastMode ?? false) ? 'placeholder:text-gray-700 dark:placeholder:text-gray-100' : 'outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'}`}
|
||||||
type="text"
|
type="text"
|
||||||
|
id="prefix-id-input"
|
||||||
bind:value={prefixId}
|
bind:value={prefixId}
|
||||||
placeholder={$i18n.t('Prefix ID')}
|
placeholder={$i18n.t('Prefix ID')}
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
@@ -340,11 +362,17 @@
|
|||||||
{#if azure}
|
{#if azure}
|
||||||
<div class="flex gap-2 mt-2">
|
<div class="flex gap-2 mt-2">
|
||||||
<div class="flex flex-col w-full">
|
<div class="flex flex-col w-full">
|
||||||
<div class=" mb-1 text-xs text-gray-500">{$i18n.t('API Version')}</div>
|
<label
|
||||||
|
for="api-version-input"
|
||||||
|
class={`mb-0.5 text-xs text-gray-500
|
||||||
|
${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100' : ''}`}
|
||||||
|
>{$i18n.t('API Version')}</label
|
||||||
|
>
|
||||||
|
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<input
|
<input
|
||||||
class="w-full text-sm bg-transparent placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden"
|
id="api-version-input"
|
||||||
|
class={`w-full text-sm bg-transparent placeholder:text-gray-300 dark:placeholder:text-gray-700 ${($settings?.highContrastMode ?? false) ? 'placeholder:text-gray-700 dark:placeholder:text-gray-100' : 'outline-hidden placeholder:text-gray-300 dark:placeholder:text-gray-700'}`}
|
||||||
type="text"
|
type="text"
|
||||||
bind:value={apiVersion}
|
bind:value={apiVersion}
|
||||||
placeholder={$i18n.t('API Version')}
|
placeholder={$i18n.t('API Version')}
|
||||||
@@ -358,7 +386,12 @@
|
|||||||
|
|
||||||
<div class="flex gap-2 mt-2">
|
<div class="flex gap-2 mt-2">
|
||||||
<div class="flex flex-col w-full">
|
<div class="flex flex-col w-full">
|
||||||
<div class=" mb-1.5 text-xs text-gray-500">{$i18n.t('Tags')}</div>
|
<div
|
||||||
|
class={`mb-0.5 text-xs text-gray-500
|
||||||
|
${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100' : ''}`}
|
||||||
|
>
|
||||||
|
{$i18n.t('Tags')}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="flex-1">
|
<div class="flex-1">
|
||||||
<Tags
|
<Tags
|
||||||
@@ -383,18 +416,26 @@
|
|||||||
|
|
||||||
<div class="flex flex-col w-full">
|
<div class="flex flex-col w-full">
|
||||||
<div class="mb-1 flex justify-between">
|
<div class="mb-1 flex justify-between">
|
||||||
<div class="text-xs text-gray-500">{$i18n.t('Model IDs')}</div>
|
<div
|
||||||
|
class={`mb-0.5 text-xs text-gray-500
|
||||||
|
${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100' : ''}`}
|
||||||
|
>
|
||||||
|
{$i18n.t('Model IDs')}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{#if modelIds.length > 0}
|
{#if modelIds.length > 0}
|
||||||
<div class="flex flex-col">
|
<ul class="flex flex-col">
|
||||||
{#each modelIds as modelId, modelIdx}
|
{#each modelIds as modelId, modelIdx}
|
||||||
<div class=" flex gap-2 w-full justify-between items-center">
|
<li class=" flex gap-2 w-full justify-between items-center">
|
||||||
<div class=" text-sm flex-1 py-1 rounded-lg">
|
<div class=" text-sm flex-1 py-1 rounded-lg">
|
||||||
{modelId}
|
{modelId}
|
||||||
</div>
|
</div>
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<button
|
<button
|
||||||
|
aria-label={$i18n.t(`Remove {{MODELID}} from list.`, {
|
||||||
|
MODELID: modelId
|
||||||
|
})}
|
||||||
type="button"
|
type="button"
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
modelIds = modelIds.filter((_, idx) => idx !== modelIdx);
|
modelIds = modelIds.filter((_, idx) => idx !== modelIdx);
|
||||||
@@ -403,11 +444,14 @@
|
|||||||
<Minus strokeWidth="2" className="size-3.5" />
|
<Minus strokeWidth="2" className="size-3.5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</ul>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="text-gray-500 text-xs text-center py-2 px-10">
|
<div
|
||||||
|
class={`text-gray-500 text-xs text-center py-2 px-10
|
||||||
|
${($settings?.highContrastMode ?? false) ? 'text-gray-800 dark:text-gray-100' : ''}`}
|
||||||
|
>
|
||||||
{#if ollama}
|
{#if ollama}
|
||||||
{$i18n.t('Leave empty to include all models from "{{url}}/api/tags" endpoint', {
|
{$i18n.t('Leave empty to include all models from "{{url}}/api/tags" endpoint', {
|
||||||
url: url
|
url: url
|
||||||
@@ -429,17 +473,22 @@
|
|||||||
<hr class=" border-gray-100 dark:border-gray-700/10 my-1.5 w-full" />
|
<hr class=" border-gray-100 dark:border-gray-700/10 my-1.5 w-full" />
|
||||||
|
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
|
<label class="sr-only" for="add-model-id-input">{$i18n.t('Add a model ID')}</label>
|
||||||
<input
|
<input
|
||||||
class="w-full py-1 text-sm rounded-lg bg-transparent {modelId
|
class="w-full py-1 text-sm rounded-lg bg-transparent {modelId
|
||||||
? ''
|
? ''
|
||||||
: 'text-gray-500'} placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden"
|
: 'text-gray-500'} {($settings?.highContrastMode ?? false)
|
||||||
|
? 'dark:placeholder:text-gray-100 placeholder:text-gray-700'
|
||||||
|
: 'placeholder:text-gray-300 dark:placeholder:text-gray-700 outline-hidden'}"
|
||||||
bind:value={modelId}
|
bind:value={modelId}
|
||||||
|
id="add-model-id-input"
|
||||||
placeholder={$i18n.t('Add a model ID')}
|
placeholder={$i18n.t('Add a model ID')}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
aria-label={$i18n.t('Add')}
|
||||||
on:click={() => {
|
on:click={() => {
|
||||||
addModelHandler();
|
addModelHandler();
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { createEventDispatcher, tick } from 'svelte';
|
import { createEventDispatcher, tick } from 'svelte';
|
||||||
import { Switch } from 'bits-ui';
|
import { Switch } from 'bits-ui';
|
||||||
export let state = true;
|
export let state = true;
|
||||||
|
export let id = '';
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
@@ -10,6 +11,7 @@
|
|||||||
|
|
||||||
<Switch.Root
|
<Switch.Root
|
||||||
bind:checked={state}
|
bind:checked={state}
|
||||||
|
{id}
|
||||||
class="flex h-5 min-h-5 w-9 shrink-0 cursor-pointer items-center rounded-full px-[3px] mx-[1px] transition {state
|
class="flex h-5 min-h-5 w-9 shrink-0 cursor-pointer items-center rounded-full px-[3px] mx-[1px] transition {state
|
||||||
? ' bg-emerald-600'
|
? ' bg-emerald-600'
|
||||||
: 'bg-gray-200 dark:bg-transparent'} outline outline-1 outline-gray-100 dark:outline-gray-800"
|
: 'bg-gray-200 dark:bg-transparent'} outline outline-1 outline-gray-100 dark:outline-gray-800"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
export let tags = [];
|
export let tags = [];
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-row flex-wrap gap-1 line-clamp-1">
|
<ul class="flex flex-row flex-wrap gap-1 line-clamp-1">
|
||||||
<TagList
|
<TagList
|
||||||
{tags}
|
{tags}
|
||||||
on:delete={(e) => {
|
on:delete={(e) => {
|
||||||
@@ -23,4 +23,4 @@
|
|||||||
dispatch('add', e.detail);
|
dispatch('add', e.detail);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</ul>
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
bind:value={tagName}
|
bind:value={tagName}
|
||||||
class=" px-2 cursor-pointer self-center text-xs h-fit bg-transparent outline-hidden line-clamp-1 w-[6.5rem]"
|
class=" px-2 cursor-pointer self-center text-xs h-fit bg-transparent outline-hidden line-clamp-1 w-[6.5rem]"
|
||||||
placeholder={$i18n.t('Add a tag')}
|
placeholder={$i18n.t('Add a tag')}
|
||||||
|
aria-label={$i18n.t('Add a tag')}
|
||||||
list="tagOptions"
|
list="tagOptions"
|
||||||
on:keydown={(event) => {
|
on:keydown={(event) => {
|
||||||
if (event.key === 'Enter') {
|
if (event.key === 'Enter') {
|
||||||
@@ -48,6 +49,7 @@
|
|||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
stroke-width="2"
|
stroke-width="2"
|
||||||
|
aria-hidden="true"
|
||||||
class="w-3 h-3"
|
class="w-3 h-3"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
@@ -72,6 +74,7 @@
|
|||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
|
aria-hidden="true"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
class="w-3 h-3 {showTagInput ? 'rotate-45' : ''} transition-all transform"
|
class="w-3 h-3 {showTagInput ? 'rotate-45' : ''} transition-all transform"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { createEventDispatcher } from 'svelte';
|
import { createEventDispatcher } from 'svelte';
|
||||||
|
import { getContext } from 'svelte';
|
||||||
|
const i18n = getContext('i18n');
|
||||||
import Tooltip from '../Tooltip.svelte';
|
import Tooltip from '../Tooltip.svelte';
|
||||||
import XMark from '$lib/components/icons/XMark.svelte';
|
import XMark from '$lib/components/icons/XMark.svelte';
|
||||||
import Badge from '../Badge.svelte';
|
import Badge from '../Badge.svelte';
|
||||||
@@ -10,7 +12,7 @@
|
|||||||
|
|
||||||
{#each tags as tag}
|
{#each tags as tag}
|
||||||
<Tooltip content={tag.name}>
|
<Tooltip content={tag.name}>
|
||||||
<div
|
<li
|
||||||
class="relative group/tags px-1.5 py-[0.2px] gap-0.5 flex justify-between h-fit max-h-fit w-fit items-center rounded-full bg-gray-500/20 text-gray-700 dark:text-gray-200 transition cursor-pointer"
|
class="relative group/tags px-1.5 py-[0.2px] gap-0.5 flex justify-between h-fit max-h-fit w-fit items-center rounded-full bg-gray-500/20 text-gray-700 dark:text-gray-200 transition cursor-pointer"
|
||||||
>
|
>
|
||||||
<div class=" text-[0.7rem] font-medium self-center line-clamp-1 w-fit">
|
<div class=" text-[0.7rem] font-medium self-center line-clamp-1 w-fit">
|
||||||
@@ -23,10 +25,11 @@
|
|||||||
dispatch('delete', tag.name);
|
dispatch('delete', tag.name);
|
||||||
}}
|
}}
|
||||||
type="button"
|
type="button"
|
||||||
|
aria-label={$i18n.t('Remove this tag from list')}
|
||||||
>
|
>
|
||||||
<XMark className="size-3" strokeWidth="2.5" />
|
<XMark className="size-3" strokeWidth="2.5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
fill="none"
|
fill="none"
|
||||||
|
aria-hidden="true"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
stroke-width={strokeWidth}
|
stroke-width={strokeWidth}
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
stroke-width={strokeWidth}
|
stroke-width={strokeWidth}
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
class={className}
|
class={className}
|
||||||
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
Reference in New Issue
Block a user