mirror of
https://github.com/langgenius/dify.git
synced 2026-05-30 13:47:52 +08:00
Compare commits
1 Commits
codex/page
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b60338ad5 |
@ -467,7 +467,8 @@ class AppListApi(Resource):
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@enterprise_license_required
|
||||
def get(self):
|
||||
@with_session(write=False)
|
||||
def get(self, session: Session):
|
||||
"""Get app list"""
|
||||
current_user, current_tenant_id = current_account_with_tenant()
|
||||
|
||||
@ -504,7 +505,7 @@ class AppListApi(Resource):
|
||||
draft_trigger_app_ids: set[str] = set()
|
||||
if workflow_capable_app_ids:
|
||||
draft_workflows = (
|
||||
db.session.execute(
|
||||
session.execute(
|
||||
select(Workflow).where(
|
||||
Workflow.version == Workflow.VERSION_DRAFT,
|
||||
Workflow.app_id.in_(workflow_capable_app_ids),
|
||||
|
||||
@ -2,6 +2,7 @@ from collections.abc import Sequence
|
||||
|
||||
from flask_restx import Resource
|
||||
from pydantic import BaseModel, Field
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from controllers.common.schema import register_enum_models, register_schema_models
|
||||
from controllers.console import console_ns
|
||||
@ -11,6 +12,7 @@ from controllers.console.app.error import (
|
||||
ProviderNotInitializeError,
|
||||
ProviderQuotaExceededError,
|
||||
)
|
||||
from controllers.console.app.wraps import with_session
|
||||
from controllers.console.wraps import account_initialization_required, setup_required, with_current_tenant_id
|
||||
from core.app.app_config.entities import ModelConfig
|
||||
from core.errors.error import ModelCurrentlyNotSupportError, ProviderTokenNotInitError, QuotaExceededError
|
||||
@ -19,7 +21,6 @@ from core.helper.code_executor.javascript.javascript_code_provider import Javasc
|
||||
from core.helper.code_executor.python3.python3_code_provider import Python3CodeProvider
|
||||
from core.llm_generator.entities import RuleCodeGeneratePayload, RuleGeneratePayload, RuleStructuredOutputPayload
|
||||
from core.llm_generator.llm_generator import LLMGenerator
|
||||
from extensions.ext_database import db
|
||||
from graphon.model_runtime.entities.llm_entities import LLMMode
|
||||
from graphon.model_runtime.errors.invoke import InvokeError
|
||||
from libs.login import login_required
|
||||
@ -158,7 +159,8 @@ class InstructionGenerateApi(Resource):
|
||||
@login_required
|
||||
@account_initialization_required
|
||||
@with_current_tenant_id
|
||||
def post(self, current_tenant_id: str):
|
||||
@with_session(write=False)
|
||||
def post(self, session: Session, current_tenant_id: str):
|
||||
args = InstructionGeneratePayload.model_validate(console_ns.payload)
|
||||
providers: list[type[CodeNodeProvider]] = [Python3CodeProvider, JavascriptCodeProvider]
|
||||
code_provider: type[CodeNodeProvider] | None = next(
|
||||
@ -168,10 +170,10 @@ class InstructionGenerateApi(Resource):
|
||||
try:
|
||||
# Generate from nothing for a workflow node
|
||||
if (args.current in (code_template, "")) and args.node_id != "":
|
||||
app = db.session.get(App, args.flow_id)
|
||||
app = session.get(App, args.flow_id)
|
||||
if not app:
|
||||
return {"error": f"app {args.flow_id} not found"}, 400
|
||||
workflow = WorkflowService().get_draft_workflow(app_model=app)
|
||||
workflow = WorkflowService().get_draft_workflow(app_model=app, session=session)
|
||||
if not workflow:
|
||||
return {"error": f"workflow {args.flow_id} not found"}, 400
|
||||
nodes: Sequence = workflow.graph_dict["nodes"]
|
||||
|
||||
@ -140,14 +140,21 @@ class WorkflowService:
|
||||
)
|
||||
return db.session.execute(stmt).scalar_one()
|
||||
|
||||
def get_draft_workflow(self, app_model: App, workflow_id: str | None = None) -> Workflow | None:
|
||||
def get_draft_workflow(
|
||||
self, app_model: App, workflow_id: str | None = None, session: Session | None = None
|
||||
) -> Workflow | None:
|
||||
"""
|
||||
Get draft workflow
|
||||
|
||||
When ``session`` is provided, reuse it so callers that already hold a
|
||||
Session avoid checking out an extra request-scoped ``db.session``
|
||||
connection. Falls back to ``db.session`` for backward compatibility.
|
||||
"""
|
||||
if workflow_id:
|
||||
return self.get_published_workflow_by_id(app_model, workflow_id)
|
||||
return self.get_published_workflow_by_id(app_model, workflow_id, session=session)
|
||||
# fetch draft workflow by app_model
|
||||
workflow = db.session.scalar(
|
||||
bind = session if session is not None else db.session
|
||||
workflow = bind.scalar(
|
||||
select(Workflow)
|
||||
.where(
|
||||
Workflow.tenant_id == app_model.tenant_id,
|
||||
|
||||
@ -7,6 +7,7 @@ from importlib import util
|
||||
from pathlib import Path
|
||||
from types import ModuleType, SimpleNamespace
|
||||
from typing import Any
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
from flask.views import MethodView
|
||||
@ -18,6 +19,15 @@ if not hasattr(builtins, "MethodView"):
|
||||
builtins.MethodView = MethodView # type: ignore[attr-defined]
|
||||
|
||||
|
||||
def _unwrap(func):
|
||||
bound_self = getattr(func, "__self__", None)
|
||||
while hasattr(func, "__wrapped__"):
|
||||
func = func.__wrapped__
|
||||
if bound_self is not None:
|
||||
return func.__get__(bound_self, bound_self.__class__)
|
||||
return func
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def app_module():
|
||||
module_name = "controllers.console.app.app"
|
||||
@ -395,3 +405,46 @@ def test_app_pagination_aliases_per_page_and_has_next(app_models):
|
||||
assert len(serialized["data"]) == 2
|
||||
assert serialized["data"][0]["icon_url"] == "signed:first-icon"
|
||||
assert serialized["data"][1]["icon_url"] is None
|
||||
|
||||
|
||||
def test_app_list_uses_injected_session_for_draft_workflows(app, app_module, monkeypatch):
|
||||
api = app_module.AppListApi()
|
||||
method = _unwrap(api.get)
|
||||
current_user = SimpleNamespace(id="user-1")
|
||||
app_item = SimpleNamespace(
|
||||
id="app-1",
|
||||
name="Workflow App",
|
||||
desc_or_prompt="Summary",
|
||||
mode="workflow",
|
||||
mode_compatible_with_agent="workflow",
|
||||
)
|
||||
app_pagination = SimpleNamespace(page=1, per_page=20, total=1, has_next=False, items=[app_item])
|
||||
workflow = SimpleNamespace(
|
||||
id="workflow-1",
|
||||
app_id="app-1",
|
||||
walk_nodes=lambda: iter([("trigger-1", {"type": "trigger-webhook"})]),
|
||||
)
|
||||
session = MagicMock()
|
||||
session.execute.return_value.scalars.return_value.all.return_value = [workflow]
|
||||
scoped_session = SimpleNamespace(execute=MagicMock(side_effect=AssertionError("db.session should not be used")))
|
||||
|
||||
monkeypatch.setattr(app_module, "current_account_with_tenant", lambda: (current_user, "tenant-1"))
|
||||
monkeypatch.setattr(
|
||||
app_module,
|
||||
"AppService",
|
||||
lambda: SimpleNamespace(get_paginate_apps=lambda *_args, **_kwargs: app_pagination),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
app_module,
|
||||
"FeatureService",
|
||||
SimpleNamespace(get_system_features=lambda: SimpleNamespace(webapp_auth=SimpleNamespace(enabled=False))),
|
||||
)
|
||||
monkeypatch.setattr(app_module, "db", SimpleNamespace(session=scoped_session))
|
||||
|
||||
with app.test_request_context("/console/api/apps?page=1&limit=20", method="GET"):
|
||||
response, status = method(session)
|
||||
|
||||
assert status == 200
|
||||
assert response["data"][0]["has_draft_trigger"] is True
|
||||
session.execute.assert_called_once()
|
||||
scoped_session.execute.assert_not_called()
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
@ -24,10 +25,17 @@ def _model_config_payload():
|
||||
|
||||
def _install_workflow_service(monkeypatch: pytest.MonkeyPatch, workflow):
|
||||
class _Service:
|
||||
def get_draft_workflow(self, app_model):
|
||||
app_model = None
|
||||
session = None
|
||||
|
||||
def get_draft_workflow(self, app_model, session=None):
|
||||
self.app_model = app_model
|
||||
self.session = session
|
||||
return workflow
|
||||
|
||||
monkeypatch.setattr(generator_module, "WorkflowService", lambda: _Service())
|
||||
service = _Service()
|
||||
monkeypatch.setattr(generator_module, "WorkflowService", lambda: service)
|
||||
return service
|
||||
|
||||
|
||||
def test_rule_generate_success(app, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
@ -68,7 +76,8 @@ def test_instruction_generate_app_not_found(app, monkeypatch: pytest.MonkeyPatch
|
||||
api = generator_module.InstructionGenerateApi()
|
||||
method = _unwrap(api.post)
|
||||
|
||||
monkeypatch.setattr(generator_module.db, "session", SimpleNamespace(get=lambda *_args, **_kwargs: None))
|
||||
session = MagicMock()
|
||||
session.get.return_value = None
|
||||
|
||||
with app.test_request_context(
|
||||
"/console/api/instruction-generate",
|
||||
@ -80,10 +89,11 @@ def test_instruction_generate_app_not_found(app, monkeypatch: pytest.MonkeyPatch
|
||||
"model_config": _model_config_payload(),
|
||||
},
|
||||
):
|
||||
response, status = method("t1")
|
||||
response, status = method(session, "t1")
|
||||
|
||||
assert status == 400
|
||||
assert response["error"] == "app app-1 not found"
|
||||
session.get.assert_called_once_with(generator_module.App, "app-1")
|
||||
|
||||
|
||||
def test_instruction_generate_workflow_not_found(app, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
@ -91,7 +101,7 @@ def test_instruction_generate_workflow_not_found(app, monkeypatch: pytest.Monkey
|
||||
method = _unwrap(api.post)
|
||||
|
||||
app_model = SimpleNamespace(id="app-1")
|
||||
monkeypatch.setattr(generator_module.db, "session", SimpleNamespace(get=lambda *_args, **_kwargs: app_model))
|
||||
session = SimpleNamespace(get=lambda *_args, **_kwargs: app_model)
|
||||
_install_workflow_service(monkeypatch, workflow=None)
|
||||
|
||||
with app.test_request_context(
|
||||
@ -104,7 +114,7 @@ def test_instruction_generate_workflow_not_found(app, monkeypatch: pytest.Monkey
|
||||
"model_config": _model_config_payload(),
|
||||
},
|
||||
):
|
||||
response, status = method("t1")
|
||||
response, status = method(session, "t1")
|
||||
|
||||
assert status == 400
|
||||
assert response["error"] == "workflow app-1 not found"
|
||||
@ -115,7 +125,7 @@ def test_instruction_generate_node_missing(app, monkeypatch: pytest.MonkeyPatch)
|
||||
method = _unwrap(api.post)
|
||||
|
||||
app_model = SimpleNamespace(id="app-1")
|
||||
monkeypatch.setattr(generator_module.db, "session", SimpleNamespace(get=lambda *_args, **_kwargs: app_model))
|
||||
session = SimpleNamespace(get=lambda *_args, **_kwargs: app_model)
|
||||
|
||||
workflow = SimpleNamespace(graph_dict={"nodes": []})
|
||||
_install_workflow_service(monkeypatch, workflow=workflow)
|
||||
@ -130,7 +140,7 @@ def test_instruction_generate_node_missing(app, monkeypatch: pytest.MonkeyPatch)
|
||||
"model_config": _model_config_payload(),
|
||||
},
|
||||
):
|
||||
response, status = method("t1")
|
||||
response, status = method(session, "t1")
|
||||
|
||||
assert status == 400
|
||||
assert response["error"] == "node node-1 not found"
|
||||
@ -141,7 +151,7 @@ def test_instruction_generate_code_node(app, monkeypatch: pytest.MonkeyPatch) ->
|
||||
method = _unwrap(api.post)
|
||||
|
||||
app_model = SimpleNamespace(id="app-1")
|
||||
monkeypatch.setattr(generator_module.db, "session", SimpleNamespace(get=lambda *_args, **_kwargs: app_model))
|
||||
session = SimpleNamespace(get=lambda *_args, **_kwargs: app_model)
|
||||
|
||||
workflow = SimpleNamespace(
|
||||
graph_dict={
|
||||
@ -150,7 +160,7 @@ def test_instruction_generate_code_node(app, monkeypatch: pytest.MonkeyPatch) ->
|
||||
]
|
||||
}
|
||||
)
|
||||
_install_workflow_service(monkeypatch, workflow=workflow)
|
||||
workflow_service = _install_workflow_service(monkeypatch, workflow=workflow)
|
||||
monkeypatch.setattr(generator_module.LLMGenerator, "generate_code", lambda **_kwargs: {"code": "x"})
|
||||
|
||||
with app.test_request_context(
|
||||
@ -163,14 +173,17 @@ def test_instruction_generate_code_node(app, monkeypatch: pytest.MonkeyPatch) ->
|
||||
"model_config": _model_config_payload(),
|
||||
},
|
||||
):
|
||||
response = method("t1")
|
||||
response = method(session, "t1")
|
||||
|
||||
assert response == {"code": "x"}
|
||||
assert workflow_service.app_model is app_model
|
||||
assert workflow_service.session is session
|
||||
|
||||
|
||||
def test_instruction_generate_legacy_modify(app, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
api = generator_module.InstructionGenerateApi()
|
||||
method = _unwrap(api.post)
|
||||
session = SimpleNamespace()
|
||||
|
||||
monkeypatch.setattr(
|
||||
generator_module.LLMGenerator,
|
||||
@ -189,7 +202,7 @@ def test_instruction_generate_legacy_modify(app, monkeypatch: pytest.MonkeyPatch
|
||||
"model_config": _model_config_payload(),
|
||||
},
|
||||
):
|
||||
response = method("t1")
|
||||
response = method(session, "t1")
|
||||
|
||||
assert response == {"instruction": "ok"}
|
||||
|
||||
@ -197,6 +210,7 @@ def test_instruction_generate_legacy_modify(app, monkeypatch: pytest.MonkeyPatch
|
||||
def test_instruction_generate_incompatible_params(app, monkeypatch: pytest.MonkeyPatch) -> None:
|
||||
api = generator_module.InstructionGenerateApi()
|
||||
method = _unwrap(api.post)
|
||||
session = SimpleNamespace()
|
||||
|
||||
with app.test_request_context(
|
||||
"/console/api/instruction-generate",
|
||||
@ -209,7 +223,7 @@ def test_instruction_generate_incompatible_params(app, monkeypatch: pytest.Monke
|
||||
"model_config": _model_config_payload(),
|
||||
},
|
||||
):
|
||||
response, status = method("t1")
|
||||
response, status = method(session, "t1")
|
||||
|
||||
assert status == 400
|
||||
assert response["error"] == "incompatible parameters"
|
||||
|
||||
@ -346,6 +346,19 @@ class TestWorkflowService:
|
||||
|
||||
assert result == mock_workflow
|
||||
|
||||
def test_get_draft_workflow_uses_provided_session(self, workflow_service, mock_db_session):
|
||||
"""Test get_draft_workflow can reuse an injected SQLAlchemy session."""
|
||||
app = TestWorkflowAssociatedDataFactory.create_app_mock()
|
||||
mock_workflow = TestWorkflowAssociatedDataFactory.create_workflow_mock()
|
||||
session = MagicMock()
|
||||
session.scalar.return_value = mock_workflow
|
||||
|
||||
result = workflow_service.get_draft_workflow(app, session=session)
|
||||
|
||||
assert result == mock_workflow
|
||||
session.scalar.assert_called_once()
|
||||
mock_db_session.session.scalar.assert_not_called()
|
||||
|
||||
def test_get_draft_workflow_returns_none(self, workflow_service, mock_db_session):
|
||||
"""Test get_draft_workflow returns None when no draft exists."""
|
||||
app = TestWorkflowAssociatedDataFactory.create_app_mock()
|
||||
@ -370,6 +383,21 @@ class TestWorkflowService:
|
||||
|
||||
assert result == mock_workflow
|
||||
|
||||
def test_get_draft_workflow_with_workflow_id_reuses_provided_session(self, workflow_service):
|
||||
"""Test get_draft_workflow passes an injected session to published workflow lookup."""
|
||||
app = TestWorkflowAssociatedDataFactory.create_app_mock()
|
||||
workflow_id = "workflow-123"
|
||||
session = MagicMock()
|
||||
mock_workflow = TestWorkflowAssociatedDataFactory.create_workflow_mock(version="v1")
|
||||
|
||||
with patch.object(
|
||||
workflow_service, "get_published_workflow_by_id", return_value=mock_workflow
|
||||
) as mock_get_published:
|
||||
result = workflow_service.get_draft_workflow(app, workflow_id=workflow_id, session=session)
|
||||
|
||||
assert result == mock_workflow
|
||||
mock_get_published.assert_called_once_with(app, workflow_id, session=session)
|
||||
|
||||
# ==================== Get Published Workflow Tests ====================
|
||||
# These tests verify retrieval of published workflows (versioned snapshots)
|
||||
|
||||
|
||||
@ -19,10 +19,6 @@ vi.mock('@/context/web-app-context', () => ({
|
||||
useWebAppStore: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/hooks/use-document-title', () => ({
|
||||
default: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/service/access-control', () => ({
|
||||
useGetUserCanAccessApp: vi.fn(),
|
||||
}))
|
||||
|
||||
@ -1,14 +1,8 @@
|
||||
import * as React from 'react'
|
||||
import ExternalKnowledgeBaseConnector from '@/app/components/datasets/external-knowledge-base/connector'
|
||||
import { DocumentTitleSetter } from '../document-title-setter'
|
||||
|
||||
const ExternalKnowledgeBaseCreation = () => {
|
||||
return (
|
||||
<>
|
||||
<DocumentTitleSetter i18nKey="pageTitle.connectExternalKnowledgeBase" namespace="dataset" />
|
||||
<ExternalKnowledgeBaseConnector />
|
||||
</>
|
||||
)
|
||||
return <ExternalKnowledgeBaseConnector />
|
||||
}
|
||||
|
||||
export default ExternalKnowledgeBaseCreation
|
||||
|
||||
@ -1,13 +1,9 @@
|
||||
import * as React from 'react'
|
||||
import CreateFromPipeline from '@/app/components/datasets/create-from-pipeline'
|
||||
import { DocumentTitleSetter } from '../document-title-setter'
|
||||
|
||||
const DatasetCreation = async () => {
|
||||
return (
|
||||
<>
|
||||
<DocumentTitleSetter i18nKey="creation.pageTitle" namespace="datasetPipeline" />
|
||||
<CreateFromPipeline />
|
||||
</>
|
||||
<CreateFromPipeline />
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,13 +1,9 @@
|
||||
import * as React from 'react'
|
||||
import DatasetUpdateForm from '@/app/components/datasets/create'
|
||||
import { DocumentTitleSetter } from '../document-title-setter'
|
||||
|
||||
const DatasetCreation = async () => {
|
||||
return (
|
||||
<>
|
||||
<DocumentTitleSetter i18nKey="createDataset" namespace="dataset" />
|
||||
<DatasetUpdateForm />
|
||||
</>
|
||||
<DatasetUpdateForm />
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
'use client'
|
||||
|
||||
import type { Namespace } from '@/i18n-config/resources'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
|
||||
type DocumentTitleSetterProps = {
|
||||
i18nKey: string
|
||||
namespace: Namespace
|
||||
}
|
||||
|
||||
export function DocumentTitleSetter({
|
||||
i18nKey,
|
||||
namespace,
|
||||
}: DocumentTitleSetterProps) {
|
||||
const { t } = useTranslation()
|
||||
useDocumentTitle(t(i18nKey, { ns: namespace }))
|
||||
|
||||
return null
|
||||
}
|
||||
@ -1,18 +1,15 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { FullScreenLoading } from '@/app/components/full-screen-loading'
|
||||
import EducationApplyPage from '@/app/education-apply/education-apply-page'
|
||||
import { useProviderContext } from '@/context/provider-context'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
import {
|
||||
useRouter,
|
||||
useSearchParams,
|
||||
} from '@/next/navigation'
|
||||
|
||||
export default function EducationApply() {
|
||||
const { t } = useTranslation()
|
||||
const router = useRouter()
|
||||
const {
|
||||
enableEducationPlan,
|
||||
@ -21,7 +18,6 @@ export default function EducationApply() {
|
||||
} = useProviderContext()
|
||||
const searchParams = useSearchParams()
|
||||
const token = searchParams.get('token')
|
||||
useDocumentTitle(t('pageTitle.verification', { ns: 'education' }))
|
||||
|
||||
useEffect(() => {
|
||||
if (!isFetchedPlanInfo)
|
||||
|
||||
@ -3,7 +3,6 @@ import type { InstalledApp as InstalledAppType } from '@/models/explore'
|
||||
import { render, screen, waitFor } from '@testing-library/react'
|
||||
|
||||
import { useWebAppStore } from '@/context/web-app-context'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
import { AccessMode } from '@/models/access-control'
|
||||
import { useGetUserCanAccessApp } from '@/service/access-control'
|
||||
import { useGetInstalledAppAccessModeByAppId, useGetInstalledAppMeta, useGetInstalledAppParams, useGetInstalledApps } from '@/service/use-explore'
|
||||
@ -13,9 +12,6 @@ import InstalledApp from '../index'
|
||||
vi.mock('@/context/web-app-context', () => ({
|
||||
useWebAppStore: vi.fn(),
|
||||
}))
|
||||
vi.mock('@/hooks/use-document-title', () => ({
|
||||
default: vi.fn(),
|
||||
}))
|
||||
vi.mock('@/service/access-control', () => ({
|
||||
useGetUserCanAccessApp: vi.fn(),
|
||||
}))
|
||||
@ -365,20 +361,6 @@ describe('InstalledApp', () => {
|
||||
})
|
||||
|
||||
describe('Effects', () => {
|
||||
it('should set document title to installed app name', () => {
|
||||
render(<InstalledApp id="installed-app-123" />)
|
||||
|
||||
expect(useDocumentTitle).toHaveBeenCalledWith('Test App')
|
||||
})
|
||||
|
||||
it('should not set document title when installedApp is not found', () => {
|
||||
setupMocks([])
|
||||
|
||||
render(<InstalledApp id="nonexistent-app" />)
|
||||
|
||||
expect(useDocumentTitle).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it('should update app info when installedApp is available', async () => {
|
||||
render(<InstalledApp id="installed-app-123" />)
|
||||
|
||||
|
||||
@ -7,22 +7,11 @@ import ChatWithHistory from '@/app/components/base/chat/chat-with-history'
|
||||
import Loading from '@/app/components/base/loading'
|
||||
import TextGenerationApp from '@/app/components/share/text-generation'
|
||||
import { useWebAppStore } from '@/context/web-app-context'
|
||||
import useDocumentTitle from '@/hooks/use-document-title'
|
||||
import { useGetUserCanAccessApp } from '@/service/access-control'
|
||||
import { useGetInstalledAppAccessModeByAppId, useGetInstalledAppMeta, useGetInstalledAppParams, useGetInstalledApps } from '@/service/use-explore'
|
||||
import { AppModeEnum } from '@/types/app'
|
||||
import AppUnavailable from '../../base/app-unavailable'
|
||||
|
||||
const InstalledAppDocumentTitle = ({
|
||||
title,
|
||||
}: {
|
||||
title: string
|
||||
}) => {
|
||||
useDocumentTitle(title)
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
const InstalledApp = ({
|
||||
id,
|
||||
}: {
|
||||
@ -30,10 +19,6 @@ const InstalledApp = ({
|
||||
}) => {
|
||||
const { data, isPending: isPendingInstalledApps, isFetching: isFetchingInstalledApps } = useGetInstalledApps()
|
||||
const installedApp = data?.installed_apps?.find(item => item.id === id)
|
||||
const installedAppDocumentTitle = installedApp
|
||||
? <InstalledAppDocumentTitle title={installedApp.app.name} />
|
||||
: null
|
||||
|
||||
const updateAppInfo = useWebAppStore(s => s.updateAppInfo)
|
||||
const updateWebAppAccessMode = useWebAppStore(s => s.updateWebAppAccessMode)
|
||||
const updateAppParams = useWebAppStore(s => s.updateAppParams)
|
||||
@ -79,52 +64,37 @@ const InstalledApp = ({
|
||||
|
||||
if (appParamsError) {
|
||||
return (
|
||||
<>
|
||||
{installedAppDocumentTitle}
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<AppUnavailable unknownReason={appParamsError.message} />
|
||||
</div>
|
||||
</>
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<AppUnavailable unknownReason={appParamsError.message} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (appMetaError) {
|
||||
return (
|
||||
<>
|
||||
{installedAppDocumentTitle}
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<AppUnavailable unknownReason={appMetaError.message} />
|
||||
</div>
|
||||
</>
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<AppUnavailable unknownReason={appMetaError.message} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (useCanAccessAppError) {
|
||||
return (
|
||||
<>
|
||||
{installedAppDocumentTitle}
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<AppUnavailable unknownReason={useCanAccessAppError.message} />
|
||||
</div>
|
||||
</>
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<AppUnavailable unknownReason={useCanAccessAppError.message} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (webAppAccessModeError) {
|
||||
return (
|
||||
<>
|
||||
{installedAppDocumentTitle}
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<AppUnavailable unknownReason={webAppAccessModeError.message} />
|
||||
</div>
|
||||
</>
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<AppUnavailable unknownReason={webAppAccessModeError.message} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (userCanAccessApp && !userCanAccessApp.result) {
|
||||
return (
|
||||
<>
|
||||
{installedAppDocumentTitle}
|
||||
<div className="flex h-full flex-col items-center justify-center gap-y-2">
|
||||
<AppUnavailable className="size-auto" code={403} unknownReason="no permission." />
|
||||
</div>
|
||||
</>
|
||||
<div className="flex h-full flex-col items-center justify-center gap-y-2">
|
||||
<AppUnavailable className="size-auto" code={403} unknownReason="no permission." />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (
|
||||
@ -133,12 +103,9 @@ const InstalledApp = ({
|
||||
|| (installedApp && (isPendingAppParams || isPendingAppMeta || isPendingWebAppAccessMode))
|
||||
) {
|
||||
return (
|
||||
<>
|
||||
{installedAppDocumentTitle}
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<Loading />
|
||||
</div>
|
||||
</>
|
||||
<div className="flex h-full items-center justify-center">
|
||||
<Loading />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
if (!installedApp) {
|
||||
@ -149,20 +116,17 @@ const InstalledApp = ({
|
||||
)
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{installedAppDocumentTitle}
|
||||
<div className="h-full bg-background-default py-2 pr-2 pl-0 sm:p-2">
|
||||
{installedApp?.app.mode !== AppModeEnum.COMPLETION && installedApp?.app.mode !== AppModeEnum.WORKFLOW && (
|
||||
<ChatWithHistory installedAppInfo={installedApp} className="overflow-hidden rounded-2xl shadow-md" />
|
||||
)}
|
||||
{installedApp?.app.mode === AppModeEnum.COMPLETION && (
|
||||
<TextGenerationApp isInstalledApp installedAppInfo={installedApp} />
|
||||
)}
|
||||
{installedApp?.app.mode === AppModeEnum.WORKFLOW && (
|
||||
<TextGenerationApp isWorkflow isInstalledApp installedAppInfo={installedApp} />
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
<div className="h-full bg-background-default py-2 pr-2 pl-0 sm:p-2">
|
||||
{installedApp?.app.mode !== AppModeEnum.COMPLETION && installedApp?.app.mode !== AppModeEnum.WORKFLOW && (
|
||||
<ChatWithHistory installedAppInfo={installedApp} className="overflow-hidden rounded-2xl shadow-md" />
|
||||
)}
|
||||
{installedApp?.app.mode === AppModeEnum.COMPLETION && (
|
||||
<TextGenerationApp isInstalledApp installedAppInfo={installedApp} />
|
||||
)}
|
||||
{installedApp?.app.mode === AppModeEnum.WORKFLOW && (
|
||||
<TextGenerationApp isWorkflow isInstalledApp installedAppInfo={installedApp} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default React.memo(InstalledApp)
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "إنشاء المعرفة",
|
||||
"creation.errorTip": "فشل إنشاء قاعدة المعرفة",
|
||||
"creation.importDSL": "استيراد من ملف DSL",
|
||||
"creation.pageTitle": "إنشاء مسار معرفة",
|
||||
"creation.successTip": "تم إنشاء قاعدة المعرفة بنجاح",
|
||||
"deletePipeline.content": "حذف قالب سير العمل لا رجعة فيه.",
|
||||
"deletePipeline.title": "هل أنت متأكد من حذف قالب سير العمل هذا؟",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "تعرف على المزيد",
|
||||
"nTo1RetrievalLegacyLinkText": " سيتم إيقاف الاسترجاع من N إلى 1 رسميًا في سبتمبر.",
|
||||
"noExternalKnowledge": "لا توجد واجهة برمجة تطبيقات معرفة خارجية حتى الآن، انقر هنا لإنشاء",
|
||||
"pageTitle.connectExternalKnowledgeBase": "ربط قاعدة معرفة خارجية",
|
||||
"parentMode.fullDoc": "مستند كامل",
|
||||
"parentMode.paragraph": "فقرة",
|
||||
"partialEnabled_one": "إجمالي {{count}} مستند، {{num}} متاح",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "تحقق مرة أخرى الآن للحصول على كوبون جديد للعام الدراسي القادم. سنضيفه إلى حسابك ويمكنك استخدامه للترقية التالية.",
|
||||
"notice.stillInEducation.isAboutToExpire": "تحقق مرة أخرى الآن للحصول على كوبون جديد للعام الدراسي القادم. سيتم حفظه في حسابك وجاهز للاستخدام في تجديدك التالي.",
|
||||
"notice.stillInEducation.title": "هل ما زلت في التعليم؟",
|
||||
"pageTitle.verification": "التحقق من التعليم",
|
||||
"planNotSupportEducationDiscount": "غير مؤهل لأسعار التعليم",
|
||||
"rejectContent": "لسوء الحظ، أنت غير مؤهل للحصول على حالة التحقق التعليمي وبالتالي لا يمكنك الحصول على كوبون حصري 100٪ لخطة Dify Professional إذا كنت تستخدم عنوان البريد الإلكتروني هذا.",
|
||||
"rejectTitle": "تم رفض التحقق التعليمي الخاص بك في Dify",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Wissen schaffen",
|
||||
"creation.errorTip": "Fehler beim Erstellen einer Wissensdatenbank",
|
||||
"creation.importDSL": "Importieren aus einer DSL-Datei",
|
||||
"creation.pageTitle": "Knowledge Pipeline erstellen",
|
||||
"creation.successTip": "Erfolgreich eine Wissensdatenbank erstellt",
|
||||
"deletePipeline.content": "Das Löschen der Pipelinevorlage kann nicht rückgängig gemacht werden.",
|
||||
"deletePipeline.title": "Sind Sie sicher, dass Sie diese Pipeline-Vorlage löschen möchten?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Mehr erfahren",
|
||||
"nTo1RetrievalLegacyLinkText": "N-zu-1-Abruf wird im September offiziell eingestellt.",
|
||||
"noExternalKnowledge": "Es gibt noch keine External Knowledge API, klicken Sie hier, um zu erstellen",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Externe Wissensdatenbank verbinden",
|
||||
"parentMode.fullDoc": "Vollständiges Dokument",
|
||||
"parentMode.paragraph": "Absatz",
|
||||
"partialEnabled_one": "Insgesamt {{count}} Dokumente, {{num}} verfügbar",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Überprüfen Sie jetzt erneut, um einen neuen Gutschein für das kommende akademische Jahr zu erhalten. Wir fügen ihn Ihrem Konto hinzu und Sie können ihn für das nächste Upgrade verwenden.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Überprüfen Sie jetzt erneut, um einen neuen Gutschein für das kommende Studienjahr zu erhalten. Er wird in Ihrem Konto gespeichert und ist bereit zur Nutzung bei Ihrer nächsten Verlängerung.",
|
||||
"notice.stillInEducation.title": "Immer noch in der Ausbildung?",
|
||||
"pageTitle.verification": "Bildungsverifizierung",
|
||||
"planNotSupportEducationDiscount": "Nicht für Bildungspreise berechtigt",
|
||||
"rejectContent": "Leider sind Sie nicht für den Status \"Education Verified\" berechtigt und können daher den exklusiven 100%-Gutschein für den Dify Professional Plan nicht erhalten, wenn Sie diese E-Mail-Adresse verwenden.",
|
||||
"rejectTitle": "Ihre Dify-Ausbildungsüberprüfung wurde abgelehnt.",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Create Knowledge",
|
||||
"creation.errorTip": "Failed to create a Knowledge Base",
|
||||
"creation.importDSL": "Import from a DSL file",
|
||||
"creation.pageTitle": "Create Knowledge Pipeline",
|
||||
"creation.successTip": "Successfully created a Knowledge Base",
|
||||
"deletePipeline.content": "Deleting the pipeline template is irreversible.",
|
||||
"deletePipeline.title": "Are you sure to delete this pipeline template?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Learn more",
|
||||
"nTo1RetrievalLegacyLinkText": " N-to-1 retrieval will be officially deprecated in September.",
|
||||
"noExternalKnowledge": "There is no External Knowledge API yet, click here to create",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Connect External Knowledge Base",
|
||||
"parentMode.fullDoc": "Full-doc",
|
||||
"parentMode.paragraph": "Paragraph",
|
||||
"partialEnabled_one": "Total of {{count}} document, {{num}} available",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Re-verify now to get a new coupon for the upcoming academic year. We'll add it to your account and you can use it for the next upgrade.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Re-verify now to get a new coupon for the upcoming academic year. It'll be saved to your account and ready to use at your next renewal.",
|
||||
"notice.stillInEducation.title": "Still in education?",
|
||||
"pageTitle.verification": "Education Verification",
|
||||
"planNotSupportEducationDiscount": "Not eligible for education pricing",
|
||||
"rejectContent": "Unfortunately, you are not eligible for Education Verified status and therefore cannot receive the exclusive 100% coupon for the Dify Professional Plan if you use this email address.",
|
||||
"rejectTitle": "Your Dify Educational Verification Has Been Rejected",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Crear conocimiento",
|
||||
"creation.errorTip": "No se pudo crear una base de conocimiento",
|
||||
"creation.importDSL": "Importar desde un archivo DSL",
|
||||
"creation.pageTitle": "Crear pipeline de conocimiento",
|
||||
"creation.successTip": "Creó con éxito una base de conocimientos",
|
||||
"deletePipeline.content": "La eliminación de la plantilla de canalización es irreversible.",
|
||||
"deletePipeline.title": "¿Está seguro de eliminar esta plantilla de canalización?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Más información",
|
||||
"nTo1RetrievalLegacyLinkText": "La recuperación N-a-1 será oficialmente obsoleta en septiembre.",
|
||||
"noExternalKnowledge": "Todavía no hay una API de conocimiento externo, haga clic aquí para crear",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Conectar base de conocimientos externa",
|
||||
"parentMode.fullDoc": "Documento completo",
|
||||
"parentMode.paragraph": "Párrafo",
|
||||
"partialEnabled_one": "Total de {{count}} documentos, {{num}} disponibles",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Verifica de nuevo ahora para obtener un nuevo cupón para el próximo año académico. Lo añadiremos a tu cuenta y podrás usarlo para la próxima actualización.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Verifica de nuevo ahora para obtener un nuevo cupón para el próximo año académico. Se guardará en tu cuenta y estará listo para usar en tu próxima renovación.",
|
||||
"notice.stillInEducation.title": "¿Aún en educación?",
|
||||
"pageTitle.verification": "Verificación educativa",
|
||||
"planNotSupportEducationDiscount": "No elegible para precios educativos",
|
||||
"rejectContent": "Desafortunadamente, no eres elegible para el estado de Educación Verificada y, por lo tanto, no puedes recibir el exclusivo cupón del 100% para el Plan Profesional de Dify si utilizas esta dirección de correo electrónico.",
|
||||
"rejectTitle": "Su verificación educativa de Dify ha sido rechazada.",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "ایجاد دانش",
|
||||
"creation.errorTip": "ایجاد پایگاه دانش ناموفق است",
|
||||
"creation.importDSL": "ایمپورت از یک فایل DSL",
|
||||
"creation.pageTitle": "ایجاد پایپلاین دانش",
|
||||
"creation.successTip": "با موفقیت یک پایگاه دانش ایجاد کرد",
|
||||
"deletePipeline.content": "حذف الگوی خط لوله برگشت ناپذیر است.",
|
||||
"deletePipeline.title": "آیا مطمئن هستید که این الگوی خط لوله را حذف می کنید؟",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "بیشتر بدانید",
|
||||
"nTo1RetrievalLegacyLinkText": " بازیابی N-to-1 از سپتامبر به طور رسمی منسوخ خواهد شد.",
|
||||
"noExternalKnowledge": "هنوز هیچ API دانش خارجی وجود ندارد، برای ایجاد اینجا را کلیک کنید",
|
||||
"pageTitle.connectExternalKnowledgeBase": "اتصال به پایگاه دانش خارجی",
|
||||
"parentMode.fullDoc": "مستند کامل",
|
||||
"parentMode.paragraph": "پاراگراف",
|
||||
"partialEnabled_one": "مجموعاً {{count}} سند، {{num}} موجود",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "هماکنون دوباره تأیید کنید تا یک کوپن جدید برای سال تحصیلی آینده دریافت کنید. ما آن را به حساب شما اضافه خواهیم کرد و میتوانید از آن برای ارتقاء بعدی استفاده کنید.",
|
||||
"notice.stillInEducation.isAboutToExpire": "در حال حاضر دوباره تأیید کنید تا یک کوپن جدید برای سال تحصیلی آینده دریافت کنید. این کوپن به حساب شما ذخیره خواهد شد و در زمان تمدید بعدی شما آماده استفاده است.",
|
||||
"notice.stillInEducation.title": "آیا هنوز در حال تحصیل هستید؟",
|
||||
"pageTitle.verification": "تأیید آموزشی",
|
||||
"planNotSupportEducationDiscount": "واجد شرایط قیمتگذاری آموزشی نیست",
|
||||
"rejectContent": "متاسفانه، شما واجد شرایط وضعیت تأیید شده آموزشی نیستید و به همین دلیل نمیتوانید کوپن انحصاری ۱۰۰٪ برای طرح حرفهای Dify را در صورت استفاده از این آدرس ایمیل دریافت کنید.",
|
||||
"rejectTitle": "تأییدیه آموزشی دیفی شما رد شده است",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Créer des connaissances",
|
||||
"creation.errorTip": "Échec de la création d’une base de connaissances",
|
||||
"creation.importDSL": "Importation à partir d’un fichier DSL",
|
||||
"creation.pageTitle": "Créer un pipeline de connaissances",
|
||||
"creation.successTip": "Création réussie d’une base de connaissances",
|
||||
"deletePipeline.content": "La suppression du modèle de pipeline est irréversible.",
|
||||
"deletePipeline.title": "Êtes-vous sûr de supprimer ce modèle de pipeline ?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "En savoir plus",
|
||||
"nTo1RetrievalLegacyLinkText": "La récupération N-à-1 sera officiellement obsolète en septembre.",
|
||||
"noExternalKnowledge": "Il n’y a pas encore d’API de connaissances externes, cliquez ici pour créer",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Connecter une base de connaissances externe",
|
||||
"parentMode.fullDoc": "Doc complet",
|
||||
"parentMode.paragraph": "Paragraphe",
|
||||
"partialEnabled_one": "Total de {{count}} documents, {{num}} disponibles",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Veuillez vérifier à nouveau maintenant pour obtenir un nouveau coupon pour la prochaine année académique. Nous l'ajouterons à votre compte et vous pourrez l'utiliser pour la prochaine mise à niveau.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Vérifiez de nouveau maintenant pour obtenir un nouveau coupon pour la prochaine année académique. Il sera enregistré dans votre compte et prêt à être utilisé lors de votre prochain renouvellement.",
|
||||
"notice.stillInEducation.title": "Encore dans l'éducation ?",
|
||||
"pageTitle.verification": "Vérification du statut éducatif",
|
||||
"planNotSupportEducationDiscount": "Non éligible aux tarifs éducatifs",
|
||||
"rejectContent": "Malheureusement, vous n'êtes pas éligible au statut Éducation Vérifié et ne pouvez donc pas recevoir le coupon exclusif de 100 % pour le Plan Professionnel Dify si vous utilisez cette adresse e-mail.",
|
||||
"rejectTitle": "Votre vérification éducative Dify a été rejetée.",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "ज्ञान उत्पन्न करें",
|
||||
"creation.errorTip": "ज्ञान आधार बनाने में विफल",
|
||||
"creation.importDSL": "एक DSL फ़ाइल से आयात करें",
|
||||
"creation.pageTitle": "ज्ञान पाइपलाइन बनाएँ",
|
||||
"creation.successTip": "सफलता से एक ज्ञान आधार बनाया गया",
|
||||
"deletePipeline.content": "पाइपलाइन टेम्पलेट को हटाना वापस नहीं किया जा सकता।",
|
||||
"deletePipeline.title": "क्या आप इस पाइपलाइन टेम्पलेट को हटाने के लिए निश्चित हैं?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "और जानें",
|
||||
"nTo1RetrievalLegacyLinkText": "N-से-1 पुनर्प्राप्ति सितंबर में आधिकारिक तौर पर बंद कर दी जाएगी।",
|
||||
"noExternalKnowledge": "अभी तक कोई बाहरी ज्ञान एपीआई नहीं है, बनाने के लिए यहां क्लिक करें",
|
||||
"pageTitle.connectExternalKnowledgeBase": "बाहरी ज्ञान आधार कनेक्ट करें",
|
||||
"parentMode.fullDoc": "पूर्ण-दस्तावेज़",
|
||||
"parentMode.paragraph": "अनुच्छेद",
|
||||
"partialEnabled_one": "कुल {{count}} दस्तावेज़, {{num}} उपलब्ध",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "अब पुनः सत्यापित करें ताकि आप आगामी शैक्षणिक वर्ष के लिए एक नया कूपन प्राप्त कर सकें। हम इसे आपके खाते में जोड़ देंगे और आप इसे अगले अपग्रेड के लिए उपयोग कर सकेंगे।",
|
||||
"notice.stillInEducation.isAboutToExpire": "अब फिर से सत्यापित करें ताकि आगामी शैक्षणिक वर्ष के लिए एक नया कूपन मिल सके। यह आपके खाते में सहेजा जाएगा और आपकी अगली नवीनीकरण पर उपयोग के लिए तैयार होगा।",
|
||||
"notice.stillInEducation.title": "क्या आप अभी भी शिक्षा में हैं?",
|
||||
"pageTitle.verification": "शैक्षिक सत्यापन",
|
||||
"planNotSupportEducationDiscount": "शिक्षा मूल्य निर्धारण के लिए पात्र नहीं",
|
||||
"rejectContent": "दुर्भाग्यवश, आप शिक्षा सत्यापित स्थिति के लिए योग्य नहीं हैं और इसलिए यदि आप इस ईमेल पते का उपयोग करते हैं, तो आप डिफाई प्रोफेशनल योजना के लिए विशेष 100% कूपन प्राप्त नहीं कर सकते।",
|
||||
"rejectTitle": "आपकी डिफाई शैक्षणिक सत्यापन को अस्वीकृत कर दिया गया है",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Ciptakan Pengetahuan",
|
||||
"creation.errorTip": "Gagal membuat Basis Pengetahuan",
|
||||
"creation.importDSL": "Mengimpor dari file DSL",
|
||||
"creation.pageTitle": "Buat Pipeline Pengetahuan",
|
||||
"creation.successTip": "Berhasil membuat Basis Pengetahuan",
|
||||
"deletePipeline.content": "Menghapus templat alur tidak dapat diubah.",
|
||||
"deletePipeline.title": "Apakah Anda yakin akan menghapus templat alur ini?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Pelajari lebih lanjut",
|
||||
"nTo1RetrievalLegacyLinkText": "Pengambilan N-to-1 akan secara resmi tidak digunakan lagi pada bulan September.",
|
||||
"noExternalKnowledge": "Belum ada API Pengetahuan Eksternal, klik di sini untuk membuat",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Hubungkan Basis Pengetahuan Eksternal",
|
||||
"parentMode.fullDoc": "Dokumen lengkap",
|
||||
"parentMode.paragraph": "Paragraf",
|
||||
"partialEnabled_one": "Total {{count}} dokumen, {{num}} tersedia",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Verifikasi ulang sekarang untuk mendapatkan kupon baru untuk tahun akademik mendatang. Kami akan menambahkannya ke akun Anda dan Anda dapat menggunakannya untuk peningkatan berikutnya.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Verifikasi ulang sekarang untuk mendapatkan kupon baru untuk tahun akademik mendatang. Ini akan disimpan ke akun Anda dan siap digunakan pada perpanjangan berikutnya.",
|
||||
"notice.stillInEducation.title": "Masih dalam pendidikan?",
|
||||
"pageTitle.verification": "Verifikasi Pendidikan",
|
||||
"planNotSupportEducationDiscount": "Tidak memenuhi syarat untuk harga pendidikan",
|
||||
"rejectContent": "Sayangnya, Anda tidak memenuhi syarat untuk status Education Verified dan oleh karena itu tidak dapat menerima kupon 100% eksklusif untuk Paket Dify Professional jika Anda menggunakan alamat email ini.",
|
||||
"rejectTitle": "Verifikasi Pendidikan Dify Anda telah ditolak",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Creare conoscenza",
|
||||
"creation.errorTip": "Impossibile creare una Knowledge Base",
|
||||
"creation.importDSL": "Importazione da un file DSL",
|
||||
"creation.pageTitle": "Crea pipeline di conoscenza",
|
||||
"creation.successTip": "Creazione di una Knowledge Base",
|
||||
"deletePipeline.content": "L'eliminazione del modello di pipeline è irreversibile.",
|
||||
"deletePipeline.title": "Sei sicuro di eliminare questo modello di pipeline?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Scopri di più",
|
||||
"nTo1RetrievalLegacyLinkText": "Il recupero N-a-1 sarà ufficialmente deprecato a settembre.",
|
||||
"noExternalKnowledge": "Non esiste ancora un'API di conoscenza esterna, fai clic qui per creare",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Connetti base di conoscenza esterna",
|
||||
"parentMode.fullDoc": "Full-doc",
|
||||
"parentMode.paragraph": "Paragrafo",
|
||||
"partialEnabled_one": "Totale di {{count}} documenti, {{num}} disponibili",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Verifica di nuovo ora per ottenere un nuovo coupon per il prossimo anno accademico. Lo aggiungeremo al tuo account e potrai usarlo per il prossimo aggiornamento.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Verifica di nuovo ora per ottenere un nuovo coupon per il prossimo anno accademico. Sarà salvato nel tuo account e pronto per essere utilizzato al tuo prossimo rinnovo.",
|
||||
"notice.stillInEducation.title": "Ancora in formazione?",
|
||||
"pageTitle.verification": "Verifica istruzione",
|
||||
"planNotSupportEducationDiscount": "Non idoneo per i prezzi educativi",
|
||||
"rejectContent": "Sfortunatamente, non sei idoneo per lo status di Educazione Verificata e quindi non puoi ricevere il coupon esclusivo del 100% per il Piano Professionale Dify se usi questo indirizzo email.",
|
||||
"rejectTitle": "La tua verifica educativa Dify è stata rifiutata.",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "ナレッジベースを作成する",
|
||||
"creation.errorTip": "ナレッジベースの作成に失敗しました",
|
||||
"creation.importDSL": "DSLファイルからインポートする",
|
||||
"creation.pageTitle": "ナレッジパイプラインを作成",
|
||||
"creation.successTip": "ナレッジベースが正常に作成されました",
|
||||
"deletePipeline.content": "パイプラインテンプレートの削除は元に戻せません。",
|
||||
"deletePipeline.title": "このパイプラインテンプレートを削除してもよろしいですか?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "詳細はこちら",
|
||||
"nTo1RetrievalLegacyLinkText": " N-to-1 Retrieval は 9 月に正式に廃止されます。",
|
||||
"noExternalKnowledge": "外部ナレッジベース連携 API がありません。ここをクリックして作成してください",
|
||||
"pageTitle.connectExternalKnowledgeBase": "外部知識ベースに接続",
|
||||
"parentMode.fullDoc": "全体",
|
||||
"parentMode.paragraph": "段落",
|
||||
"partialEnabled_one": "合計 {{count}} 件のドキュメント、{{num}} 件が利用可能",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "今すぐ再認証して、次の学年度向けの教育クーポンを取得してください。クーポンはあなたのアカウントに追加され、次回のアップグレード時にご利用いただけます。",
|
||||
"notice.stillInEducation.isAboutToExpire": "今すぐ再認証して、次の学年度向けの教育クーポンを取得してください。クーポンは個人のアカウントに保存され、次回の更新時に使用できます。",
|
||||
"notice.stillInEducation.title": "まだ在学中ですか?",
|
||||
"pageTitle.verification": "教育認証",
|
||||
"planNotSupportEducationDiscount": "教育価格の対象外",
|
||||
"rejectContent": "申し訳ございませんが、このメールアドレスでは 教育認証 の資格を取得できず、Dify プロフェッショナルプランの 100%割引クーポン を受け取ることはできません。",
|
||||
"rejectTitle": "Dify 教育認証が拒否されました",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "지식 창출",
|
||||
"creation.errorTip": "기술 자료를 만들지 못했습니다.",
|
||||
"creation.importDSL": "DSL 파일에서 가져오기",
|
||||
"creation.pageTitle": "지식 파이프라인 생성",
|
||||
"creation.successTip": "기술 자료를 성공적으로 만들었습니다.",
|
||||
"deletePipeline.content": "파이프라인 템플릿을 삭제하는 것은 되돌릴 수 없습니다.",
|
||||
"deletePipeline.title": "이 파이프라인 템플릿을 삭제하시겠습니까?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "자세히 알아보기",
|
||||
"nTo1RetrievalLegacyLinkText": "N-대 -1 검색은 9 월에 공식적으로 더 이상 사용되지 않습니다.",
|
||||
"noExternalKnowledge": "아직 외부 지식 API 가 없으므로 여기를 클릭하여 생성하십시오.",
|
||||
"pageTitle.connectExternalKnowledgeBase": "외부 지식 베이스 연결",
|
||||
"parentMode.fullDoc": "전체 문서",
|
||||
"parentMode.paragraph": "단락",
|
||||
"partialEnabled_one": "총 {{count}}개의 문서 중 {{num}}개 사용 가능",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "지금 다시 확인하여 다가오는 학년도에 사용할 새 쿠폰을 받아보세요. 우리는 그것을 귀하의 계정에 추가하며, 다음 업그레이드에 사용할 수 있습니다.",
|
||||
"notice.stillInEducation.isAboutToExpire": "새로운 학년을 위한 쿠폰을 받으시려면 지금 다시 인증하십시오. 쿠폰은 귀하의 계정에 저장되어 다음 갱신 시 사용할 수 있습니다.",
|
||||
"notice.stillInEducation.title": "아직 학업 중이신가요?",
|
||||
"pageTitle.verification": "교육 인증",
|
||||
"planNotSupportEducationDiscount": "교육 가격 대상 아님",
|
||||
"rejectContent": "안타깝게도, 귀하는 교육 인증 상태에 적합하지 않으므로 이 이메일 주소를 사용할 경우 Dify Professional Plan 의 독점 100% 쿠폰을 받을 수 없습니다.",
|
||||
"rejectTitle": "귀하의 Dify 교육 인증이 거부되었습니다.",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Create Knowledge",
|
||||
"creation.errorTip": "Failed to create a Knowledge Base",
|
||||
"creation.importDSL": "Import from a DSL file",
|
||||
"creation.pageTitle": "Knowledge Pipeline maken",
|
||||
"creation.successTip": "Successfully created a Knowledge Base",
|
||||
"deletePipeline.content": "Deleting the pipeline template is irreversible.",
|
||||
"deletePipeline.title": "Are you sure to delete this pipeline template?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Learn more",
|
||||
"nTo1RetrievalLegacyLinkText": " N-to-1 retrieval will be officially deprecated in September.",
|
||||
"noExternalKnowledge": "There is no External Knowledge API yet, click here to create",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Externe kennisbank verbinden",
|
||||
"parentMode.fullDoc": "Full-doc",
|
||||
"parentMode.paragraph": "Paragraph",
|
||||
"partialEnabled_one": "Total of {{count}} document, {{num}} available",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Re-verify now to get a new coupon for the upcoming academic year. We'll add it to your account and you can use it for the next upgrade.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Re-verify now to get a new coupon for the upcoming academic year. It'll be saved to your account and ready to use at your next renewal.",
|
||||
"notice.stillInEducation.title": "Still in education?",
|
||||
"pageTitle.verification": "Onderwijsverificatie",
|
||||
"planNotSupportEducationDiscount": "Niet in aanmerking voor onderwijsprijzen",
|
||||
"rejectContent": "Unfortunately, you are not eligible for Education Verified status and therefore cannot receive the exclusive 100% coupon for the Dify Professional Plan if you use this email address.",
|
||||
"rejectTitle": "Your Dify Educational Verification Has Been Rejected",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Tworzenie wiedzy",
|
||||
"creation.errorTip": "Nie można utworzyć bazy wiedzy",
|
||||
"creation.importDSL": "Importowanie z pliku DSL",
|
||||
"creation.pageTitle": "Utwórz potok wiedzy",
|
||||
"creation.successTip": "Pomyślnie utworzono bazę wiedzy",
|
||||
"deletePipeline.content": "Usunięcie szablonu potoku jest nieodwracalne.",
|
||||
"deletePipeline.title": "Czy na pewno chcesz usunąć ten szablon potoku?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Dowiedz się więcej",
|
||||
"nTo1RetrievalLegacyLinkText": "Wyszukiwanie N-do-1 zostanie oficjalnie wycofane we wrześniu.",
|
||||
"noExternalKnowledge": "Nie ma jeszcze interfejsu API wiedzy zewnętrznej, kliknij tutaj, aby utworzyć",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Połącz zewnętrzną bazę wiedzy",
|
||||
"parentMode.fullDoc": "Pełna wersja dokumentu",
|
||||
"parentMode.paragraph": "Akapit",
|
||||
"partialEnabled_one": "Łącznie {{count}} dokumentów, {{num}} dostępnych",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Sprawdź ponownie teraz, aby otrzymać nowy kupon na nadchodzący rok akademicki. Dodamy go do twojego konta i będziesz mógł go użyć przy następnej aktualizacji.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Zweryfikuj ponownie teraz, aby otrzymać nowy kupon na nadchodzący rok akademicki. Zostanie zapisany na Twoim koncie i gotowy do użycia przy następnej odnowie.",
|
||||
"notice.stillInEducation.title": "Wciąż w edukacji?",
|
||||
"pageTitle.verification": "Weryfikacja edukacyjna",
|
||||
"planNotSupportEducationDiscount": "Nie kwalifikuje się do cen edukacyjnych",
|
||||
"rejectContent": "Niestety, nie kwalifikujesz się do statusu Zweryfikowanej Edukacji i w związku z tym nie możesz otrzymać ekskluzywnego kuponu 100% na plan Dify Professional, jeśli korzystasz z tego adresu e-mail.",
|
||||
"rejectTitle": "Twoja weryfikacja edukacyjna Dify została odrzucona",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Criar conhecimento",
|
||||
"creation.errorTip": "Falha ao criar uma base de dados de conhecimento",
|
||||
"creation.importDSL": "Importar de um arquivo DSL",
|
||||
"creation.pageTitle": "Criar pipeline de conhecimento",
|
||||
"creation.successTip": "Criou com sucesso uma Base de Dados de Conhecimento",
|
||||
"deletePipeline.content": "A exclusão do modelo de pipeline é irreversível.",
|
||||
"deletePipeline.title": "Tem certeza de que deseja excluir este modelo de pipeline?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Saiba mais",
|
||||
"nTo1RetrievalLegacyLinkText": "A recuperação N-para-1 será oficialmente descontinuada em setembro.",
|
||||
"noExternalKnowledge": "Ainda não existe uma API de conhecimento externo, clique aqui para criar",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Conectar base de conhecimento externa",
|
||||
"parentMode.fullDoc": "Documento completo",
|
||||
"parentMode.paragraph": "Parágrafo",
|
||||
"partialEnabled_one": "Total de {{count}} documentos, {{num}} disponíveis",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Reveja agora para obter um novo cupom para o próximo ano acadêmico. Nós o adicionaremos à sua conta e você poderá usá-lo na próxima atualização.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Verifique novamente agora para receber um novo cupom para o próximo ano acadêmico. Ele será salvo na sua conta e estará pronto para ser usado na sua próxima renovação.",
|
||||
"notice.stillInEducation.title": "Ainda na educação?",
|
||||
"pageTitle.verification": "Verificação educacional",
|
||||
"planNotSupportEducationDiscount": "Não elegível para preço educacional",
|
||||
"rejectContent": "Infelizmente, você não é elegível para o status de Educação Verificada e, portanto, não pode receber o cupom exclusivo de 100% para o Plano Profissional Dify se usar este endereço de e-mail.",
|
||||
"rejectTitle": "A sua verificação educacional Dify foi rejeitada.",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Creați cunoștințe",
|
||||
"creation.errorTip": "Nu s-a reușit crearea unei baze de cunoștințe",
|
||||
"creation.importDSL": "Importul dintr-un fișier DSL",
|
||||
"creation.pageTitle": "Creează pipeline de cunoștințe",
|
||||
"creation.successTip": "Crearea cu succes a unei baze de cunoștințe",
|
||||
"deletePipeline.content": "Ștergerea șablonului de conductă este ireversibilă.",
|
||||
"deletePipeline.title": "Sunteți sigur că ștergeți acest șablon de conductă?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Află mai multe",
|
||||
"nTo1RetrievalLegacyLinkText": "Recuperarea N-la-1 va fi oficial depreciată în septembrie.",
|
||||
"noExternalKnowledge": "Nu există încă un API de cunoștințe externe, faceți clic aici pentru a crea",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Conectează baza de cunoștințe externă",
|
||||
"parentMode.fullDoc": "Documentar complet",
|
||||
"parentMode.paragraph": "Paragraf",
|
||||
"partialEnabled_one": "Total de {{count}} documente, {{num}} disponibile",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Re-verificați acum pentru a obține un nou cupon pentru următorul an academic. Vom adăuga acest cupon în contul dvs. și îl puteți folosi pentru următoarea actualizare.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Re-verifică acum pentru a obține un nou cupon pentru anul universitar următor. Va fi salvat în contul tău și gata de utilizat la următoarea reînnoire.",
|
||||
"notice.stillInEducation.title": "Încă în educație?",
|
||||
"pageTitle.verification": "Verificare educațională",
|
||||
"planNotSupportEducationDiscount": "Nu este eligibil pentru prețuri educaționale",
|
||||
"rejectContent": "Din păcate, nu ești eligibil pentru statutul de Verificat Educațional și, prin urmare, nu poți primi cuponul exclusiv de 100% pentru Planul Profesional Dify dacă folosești această adresă de email.",
|
||||
"rejectTitle": "Verificarea educațională Dify a fost respinsă",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Создание знаний",
|
||||
"creation.errorTip": "Не удалось создать базу знаний",
|
||||
"creation.importDSL": "Импорт из файла DSL",
|
||||
"creation.pageTitle": "Создать конвейер знаний",
|
||||
"creation.successTip": "Успешно создали базу знаний",
|
||||
"deletePipeline.content": "Удаление шаблона конвейера является необратимым.",
|
||||
"deletePipeline.title": "Вы уверены, что удалите этот шаблон воронки продаж?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Узнать больше",
|
||||
"nTo1RetrievalLegacyLinkText": " Поиск N-к-1 будет официально прекращен в сентябре.",
|
||||
"noExternalKnowledge": "У нас еще нет External Knowledge API, нажмите здесь, чтобы создать",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Подключить внешнюю базу знаний",
|
||||
"parentMode.fullDoc": "Полный документ",
|
||||
"parentMode.paragraph": "Параграф",
|
||||
"partialEnabled_one": "Всего {{count}} документов, доступно {{num}}",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Переутвердите сейчас, чтобы получить новый купон на предстоящий учебный год. Мы добавим его на ваш аккаунт, и вы сможете использовать его для следующего обновления.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Проверьте еще раз, чтобы получить новый купон на предстоящий учебный год. Он будет сохранен в вашем аккаунте и готов к использованию при следующем продлении.",
|
||||
"notice.stillInEducation.title": "Все еще учишься?",
|
||||
"pageTitle.verification": "Проверка статуса обучения",
|
||||
"planNotSupportEducationDiscount": "Не подходит для образовательной цены",
|
||||
"rejectContent": "К сожалению, вы не имеете права на статус Проверенного образованием и, следовательно, не можете получить эксклюзивный купон на 100% для профессионального плана Dify, если вы используете этот адрес электронной почты.",
|
||||
"rejectTitle": "Ваша образовательная проверка Dify была отклонена",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Ustvarite znanje",
|
||||
"creation.errorTip": "Ustvarjanje zbirke znanja ni uspelo",
|
||||
"creation.importDSL": "Uvoz iz datoteke DSL",
|
||||
"creation.pageTitle": "Ustvari cevovod znanja",
|
||||
"creation.successTip": "Uspešno ustvarjena baza znanja",
|
||||
"deletePipeline.content": "Brisanje predloge cevovoda je nepovratno.",
|
||||
"deletePipeline.title": "Ali ste prepričani, da boste izbrisali to predlogo cevovoda?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Izvedite več",
|
||||
"nTo1RetrievalLegacyLinkText": "N-to-1 pridobivanje bo uradno ukinjeno septembra.",
|
||||
"noExternalKnowledge": "Zunanjega API-ja za znanje še ni, kliknite tukaj za ustvarjanje",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Poveži zunanjo bazo znanja",
|
||||
"parentMode.fullDoc": "Celoten dokument",
|
||||
"parentMode.paragraph": "Odstavek",
|
||||
"partialEnabled_one": "Skupno {{count}} dokumentov, na voljo {{num}}",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Ponovno preverite zdaj, da pridobite nov kupon za prihajajoče šolsko leto. Dodali ga bomo vašemu računu in lahko ga uporabite za naslednjo nadgradnjo.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Ponovno preverite zdaj, da pridobite nov kupon za prihajajoče akademsko leto. Shranjen bo na vašem računu in pripravljen za uporabo ob vaši naslednji obnovitvi.",
|
||||
"notice.stillInEducation.title": "Še vedno v izobraževanju?",
|
||||
"pageTitle.verification": "Preverjanje izobraževalnega statusa",
|
||||
"planNotSupportEducationDiscount": "Ni upravičen do izobraževalnih cen",
|
||||
"rejectContent": "Na žalost niste upravičeni do statusa Verificirane izobrazbe in zato ne morete prejeti ekskluzivnega 100-odstotnega kupona za Dify profesionalni načrt, če uporabljate ta e-poštni naslov.",
|
||||
"rejectTitle": "Vaša Dify izobraževalna verifikacija je bila zavrnjena.",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "สร้างความรู้",
|
||||
"creation.errorTip": "สร้างฐานความรู้ไม่สําเร็จ",
|
||||
"creation.importDSL": "นําเข้าจากไฟล์ DSL",
|
||||
"creation.pageTitle": "สร้างไปป์ไลน์ความรู้",
|
||||
"creation.successTip": "สร้างฐานความรู้สําเร็จ",
|
||||
"deletePipeline.content": "การลบเทมเพลตไปป์ไลน์ไม่สามารถย้อนกลับได้",
|
||||
"deletePipeline.title": "คุณแน่ใจที่จะลบเทมเพลตไปป์ไลน์นี้หรือไม่",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "ศึกษาเพิ่มเติม",
|
||||
"nTo1RetrievalLegacyLinkText": "การดึงข้อมูล N-to-1 จะเลิกใช้อย่างเป็นทางการในเดือนกันยายน",
|
||||
"noExternalKnowledge": "ยังไม่มี External Knowledge API คลิกที่นี่เพื่อสร้าง",
|
||||
"pageTitle.connectExternalKnowledgeBase": "เชื่อมต่อฐานความรู้ภายนอก",
|
||||
"parentMode.fullDoc": "เอกสารฉบับเต็ม",
|
||||
"parentMode.paragraph": "วรรค",
|
||||
"partialEnabled_one": "รวม {{count}} เอกสาร, {{num}} ใช้งานได้",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "ตรวจสอบอีกครั้งตอนนี้เพื่อรับคูปองใหม่สำหรับปีการศึกษาใหม่ เราจะเพิ่มมันเข้ากับบัญชีของคุณและคุณสามารถใช้มันสำหรับการอัปเกรดครั้งถัดไปได้",
|
||||
"notice.stillInEducation.isAboutToExpire": "ตรวจสอบอีกครั้งเดี๋ยวนี้เพื่อรับคูปองใหม่สำหรับปีการศึกษาที่จะมาถึง มันจะถูกบันทึกในบัญชีของคุณและพร้อมใช้งานในการต่ออายุครั้งถัดไปของคุณ.",
|
||||
"notice.stillInEducation.title": "ยังอยู่ในวัยเรียนใช่ไหม?",
|
||||
"pageTitle.verification": "การยืนยันสถานะการศึกษา",
|
||||
"planNotSupportEducationDiscount": "ไม่มีสิทธิ์รับราคาการศึกษา",
|
||||
"rejectContent": "น่าเสียดายที่คุณไม่มีสิทธิ์ได้รับสถานะการตรวจสอบการศึกษาและดังนั้นคุณจึงไม่สามารถรับคูปองพิเศษ 100% สำหรับแผนมืออาชีพ Dify หากคุณใช้ที่อยู่อีเมลนี้.",
|
||||
"rejectTitle": "การตรวจสอบการศึกษา Dify ของคุณถูกปฏิเสธ",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Bilgi Oluştur",
|
||||
"creation.errorTip": "Bilgi Bankası oluşturulamadı",
|
||||
"creation.importDSL": "DSL dosyasından içe aktarma",
|
||||
"creation.pageTitle": "Bilgi işlem hattı oluştur",
|
||||
"creation.successTip": "Başarıyla bir Bilgi Bankası oluşturuldu",
|
||||
"deletePipeline.content": "İşlem hattı şablonunun silinmesi geri alınamaz.",
|
||||
"deletePipeline.title": "Bu işlem hattı şablonunu sildiğinizden emin misiniz?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Daha fazla bilgi edin",
|
||||
"nTo1RetrievalLegacyLinkText": "N-1 geri alma Eylül ayında resmi olarak kullanımdan kaldırılacaktır.",
|
||||
"noExternalKnowledge": "Henüz Harici Bilgi API'si yok, oluşturmak için buraya tıklayın",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Harici bilgi tabanını bağla",
|
||||
"parentMode.fullDoc": "Tam doküman",
|
||||
"parentMode.paragraph": "Paragraf",
|
||||
"partialEnabled_one": "Toplam {{count}} belge, {{num}} mevcut",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Şimdi yeniden doğrulayın, böylece yaklaşan akademik yıl için yeni bir kupon alın. Bu kuponu hesabınıza ekleyeceğiz ve sonraki yükseltme için kullanabilirsiniz.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Şimdi yeniden doğrulayın ve gelecek akademik yıl için yeni bir kupon alın. Bu, hesabınıza kaydedilecek ve bir sonraki yenilemenizde kullanıma hazır olacak.",
|
||||
"notice.stillInEducation.title": "Hala eğitimde misin?",
|
||||
"pageTitle.verification": "Eğitim doğrulaması",
|
||||
"planNotSupportEducationDiscount": "Eğitim fiyatlandırması için uygun değil",
|
||||
"rejectContent": "Maalesef, Eğitim Doğrulama statüsüne uygun değilsiniz ve bu nedenle bu e-posta adresini kullanıyorsanız Dify Profesyonel Planı için özel %100 kuponu alamazsınız.",
|
||||
"rejectTitle": "Dify Eğitim Doğrulamanız Rededildi",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Створюйте знання",
|
||||
"creation.errorTip": "Не вдалося створити базу знань",
|
||||
"creation.importDSL": "Імпорт із файлу DSL",
|
||||
"creation.pageTitle": "Створити конвеєр знань",
|
||||
"creation.successTip": "Успішно створили Базу знань",
|
||||
"deletePipeline.content": "Видалення шаблону трубопроводу є незворотнім.",
|
||||
"deletePipeline.title": "Ви впевнені, що видалили цей шаблон пайплайну?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Дізнатися більше",
|
||||
"nTo1RetrievalLegacyLinkText": "N-до-1 пошук буде офіційно застарілим у вересні.",
|
||||
"noExternalKnowledge": "API зовнішніх знань поки що не існує, натисніть тут, щоб створити",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Підключити зовнішню базу знань",
|
||||
"parentMode.fullDoc": "Повний документ",
|
||||
"parentMode.paragraph": "Абзац",
|
||||
"partialEnabled_one": "Всього {{count}} документів, доступно {{num}}",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Перевірте ще раз зараз, щоб отримати новий купон на наступний навчальний рік. Ми додамо його до вашого облікового запису, і ви зможете скористатися ним для наступного оновлення.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Перевірте ще раз зараз, щоб отримати новий купон на наступний навчальний рік. Він буде збережений у вашому обліковому записі та готовий до використання при наступному поновленні.",
|
||||
"notice.stillInEducation.title": "Все ще навчаєшся?",
|
||||
"pageTitle.verification": "Перевірка освітнього статусу",
|
||||
"planNotSupportEducationDiscount": "Не підходить для освітньої ціни",
|
||||
"rejectContent": "На жаль, ви не відповідаєте вимогам для статусу Education Verified і тому не можете отримати ексклюзивний купон на 100% для професійного плану Dify, якщо використовуєте цю електронну адресу.",
|
||||
"rejectTitle": "Ваша перевірка освіти Dify була відхилена",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "Tạo kiến thức",
|
||||
"creation.errorTip": "Không thể tạo Cơ sở kiến thức",
|
||||
"creation.importDSL": "Nhập từ tệp DSL",
|
||||
"creation.pageTitle": "Tạo quy trình tri thức",
|
||||
"creation.successTip": "Tạo thành công Cơ sở tri thức",
|
||||
"deletePipeline.content": "Xóa mẫu quy trình là không thể đảo ngược.",
|
||||
"deletePipeline.title": "Bạn có chắc chắn xóa mẫu quy trình này không?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "Tìm hiểu thêm",
|
||||
"nTo1RetrievalLegacyLinkText": "Truy xuất N-đến-1 sẽ chính thức bị loại bỏ vào tháng 9.",
|
||||
"noExternalKnowledge": "Chưa có API Kiến thức Bên ngoài, hãy nhấp vào đây để tạo",
|
||||
"pageTitle.connectExternalKnowledgeBase": "Kết nối cơ sở kiến thức bên ngoài",
|
||||
"parentMode.fullDoc": "Tài liệu đầy đủ",
|
||||
"parentMode.paragraph": "Đoạn",
|
||||
"partialEnabled_one": "Tổng cộng {{count}} tài liệu, {{num}} có sẵn",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "Xác minh lại ngay bây giờ để nhận một phiếu giảm giá mới cho năm học sắp tới. Chúng tôi sẽ thêm nó vào tài khoản của bạn và bạn có thể sử dụng nó cho lần nâng cấp tiếp theo.",
|
||||
"notice.stillInEducation.isAboutToExpire": "Xác minh lại ngay bây giờ để nhận một phiếu giảm giá mới cho năm học sắp tới. Nó sẽ được lưu vào tài khoản của bạn và sẵn sàng sử dụng khi bạn gia hạn tiếp theo.",
|
||||
"notice.stillInEducation.title": "Vẫn đang học tập?",
|
||||
"pageTitle.verification": "Xác minh giáo dục",
|
||||
"planNotSupportEducationDiscount": "Không đủ điều kiện cho giá giáo dục",
|
||||
"rejectContent": "Rất tiếc, bạn không đủ điều kiện để nhận trạng thái Xác minh Giáo dục và do đó không thể nhận được mã giảm giá độc quyền 100% cho Kế hoạch Chuyên nghiệp Dify nếu bạn sử dụng địa chỉ email này.",
|
||||
"rejectTitle": "Yêu cầu xác minh giáo dục Dify của bạn đã bị từ chối",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "创建知识流水线",
|
||||
"creation.errorTip": "创建知识流水线失败",
|
||||
"creation.importDSL": "从 DSL 文件导入",
|
||||
"creation.pageTitle": "创建知识流水线",
|
||||
"creation.successTip": "成功创建知识流水线",
|
||||
"deletePipeline.content": "删除知识流水线模板是不可逆的。",
|
||||
"deletePipeline.title": "要删除此知识流水线模板吗?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "了解更多",
|
||||
"nTo1RetrievalLegacyLinkText": "9 月 1 日起我们将不再提供此能力。",
|
||||
"noExternalKnowledge": "还没有外部知识库 API,点击此处创建",
|
||||
"pageTitle.connectExternalKnowledgeBase": "连接外部知识库",
|
||||
"parentMode.fullDoc": "全文",
|
||||
"parentMode.paragraph": "段落",
|
||||
"partialEnabled_one": "共计 {{count}} 个文档, {{num}} 可用",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "立即重新认证,获取新学年的教育优惠券。优惠券将发放至您的账户,并可在下次升级时使用。",
|
||||
"notice.stillInEducation.isAboutToExpire": "立即重新验证,获取新学年的教育优惠券。优惠券将发放至您的账户,并可在下次续订时使用。",
|
||||
"notice.stillInEducation.title": "仍在就读?",
|
||||
"pageTitle.verification": "教育认证",
|
||||
"planNotSupportEducationDiscount": "不适用教育优惠价格",
|
||||
"rejectContent": "非常遗憾,您无法使用此电子邮件以获得教育版认证资格,也无法领取 Dify Professional 版的 100% 独家优惠券。",
|
||||
"rejectTitle": "您的 Dify 教育版认证已被拒绝",
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
"creation.createKnowledge": "創造知識",
|
||||
"creation.errorTip": "無法建立知識庫",
|
||||
"creation.importDSL": "從 DSL 檔案匯入",
|
||||
"creation.pageTitle": "建立知識流水線",
|
||||
"creation.successTip": "成功建立知識庫",
|
||||
"deletePipeline.content": "刪除管線範本是不可逆的。",
|
||||
"deletePipeline.title": "您確定要刪除此管線範本嗎?",
|
||||
|
||||
@ -146,7 +146,6 @@
|
||||
"nTo1RetrievalLegacyLink": "了解更多",
|
||||
"nTo1RetrievalLegacyLinkText": "N 對 1 檢索將於 9 月正式棄用。",
|
||||
"noExternalKnowledge": "目前還沒有外部知識 API,按兩下此處創建",
|
||||
"pageTitle.connectExternalKnowledgeBase": "連接外部知識庫",
|
||||
"parentMode.fullDoc": "完整文件",
|
||||
"parentMode.paragraph": "段",
|
||||
"partialEnabled_one": "共 {{count}} 份文件,{{num}} 份可用",
|
||||
|
||||
@ -51,7 +51,6 @@
|
||||
"notice.stillInEducation.expired": "立即重新驗證,以獲得即將到來的學年新優惠券。我們會將其新增到您的帳戶中,您可以用於下一次升級。",
|
||||
"notice.stillInEducation.isAboutToExpire": "現在重新驗證以獲得即將到來的學年新優惠券。它將保存在您的帳戶中,並在下次續訂時隨時可以使用。",
|
||||
"notice.stillInEducation.title": "仍在接受教育嗎?",
|
||||
"pageTitle.verification": "教育認證",
|
||||
"planNotSupportEducationDiscount": "不適用教育優惠價格",
|
||||
"rejectContent": "不幸的是,您不符合教育驗證狀態,因此如果您使用此電子郵件地址,將無法獲得 Dify 專業計劃的 100% 獨家優惠券。",
|
||||
"rejectTitle": "您的 Dify 教育驗證已被拒絕",
|
||||
|
||||
Reference in New Issue
Block a user