diff --git a/web/src/assets/svg/google-scholar.svg b/web/src/assets/svg/google-scholar.svg new file mode 100644 index 000000000..973763a16 --- /dev/null +++ b/web/src/assets/svg/google-scholar.svg @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/web/src/components/file-upload-modal/index.less b/web/src/components/file-upload-modal/index.less index a840e8aed..8472339fe 100644 --- a/web/src/components/file-upload-modal/index.less +++ b/web/src/components/file-upload-modal/index.less @@ -6,3 +6,8 @@ } } } + +.uploadLimit { + color: red; + font-size: 12px; +} diff --git a/web/src/components/file-upload-modal/index.tsx b/web/src/components/file-upload-modal/index.tsx index 3e7c2e8c6..1d827af78 100644 --- a/web/src/components/file-upload-modal/index.tsx +++ b/web/src/components/file-upload-modal/index.tsx @@ -53,6 +53,7 @@ const FileUpload = ({

{t('uploadTitle')}

{t('uploadDescription')}

+ {false &&

{t('uploadLimit')}

} ); }; diff --git a/web/src/locales/en.ts b/web/src/locales/en.ts index fff690c10..360befc0a 100644 --- a/web/src/locales/en.ts +++ b/web/src/locales/en.ts @@ -562,6 +562,8 @@ The above is the content you need to summarize.`, s3: 'S3 uploads', preview: 'Preview', fileError: 'File error', + uploadLimit: + 'The file size cannot exceed 10M, and the total number of files cannot exceed 128', }, flow: { cite: 'Cite', @@ -650,6 +652,13 @@ The above is the content you need to summarize.`, apiKey: 'Api Key', country: 'Country', language: 'Language', + googleScholar: 'Google Scholar', + googleScholarDescription: + 'This component is used to get search result from https://scholar.google.com/. Typically, it performs as a supplement to knowledgebases. Top N specifies the number of search results you need to adapt.', + yearLow: 'Year low', + yearHigh: 'Year high', + patents: 'Patents', + data: 'Data', }, footer: { profile: 'All rights reserved @ React', diff --git a/web/src/locales/zh-traditional.ts b/web/src/locales/zh-traditional.ts index fcedfe58d..fc2502037 100644 --- a/web/src/locales/zh-traditional.ts +++ b/web/src/locales/zh-traditional.ts @@ -523,6 +523,7 @@ export default { s3: 'S3 上傳', preview: '預覽', fileError: '文件錯誤', + uploadLimit: '文件大小不能超過10M,文件總數不超過128個', }, flow: { cite: '引用', @@ -610,6 +611,12 @@ export default { apiKey: 'Api Key', country: '國家', language: '語言', + googleScholar: '谷歌學術', + googleScholarDescription: `該元件用於從 https://scholar.google.com/ 取得搜尋結果。通常,它充當知識庫的補充。 Top N 指定您需要調整的搜尋結果的數量。`, + yearLow: '開始年份', + yearHigh: '結束年份', + patents: '專利', + data: '數據', }, footer: { profile: '“保留所有權利 @ react”', diff --git a/web/src/locales/zh.ts b/web/src/locales/zh.ts index f289c48dd..c30ecee9c 100644 --- a/web/src/locales/zh.ts +++ b/web/src/locales/zh.ts @@ -541,6 +541,7 @@ export default { s3: 'S3 上传', preview: '预览', fileError: '文件错误', + uploadLimit: '文件大小不能超过10M,文件总数不超过128个', }, flow: { flow: '工作流', @@ -628,6 +629,12 @@ export default { apiKey: 'Api Key', country: '国家', language: '语言', + googleScholar: '谷歌学术', + googleScholarDescription: `此组件用于从 https://scholar.google.com/ 获取搜索结果。通常,它作为知识库的补充。Top N 指定您需要调整的搜索结果数量。`, + yearLow: '开始年份', + yearHigh: '结束年份', + patents: '专利', + data: '数据', }, footer: { profile: 'All rights reserved @ React', diff --git a/web/src/pages/flow/constant.tsx b/web/src/pages/flow/constant.tsx index 97810cbae..62d6c85b2 100644 --- a/web/src/pages/flow/constant.tsx +++ b/web/src/pages/flow/constant.tsx @@ -2,6 +2,7 @@ import { ReactComponent as ArXivIcon } from '@/assets/svg/arxiv.svg'; import { ReactComponent as BaiduIcon } from '@/assets/svg/baidu.svg'; import { ReactComponent as BingIcon } from '@/assets/svg/bing.svg'; import { ReactComponent as DuckIcon } from '@/assets/svg/duck.svg'; +import { ReactComponent as GoogleScholarIcon } from '@/assets/svg/google-scholar.svg'; import { ReactComponent as GoogleIcon } from '@/assets/svg/google.svg'; import { ReactComponent as KeywordIcon } from '@/assets/svg/keyword.svg'; import { ReactComponent as PubMedIcon } from '@/assets/svg/pubmed.svg'; @@ -44,6 +45,7 @@ export enum Operator { ArXiv = 'ArXiv', Google = 'Google', Bing = 'Bing', + GoogleScholar = 'GoogleScholar', } export const operatorIconMap = { @@ -63,6 +65,7 @@ export const operatorIconMap = { [Operator.ArXiv]: ArXivIcon, [Operator.Google]: GoogleIcon, [Operator.Bing]: BingIcon, + [Operator.GoogleScholar]: GoogleScholarIcon, }; export const operatorMap = { @@ -145,6 +148,7 @@ export const operatorMap = { backgroundColor: 'pink', }, [Operator.Bing]: {}, + [Operator.GoogleScholar]: {}, }; export const componentMenuList = [ @@ -193,6 +197,9 @@ export const componentMenuList = [ { name: Operator.Bing, }, + { + name: Operator.GoogleScholar, + }, ]; export const initialRetrievalValues = { @@ -291,6 +298,12 @@ export const initialBingValues = { language: 'en', }; +export const initialGoogleScholarValues = { + top_n: 5, + sort_by: 'relevance', + patents: true, +}; + export const CategorizeAnchorPointPositions = [ { top: 1, right: 34 }, { top: 8, right: 18 }, @@ -354,6 +367,7 @@ export const RestrictedUpstreamMap = { [Operator.ArXiv]: [Operator.Begin, Operator.Retrieval], [Operator.Google]: [Operator.Begin, Operator.Retrieval], [Operator.Bing]: [Operator.Begin, Operator.Retrieval], + [Operator.GoogleScholar]: [Operator.Begin, Operator.Retrieval], }; export const NodeMap = { @@ -373,6 +387,7 @@ export const NodeMap = { [Operator.ArXiv]: 'ragNode', [Operator.Google]: 'ragNode', [Operator.Bing]: 'ragNode', + [Operator.GoogleScholar]: 'ragNode', }; export const LanguageOptions = [ diff --git a/web/src/pages/flow/flow-drawer/index.tsx b/web/src/pages/flow/flow-drawer/index.tsx index c6c7e7984..52c25c3bf 100644 --- a/web/src/pages/flow/flow-drawer/index.tsx +++ b/web/src/pages/flow/flow-drawer/index.tsx @@ -13,6 +13,7 @@ import { Operator } from '../constant'; import DuckDuckGoForm from '../duckduckgo-form'; import GenerateForm from '../generate-form'; import GoogleForm from '../google-form'; +import GoogleScholarForm from '../google-scholar-form'; import { useHandleFormValuesChange, useHandleNodeNameChange } from '../hooks'; import KeywordExtractForm from '../keyword-extract-form'; import MessageForm from '../message-form'; @@ -46,6 +47,7 @@ const FormMap = { [Operator.ArXiv]: ArXivForm, [Operator.Google]: GoogleForm, [Operator.Bing]: BingForm, + [Operator.GoogleScholar]: GoogleScholarForm, }; const EmptyContent = () =>
empty
; diff --git a/web/src/pages/flow/google-scholar-form/index.tsx b/web/src/pages/flow/google-scholar-form/index.tsx new file mode 100644 index 000000000..9dfa973b4 --- /dev/null +++ b/web/src/pages/flow/google-scholar-form/index.tsx @@ -0,0 +1,78 @@ +import TopNItem from '@/components/top-n-item'; +import { useTranslate } from '@/hooks/common-hooks'; +import { DatePicker, DatePickerProps, Form, Select, Switch } from 'antd'; +import dayjs from 'dayjs'; +import { useCallback, useMemo } from 'react'; +import { IOperatorForm } from '../interface'; + +const YearPicker = ({ + onChange, + value, +}: { + onChange?: (val: number | undefined) => void; + value?: number | undefined; +}) => { + const handleChange: DatePickerProps['onChange'] = useCallback( + (val: any) => { + const nextVal = val?.format('YYYY'); + onChange?.(nextVal ? Number(nextVal) : undefined); + }, + [onChange], + ); + // The year needs to be converted into a number and saved to the backend + const nextValue = useMemo(() => { + if (value) { + return dayjs(value.toString()); + } + return undefined; + }, [value]); + + return ; +}; + +const GoogleScholarForm = ({ onValuesChange, form }: IOperatorForm) => { + const { t } = useTranslate('flow'); + + const options = useMemo(() => { + return ['data', 'relevance'].map((x) => ({ + value: x, + label: t(x), + })); + }, [t]); + + return ( +
+ + + + + + + + + + + + + +
+ ); +}; + +export default GoogleScholarForm; diff --git a/web/src/pages/flow/hooks.ts b/web/src/pages/flow/hooks.ts index 46e407a4b..93709ff75 100644 --- a/web/src/pages/flow/hooks.ts +++ b/web/src/pages/flow/hooks.ts @@ -37,6 +37,7 @@ import { initialCategorizeValues, initialDuckValues, initialGenerateValues, + initialGoogleScholarValues, initialGoogleValues, initialKeywordExtractValues, initialMessageValues, @@ -97,6 +98,7 @@ export const useInitializeOperatorParams = () => { [Operator.ArXiv]: initialArXivValues, [Operator.Google]: initialGoogleValues, [Operator.Bing]: initialBingValues, + [Operator.GoogleScholar]: initialGoogleScholarValues, }; }, [llmId]);