diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/ActionsBar.tsx b/frontend/app/chat/[chatId]/components/ActionsBar/ActionsBar.tsx index d86fea2a2..6a4190633 100644 --- a/frontend/app/chat/[chatId]/components/ActionsBar/ActionsBar.tsx +++ b/frontend/app/chat/[chatId]/components/ActionsBar/ActionsBar.tsx @@ -1,14 +1,14 @@ -import { ChatInput, Feed } from "./components"; +import { ChatInput, KnowledgeToFeed } from "./components"; import { useActionBar } from "./hooks/useActionBar"; export const ActionsBar = (): JSX.Element => { const { isUploading, setIsUploading } = useActionBar(); return ( -
+
{isUploading && ( -
- setIsUploading(false)} /> +
+ setIsUploading(false)} />
)}
diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/Crawler/helpers/isValidUrl.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/Crawler/helpers/isValidUrl.ts deleted file mode 100644 index 3f86d1ad5..000000000 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/Crawler/helpers/isValidUrl.ts +++ /dev/null @@ -1,9 +0,0 @@ -export const isValidUrl = (string: string): boolean => { - try { - new URL(string); - - return true; - } catch (_) { - return false; - } -}; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/index.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/index.ts deleted file mode 100644 index 75b8a9a6f..000000000 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./Feed"; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/Feed.tsx b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/KnowledgeToFeed.tsx similarity index 62% rename from frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/Feed.tsx rename to frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/KnowledgeToFeed.tsx index 07833aa23..98131d306 100644 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/Feed.tsx +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/KnowledgeToFeed.tsx @@ -4,17 +4,20 @@ import { MdClose } from "react-icons/md"; import Button from "@/lib/components/ui/Button"; import { Divider } from "@/lib/components/ui/Divider"; +import { FeedItems } from "./components"; import { Crawler } from "./components/Crawler"; import { FileUploader } from "./components/FileUploader"; +import { useKnowledgeToFeed } from "./hooks/useKnowledgeToFeed"; type FeedProps = { onClose: () => void; }; -export const Feed = ({ onClose }: FeedProps): JSX.Element => { +export const KnowledgeToFeed = ({ onClose }: FeedProps): JSX.Element => { const { t } = useTranslation(["translation"]); + const { addContent, contents, removeContent } = useKnowledgeToFeed(); return ( -
+
- + +
); }; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/Crawler/helpers/isValidUrl.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/Crawler/helpers/isValidUrl.ts new file mode 100644 index 000000000..127afa53c --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/Crawler/helpers/isValidUrl.ts @@ -0,0 +1,13 @@ +export const isValidUrl = (urlString: string): boolean => { + const urlPattern = new RegExp( + "^(https?:\\/\\/)?" + // validate protocol + "((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // validate domain name + "((\\d{1,3}\\.){3}\\d{1,3}))" + // validate OR ip (v4) address + "(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*" + // validate port and path + "(\\?[;&a-z\\d%_.~+=-]*)?" + // validate query string + "(\\#[-a-z\\d_]*)?$", + "i" + ); // validate fragment locator + + return !!urlPattern.test(urlString); +}; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/Crawler/hooks/useCrawler.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/Crawler/hooks/useCrawler.ts new file mode 100644 index 000000000..ff828c182 --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/Crawler/hooks/useCrawler.ts @@ -0,0 +1,57 @@ +"use client"; +import { useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; + +import { useSupabase } from "@/lib/context/SupabaseProvider"; +import { useToast } from "@/lib/hooks"; +import { redirectToLogin } from "@/lib/router/redirectToLogin"; +import { useEventTracking } from "@/services/analytics/useEventTracking"; + +import { FeedItemType } from "../../../types"; +import { isValidUrl } from "../helpers/isValidUrl"; + +type UseCrawlerProps = { + addContent: (content: FeedItemType) => void; +}; + +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export const useCrawler = ({ addContent }: UseCrawlerProps) => { + const urlInputRef = useRef(null); + const { session } = useSupabase(); + const { publish } = useToast(); + const { t } = useTranslation(["translation", "upload"]); + const [urlToCrawl, setUrlToCrawl] = useState(""); + const { track } = useEventTracking(); + + if (session === null) { + redirectToLogin(); + } + + const handleSubmit = () => { + if (urlToCrawl === "") { + return; + } + if (!isValidUrl(urlToCrawl)) { + void track("URL_INVALID"); + publish({ + variant: "danger", + text: t("invalidUrl"), + }); + + return; + } + void track("URL_CRAWLED"); + addContent({ + source: "crawl", + url: urlToCrawl, + }); + setUrlToCrawl(""); + }; + + return { + urlInputRef, + urlToCrawl, + setUrlToCrawl, + handleSubmit, + }; +}; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/Crawler/index.tsx b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/Crawler/index.tsx new file mode 100644 index 000000000..b2a32e345 --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/Crawler/index.tsx @@ -0,0 +1,49 @@ +"use client"; +import { useTranslation } from "react-i18next"; +import { MdSend } from "react-icons/md"; + +import Button from "@/lib/components/ui/Button"; +import Field from "@/lib/components/ui/Field"; + +import { useCrawler } from "./hooks/useCrawler"; +import { FeedItemType } from "../../types"; + +type CrawlerProps = { + addContent: (content: FeedItemType) => void; +}; + +export const Crawler = ({ addContent }: CrawlerProps): JSX.Element => { + const { urlInputRef, urlToCrawl, handleSubmit, setUrlToCrawl } = useCrawler({ + addContent, + }); + const { t } = useTranslation(["translation", "upload"]); + + return ( +
+
+
{ + e.preventDefault(); + handleSubmit(); + }} + className="w-full" + > + setUrlToCrawl(e.target.value)} + icon={ + + } + /> + +
+
+ ); +}; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/FeedItems.tsx b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/FeedItems.tsx new file mode 100644 index 000000000..69559b209 --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/FeedItems.tsx @@ -0,0 +1,40 @@ +import { Fragment } from "react"; +import { IoMdCloseCircle } from "react-icons/io"; +import { MdLink } from "react-icons/md"; + +import { UrlDisplay } from "./components"; +import { FeedItemType } from "../../types"; + +type FeedItemsProps = { + contents: FeedItemType[]; + removeContent: (index: number) => void; +}; + +export const FeedItems = ({ + contents, + removeContent, +}: FeedItemsProps): JSX.Element => { + if (contents.length === 0) { + return ; + } + + return ( +
+ {contents.map((item, index) => ( +
+ removeContent(index)} + /> +
+ + +
+
+ ))} +
+ ); +}; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/components/UrlDisplay/UrlDisplay.tsx b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/components/UrlDisplay/UrlDisplay.tsx new file mode 100644 index 000000000..9030df065 --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/components/UrlDisplay/UrlDisplay.tsx @@ -0,0 +1,23 @@ +import { useState } from "react"; + +import { enhanceUrlDisplay } from "./utils/enhanceUrlDisplay"; + +type UrlDisplayProps = { + url: string; +}; + +export const UrlDisplay = ({ url }: UrlDisplayProps): JSX.Element => { + const [showFullUrl, setShowFullUrl] = useState(false); + + const toggleShowFullUrl = () => { + setShowFullUrl(!showFullUrl); + }; + + return ( +
+ + {showFullUrl ? url : enhanceUrlDisplay(url)} + +
+ ); +}; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/components/UrlDisplay/index.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/components/UrlDisplay/index.ts new file mode 100644 index 000000000..0632ac2eb --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/components/UrlDisplay/index.ts @@ -0,0 +1 @@ +export * from "./UrlDisplay"; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/components/UrlDisplay/utils/enhanceUrlDisplay.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/components/UrlDisplay/utils/enhanceUrlDisplay.ts new file mode 100644 index 000000000..ef491720f --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/components/UrlDisplay/utils/enhanceUrlDisplay.ts @@ -0,0 +1,24 @@ +export const enhanceUrlDisplay = (url: string): string => { + const parts = url.split("/"); + + // Check if the URL has at least 3 parts (protocol, domain, and one more segment) + if (parts.length >= 3) { + const domain = parts[2]; + const path = parts.slice(3).join("/"); + + // Split the domain by "." to check for subdomains and remove "www" + const domainParts = domain.split("."); + if (domainParts[0] === "www") { + domainParts.shift(); // Remove "www" + } + + // Combine the beginning (subdomain/domain) and the end (trimmed path) + const beginning = domainParts.join("."); + const trimmedPath = path.slice(0, 5) + "..." + path.slice(-5); // Display the beginning and end of the path + + return `${beginning}/${trimmedPath}`; + } + + // If the URL doesn't have enough parts, return it as is + return url; +}; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/components/index.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/components/index.ts new file mode 100644 index 000000000..0632ac2eb --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/components/index.ts @@ -0,0 +1 @@ +export * from "./UrlDisplay"; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/index.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/index.ts new file mode 100644 index 000000000..0096f92ff --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FeedItems/index.ts @@ -0,0 +1 @@ +export * from "./FeedItems"; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/FileUploader/components/FileComponent.tsx b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FileUploader/components/FileComponent.tsx similarity index 100% rename from frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/FileUploader/components/FileComponent.tsx rename to frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FileUploader/components/FileComponent.tsx diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/FileUploader/hooks/useFileUploader.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FileUploader/hooks/useFileUploader.ts similarity index 100% rename from frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/FileUploader/hooks/useFileUploader.ts rename to frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FileUploader/hooks/useFileUploader.ts diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/FileUploader/index.tsx b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FileUploader/index.tsx similarity index 100% rename from frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/FileUploader/index.tsx rename to frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/FileUploader/index.tsx diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/index.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/index.ts similarity index 67% rename from frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/index.ts rename to frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/index.ts index 79b22de10..f2d053e24 100644 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/index.ts +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/index.ts @@ -1,2 +1,3 @@ export * from "./Crawler"; +export * from "./FeedItems"; export * from "./FileUploader"; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/hooks/useKnowledgeToFeed.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/hooks/useKnowledgeToFeed.ts new file mode 100644 index 000000000..7f5ea8b9d --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/hooks/useKnowledgeToFeed.ts @@ -0,0 +1,22 @@ +import { useState } from "react"; + +import { FeedItemType } from "../types"; + +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +export const useKnowledgeToFeed = () => { + const [contents, setContents] = useState([]); + + const addContent = (content: FeedItemType) => { + setContents((prevContents) => [...prevContents, content]); + }; + const removeContent = (index: number) => { + setContents((prevContents) => prevContents.filter((_, i) => i !== index)); + }; + + return { + addContent, + contents, + setContents, + removeContent, + }; +}; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/index.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/index.ts new file mode 100644 index 000000000..87c3aadd3 --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/index.ts @@ -0,0 +1 @@ +export * from "./KnowledgeToFeed"; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/types.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/types.ts new file mode 100644 index 000000000..0e348b9c8 --- /dev/null +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/types.ts @@ -0,0 +1,6 @@ +export type FeedItemSource = "crawl" | "upload"; + +export type FeedItemType = { + source: FeedItemSource; + url: string; +}; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/index.ts b/frontend/app/chat/[chatId]/components/ActionsBar/components/index.ts index 22d6149ec..77e5a4298 100644 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/index.ts +++ b/frontend/app/chat/[chatId]/components/ActionsBar/components/index.ts @@ -1,2 +1,2 @@ export * from "./ChatInput"; -export * from "./Feed"; +export * from "./KnowledgeToFeed"; diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/Crawler/hooks/useCrawler.ts b/frontend/app/upload/Crawler/hooks/useCrawler.ts similarity index 94% rename from frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/Crawler/hooks/useCrawler.ts rename to frontend/app/upload/Crawler/hooks/useCrawler.ts index e8da84e48..c93b6d47b 100644 --- a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/Crawler/hooks/useCrawler.ts +++ b/frontend/app/upload/Crawler/hooks/useCrawler.ts @@ -3,14 +3,13 @@ import { UUID } from "crypto"; import { useCallback, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; +import { isValidUrl } from "@/app/chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components/Crawler/helpers/isValidUrl"; import { useCrawlApi } from "@/lib/api/crawl/useCrawlApi"; import { useSupabase } from "@/lib/context/SupabaseProvider"; import { useToast } from "@/lib/hooks"; import { redirectToLogin } from "@/lib/router/redirectToLogin"; import { useEventTracking } from "@/services/analytics/useEventTracking"; -import { isValidUrl } from "../helpers/isValidUrl"; - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export const useCrawler = () => { const [isCrawling, setCrawling] = useState(false); diff --git a/frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/Crawler/index.tsx b/frontend/app/upload/Crawler/index.tsx similarity index 100% rename from frontend/app/chat/[chatId]/components/ActionsBar/components/Feed/components/Crawler/index.tsx rename to frontend/app/upload/Crawler/index.tsx diff --git a/frontend/app/upload/page.tsx b/frontend/app/upload/page.tsx index d36bebd55..8d6315da2 100644 --- a/frontend/app/upload/page.tsx +++ b/frontend/app/upload/page.tsx @@ -9,11 +9,9 @@ import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainConte import { useSupabase } from "@/lib/context/SupabaseProvider"; import { redirectToLogin } from "@/lib/router/redirectToLogin"; +import { Crawler } from "./Crawler"; import { requiredRolesForUpload } from "./config"; -import { - Crawler, - FileUploader, -} from "../chat/[chatId]/components/ActionsBar/components/Feed/components"; +import { FileUploader } from "../chat/[chatId]/components/ActionsBar/components/KnowledgeToFeed/components"; const UploadPage = (): JSX.Element => { const { currentBrain } = useBrainContext(); diff --git a/frontend/lib/components/ui/Field.tsx b/frontend/lib/components/ui/Field.tsx index 669c9e139..3187a642e 100644 --- a/frontend/lib/components/ui/Field.tsx +++ b/frontend/lib/components/ui/Field.tsx @@ -1,4 +1,3 @@ -/* eslint-disable */ import { DetailedHTMLProps, forwardRef, @@ -15,28 +14,36 @@ interface FieldProps > { label?: string; name: string; + icon?: React.ReactNode; } const Field = forwardRef( ( - { label, className, name, required = false, ...props }: FieldProps, + { label, className, name, required = false, icon, ...props }: FieldProps, forwardedRef ) => { return (
- {label && ( + {label !== undefined && ( )} - } - className="w-full bg-gray-50 dark:bg-gray-900 px-4 py-2 border rounded-md border-black/10 dark:border-white/25" - name={name} - id={name} - {...props} - /> +
+ } + className={`w-full bg-gray-50 dark:bg-gray-900 px-4 py-2 border rounded-md border-black/10 dark:border-white/25`} + name={name} + id={name} + {...props} + /> + {icon !== undefined && ( +
+ {icon} +
+ )} +
); } diff --git a/frontend/public/locales/en/translation.json b/frontend/public/locales/en/translation.json index d68e6a2c8..d74f9f14a 100644 --- a/frontend/public/locales/en/translation.json +++ b/frontend/public/locales/en/translation.json @@ -27,7 +27,6 @@ "updateButton": "Update", "uploadButton": "Upload", "uploadingButton": "Uploading...", - "crawlButton": "Crawl", "chatButton": "Chat", "deleteButton": "Delete", "deleteForeverButton": "Delete forever", @@ -44,5 +43,7 @@ "Viewer": "Viewer", "Editor": "Editor", "Owner": "Owner", - "saveButton": "Save" + "saveButton": "Save", + "invalidUrl": "Invalid URL", + "crawlButton": "Crawl" } diff --git a/frontend/public/locales/es/translation.json b/frontend/public/locales/es/translation.json index 49e7ad223..9c38a844d 100644 --- a/frontend/public/locales/es/translation.json +++ b/frontend/public/locales/es/translation.json @@ -4,7 +4,6 @@ "Chat": "Conversar", "chatButton": "Conversar", "comingSoon": "Próximamente", - "crawlButton": "Rastrear", "createButton": "Crear", "deleteButton": "Borrar", "deleteForeverButton": "Borrar para siempre", @@ -44,5 +43,7 @@ "uploadButton": "Subir", "uploadingButton": "Subiendo...", "Viewer": "Espectador", - "saveButton": "Guardar" + "saveButton": "Guardar", + "invalidUrl": "URL inválida", + "crawlButton": "Rastrear" } diff --git a/frontend/public/locales/fr/translation.json b/frontend/public/locales/fr/translation.json index 14d41c1c8..0f17c2eed 100644 --- a/frontend/public/locales/fr/translation.json +++ b/frontend/public/locales/fr/translation.json @@ -27,7 +27,6 @@ "updateButton": "Mettre à jour", "uploadButton": "Télécharger", "uploadingButton": "Téléchargement...", - "crawlButton": "Explorer", "chatButton": "Chat", "deleteButton": "Supprimer", "deleteForeverButton": "Supprimer définitivement", @@ -44,5 +43,7 @@ "Viewer": "Visualiseur", "Editor": "Éditeur", "Owner": "Propriétaire", - "saveButton": "Sauvegarder" + "saveButton": "Sauvegarder", + "invalidUrl": "URL invalide", + "crawlButton": "Crawler" } diff --git a/frontend/public/locales/pt-br/translation.json b/frontend/public/locales/pt-br/translation.json index a3f7563f1..213d926f8 100644 --- a/frontend/public/locales/pt-br/translation.json +++ b/frontend/public/locales/pt-br/translation.json @@ -27,7 +27,6 @@ "updateButton": "Atualizar", "uploadButton": "Enviar", "uploadingButton": "Enviando...", - "crawlButton": "Rastrear", "chatButton": "Chat", "deleteButton": "Excluir", "deleteForeverButton": "Excluir permanentemente", @@ -44,5 +43,7 @@ "Viewer": "Visualizador", "Editor": "Editor", "Owner": "Proprietário", - "saveButton": "Salvar" + "saveButton": "Salvar", + "invalidUrl": "URL inválida", + "crawlButton": "Rastrear" } diff --git a/frontend/public/locales/ru/translation.json b/frontend/public/locales/ru/translation.json index c0fe5de26..bf2a26ab3 100644 --- a/frontend/public/locales/ru/translation.json +++ b/frontend/public/locales/ru/translation.json @@ -27,7 +27,6 @@ "updateButton": "Обновить", "uploadButton": "Загрузить", "uploadingButton": "Загрузка...", - "crawlButton": "Извлечь информацию", "chatButton": "Чат", "deleteButton": "Удалить", "deleteForeverButton": "Удалить навсегда", @@ -44,5 +43,7 @@ "Viewer": "Просмотр", "Editor": "Редактор", "Owner": "Владелец", - "saveButton": "Сохранить" + "saveButton": "Сохранить", + "invalidUrl": "Неверный URL", + "crawlButton": "Поиск" } diff --git a/frontend/public/locales/zh-cn/translation.json b/frontend/public/locales/zh-cn/translation.json index e07afd6de..eb0096a96 100644 --- a/frontend/public/locales/zh-cn/translation.json +++ b/frontend/public/locales/zh-cn/translation.json @@ -27,7 +27,6 @@ "updateButton": "更新", "uploadButton": "上传", "uploadingButton": "上传中...", - "crawlButton": "抓取", "chatButton": "聊天", "deleteButton": "删除", "deleteForeverButton": "永久删除", @@ -44,5 +43,7 @@ "Viewer": "查看", "Editor": "编辑", "Owner": "作者", - "saveButton": "保存" + "saveButton": "保存", + "invalidUrl": "无效的URL", + "crawlButton": "爬取" }