Merge branch 'main' into feat-agent-mask

This commit is contained in:
GuanMu 2025-11-05 19:47:49 +08:00 committed by GitHub
commit 2ce31ff07d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
41 changed files with 202 additions and 644 deletions

View File

@ -1601,7 +1601,7 @@ def transform_datasource_credentials():
"integration_secret": api_key,
}
datasource_provider = DatasourceProvider(
provider="jina",
provider="jinareader",
tenant_id=tenant_id,
plugin_id=jina_plugin_id,
auth_type=api_key_credential_type.value,

View File

@ -22,6 +22,11 @@ class WeaviateConfig(BaseSettings):
default=True,
)
WEAVIATE_GRPC_ENDPOINT: str | None = Field(
description="URL of the Weaviate gRPC server (e.g., 'grpc://localhost:50051' or 'grpcs://weaviate.example.com:443')",
default=None,
)
WEAVIATE_BATCH_SIZE: PositiveInt = Field(
description="Number of objects to be processed in a single batch operation (default is 100)",
default=100,

View File

@ -102,7 +102,18 @@ class DraftWorkflowApi(Resource):
},
)
)
@api.response(200, "Draft workflow synced successfully", workflow_fields)
@api.response(
200,
"Draft workflow synced successfully",
api.model(
"SyncDraftWorkflowResponse",
{
"result": fields.String,
"hash": fields.String,
"updated_at": fields.String,
},
),
)
@api.response(400, "Invalid workflow configuration")
@api.response(403, "Permission denied")
@edit_permission_required

View File

@ -67,6 +67,7 @@ def validate_app_token(view: Callable[P, R] | None = None, *, fetch_user_arg: Fe
kwargs["app_model"] = app_model
# If caller needs end-user context, attach EndUser to current_user
if fetch_user_arg:
if fetch_user_arg.fetch_from == WhereisUserArg.QUERY:
user_id = request.args.get("user")
@ -75,7 +76,6 @@ def validate_app_token(view: Callable[P, R] | None = None, *, fetch_user_arg: Fe
elif fetch_user_arg.fetch_from == WhereisUserArg.FORM:
user_id = request.form.get("user")
else:
# use default-user
user_id = None
if not user_id and fetch_user_arg.required:
@ -90,6 +90,28 @@ def validate_app_token(view: Callable[P, R] | None = None, *, fetch_user_arg: Fe
# Set EndUser as current logged-in user for flask_login.current_user
current_app.login_manager._update_request_context_with_user(end_user) # type: ignore
user_logged_in.send(current_app._get_current_object(), user=end_user) # type: ignore
else:
# For service API without end-user context, ensure an Account is logged in
# so services relying on current_account_with_tenant() work correctly.
tenant_owner_info = (
db.session.query(Tenant, Account)
.join(TenantAccountJoin, Tenant.id == TenantAccountJoin.tenant_id)
.join(Account, TenantAccountJoin.account_id == Account.id)
.where(
Tenant.id == app_model.tenant_id,
TenantAccountJoin.role == "owner",
Tenant.status == TenantStatus.NORMAL,
)
.one_or_none()
)
if tenant_owner_info:
tenant_model, account = tenant_owner_info
account.current_tenant = tenant_model
current_app.login_manager._update_request_context_with_user(account) # type: ignore
user_logged_in.send(current_app._get_current_object(), user=current_user) # type: ignore
else:
raise Unauthorized("Tenant owner account not found or tenant is not active.")
return view_func(*args, **kwargs)

View File

@ -6,10 +6,7 @@ from core.helper.code_executor.template_transformer import TemplateTransformer
class NodeJsTemplateTransformer(TemplateTransformer):
@classmethod
def get_runner_script(cls) -> str:
runner_script = dedent(
f"""
// declare main function
{cls._code_placeholder}
runner_script = dedent(f""" {cls._code_placeholder}
// decode and prepare input object
var inputs_obj = JSON.parse(Buffer.from('{cls._inputs_placeholder}', 'base64').toString('utf-8'))
@ -21,6 +18,5 @@ class NodeJsTemplateTransformer(TemplateTransformer):
var output_json = JSON.stringify(output_obj)
var result = `<<RESULT>>${{output_json}}<<RESULT>>`
console.log(result)
"""
)
""")
return runner_script

View File

@ -6,9 +6,7 @@ from core.helper.code_executor.template_transformer import TemplateTransformer
class Python3TemplateTransformer(TemplateTransformer):
@classmethod
def get_runner_script(cls) -> str:
runner_script = dedent(f"""
# declare main function
{cls._code_placeholder}
runner_script = dedent(f""" {cls._code_placeholder}
import json
from base64 import b64decode

View File

@ -39,11 +39,13 @@ class WeaviateConfig(BaseModel):
Attributes:
endpoint: Weaviate server endpoint URL
grpc_endpoint: Optional Weaviate gRPC server endpoint URL
api_key: Optional API key for authentication
batch_size: Number of objects to batch per insert operation
"""
endpoint: str
grpc_endpoint: str | None = None
api_key: str | None = None
batch_size: int = 100
@ -88,9 +90,22 @@ class WeaviateVector(BaseVector):
http_secure = p.scheme == "https"
http_port = p.port or (443 if http_secure else 80)
grpc_host = host
grpc_secure = http_secure
grpc_port = 443 if grpc_secure else 50051
# Parse gRPC configuration
if config.grpc_endpoint:
# Urls without scheme won't be parsed correctly in some python verions,
# see https://bugs.python.org/issue27657
grpc_endpoint_with_scheme = (
config.grpc_endpoint if "://" in config.grpc_endpoint else f"grpc://{config.grpc_endpoint}"
)
grpc_p = urlparse(grpc_endpoint_with_scheme)
grpc_host = grpc_p.hostname or "localhost"
grpc_port = grpc_p.port or (443 if grpc_p.scheme == "grpcs" else 50051)
grpc_secure = grpc_p.scheme == "grpcs"
else:
# Infer from HTTP endpoint as fallback
grpc_host = host
grpc_secure = http_secure
grpc_port = 443 if grpc_secure else 50051
client = weaviate.connect_to_custom(
http_host=host,
@ -432,6 +447,7 @@ class WeaviateVectorFactory(AbstractVectorFactory):
collection_name=collection_name,
config=WeaviateConfig(
endpoint=dify_config.WEAVIATE_ENDPOINT or "",
grpc_endpoint=dify_config.WEAVIATE_GRPC_ENDPOINT or "",
api_key=dify_config.WEAVIATE_API_KEY,
batch_size=dify_config.WEAVIATE_BATCH_SIZE,
),

View File

@ -0,0 +1,12 @@
from core.helper.code_executor.javascript.javascript_code_provider import JavascriptCodeProvider
from core.helper.code_executor.javascript.javascript_transformer import NodeJsTemplateTransformer
def test_get_runner_script():
code = JavascriptCodeProvider.get_default_code()
inputs = {"arg1": "hello, ", "arg2": "world!"}
script = NodeJsTemplateTransformer.assemble_runner_script(code, inputs)
script_lines = script.splitlines()
code_lines = code.splitlines()
# Check that the first lines of script are exactly the same as code
assert script_lines[: len(code_lines)] == code_lines

View File

@ -0,0 +1,12 @@
from core.helper.code_executor.python3.python3_code_provider import Python3CodeProvider
from core.helper.code_executor.python3.python3_transformer import Python3TemplateTransformer
def test_get_runner_script():
code = Python3CodeProvider.get_default_code()
inputs = {"arg1": "hello, ", "arg2": "world!"}
script = Python3TemplateTransformer.assemble_runner_script(code, inputs)
script_lines = script.splitlines()
code_lines = code.splitlines()
# Check that the first lines of script are exactly the same as code
assert script_lines[: len(code_lines)] == code_lines

View File

@ -492,6 +492,7 @@ VECTOR_INDEX_NAME_PREFIX=Vector_index
# The Weaviate endpoint URL. Only available when VECTOR_STORE is `weaviate`.
WEAVIATE_ENDPOINT=http://weaviate:8080
WEAVIATE_API_KEY=WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih
WEAVIATE_GRPC_ENDPOINT=grpc://weaviate:50051
# The Qdrant endpoint URL. Only available when VECTOR_STORE is `qdrant`.
QDRANT_URL=http://qdrant:6333

View File

@ -157,6 +157,7 @@ x-shared-env: &shared-api-worker-env
VECTOR_INDEX_NAME_PREFIX: ${VECTOR_INDEX_NAME_PREFIX:-Vector_index}
WEAVIATE_ENDPOINT: ${WEAVIATE_ENDPOINT:-http://weaviate:8080}
WEAVIATE_API_KEY: ${WEAVIATE_API_KEY:-WVF5YThaHlkYwhGUSmCRgsX3tD5ngdN8pkih}
WEAVIATE_GRPC_ENDPOINT: ${WEAVIATE_GRPC_ENDPOINT:-grpc://weaviate:50051}
QDRANT_URL: ${QDRANT_URL:-http://qdrant:6333}
QDRANT_API_KEY: ${QDRANT_API_KEY:-difyai123456}
QDRANT_CLIENT_TIMEOUT: ${QDRANT_CLIENT_TIMEOUT:-20}

View File

@ -4,27 +4,27 @@ import { RiFeedbackLine } from '@remixicon/react'
import i18n from '@/i18n-config/i18next-config'
import { registerCommands, unregisterCommands } from './command-bus'
// Feedback command dependency types
type FeedbackDeps = Record<string, never>
// Forum command dependency types
type ForumDeps = Record<string, never>
/**
* Feedback command - Opens GitHub feedback discussions
* Forum command - Opens Dify community forum
*/
export const feedbackCommand: SlashCommandHandler<FeedbackDeps> = {
name: 'feedback',
description: 'Open feedback discussions',
export const forumCommand: SlashCommandHandler<ForumDeps> = {
name: 'forum',
description: 'Open Dify community forum',
mode: 'direct',
// Direct execution function
execute: () => {
const url = 'https://github.com/langgenius/dify/discussions/categories/feedbacks'
const url = 'https://forum.dify.ai'
window.open(url, '_blank', 'noopener,noreferrer')
},
async search(args: string, locale: string = 'en') {
return [{
id: 'feedback',
title: i18n.t('common.userProfile.communityFeedback', { lng: locale }),
id: 'forum',
title: i18n.t('common.userProfile.forum', { lng: locale }),
description: i18n.t('app.gotoAnything.actions.feedbackDesc', { lng: locale }) || 'Open community feedback discussions',
type: 'command' as const,
icon: (
@ -32,20 +32,20 @@ export const feedbackCommand: SlashCommandHandler<FeedbackDeps> = {
<RiFeedbackLine className='h-4 w-4 text-text-tertiary' />
</div>
),
data: { command: 'navigation.feedback', args: { url: 'https://github.com/langgenius/dify/discussions/categories/feedbacks' } },
data: { command: 'navigation.forum', args: { url: 'https://forum.dify.ai' } },
}]
},
register(_deps: FeedbackDeps) {
register(_deps: ForumDeps) {
registerCommands({
'navigation.feedback': async (args) => {
const url = args?.url || 'https://github.com/langgenius/dify/discussions/categories/feedbacks'
'navigation.forum': async (args) => {
const url = args?.url || 'https://forum.dify.ai'
window.open(url, '_blank', 'noopener,noreferrer')
},
})
},
unregister() {
unregisterCommands(['navigation.feedback'])
unregisterCommands(['navigation.forum'])
},
}

View File

@ -7,7 +7,7 @@ import { useTheme } from 'next-themes'
import { setLocaleOnClient } from '@/i18n-config'
import { themeCommand } from './theme'
import { languageCommand } from './language'
import { feedbackCommand } from './feedback'
import { forumCommand } from './forum'
import { docsCommand } from './docs'
import { communityCommand } from './community'
import { accountCommand } from './account'
@ -34,7 +34,7 @@ export const registerSlashCommands = (deps: Record<string, any>) => {
// Register command handlers to the registry system with their respective dependencies
slashCommandRegistry.register(themeCommand, { setTheme: deps.setTheme })
slashCommandRegistry.register(languageCommand, { setLocale: deps.setLocale })
slashCommandRegistry.register(feedbackCommand, {})
slashCommandRegistry.register(forumCommand, {})
slashCommandRegistry.register(docsCommand, {})
slashCommandRegistry.register(communityCommand, {})
slashCommandRegistry.register(accountCommand, {})
@ -44,7 +44,7 @@ export const unregisterSlashCommands = () => {
// Remove command handlers from registry system (automatically calls each command's unregister method)
slashCommandRegistry.unregister('theme')
slashCommandRegistry.unregister('language')
slashCommandRegistry.unregister('feedback')
slashCommandRegistry.unregister('forum')
slashCommandRegistry.unregister('docs')
slashCommandRegistry.unregister('community')
slashCommandRegistry.unregister('account')

View File

@ -1,5 +1,5 @@
import { Menu, MenuButton, MenuItem, MenuItems, Transition } from '@headlessui/react'
import { RiArrowRightSLine, RiArrowRightUpLine, RiChatSmile2Line, RiDiscordLine, RiFeedbackLine, RiMailSendLine, RiQuestionLine } from '@remixicon/react'
import { RiArrowRightSLine, RiArrowRightUpLine, RiChatSmile2Line, RiDiscordLine, RiDiscussLine, RiMailSendLine, RiQuestionLine } from '@remixicon/react'
import { Fragment } from 'react'
import Link from 'next/link'
import { useTranslation } from 'react-i18next'
@ -86,10 +86,10 @@ export default function Support({ closeAccountDropdown }: SupportProps) {
className={cn(itemClassName, 'group justify-between',
'data-[active]:bg-state-base-hover',
)}
href='https://github.com/langgenius/dify/discussions/categories/feedbacks'
href='https://forum.dify.ai/'
target='_blank' rel='noopener noreferrer'>
<RiFeedbackLine className='size-4 shrink-0 text-text-tertiary' />
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.communityFeedback')}</div>
<RiDiscussLine className='size-4 shrink-0 text-text-tertiary' />
<div className='system-md-regular grow px-1 text-text-secondary'>{t('common.userProfile.forum')}</div>
<RiArrowRightUpLine className='size-[14px] shrink-0 text-text-tertiary' />
</Link>
</MenuItem>

View File

@ -106,7 +106,7 @@ const StatusPanel: FC<ResultProps> = ({
{status === 'failed' && error && (
<>
<div className='my-2 h-[0.5px] bg-divider-subtle'/>
<div className='system-xs-regular text-text-destructive'>{error}</div>
<div className='system-xs-regular whitespace-pre-wrap text-text-destructive'>{error}</div>
{
!!exceptionCounts && (
<>

View File

@ -161,7 +161,6 @@ const translation = {
workspace: 'Arbeitsbereich',
createWorkspace: 'Arbeitsbereich erstellen',
helpCenter: 'Hilfe',
communityFeedback: 'Rückmeldung',
roadmap: 'Fahrplan',
community: 'Gemeinschaft',
about: 'Über',
@ -170,6 +169,7 @@ const translation = {
support: 'Unterstützung',
github: 'GitHub',
contactUs: 'Kontaktieren Sie uns',
forum: 'Forum',
},
settings: {
accountGroup: 'KONTO',
@ -726,6 +726,7 @@ const translation = {
uploadFromComputerLimit: 'Datei hochladen darf {{size}} nicht überschreiten',
uploadFromComputerReadError: 'Lesen der Datei fehlgeschlagen, bitte versuchen Sie es erneut.',
fileExtensionNotSupport: 'Dateiendung nicht bedient',
fileExtensionBlocked: 'Dieser Dateityp ist aus Sicherheitsgründen gesperrt',
},
license: {
expiring: 'Läuft an einem Tag ab',

View File

@ -177,7 +177,7 @@ const translation = {
helpCenter: 'Docs',
support: 'Support',
compliance: 'Compliance',
communityFeedback: 'Feedback',
forum: 'Forum',
roadmap: 'Roadmap',
github: 'GitHub',
community: 'Community',

View File

@ -165,7 +165,6 @@ const translation = {
workspace: 'Espacio de trabajo',
createWorkspace: 'Crear espacio de trabajo',
helpCenter: 'Ayuda',
communityFeedback: 'Comentarios',
roadmap: 'Hoja de ruta',
community: 'Comunidad',
about: 'Acerca de',
@ -174,6 +173,7 @@ const translation = {
compliance: 'Cumplimiento',
github: 'GitHub',
contactUs: 'Contáctenos',
forum: 'Foro',
},
settings: {
accountGroup: 'CUENTA',
@ -726,6 +726,7 @@ const translation = {
fileExtensionNotSupport: 'Extensión de archivo no compatible',
pasteFileLinkInputPlaceholder: 'Introduzca la URL...',
uploadFromComputerLimit: 'El archivo de carga no puede exceder {{size}}',
fileExtensionBlocked: 'Este tipo de archivo está bloqueado por motivos de seguridad',
},
license: {
expiring: 'Caduca en un día',

View File

@ -165,7 +165,6 @@ const translation = {
workspace: 'فضای کاری',
createWorkspace: 'ایجاد فضای کاری',
helpCenter: 'راهنما',
communityFeedback: 'بازخورد',
roadmap: 'نقشه راه',
community: 'انجمن',
about: 'درباره',
@ -174,6 +173,7 @@ const translation = {
compliance: 'انطباق',
support: 'پشتیبانی',
contactUs: 'با ما تماس بگیرید',
forum: 'انجمن',
},
settings: {
accountGroup: 'حساب کاربری',
@ -726,6 +726,7 @@ const translation = {
uploadFromComputerUploadError: 'آپلود فایل انجام نشد، لطفا دوباره آپلود کنید.',
pasteFileLink: 'پیوند فایل را جایگذاری کنید',
uploadFromComputerLimit: 'آپلود فایل نمی تواند از {{size}} تجاوز کند',
fileExtensionBlocked: 'این نوع فایل به دلایل امنیتی مسدود شده است',
},
license: {
expiring_plural: 'انقضا در {{count}} روز',

View File

@ -161,7 +161,6 @@ const translation = {
workspace: 'Espace de travail',
createWorkspace: 'Créer un Espace de Travail',
helpCenter: 'Aide',
communityFeedback: 'Retour d\'information',
roadmap: 'Feuille de route',
community: 'Communauté',
about: 'À propos',
@ -170,6 +169,7 @@ const translation = {
github: 'GitHub',
compliance: 'Conformité',
contactUs: 'Contactez-nous',
forum: 'Forum',
},
settings: {
accountGroup: 'COMPTE',
@ -727,6 +727,7 @@ const translation = {
fileExtensionNotSupport: 'Extension de fichier non prise en charge',
pasteFileLinkInvalid: 'Lien de fichier non valide',
uploadFromComputerLimit: 'Le fichier de téléchargement ne peut pas dépasser {{size}}',
fileExtensionBlocked: 'Ce type de fichier est bloqué pour des raisons de sécurité',
},
license: {
expiring: 'Expirant dans un jour',

View File

@ -170,7 +170,6 @@ const translation = {
workspace: 'वर्कस्पेस',
createWorkspace: 'वर्कस्पेस बनाएं',
helpCenter: 'सहायता',
communityFeedback: 'प्रतिक्रिया',
roadmap: 'रोडमैप',
community: 'समुदाय',
about: 'के बारे में',
@ -179,6 +178,7 @@ const translation = {
github: 'गिटहब',
support: 'समर्थन',
contactUs: 'संपर्क करें',
forum: 'फोरम',
},
settings: {
accountGroup: 'खाता',
@ -748,6 +748,7 @@ const translation = {
pasteFileLink: 'फ़ाइल लिंक पेस्ट करें',
fileExtensionNotSupport: 'फ़ाइल एक्सटेंशन समर्थित नहीं है',
uploadFromComputer: 'स्थानीय अपलोड',
fileExtensionBlocked: 'सुरक्षा कारणों से इस फ़ाइल प्रकार को अवरुद्ध कर दिया गया है',
},
license: {
expiring: 'एक दिन में समाप्त हो रहा है',

View File

@ -163,7 +163,6 @@ const translation = {
helpCenter: 'Docs',
compliance: 'Kepatuhan',
community: 'Masyarakat',
communityFeedback: 'Umpan balik',
roadmap: 'Peta jalan',
logout: 'Keluar',
settings: 'Pengaturan',
@ -173,6 +172,7 @@ const translation = {
workspace: 'Workspace',
createWorkspace: 'Membuat Ruang Kerja',
contactUs: 'Hubungi Kami',
forum: 'Forum',
},
compliance: {
soc2Type2: 'Laporan SOC 2 Tipe II',
@ -701,6 +701,7 @@ const translation = {
pasteFileLinkInvalid: 'Tautan file tidak valid',
pasteFileLinkInputPlaceholder: 'Masukkan URL...',
uploadFromComputerReadError: 'Pembacaan file gagal, silakan coba lagi.',
fileExtensionBlocked: 'Tipe file ini diblokir karena alasan keamanan',
},
tag: {
noTag: 'Tidak ada tag',

View File

@ -170,7 +170,6 @@ const translation = {
workspace: 'Workspace',
createWorkspace: 'Crea Workspace',
helpCenter: 'Aiuto',
communityFeedback: 'Feedback',
roadmap: 'Tabella di marcia',
community: 'Comunità',
about: 'Informazioni',
@ -179,6 +178,7 @@ const translation = {
compliance: 'Conformità',
github: 'GitHub',
contactUs: 'Contattaci',
forum: 'Forum',
},
settings: {
accountGroup: 'ACCOUNT',
@ -756,6 +756,7 @@ const translation = {
uploadFromComputerUploadError: 'Caricamento del file non riuscito, carica di nuovo.',
pasteFileLink: 'Incolla il collegamento del file',
uploadFromComputerReadError: 'Lettura del file non riuscita, riprovare.',
fileExtensionBlocked: 'Questo tipo di file è bloccato per motivi di sicurezza',
},
license: {
expiring_plural: 'Scadenza tra {{count}} giorni',

View File

@ -173,13 +173,13 @@ const translation = {
helpCenter: 'ヘルプ',
support: 'サポート',
compliance: 'コンプライアンス',
communityFeedback: 'フィードバック',
roadmap: 'ロードマップ',
community: 'コミュニティ',
about: 'Dify について',
logout: 'ログアウト',
github: 'GitHub',
contactUs: 'お問い合わせ',
forum: 'フォーラム',
},
compliance: {
soc2Type1: 'SOC 2 Type I 報告書',
@ -740,6 +740,7 @@ const translation = {
uploadFromComputerReadError: 'ファイルの読み取りに失敗しました。もう一度やり直してください。',
fileExtensionNotSupport: 'ファイル拡張子はサポートされていません',
pasteFileLinkInvalid: '無効なファイルリンク',
fileExtensionBlocked: 'このファイルタイプは、セキュリティ上の理由でブロックされています',
},
license: {
expiring_plural: '有効期限 {{count}} 日',

View File

@ -157,7 +157,6 @@ const translation = {
workspace: '작업 공간',
createWorkspace: '작업 공간 만들기',
helpCenter: '도움말 센터',
communityFeedback: '로드맵 및 피드백',
roadmap: '로드맵',
community: '커뮤니티',
about: 'Dify 소개',
@ -166,6 +165,7 @@ const translation = {
compliance: '컴플라이언스',
support: '지원',
contactUs: '문의하기',
forum: '포럼',
},
settings: {
accountGroup: '계정',
@ -722,6 +722,7 @@ const translation = {
fileExtensionNotSupport: '지원되지 않는 파일 확장자',
uploadFromComputerLimit: '업로드 파일은 {{size}}를 초과할 수 없습니다.',
uploadFromComputerUploadError: '파일 업로드에 실패했습니다. 다시 업로드하십시오.',
fileExtensionBlocked: '보안상의 이유로 이 파일 형식은 차단되었습니다',
},
license: {
expiring_plural: '{{count}}일 후에 만료',

View File

@ -166,7 +166,6 @@ const translation = {
workspace: 'Przestrzeń robocza',
createWorkspace: 'Utwórz przestrzeń roboczą',
helpCenter: 'Pomoc',
communityFeedback: 'Opinie',
roadmap: 'Plan działania',
community: 'Społeczność',
about: 'O',
@ -175,6 +174,7 @@ const translation = {
github: 'GitHub',
compliance: 'Zgodność',
contactUs: 'Skontaktuj się z nami',
forum: 'Forum',
},
settings: {
accountGroup: 'KONTO',
@ -744,6 +744,7 @@ const translation = {
uploadFromComputerReadError: 'Odczyt pliku nie powiódł się, spróbuj ponownie.',
fileExtensionNotSupport: 'Rozszerzenie pliku nie jest obsługiwane',
uploadFromComputer: 'Przesyłanie lokalne',
fileExtensionBlocked: 'Ten typ pliku jest zablokowany ze względów bezpieczeństwa',
},
license: {
expiring_plural: 'Wygasa za {{count}} dni',

View File

@ -161,7 +161,6 @@ const translation = {
workspace: 'Espaço de trabalho',
createWorkspace: 'Criar Espaço de Trabalho',
helpCenter: 'Ajuda',
communityFeedback: 'Feedback',
roadmap: 'Roteiro',
community: 'Comunidade',
about: 'Sobre',
@ -170,6 +169,7 @@ const translation = {
support: 'Suporte',
compliance: 'Conformidade',
contactUs: 'Contate-Nos',
forum: 'Fórum',
},
settings: {
accountGroup: 'CONTA',
@ -726,6 +726,7 @@ const translation = {
uploadFromComputerReadError: 'Falha na leitura do arquivo, tente novamente.',
uploadFromComputerLimit: 'Carregar arquivo não pode exceder {{size}}',
uploadFromComputerUploadError: 'Falha no upload do arquivo, faça o upload novamente.',
fileExtensionBlocked: 'Este tipo de arquivo está bloqueado por razões de segurança',
},
license: {
expiring: 'Expirando em um dia',

View File

@ -161,7 +161,6 @@ const translation = {
workspace: 'Spațiu de lucru',
createWorkspace: 'Creează Spațiu de lucru',
helpCenter: 'Ajutor',
communityFeedback: 'Feedback',
roadmap: 'Plan de acțiune',
community: 'Comunitate',
about: 'Despre',
@ -170,6 +169,7 @@ const translation = {
support: 'Suport',
compliance: 'Conformitate',
contactUs: 'Contactați-ne',
forum: 'Forum',
},
settings: {
accountGroup: 'CONT',
@ -726,6 +726,7 @@ const translation = {
pasteFileLinkInvalid: 'Link fișier nevalid',
uploadFromComputerLimit: 'Încărcarea fișierului nu poate depăși {{size}}',
pasteFileLink: 'Lipiți linkul fișierului',
fileExtensionBlocked: 'Acest tip de fișier este blocat din motive de securitate',
},
license: {
expiring: 'Expiră într-o zi',

View File

@ -165,7 +165,6 @@ const translation = {
workspace: 'Рабочее пространство',
createWorkspace: 'Создать рабочее пространство',
helpCenter: 'Помощь',
communityFeedback: 'Обратная связь',
roadmap: 'План развития',
community: 'Сообщество',
about: 'О нас',
@ -174,6 +173,7 @@ const translation = {
compliance: 'Соблюдение',
support: 'Поддержка',
contactUs: 'Свяжитесь с нами',
forum: 'Форум',
},
settings: {
accountGroup: 'АККАУНТ',
@ -726,6 +726,7 @@ const translation = {
pasteFileLinkInvalid: 'Неверная ссылка на файл',
uploadFromComputerLimit: 'Файл загрузки не может превышать {{size}}',
uploadFromComputerUploadError: 'Загрузка файла не удалась, пожалуйста, загрузите еще раз.',
fileExtensionBlocked: 'Этот тип файла заблокирован по соображениям безопасности',
},
license: {
expiring: 'Срок действия истекает за один день',

View File

@ -165,7 +165,6 @@ const translation = {
workspace: 'Delovni prostor',
createWorkspace: 'Ustvari delovni prostor',
helpCenter: 'Pomoč',
communityFeedback: 'Povratne informacije',
roadmap: 'Načrt razvoja',
community: 'Skupnost',
about: 'O nas',
@ -174,6 +173,7 @@ const translation = {
github: 'GitHub',
compliance: 'Skladnost',
contactUs: 'Kontaktirajte nas',
forum: 'Forum',
},
settings: {
accountGroup: 'SPLOŠNO',
@ -792,6 +792,7 @@ const translation = {
uploadFromComputer: 'Lokalno nalaganje',
uploadFromComputerLimit: 'Nalaganje {{type}} ne sme presegati {{size}}',
uploadFromComputerReadError: 'Branje datoteke ni uspelo, poskusite znova.',
fileExtensionBlocked: 'Ta vrsta datoteke je zaradi varnostnih razlogov blokirana',
},
tag: {
addTag: 'Dodajanje oznak',

View File

@ -160,7 +160,6 @@ const translation = {
workspace: 'พื้นที่',
createWorkspace: 'สร้างพื้นที่ทํางาน',
helpCenter: 'วิธีใช้',
communityFeedback: 'การตอบสนอง',
roadmap: 'แผนงาน',
community: 'ชุมชน',
about: 'ประมาณ',
@ -169,6 +168,7 @@ const translation = {
compliance: 'การปฏิบัติตามข้อกำหนด',
support: 'การสนับสนุน',
contactUs: 'ติดต่อเรา',
forum: 'ฟอรั่ม',
},
settings: {
accountGroup: 'ทั่วไป',
@ -706,6 +706,7 @@ const translation = {
uploadFromComputerLimit: 'อัปโหลด {{type}} ต้องไม่เกิน {{size}}',
pasteFileLinkInvalid: 'ลิงก์ไฟล์ไม่ถูกต้อง',
fileExtensionNotSupport: 'ไม่รองรับนามสกุลไฟล์',
fileExtensionBlocked: 'ประเภทไฟล์นี้ถูกบล็อกด้วยเหตุผลด้านความปลอดภัย',
},
tag: {
placeholder: 'แท็กทั้งหมด',

View File

@ -165,7 +165,6 @@ const translation = {
workspace: 'Çalışma Alanı',
createWorkspace: 'Çalışma Alanı Oluştur',
helpCenter: 'Yardım',
communityFeedback: 'Geri Bildirim',
roadmap: 'Yol haritası',
community: 'Topluluk',
about: 'Hakkında',
@ -174,6 +173,7 @@ const translation = {
compliance: 'Uygunluk',
github: 'GitHub',
contactUs: 'Bize Ulaşın',
forum: 'Forum',
},
settings: {
accountGroup: 'HESAP',
@ -726,6 +726,7 @@ const translation = {
pasteFileLinkInputPlaceholder: 'URL\'yi giriniz...',
pasteFileLinkInvalid: 'Geçersiz dosya bağlantısı',
fileExtensionNotSupport: 'Dosya uzantısı desteklenmiyor',
fileExtensionBlocked: 'Bu dosya türü güvenlik nedenleriyle engellenmiştir',
},
license: {
expiring_plural: '{{count}} gün içinde sona eriyor',

View File

@ -161,7 +161,6 @@ const translation = {
workspace: 'Робочий простір',
createWorkspace: 'Створити робочий простір',
helpCenter: 'Довідковий центр',
communityFeedback: 'відгуки',
roadmap: 'Дорожня карта',
community: 'Спільнота',
about: 'Про нас',
@ -170,6 +169,7 @@ const translation = {
support: 'Підтримка',
github: 'Гітхаб',
contactUs: 'Зв’яжіться з нами',
forum: 'Форум',
},
settings: {
accountGroup: 'ОБЛІКОВИЙ ЗАПИС',
@ -727,6 +727,7 @@ const translation = {
fileExtensionNotSupport: 'Розширення файлу не підтримується',
uploadFromComputerReadError: 'Не вдалося прочитати файл, будь ласка, спробуйте ще раз.',
uploadFromComputerUploadError: 'Не вдалося завантажити файл, будь ласка, завантажте ще раз.',
fileExtensionBlocked: 'Цей тип файлу заблоковано з міркувань безпеки',
},
license: {
expiring: 'Термін дії закінчується за один день',

View File

@ -161,7 +161,6 @@ const translation = {
workspace: 'Không gian làm việc',
createWorkspace: 'Tạo Không gian làm việc',
helpCenter: 'Trung tâm trợ giúp',
communityFeedback: 'Phản hồi',
roadmap: 'Lộ trình',
community: 'Cộng đồng',
about: 'Về chúng tôi',
@ -170,6 +169,7 @@ const translation = {
github: 'GitHub',
support: 'Hỗ trợ',
contactUs: 'Liên hệ với chúng tôi',
forum: 'Diễn đàn',
},
settings: {
accountGroup: 'TÀI KHOẢN',
@ -726,6 +726,7 @@ const translation = {
pasteFileLinkInvalid: 'Liên kết tệp không hợp lệ',
uploadFromComputerUploadError: 'Tải lên tệp không thành công, vui lòng tải lên lại.',
uploadFromComputerReadError: 'Đọc tệp không thành công, vui lòng thử lại.',
fileExtensionBlocked: 'Loại tệp này bị chặn vì lý do bảo mật',
},
license: {
expiring_plural: 'Hết hạn sau {{count}} ngày',

View File

@ -176,7 +176,7 @@ const translation = {
helpCenter: '帮助文档',
support: '支持',
compliance: '合规',
communityFeedback: '用户反馈',
forum: '论坛',
roadmap: '路线图',
github: 'GitHub',
community: '社区',

View File

@ -161,7 +161,6 @@ const translation = {
workspace: '工作空間',
createWorkspace: '建立工作空間',
helpCenter: '幫助文件',
communityFeedback: '使用者反饋',
roadmap: '路線圖',
community: '社群',
about: '關於',
@ -170,6 +169,7 @@ const translation = {
github: 'GitHub',
compliance: '合規',
contactUs: '聯絡我們',
forum: '論壇',
},
settings: {
accountGroup: '賬戶',
@ -726,6 +726,7 @@ const translation = {
uploadFromComputer: '本地上傳',
fileExtensionNotSupport: '不支援檔擴展名',
uploadFromComputerLimit: '上傳文件不能超過 {{size}}',
fileExtensionBlocked: '出於安全原因,此檔案類型被阻止',
},
license: {
expiring: '將在 1 天內過期',

View File

@ -208,7 +208,7 @@
"canvas": "^3.2.0",
"esbuild": "~0.25.0",
"pbkdf2": "~3.1.3",
"vite": "~6.2",
"vite": "~6.4.1",
"prismjs": "~1.30",
"brace-expansion": "~2.0"
},
@ -231,7 +231,7 @@
"esbuild@<0.25.0": "0.25.0",
"pbkdf2@<3.1.3": "3.1.3",
"prismjs@<1.30.0": "1.30.0",
"vite@<6.2.7": "6.2.7",
"vite@<6.4.1": "6.4.1",
"array-includes": "npm:@nolyfill/array-includes@^1",
"array.prototype.findlast": "npm:@nolyfill/array.prototype.findlast@^1",
"array.prototype.findlastindex": "npm:@nolyfill/array.prototype.findlastindex@^1",

File diff suppressed because it is too large Load Diff