feat: enhance GotoAnything UX with @ command selector (#23738)
This commit is contained in:
51
web/app/components/goto-anything/command-selector.tsx
Normal file
51
web/app/components/goto-anything/command-selector.tsx
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import type { FC } from 'react'
|
||||||
|
import { Command } from 'cmdk'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import type { ActionItem } from './actions/types'
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
actions: Record<string, ActionItem>
|
||||||
|
onCommandSelect: (commandKey: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
const CommandSelector: FC<Props> = ({ actions, onCommandSelect }) => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="p-4">
|
||||||
|
<div className="mb-3 text-left text-sm font-medium text-text-secondary">
|
||||||
|
{t('app.gotoAnything.selectSearchType')}
|
||||||
|
</div>
|
||||||
|
<Command.Group className="space-y-1">
|
||||||
|
{Object.values(actions).map(action => (
|
||||||
|
<Command.Item
|
||||||
|
key={action.key}
|
||||||
|
value={action.shortcut}
|
||||||
|
className="flex cursor-pointer items-center rounded-md
|
||||||
|
p-2.5
|
||||||
|
transition-all
|
||||||
|
duration-150 hover:bg-state-base-hover aria-[selected=true]:bg-state-base-hover"
|
||||||
|
onSelect={() => onCommandSelect(action.shortcut)}
|
||||||
|
>
|
||||||
|
<span className="min-w-[4.5rem] text-left font-mono text-xs text-text-tertiary">
|
||||||
|
{action.shortcut}
|
||||||
|
</span>
|
||||||
|
<span className="ml-3 text-sm text-text-secondary">
|
||||||
|
{(() => {
|
||||||
|
const keyMap: Record<string, string> = {
|
||||||
|
'@app': 'app.gotoAnything.actions.searchApplicationsDesc',
|
||||||
|
'@plugin': 'app.gotoAnything.actions.searchPluginsDesc',
|
||||||
|
'@knowledge': 'app.gotoAnything.actions.searchKnowledgeBasesDesc',
|
||||||
|
'@node': 'app.gotoAnything.actions.searchWorkflowNodesDesc',
|
||||||
|
}
|
||||||
|
return t(keyMap[action.key])
|
||||||
|
})()}
|
||||||
|
</span>
|
||||||
|
</Command.Item>
|
||||||
|
))}
|
||||||
|
</Command.Group>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CommandSelector
|
@@ -17,6 +17,7 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import InstallFromMarketplace from '../plugins/install-plugin/install-from-marketplace'
|
import InstallFromMarketplace from '../plugins/install-plugin/install-from-marketplace'
|
||||||
import type { Plugin } from '../plugins/types'
|
import type { Plugin } from '../plugins/types'
|
||||||
import { Command } from 'cmdk'
|
import { Command } from 'cmdk'
|
||||||
|
import CommandSelector from './command-selector'
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
onHide?: () => void
|
onHide?: () => void
|
||||||
@@ -81,11 +82,15 @@ const GotoAnything: FC<Props> = ({
|
|||||||
wait: 300,
|
wait: 300,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const isCommandsMode = searchQuery.trim() === '@'
|
||||||
|
|
||||||
const searchMode = useMemo(() => {
|
const searchMode = useMemo(() => {
|
||||||
|
if (isCommandsMode) return 'commands'
|
||||||
|
|
||||||
const query = searchQueryDebouncedValue.toLowerCase()
|
const query = searchQueryDebouncedValue.toLowerCase()
|
||||||
const action = matchAction(query, Actions)
|
const action = matchAction(query, Actions)
|
||||||
return action ? action.key : 'general'
|
return action ? action.key : 'general'
|
||||||
}, [searchQueryDebouncedValue, Actions])
|
}, [searchQueryDebouncedValue, Actions, isCommandsMode])
|
||||||
|
|
||||||
const { data: searchResults = [], isLoading, isError, error } = useQuery(
|
const { data: searchResults = [], isLoading, isError, error } = useQuery(
|
||||||
{
|
{
|
||||||
@@ -103,12 +108,20 @@ const GotoAnything: FC<Props> = ({
|
|||||||
const action = matchAction(query, Actions)
|
const action = matchAction(query, Actions)
|
||||||
return await searchAnything(defaultLocale, query, action)
|
return await searchAnything(defaultLocale, query, action)
|
||||||
},
|
},
|
||||||
enabled: !!searchQueryDebouncedValue,
|
enabled: !!searchQueryDebouncedValue && !isCommandsMode,
|
||||||
staleTime: 30000,
|
staleTime: 30000,
|
||||||
gcTime: 300000,
|
gcTime: 300000,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const handleCommandSelect = useCallback((commandKey: string) => {
|
||||||
|
setSearchQuery(`${commandKey} `)
|
||||||
|
setCmdVal('')
|
||||||
|
setTimeout(() => {
|
||||||
|
inputRef.current?.focus()
|
||||||
|
}, 0)
|
||||||
|
}, [])
|
||||||
|
|
||||||
// Handle navigation to selected result
|
// Handle navigation to selected result
|
||||||
const handleNavigate = useCallback((result: SearchResult) => {
|
const handleNavigate = useCallback((result: SearchResult) => {
|
||||||
setShow(false)
|
setShow(false)
|
||||||
@@ -141,7 +154,7 @@ const GotoAnything: FC<Props> = ({
|
|||||||
[searchResults])
|
[searchResults])
|
||||||
|
|
||||||
const emptyResult = useMemo(() => {
|
const emptyResult = useMemo(() => {
|
||||||
if (searchResults.length || !searchQueryDebouncedValue.trim() || isLoading)
|
if (searchResults.length || !searchQuery.trim() || isLoading || isCommandsMode)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
const isCommandSearch = searchMode !== 'general'
|
const isCommandSearch = searchMode !== 'general'
|
||||||
@@ -186,34 +199,22 @@ const GotoAnything: FC<Props> = ({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}, [searchResults, searchQueryDebouncedValue, Actions, searchMode, isLoading, isError])
|
}, [searchResults, searchQuery, Actions, searchMode, isLoading, isError, isCommandsMode])
|
||||||
|
|
||||||
const defaultUI = useMemo(() => {
|
const defaultUI = useMemo(() => {
|
||||||
if (searchQueryDebouncedValue.trim())
|
if (searchQuery.trim())
|
||||||
return null
|
return null
|
||||||
|
|
||||||
return (<div className="flex items-center justify-center py-8 text-center text-text-tertiary">
|
return (<div className="flex items-center justify-center py-12 text-center text-text-tertiary">
|
||||||
<div>
|
<div>
|
||||||
<div className='text-sm font-medium'>{t('app.gotoAnything.searchTitle')}</div>
|
<div className='text-sm font-medium'>{t('app.gotoAnything.searchTitle')}</div>
|
||||||
<div className='mt-3 space-y-2 text-xs text-text-quaternary'>
|
<div className='mt-3 space-y-1 text-xs text-text-quaternary'>
|
||||||
{Object.values(Actions).map(action => (
|
<div>{t('app.gotoAnything.searchHint')}</div>
|
||||||
<div key={action.key} className='flex items-center gap-2'>
|
<div>{t('app.gotoAnything.commandHint')}</div>
|
||||||
<span className='inline-flex items-center rounded bg-gray-200 px-2 py-1 font-mono text-xs font-medium text-gray-600 dark:bg-gray-700 dark:text-gray-200'>{action.shortcut}</span>
|
|
||||||
<span>{(() => {
|
|
||||||
const keyMap: Record<string, string> = {
|
|
||||||
'@app': 'app.gotoAnything.actions.searchApplicationsDesc',
|
|
||||||
'@plugin': 'app.gotoAnything.actions.searchPluginsDesc',
|
|
||||||
'@knowledge': 'app.gotoAnything.actions.searchKnowledgeBasesDesc',
|
|
||||||
'@node': 'app.gotoAnything.actions.searchWorkflowNodesDesc',
|
|
||||||
}
|
|
||||||
return t(keyMap[action.key])
|
|
||||||
})()}</span>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>)
|
</div>)
|
||||||
}, [searchQueryDebouncedValue, Actions])
|
}, [searchQuery, Actions])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (show) {
|
if (show) {
|
||||||
@@ -296,7 +297,13 @@ const GotoAnything: FC<Props> = ({
|
|||||||
)}
|
)}
|
||||||
{!isLoading && !isError && (
|
{!isLoading && !isError && (
|
||||||
<>
|
<>
|
||||||
{Object.entries(groupedResults).map(([type, results], groupIndex) => (
|
{isCommandsMode ? (
|
||||||
|
<CommandSelector
|
||||||
|
actions={Actions}
|
||||||
|
onCommandSelect={handleCommandSelect}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
Object.entries(groupedResults).map(([type, results], groupIndex) => (
|
||||||
<Command.Group key={groupIndex} heading={(() => {
|
<Command.Group key={groupIndex} heading={(() => {
|
||||||
const typeMap: Record<string, string> = {
|
const typeMap: Record<string, string> = {
|
||||||
'app': 'app.gotoAnything.groups.apps',
|
'app': 'app.gotoAnything.groups.apps',
|
||||||
@@ -330,9 +337,10 @@ const GotoAnything: FC<Props> = ({
|
|||||||
</Command.Item>
|
</Command.Item>
|
||||||
))}
|
))}
|
||||||
</Command.Group>
|
</Command.Group>
|
||||||
))}
|
))
|
||||||
{emptyResult}
|
)}
|
||||||
{defaultUI}
|
{!isCommandsMode && emptyResult}
|
||||||
|
{!isCommandsMode && defaultUI}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Command.List>
|
</Command.List>
|
||||||
|
@@ -288,6 +288,9 @@ const translation = {
|
|||||||
useAtForSpecific: 'Verwenden von @ für bestimmte Typen',
|
useAtForSpecific: 'Verwenden von @ für bestimmte Typen',
|
||||||
searchTitle: 'Suchen Sie nach irgendetwas',
|
searchTitle: 'Suchen Sie nach irgendetwas',
|
||||||
searching: 'Suche...',
|
searching: 'Suche...',
|
||||||
|
selectSearchType: 'Wählen Sie aus, wonach gesucht werden soll',
|
||||||
|
commandHint: 'Geben Sie @ ein, um nach Kategorie zu suchen',
|
||||||
|
searchHint: 'Beginnen Sie mit der Eingabe, um alles sofort zu durchsuchen',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -266,6 +266,9 @@ const translation = {
|
|||||||
inScope: 'in {{scope}}s',
|
inScope: 'in {{scope}}s',
|
||||||
clearToSearchAll: 'Clear @ to search all',
|
clearToSearchAll: 'Clear @ to search all',
|
||||||
useAtForSpecific: 'Use @ for specific types',
|
useAtForSpecific: 'Use @ for specific types',
|
||||||
|
selectSearchType: 'Choose what to search for',
|
||||||
|
searchHint: 'Start typing to search everything instantly',
|
||||||
|
commandHint: 'Type @ to browse by category',
|
||||||
actions: {
|
actions: {
|
||||||
searchApplications: 'Search Applications',
|
searchApplications: 'Search Applications',
|
||||||
searchApplicationsDesc: 'Search and navigate to your applications',
|
searchApplicationsDesc: 'Search and navigate to your applications',
|
||||||
|
@@ -286,6 +286,9 @@ const translation = {
|
|||||||
searchTitle: 'Busca cualquier cosa',
|
searchTitle: 'Busca cualquier cosa',
|
||||||
someServicesUnavailable: 'Algunos servicios de búsqueda no están disponibles',
|
someServicesUnavailable: 'Algunos servicios de búsqueda no están disponibles',
|
||||||
servicesUnavailableMessage: 'Algunos servicios de búsqueda pueden estar experimentando problemas. Inténtalo de nuevo en un momento.',
|
servicesUnavailableMessage: 'Algunos servicios de búsqueda pueden estar experimentando problemas. Inténtalo de nuevo en un momento.',
|
||||||
|
searchHint: 'Empieza a escribir para buscar todo al instante',
|
||||||
|
commandHint: 'Escriba @ para buscar por categoría',
|
||||||
|
selectSearchType: 'Elige qué buscar',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -286,6 +286,9 @@ const translation = {
|
|||||||
searchTemporarilyUnavailable: 'جستجو به طور موقت در دسترس نیست',
|
searchTemporarilyUnavailable: 'جستجو به طور موقت در دسترس نیست',
|
||||||
servicesUnavailableMessage: 'برخی از سرویس های جستجو ممکن است با مشکل مواجه شوند. یک لحظه دیگر دوباره امتحان کنید.',
|
servicesUnavailableMessage: 'برخی از سرویس های جستجو ممکن است با مشکل مواجه شوند. یک لحظه دیگر دوباره امتحان کنید.',
|
||||||
someServicesUnavailable: 'برخی از سرویس های جستجو دردسترس نیستند',
|
someServicesUnavailable: 'برخی از سرویس های جستجو دردسترس نیستند',
|
||||||
|
selectSearchType: 'انتخاب کنید چه چیزی را جستجو کنید',
|
||||||
|
commandHint: '@ را برای مرور بر اساس دسته بندی تایپ کنید',
|
||||||
|
searchHint: 'شروع به تایپ کنید تا فورا همه چیز را جستجو کنید',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -286,6 +286,9 @@ const translation = {
|
|||||||
searchPlaceholder: 'Recherchez ou tapez @ pour les commandes...',
|
searchPlaceholder: 'Recherchez ou tapez @ pour les commandes...',
|
||||||
searchFailed: 'Echec de la recherche',
|
searchFailed: 'Echec de la recherche',
|
||||||
noResults: 'Aucun résultat trouvé',
|
noResults: 'Aucun résultat trouvé',
|
||||||
|
commandHint: 'Tapez @ pour parcourir par catégorie',
|
||||||
|
selectSearchType: 'Choisissez les éléments de recherche',
|
||||||
|
searchHint: 'Commencez à taper pour tout rechercher instantanément',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -286,6 +286,9 @@ const translation = {
|
|||||||
searchPlaceholder: 'कमांड के लिए खोजें या टाइप करें @...',
|
searchPlaceholder: 'कमांड के लिए खोजें या टाइप करें @...',
|
||||||
searchTemporarilyUnavailable: 'खोज अस्थायी रूप से उपलब्ध नहीं है',
|
searchTemporarilyUnavailable: 'खोज अस्थायी रूप से उपलब्ध नहीं है',
|
||||||
servicesUnavailableMessage: 'कुछ खोज सेवाएँ समस्याओं का सामना कर सकती हैं। थोड़ी देर बाद फिर से प्रयास करें।',
|
servicesUnavailableMessage: 'कुछ खोज सेवाएँ समस्याओं का सामना कर सकती हैं। थोड़ी देर बाद फिर से प्रयास करें।',
|
||||||
|
commandHint: '@ का उपयोग कर श्रेणी के अनुसार ब्राउज़ करें',
|
||||||
|
selectSearchType: 'खोजने के लिए क्या चुनें',
|
||||||
|
searchHint: 'सब कुछ तुरंत खोजने के लिए टाइप करना शुरू करें',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -292,6 +292,9 @@ const translation = {
|
|||||||
noResults: 'Nessun risultato trovato',
|
noResults: 'Nessun risultato trovato',
|
||||||
useAtForSpecific: 'Utilizzare @ per tipi specifici',
|
useAtForSpecific: 'Utilizzare @ per tipi specifici',
|
||||||
clearToSearchAll: 'Cancella @ per cercare tutto',
|
clearToSearchAll: 'Cancella @ per cercare tutto',
|
||||||
|
selectSearchType: 'Scegli cosa cercare',
|
||||||
|
commandHint: 'Digita @ per sfogliare per categoria',
|
||||||
|
searchHint: 'Inizia a digitare per cercare tutto all\'istante',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -265,6 +265,9 @@ const translation = {
|
|||||||
inScope: '{{scope}}s 内',
|
inScope: '{{scope}}s 内',
|
||||||
clearToSearchAll: '@ をクリアしてすべてを検索',
|
clearToSearchAll: '@ をクリアしてすべてを検索',
|
||||||
useAtForSpecific: '特定のタイプには @ を使用',
|
useAtForSpecific: '特定のタイプには @ を使用',
|
||||||
|
selectSearchType: '検索対象を選択',
|
||||||
|
searchHint: '入力を開始してすべてを瞬時に検索',
|
||||||
|
commandHint: '@ を入力してカテゴリ別に参照',
|
||||||
actions: {
|
actions: {
|
||||||
searchApplications: 'アプリケーションを検索',
|
searchApplications: 'アプリケーションを検索',
|
||||||
searchApplicationsDesc: 'アプリケーションを検索してナビゲート',
|
searchApplicationsDesc: 'アプリケーションを検索してナビゲート',
|
||||||
|
@@ -306,6 +306,9 @@ const translation = {
|
|||||||
searchFailed: '검색 실패',
|
searchFailed: '검색 실패',
|
||||||
searchPlaceholder: '명령을 검색하거나 @를 입력합니다...',
|
searchPlaceholder: '명령을 검색하거나 @를 입력합니다...',
|
||||||
clearToSearchAll: '@를 지우면 모두 검색됩니다.',
|
clearToSearchAll: '@를 지우면 모두 검색됩니다.',
|
||||||
|
selectSearchType: '검색할 항목 선택',
|
||||||
|
commandHint: '@를 입력하여 카테고리별로 찾아봅니다.',
|
||||||
|
searchHint: '즉시 모든 것을 검색하려면 입력을 시작하세요.',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -287,6 +287,9 @@ const translation = {
|
|||||||
searchTemporarilyUnavailable: 'Wyszukiwanie chwilowo niedostępne',
|
searchTemporarilyUnavailable: 'Wyszukiwanie chwilowo niedostępne',
|
||||||
servicesUnavailableMessage: 'W przypadku niektórych usług wyszukiwania mogą występować problemy. Spróbuj ponownie za chwilę.',
|
servicesUnavailableMessage: 'W przypadku niektórych usług wyszukiwania mogą występować problemy. Spróbuj ponownie za chwilę.',
|
||||||
searchFailed: 'Wyszukiwanie nie powiodło się',
|
searchFailed: 'Wyszukiwanie nie powiodło się',
|
||||||
|
searchHint: 'Zacznij pisać, aby natychmiast wszystko przeszukać',
|
||||||
|
commandHint: 'Wpisz @, aby przeglądać według kategorii',
|
||||||
|
selectSearchType: 'Wybierz, czego chcesz szukać',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -286,6 +286,9 @@ const translation = {
|
|||||||
useAtForSpecific: 'Use @ para tipos específicos',
|
useAtForSpecific: 'Use @ para tipos específicos',
|
||||||
clearToSearchAll: 'Desmarque @ para pesquisar tudo',
|
clearToSearchAll: 'Desmarque @ para pesquisar tudo',
|
||||||
searchFailed: 'Falha na pesquisa',
|
searchFailed: 'Falha na pesquisa',
|
||||||
|
searchHint: 'Comece a digitar para pesquisar tudo instantaneamente',
|
||||||
|
commandHint: 'Digite @ para navegar por categoria',
|
||||||
|
selectSearchType: 'Escolha o que pesquisar',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -286,6 +286,9 @@ const translation = {
|
|||||||
servicesUnavailableMessage: 'Este posibil ca unele servicii de căutare să întâmpine probleme. Încercați din nou într-o clipă.',
|
servicesUnavailableMessage: 'Este posibil ca unele servicii de căutare să întâmpine probleme. Încercați din nou într-o clipă.',
|
||||||
someServicesUnavailable: 'Unele servicii de căutare nu sunt disponibile',
|
someServicesUnavailable: 'Unele servicii de căutare nu sunt disponibile',
|
||||||
clearToSearchAll: 'Ștergeți @ pentru a căuta toate',
|
clearToSearchAll: 'Ștergeți @ pentru a căuta toate',
|
||||||
|
selectSearchType: 'Alegeți ce să căutați',
|
||||||
|
commandHint: 'Tastați @ pentru a naviga după categorie',
|
||||||
|
searchHint: 'Începeți să tastați pentru a căuta totul instantaneu',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -286,6 +286,9 @@ const translation = {
|
|||||||
searchPlaceholder: 'Найдите или введите @ для команд...',
|
searchPlaceholder: 'Найдите или введите @ для команд...',
|
||||||
someServicesUnavailable: 'Некоторые поисковые сервисы недоступны',
|
someServicesUnavailable: 'Некоторые поисковые сервисы недоступны',
|
||||||
servicesUnavailableMessage: 'В некоторых поисковых службах могут возникать проблемы. Повторите попытку через мгновение.',
|
servicesUnavailableMessage: 'В некоторых поисковых службах могут возникать проблемы. Повторите попытку через мгновение.',
|
||||||
|
searchHint: 'Начните печатать, чтобы мгновенно искать все',
|
||||||
|
commandHint: 'Введите @ для просмотра по категориям',
|
||||||
|
selectSearchType: 'Выберите, что искать',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -286,6 +286,9 @@ const translation = {
|
|||||||
searchFailed: 'Iskanje ni uspelo',
|
searchFailed: 'Iskanje ni uspelo',
|
||||||
useAtForSpecific: 'Uporaba znaka @ za določene vrste',
|
useAtForSpecific: 'Uporaba znaka @ za določene vrste',
|
||||||
servicesUnavailableMessage: 'Pri nekaterih iskalnih storitvah se morda pojavljajo težave. Poskusite znova čez trenutek.',
|
servicesUnavailableMessage: 'Pri nekaterih iskalnih storitvah se morda pojavljajo težave. Poskusite znova čez trenutek.',
|
||||||
|
commandHint: 'Vnesite @ za brskanje po kategoriji',
|
||||||
|
selectSearchType: 'Izberite, kaj želite iskati',
|
||||||
|
searchHint: 'Začnite tipkati, da takoj preiščete vse',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -282,6 +282,9 @@ const translation = {
|
|||||||
searchPlaceholder: 'ค้นหาหรือพิมพ์ @ สําหรับคําสั่ง...',
|
searchPlaceholder: 'ค้นหาหรือพิมพ์ @ สําหรับคําสั่ง...',
|
||||||
servicesUnavailableMessage: 'บริการค้นหาบางบริการอาจประสบปัญหา ลองอีกครั้งในอีกสักครู่',
|
servicesUnavailableMessage: 'บริการค้นหาบางบริการอาจประสบปัญหา ลองอีกครั้งในอีกสักครู่',
|
||||||
searching: 'กำลังค้นหา...',
|
searching: 'กำลังค้นหา...',
|
||||||
|
searchHint: 'เริ่มพิมพ์เพื่อค้นหาทุกอย่างได้ทันที',
|
||||||
|
selectSearchType: 'เลือกสิ่งที่จะค้นหา',
|
||||||
|
commandHint: 'พิมพ์ @ เพื่อเรียกดูตามหมวดหมู่',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -282,6 +282,9 @@ const translation = {
|
|||||||
noResults: 'Sonuç bulunamadı',
|
noResults: 'Sonuç bulunamadı',
|
||||||
servicesUnavailableMessage: 'Bazı arama hizmetlerinde sorunlar yaşanıyor olabilir. Kısa bir süre sonra tekrar deneyin.',
|
servicesUnavailableMessage: 'Bazı arama hizmetlerinde sorunlar yaşanıyor olabilir. Kısa bir süre sonra tekrar deneyin.',
|
||||||
searching: 'Araştırıcı...',
|
searching: 'Araştırıcı...',
|
||||||
|
selectSearchType: 'Ne arayacağınızı seçin',
|
||||||
|
searchHint: 'Her şeyi anında aramak için yazmaya başlayın',
|
||||||
|
commandHint: 'Kategoriye göre göz atmak için @ yazın',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -286,6 +286,9 @@ const translation = {
|
|||||||
useAtForSpecific: 'Використовуйте @ для конкретних типів',
|
useAtForSpecific: 'Використовуйте @ для конкретних типів',
|
||||||
someServicesUnavailable: 'Деякі пошукові сервіси недоступні',
|
someServicesUnavailable: 'Деякі пошукові сервіси недоступні',
|
||||||
servicesUnavailableMessage: 'У деяких пошукових службах можуть виникати проблеми. Повторіть спробу за мить.',
|
servicesUnavailableMessage: 'У деяких пошукових службах можуть виникати проблеми. Повторіть спробу за мить.',
|
||||||
|
selectSearchType: 'Виберіть, що шукати',
|
||||||
|
commandHint: 'Введіть @ для навігації за категоріями',
|
||||||
|
searchHint: 'Почніть вводити текст, щоб миттєво шукати все',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -286,6 +286,9 @@ const translation = {
|
|||||||
useAtForSpecific: 'Sử dụng @ cho các loại cụ thể',
|
useAtForSpecific: 'Sử dụng @ cho các loại cụ thể',
|
||||||
someServicesUnavailable: 'Một số dịch vụ tìm kiếm không khả dụng',
|
someServicesUnavailable: 'Một số dịch vụ tìm kiếm không khả dụng',
|
||||||
servicesUnavailableMessage: 'Một số dịch vụ tìm kiếm có thể gặp sự cố. Thử lại trong giây lát.',
|
servicesUnavailableMessage: 'Một số dịch vụ tìm kiếm có thể gặp sự cố. Thử lại trong giây lát.',
|
||||||
|
searchHint: 'Bắt đầu nhập để tìm kiếm mọi thứ ngay lập tức',
|
||||||
|
commandHint: 'Nhập @ để duyệt theo danh mục',
|
||||||
|
selectSearchType: 'Chọn nội dung để tìm kiếm',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -265,6 +265,9 @@ const translation = {
|
|||||||
inScope: '在 {{scope}}s 中',
|
inScope: '在 {{scope}}s 中',
|
||||||
clearToSearchAll: '清除 @ 以搜索全部',
|
clearToSearchAll: '清除 @ 以搜索全部',
|
||||||
useAtForSpecific: '使用 @ 进行特定类型搜索',
|
useAtForSpecific: '使用 @ 进行特定类型搜索',
|
||||||
|
selectSearchType: '选择搜索内容',
|
||||||
|
searchHint: '开始输入即可立即搜索所有内容',
|
||||||
|
commandHint: '输入 @ 按类别浏览',
|
||||||
actions: {
|
actions: {
|
||||||
searchApplications: '搜索应用程序',
|
searchApplications: '搜索应用程序',
|
||||||
searchApplicationsDesc: '搜索并导航到您的应用程序',
|
searchApplicationsDesc: '搜索并导航到您的应用程序',
|
||||||
|
@@ -285,6 +285,9 @@ const translation = {
|
|||||||
someServicesUnavailable: '某些搜索服務不可用',
|
someServicesUnavailable: '某些搜索服務不可用',
|
||||||
useAtForSpecific: '對特定類型使用 @',
|
useAtForSpecific: '對特定類型使用 @',
|
||||||
searchTemporarilyUnavailable: '搜索暫時不可用',
|
searchTemporarilyUnavailable: '搜索暫時不可用',
|
||||||
|
selectSearchType: '選擇要搜索的內容',
|
||||||
|
commandHint: '鍵入 @ 按類別流覽',
|
||||||
|
searchHint: '開始輸入以立即搜索所有內容',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user