diff --git a/web/app/components/plugins/hooks.ts b/web/app/components/plugins/hooks.ts new file mode 100644 index 0000000000..ef69cf5f23 --- /dev/null +++ b/web/app/components/plugins/hooks.ts @@ -0,0 +1,72 @@ +import { useTranslation } from 'react-i18next' + +export const useTags = () => { + const { t } = useTranslation() + + return [ + { + name: 'search', + label: t('pluginTags.search'), + }, + { + name: 'image', + label: t('pluginTags.image'), + }, + { + name: 'videos', + label: t('pluginTags.videos'), + }, + { + name: 'weather', + label: t('pluginTags.weather'), + }, + { + name: 'finance', + label: t('pluginTags.finance'), + }, + { + name: 'design', + label: t('pluginTags.design'), + }, + { + name: 'travel', + label: t('pluginTags.travel'), + }, + { + name: 'social', + label: t('pluginTags.social'), + }, + { + name: 'news', + label: t('pluginTags.news'), + }, + { + name: 'medical', + label: t('pluginTags.medical'), + }, + { + name: 'productivity', + label: t('pluginTags.productivity'), + }, + { + name: 'education', + label: t('pluginTags.education'), + }, + { + name: 'business', + label: t('pluginTags.business'), + }, + { + name: 'entertainment', + label: t('pluginTags.entertainment'), + }, + { + name: 'utilities', + label: t('pluginTags.utilities'), + }, + { + name: 'other', + label: t('pluginTags.other'), + }, + ] +} diff --git a/web/app/components/plugins/marketplace/hooks.ts b/web/app/components/plugins/marketplace/hooks.ts index 89a0908ee6..83b7ee5435 100644 --- a/web/app/components/plugins/marketplace/hooks.ts +++ b/web/app/components/plugins/marketplace/hooks.ts @@ -40,7 +40,7 @@ export const useMarketplaceCollectionsAndPlugins = () => { export const useMarketplacePlugins = () => { const [isLoading, setIsLoading] = useState(false) - const [plugins, setPlugins] = useState([]) + const [plugins, setPlugins] = useState() const queryPlugins = useCallback(async (query: PluginsSearchParams) => { setIsLoading(true) diff --git a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx index 5114765544..c7a1a4e57e 100644 --- a/web/app/components/plugins/marketplace/search-box/tags-filter.tsx +++ b/web/app/components/plugins/marketplace/search-box/tags-filter.tsx @@ -14,6 +14,7 @@ import { import Checkbox from '@/app/components/base/checkbox' import cn from '@/utils/classnames' import Input from '@/app/components/base/input' +import { useTags } from '@/app/components/plugins/hooks' type TagsFilterProps = { tags: string[] @@ -27,17 +28,8 @@ const TagsFilter = ({ }: TagsFilterProps) => { const [open, setOpen] = useState(false) const [searchText, setSearchText] = useState('') - const options = [ - { - value: 'search', - text: 'Search', - }, - { - value: 'image', - text: 'Image', - }, - ] - const filteredOptions = options.filter(option => option.text.toLowerCase().includes(searchText.toLowerCase())) + const options = useTags() + const filteredOptions = options.filter(option => option.label.toLowerCase().includes(searchText.toLowerCase())) const handleCheck = (id: string) => { if (tags.includes(id)) onTagsChange(tags.filter((tag: string) => tag !== id)) @@ -115,16 +107,16 @@ const TagsFilter = ({ { filteredOptions.map(option => (
handleCheck(option.value)} + onClick={() => handleCheck(option.name)} >
- {option.text} + {option.label}
)) diff --git a/web/app/components/plugins/marketplace/utils.ts b/web/app/components/plugins/marketplace/utils.ts index 99b34fa570..a8e50b5e20 100644 --- a/web/app/components/plugins/marketplace/utils.ts +++ b/web/app/components/plugins/marketplace/utils.ts @@ -14,13 +14,13 @@ export const getMarketplaceCollectionsAndPlugins = async (query?: CollectionsAnd let marketplaceCollections = [] as MarketplaceCollection[] let marketplaceCollectionPluginsMap = {} as Record try { - const marketplaceCollectionsData = await globalThis.fetch(`${MARKETPLACE_API_PREFIX}/collections`, { cache: 'no-store' }) + const marketplaceCollectionsData = await globalThis.fetch(`${MARKETPLACE_API_PREFIX}/collections?page=1&page_size=100`, { cache: 'no-store' }) const marketplaceCollectionsDataJson = await marketplaceCollectionsData.json() marketplaceCollections = marketplaceCollectionsDataJson.data.collections await Promise.all(marketplaceCollections.map(async (collection: MarketplaceCollection) => { - let url = `${MARKETPLACE_API_PREFIX}/collections/${collection.name}/plugins` + let url = `${MARKETPLACE_API_PREFIX}/collections/${collection.name}/plugins?page=1&page_size=100` if (query?.category) - url += `?category=${query.category}` + url += `&category=${query.category}` const marketplaceCollectionPluginsData = await globalThis.fetch(url, { cache: 'no-store' }) const marketplaceCollectionPluginsDataJson = await marketplaceCollectionPluginsData.json() const plugins = marketplaceCollectionPluginsDataJson.data.plugins.map((plugin: Plugin) => { diff --git a/web/app/components/plugins/plugin-page/install-info.tsx b/web/app/components/plugins/plugin-page/install-info.tsx index 4d3b076883..bb0a31f4be 100644 --- a/web/app/components/plugins/plugin-page/install-info.tsx +++ b/web/app/components/plugins/plugin-page/install-info.tsx @@ -59,7 +59,7 @@ const InstallInfo = () => { - +
3 plugins failed to install
diff --git a/web/app/components/tools/labels/constant.ts b/web/app/components/tools/labels/constant.ts index 3f073859d9..ad4836e6a8 100644 --- a/web/app/components/tools/labels/constant.ts +++ b/web/app/components/tools/labels/constant.ts @@ -1,6 +1,4 @@ -import type { TypeWithI18N } from '@/app/components/header/account-setting/model-provider-page/declarations' export type Label = { name: string - icon: string - label: TypeWithI18N + label: string } diff --git a/web/app/components/tools/labels/filter.tsx b/web/app/components/tools/labels/filter.tsx index 36c1c1ba83..f33a63f480 100644 --- a/web/app/components/tools/labels/filter.tsx +++ b/web/app/components/tools/labels/filter.tsx @@ -1,10 +1,8 @@ import type { FC } from 'react' import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' -import { useContext } from 'use-context-selector' -import { useDebounceFn, useMount } from 'ahooks' +import { useDebounceFn } from 'ahooks' import { RiArrowDownSLine } from '@remixicon/react' -import { useStore as useLabelStore } from './store' import cn from '@/utils/classnames' import { PortalToFollowElem, @@ -16,11 +14,9 @@ import { Tag01, Tag03 } from '@/app/components/base/icons/src/vender/line/financ import { Check } from '@/app/components/base/icons/src/vender/line/general' import { XCircle } from '@/app/components/base/icons/src/vender/solid/general' import type { Label } from '@/app/components/tools/labels/constant' -import { fetchLabelList } from '@/service/tools' -import I18n from '@/context/i18n' -import { getLanguage } from '@/i18n/language' +import { useTags } from '@/app/components/plugins/hooks' -interface LabelFilterProps { +type LabelFilterProps = { value: string[] onChange: (v: string[]) => void } @@ -29,12 +25,9 @@ const LabelFilter: FC = ({ onChange, }) => { const { t } = useTranslation() - const { locale } = useContext(I18n) - const language = getLanguage(locale) const [open, setOpen] = useState(false) - const labelList = useLabelStore(s => s.labelList) - const setLabelList = useLabelStore(s => s.setLabelList) + const labelList = useTags() const [keywords, setKeywords] = useState('') const [searchKeywords, setSearchKeywords] = useState('') @@ -61,12 +54,6 @@ const LabelFilter: FC = ({ onChange([...value, label.name]) } - useMount(() => { - fetchLabelList().then((res) => { - setLabelList(res) - }) - }) - return ( = ({
{!value.length && t('common.tag.placeholder')} - {!!value.length && currentLabel?.label[language]} + {!!value.length && currentLabel?.label}
{value.length > 1 && (
{`+${value.length - 1}`}
@@ -128,7 +115,7 @@ const LabelFilter: FC = ({ className='flex items-center gap-2 pl-3 py-[6px] pr-2 rounded-lg cursor-pointer hover:bg-gray-100' onClick={() => selectLabel(label)} > -
{label.label[language]}
+
{label.label}
{value.includes(label.name) && }
))} diff --git a/web/app/components/tools/labels/selector.tsx b/web/app/components/tools/labels/selector.tsx index baa043010e..0c64ebb142 100644 --- a/web/app/components/tools/labels/selector.tsx +++ b/web/app/components/tools/labels/selector.tsx @@ -1,10 +1,8 @@ import type { FC } from 'react' import { useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' -import { useContext } from 'use-context-selector' -import { useDebounceFn, useMount } from 'ahooks' +import { useDebounceFn } from 'ahooks' import { RiArrowDownSLine } from '@remixicon/react' -import { useStore as useLabelStore } from './store' import cn from '@/utils/classnames' import { PortalToFollowElem, @@ -15,11 +13,9 @@ import Input from '@/app/components/base/input' import { Tag03 } from '@/app/components/base/icons/src/vender/line/financeAndECommerce' import Checkbox from '@/app/components/base/checkbox' import type { Label } from '@/app/components/tools/labels/constant' -import { fetchLabelList } from '@/service/tools' -import I18n from '@/context/i18n' -import { getLanguage } from '@/i18n/language' +import { useTags } from '@/app/components/plugins/hooks' -interface LabelSelectorProps { +type LabelSelectorProps = { value: string[] onChange: (v: string[]) => void } @@ -28,12 +24,9 @@ const LabelSelector: FC = ({ onChange, }) => { const { t } = useTranslation() - const { locale } = useContext(I18n) - const language = getLanguage(locale) const [open, setOpen] = useState(false) - const labelList = useLabelStore(s => s.labelList) - const setLabelList = useLabelStore(s => s.setLabelList) + const labelList = useTags() const [keywords, setKeywords] = useState('') const [searchKeywords, setSearchKeywords] = useState('') @@ -50,8 +43,8 @@ const LabelSelector: FC = ({ }, [labelList, searchKeywords]) const selectedLabels = useMemo(() => { - return value.map(v => labelList.find(l => l.name === v)?.label[language]).join(', ') - }, [value, labelList, language]) + return value.map(v => labelList.find(l => l.name === v)?.label).join(', ') + }, [value, labelList]) const selectLabel = (label: Label) => { if (value.includes(label.name)) @@ -60,12 +53,6 @@ const LabelSelector: FC = ({ onChange([...value, label.name]) } - useMount(() => { - fetchLabelList().then((res) => { - setLabelList(res) - }) - }) - return ( = ({ checked={value.includes(label.name)} onCheck={() => { }} /> -
{label.label[language]}
+
{label.label}
))} {!filteredLabelList.length && ( diff --git a/web/app/components/tools/labels/store.ts b/web/app/components/tools/labels/store.ts deleted file mode 100644 index c19991dfd4..0000000000 --- a/web/app/components/tools/labels/store.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { create } from 'zustand' -import type { Label } from './constant' - -type State = { - labelList: Label[] -} - -type Action = { - setLabelList: (labelList?: Label[]) => void -} - -export const useStore = create(set => ({ - labelList: [], - setLabelList: labelList => set(() => ({ labelList })), -})) diff --git a/web/app/components/tools/marketplace/hooks.ts b/web/app/components/tools/marketplace/hooks.ts index d1558e7aaf..82f019ef14 100644 --- a/web/app/components/tools/marketplace/hooks.ts +++ b/web/app/components/tools/marketplace/hooks.ts @@ -37,7 +37,7 @@ export const useMarketplace = (searchPluginText: string, filterPluginTags: strin } else { queryMarketplaceCollectionsAndPlugins() - setPlugins([]) + setPlugins(undefined) } }, [searchPluginText, filterPluginTags, queryPlugins, queryMarketplaceCollectionsAndPlugins, queryPluginsWithDebounced, setPlugins]) diff --git a/web/i18n/de-DE/plugin-tags.ts b/web/i18n/de-DE/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/de-DE/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/en-US/plugin-tags.ts b/web/i18n/en-US/plugin-tags.ts new file mode 100644 index 0000000000..6eca3ac8a2 --- /dev/null +++ b/web/i18n/en-US/plugin-tags.ts @@ -0,0 +1,20 @@ +const translation = { + search: 'Search', + image: 'Image', + videos: 'Videos', + weather: 'Weather', + finance: 'Finance', + design: 'Design', + travel: 'Travel', + social: 'Social', + news: 'News', + medical: 'Medical', + productivity: 'Productivity', + education: 'Education', + business: 'Business', + entertainment: 'Entertainment', + utilities: 'Utilities', + other: 'Other', +} + +export default translation diff --git a/web/i18n/es-ES/plugin-tags.ts b/web/i18n/es-ES/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/es-ES/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/fa-IR/plugin-tags.ts b/web/i18n/fa-IR/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/fa-IR/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/fr-FR/plugin-tags.ts b/web/i18n/fr-FR/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/fr-FR/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/hi-IN/plugin-tags.ts b/web/i18n/hi-IN/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/hi-IN/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/i18next-config.ts b/web/i18n/i18next-config.ts index be8b4c46e1..bbba4c7c35 100644 --- a/web/i18n/i18next-config.ts +++ b/web/i18n/i18next-config.ts @@ -29,6 +29,7 @@ const loadLangResources = (lang: string) => ({ workflow: require(`./${lang}/workflow`).default, runLog: require(`./${lang}/run-log`).default, plugin: require(`./${lang}/plugin`).default, + pluginTags: require(`./${lang}/plugin-tags`).default, }, }) diff --git a/web/i18n/it-IT/plugin-tags.ts b/web/i18n/it-IT/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/it-IT/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ja-JP/plugin-tags.ts b/web/i18n/ja-JP/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ja-JP/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ko-KR/plugin-tags.ts b/web/i18n/ko-KR/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ko-KR/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/pl-PL/plugin-tags.ts b/web/i18n/pl-PL/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/pl-PL/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/pt-BR/plugin-tags.ts b/web/i18n/pt-BR/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/pt-BR/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ro-RO/plugin-tags.ts b/web/i18n/ro-RO/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ro-RO/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/ru-RU/plugin-tags.ts b/web/i18n/ru-RU/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/ru-RU/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/tr-TR/plugin-tags.ts b/web/i18n/tr-TR/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/tr-TR/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/uk-UA/plugin-tags.ts b/web/i18n/uk-UA/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/uk-UA/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/vi-VN/plugin-tags.ts b/web/i18n/vi-VN/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/vi-VN/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation diff --git a/web/i18n/zh-Hans/plugin-tags.ts b/web/i18n/zh-Hans/plugin-tags.ts new file mode 100644 index 0000000000..f8251d339d --- /dev/null +++ b/web/i18n/zh-Hans/plugin-tags.ts @@ -0,0 +1,20 @@ +const translation = { + search: '搜索', + image: '图片', + videos: '视频', + weather: '天气', + finance: '金融', + design: '设计', + travel: '旅行', + social: '社交', + news: '新闻', + medical: '医疗', + productivity: '生产力', + education: '教育', + business: '商业', + entertainment: '娱乐', + utilities: '工具', + other: '其他', +} + +export default translation diff --git a/web/i18n/zh-Hant/plugin-tags.ts b/web/i18n/zh-Hant/plugin-tags.ts new file mode 100644 index 0000000000..928649474b --- /dev/null +++ b/web/i18n/zh-Hant/plugin-tags.ts @@ -0,0 +1,4 @@ +const translation = { +} + +export default translation