Files
Memoh/apps/web/src/pages/bots/components/browser-context-select.vue
T
Acbox c0057b5c54 refactor(web): align route paths, page dirs and i18n keys with sidebar labels
- Rename route paths to match sidebar tab labels:
  models→providers, search-providers→web-search,
  memory-providers→memory, tts-providers→speech,
  email-providers→email, browser-contexts→browser,
  settings(profile)→profile
- Rename page directories accordingly
- Rename i18n keys: sidebar.models→providers, searchProvider→webSearch,
  memoryProvider→memory, ttsProvider→speech, emailProvider→email,
  browserContext→browser
- Fix bot detail tab value 'settings' → 'general' to match label
- Fix ZH bots.tabs.general untranslated ("General" → "通用")
- Align usage page title with sidebar label
2026-03-28 23:34:53 +08:00

84 lines
2.5 KiB
Vue

<template>
<SearchableSelectPopover
v-model="selected"
:options="options"
:placeholder="placeholder || ''"
:aria-label="placeholder || 'Select browser context'"
:search-placeholder="$t('browser.searchPlaceholder')"
search-aria-label="Search browser contexts"
:empty-text="$t('browser.emptyTitle')"
:show-group-headers="false"
>
<template #trigger="{ open, displayLabel }">
<Button
variant="outline"
role="combobox"
:aria-expanded="open"
:aria-label="placeholder || 'Select browser context'"
class="w-full justify-between font-normal"
>
<span class="flex items-center gap-2 truncate">
<FontAwesomeIcon
v-if="selected"
:icon="['fas', 'window-maximize']"
class="size-3.5 text-muted-foreground"
/>
<span class="truncate">{{ displayLabel || placeholder }}</span>
</span>
<FontAwesomeIcon
:icon="['fas', 'magnifying-glass']"
class="ml-2 size-3.5 shrink-0 text-muted-foreground"
/>
</Button>
</template>
<template #option-icon="{ option }">
<FontAwesomeIcon
v-if="option.value"
:icon="['fas', 'window-maximize']"
class="size-3.5 text-muted-foreground"
/>
</template>
<template #option-label="{ option }">
<span
class="truncate"
:class="{ 'text-muted-foreground': !option.value }"
>
{{ option.label }}
</span>
</template>
</SearchableSelectPopover>
</template>
<script setup lang="ts">
import { Button } from '@memohai/ui'
import { computed } from 'vue'
import type { BrowsercontextsBrowserContext } from '@memohai/sdk'
import { useI18n } from 'vue-i18n'
import SearchableSelectPopover from '@/components/searchable-select-popover/index.vue'
import type { SearchableSelectOption } from '@/components/searchable-select-popover/index.vue'
const props = defineProps<{
contexts: BrowsercontextsBrowserContext[]
placeholder?: string
}>()
const { t } = useI18n()
const selected = defineModel<string>({ default: '' })
const options = computed<SearchableSelectOption[]>(() => {
const noneOption: SearchableSelectOption = {
value: '',
label: t('common.none'),
keywords: [t('common.none')],
}
const contextOptions = props.contexts.map((ctx) => ({
value: ctx.id || '',
label: ctx.name || ctx.id || '',
keywords: [ctx.name ?? ''],
}))
return [noneOption, ...contextOptions]
})
</script>