From ad67094e54838fe7bbd23ef2b74ee6f1fbcd75c2 Mon Sep 17 00:00:00 2001 From: Maries Date: Wed, 23 Jul 2025 13:12:39 +0800 Subject: [PATCH 01/10] feat: oauth refresh token (#22744) Co-authored-by: Yeuoly --- .../console/workspace/tool_providers.py | 8 +++- api/core/plugin/entities/plugin_daemon.py | 4 ++ api/core/plugin/impl/oauth.py | 35 ++++++++++++++++ api/core/tools/tool_manager.py | 42 ++++++++++++++++++- ...2_0019-375fe79ead14_oauth_refresh_token.py | 34 +++++++++++++++ api/models/tools.py | 1 + .../tools/builtin_tools_manage_service.py | 5 +++ 7 files changed, 125 insertions(+), 4 deletions(-) create mode 100644 api/migrations/versions/2025_07_22_0019-375fe79ead14_oauth_refresh_token.py diff --git a/api/controllers/console/workspace/tool_providers.py b/api/controllers/console/workspace/tool_providers.py index c70bf84d2a..c4d1ef70d8 100644 --- a/api/controllers/console/workspace/tool_providers.py +++ b/api/controllers/console/workspace/tool_providers.py @@ -739,7 +739,7 @@ class ToolOAuthCallback(Resource): raise Forbidden("no oauth available client config found for this tool provider") redirect_uri = f"{dify_config.CONSOLE_API_URL}/console/api/oauth/plugin/{provider}/tool/callback" - credentials = oauth_handler.get_credentials( + credentials_response = oauth_handler.get_credentials( tenant_id=tenant_id, user_id=user_id, plugin_id=plugin_id, @@ -747,7 +747,10 @@ class ToolOAuthCallback(Resource): redirect_uri=redirect_uri, system_credentials=oauth_client_params, request=request, - ).credentials + ) + + credentials = credentials_response.credentials + expires_at = credentials_response.expires_at if not credentials: raise Exception("the plugin credentials failed") @@ -758,6 +761,7 @@ class ToolOAuthCallback(Resource): tenant_id=tenant_id, provider=provider, credentials=dict(credentials), + expires_at=expires_at, api_type=CredentialType.OAUTH2, ) return redirect(f"{dify_config.CONSOLE_WEB_URL}/oauth-callback") diff --git a/api/core/plugin/entities/plugin_daemon.py b/api/core/plugin/entities/plugin_daemon.py index 00253b8a11..16ab661092 100644 --- a/api/core/plugin/entities/plugin_daemon.py +++ b/api/core/plugin/entities/plugin_daemon.py @@ -182,6 +182,10 @@ class PluginOAuthAuthorizationUrlResponse(BaseModel): class PluginOAuthCredentialsResponse(BaseModel): + metadata: Mapping[str, Any] = Field( + default_factory=dict, description="The metadata of the OAuth, like avatar url, name, etc." + ) + expires_at: int = Field(default=-1, description="The expires at time of the credentials. UTC timestamp.") credentials: Mapping[str, Any] = Field(description="The credentials of the OAuth.") diff --git a/api/core/plugin/impl/oauth.py b/api/core/plugin/impl/oauth.py index d73e5d9f9e..7f022992ff 100644 --- a/api/core/plugin/impl/oauth.py +++ b/api/core/plugin/impl/oauth.py @@ -84,6 +84,41 @@ class OAuthHandler(BasePluginClient): except Exception as e: raise ValueError(f"Error getting credentials: {e}") + def refresh_credentials( + self, + tenant_id: str, + user_id: str, + plugin_id: str, + provider: str, + redirect_uri: str, + system_credentials: Mapping[str, Any], + credentials: Mapping[str, Any], + ) -> PluginOAuthCredentialsResponse: + try: + response = self._request_with_plugin_daemon_response_stream( + "POST", + f"plugin/{tenant_id}/dispatch/oauth/refresh_credentials", + PluginOAuthCredentialsResponse, + data={ + "user_id": user_id, + "data": { + "provider": provider, + "redirect_uri": redirect_uri, + "system_credentials": system_credentials, + "credentials": credentials, + }, + }, + headers={ + "X-Plugin-ID": plugin_id, + "Content-Type": "application/json", + }, + ) + for resp in response: + return resp + raise ValueError("No response received from plugin daemon for refresh credentials request.") + except Exception as e: + raise ValueError(f"Error refreshing credentials: {e}") + def _convert_request_to_raw_data(self, request: Request) -> bytes: """ Convert a Request object to raw HTTP data. diff --git a/api/core/tools/tool_manager.py b/api/core/tools/tool_manager.py index 7822bc389c..abbdf8de3f 100644 --- a/api/core/tools/tool_manager.py +++ b/api/core/tools/tool_manager.py @@ -1,16 +1,19 @@ import json import logging import mimetypes -from collections.abc import Generator +import time +from collections.abc import Generator, Mapping from os import listdir, path from threading import Lock from typing import TYPE_CHECKING, Any, Literal, Optional, Union, cast +from pydantic import TypeAdapter from yarl import URL import contexts from core.helper.provider_cache import ToolProviderCredentialsCache from core.plugin.entities.plugin import ToolProviderID +from core.plugin.impl.oauth import OAuthHandler from core.plugin.impl.tool import PluginToolManager from core.tools.__base.tool_provider import ToolProviderController from core.tools.__base.tool_runtime import ToolRuntime @@ -244,12 +247,47 @@ class ToolManager: tenant_id=tenant_id, provider=provider_id, credential_id=builtin_provider.id ), ) + + # decrypt the credentials + decrypted_credentials: Mapping[str, Any] = encrypter.decrypt(builtin_provider.credentials) + + # check if the credentials is expired + if builtin_provider.expires_at != -1 and (builtin_provider.expires_at - 60) < int(time.time()): + # TODO: circular import + from services.tools.builtin_tools_manage_service import BuiltinToolManageService + + # refresh the credentials + tool_provider = ToolProviderID(provider_id) + provider_name = tool_provider.provider_name + redirect_uri = f"{dify_config.CONSOLE_API_URL}/console/api/oauth/plugin/{provider_id}/tool/callback" + system_credentials = BuiltinToolManageService.get_oauth_client(tenant_id, provider_id) + oauth_handler = OAuthHandler() + # refresh the credentials + refreshed_credentials = oauth_handler.refresh_credentials( + tenant_id=tenant_id, + user_id=builtin_provider.user_id, + plugin_id=tool_provider.plugin_id, + provider=provider_name, + redirect_uri=redirect_uri, + system_credentials=system_credentials or {}, + credentials=decrypted_credentials, + ) + # update the credentials + builtin_provider.encrypted_credentials = ( + TypeAdapter(dict[str, Any]) + .dump_json(encrypter.encrypt(dict(refreshed_credentials.credentials))) + .decode("utf-8") + ) + builtin_provider.expires_at = refreshed_credentials.expires_at + db.session.commit() + decrypted_credentials = refreshed_credentials.credentials + return cast( BuiltinTool, builtin_tool.fork_tool_runtime( runtime=ToolRuntime( tenant_id=tenant_id, - credentials=encrypter.decrypt(builtin_provider.credentials), + credentials=dict(decrypted_credentials), credential_type=CredentialType.of(builtin_provider.credential_type), runtime_parameters={}, invoke_from=invoke_from, diff --git a/api/migrations/versions/2025_07_22_0019-375fe79ead14_oauth_refresh_token.py b/api/migrations/versions/2025_07_22_0019-375fe79ead14_oauth_refresh_token.py new file mode 100644 index 0000000000..76d0cb2940 --- /dev/null +++ b/api/migrations/versions/2025_07_22_0019-375fe79ead14_oauth_refresh_token.py @@ -0,0 +1,34 @@ +"""oauth_refresh_token + +Revision ID: 375fe79ead14 +Revises: 1a83934ad6d1 +Create Date: 2025-07-22 00:19:45.599636 + +""" +from alembic import op +import models as models +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '375fe79ead14' +down_revision = '1a83934ad6d1' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table('tool_builtin_providers', schema=None) as batch_op: + batch_op.add_column(sa.Column('expires_at', sa.BigInteger(), server_default=sa.text('-1'), nullable=False)) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + + with op.batch_alter_table('tool_builtin_providers', schema=None) as batch_op: + batch_op.drop_column('expires_at') + + # ### end Alembic commands ### diff --git a/api/models/tools.py b/api/models/tools.py index a0b7e54175..8c91e91f0e 100644 --- a/api/models/tools.py +++ b/api/models/tools.py @@ -93,6 +93,7 @@ class BuiltinToolProvider(Base): credential_type: Mapped[str] = mapped_column( db.String(32), nullable=False, server_default=db.text("'api-key'::character varying") ) + expires_at: Mapped[int] = mapped_column(db.BigInteger, nullable=False, server_default=db.text("-1")) @property def credentials(self) -> dict: diff --git a/api/services/tools/builtin_tools_manage_service.py b/api/services/tools/builtin_tools_manage_service.py index 430575b532..b8e3ce2650 100644 --- a/api/services/tools/builtin_tools_manage_service.py +++ b/api/services/tools/builtin_tools_manage_service.py @@ -38,6 +38,7 @@ logger = logging.getLogger(__name__) class BuiltinToolManageService: __MAX_BUILTIN_TOOL_PROVIDER_COUNT__ = 100 + __DEFAULT_EXPIRES_AT__ = 2147483647 @staticmethod def delete_custom_oauth_client_params(tenant_id: str, provider: str): @@ -212,6 +213,7 @@ class BuiltinToolManageService: tenant_id: str, provider: str, credentials: dict, + expires_at: int = -1, name: str | None = None, ): """ @@ -269,6 +271,9 @@ class BuiltinToolManageService: encrypted_credentials=json.dumps(encrypter.encrypt(credentials)), credential_type=api_type.value, name=name, + expires_at=expires_at + if expires_at is not None + else BuiltinToolManageService.__DEFAULT_EXPIRES_AT__, ) session.add(db_provider) From 82cc37bf512d84fc461caeb499e2eee155a15c58 Mon Sep 17 00:00:00 2001 From: -LAN- Date: Wed, 23 Jul 2025 13:22:15 +0800 Subject: [PATCH 02/10] chore(tests): Remove outdated tests (#22816) Signed-off-by: -LAN- --- ...est_provider_update_deadlock_prevention.py | 248 ------------------ 1 file changed, 248 deletions(-) delete mode 100644 tests/unit_tests/events/test_provider_update_deadlock_prevention.py diff --git a/tests/unit_tests/events/test_provider_update_deadlock_prevention.py b/tests/unit_tests/events/test_provider_update_deadlock_prevention.py deleted file mode 100644 index 47c175acd7..0000000000 --- a/tests/unit_tests/events/test_provider_update_deadlock_prevention.py +++ /dev/null @@ -1,248 +0,0 @@ -import threading -from unittest.mock import Mock, patch - -from core.app.entities.app_invoke_entities import ChatAppGenerateEntity -from core.entities.provider_entities import QuotaUnit -from events.event_handlers.update_provider_when_message_created import ( - handle, - get_update_stats, -) -from models.provider import ProviderType -from sqlalchemy.exc import OperationalError - - -class TestProviderUpdateDeadlockPrevention: - """Test suite for deadlock prevention in Provider updates.""" - - def setup_method(self): - """Setup test fixtures.""" - self.mock_message = Mock() - self.mock_message.answer_tokens = 100 - - self.mock_app_config = Mock() - self.mock_app_config.tenant_id = "test-tenant-123" - - self.mock_model_conf = Mock() - self.mock_model_conf.provider = "openai" - - self.mock_system_config = Mock() - self.mock_system_config.current_quota_type = QuotaUnit.TOKENS - - self.mock_provider_config = Mock() - self.mock_provider_config.using_provider_type = ProviderType.SYSTEM - self.mock_provider_config.system_configuration = self.mock_system_config - - self.mock_provider_bundle = Mock() - self.mock_provider_bundle.configuration = self.mock_provider_config - - self.mock_model_conf.provider_model_bundle = self.mock_provider_bundle - - self.mock_generate_entity = Mock(spec=ChatAppGenerateEntity) - self.mock_generate_entity.app_config = self.mock_app_config - self.mock_generate_entity.model_conf = self.mock_model_conf - - @patch("events.event_handlers.update_provider_when_message_created.db") - def test_consolidated_handler_basic_functionality(self, mock_db): - """Test that the consolidated handler performs both updates correctly.""" - # Setup mock query chain - mock_query = Mock() - mock_db.session.query.return_value = mock_query - mock_query.filter.return_value = mock_query - mock_query.order_by.return_value = mock_query - mock_query.update.return_value = 1 # 1 row affected - - # Call the handler - handle(self.mock_message, application_generate_entity=self.mock_generate_entity) - - # Verify db.session.query was called - assert mock_db.session.query.called - - # Verify commit was called - mock_db.session.commit.assert_called_once() - - # Verify no rollback was called - assert not mock_db.session.rollback.called - - @patch("events.event_handlers.update_provider_when_message_created.db") - def test_deadlock_retry_mechanism(self, mock_db): - """Test that deadlock errors trigger retry logic.""" - # Setup mock to raise deadlock error on first attempt, succeed on second - mock_query = Mock() - mock_db.session.query.return_value = mock_query - mock_query.filter.return_value = mock_query - mock_query.order_by.return_value = mock_query - mock_query.update.return_value = 1 - - # First call raises deadlock, second succeeds - mock_db.session.commit.side_effect = [ - OperationalError("deadlock detected", None, None), - None, # Success on retry - ] - - # Call the handler - handle(self.mock_message, application_generate_entity=self.mock_generate_entity) - - # Verify commit was called twice (original + retry) - assert mock_db.session.commit.call_count == 2 - - # Verify rollback was called once (after first failure) - mock_db.session.rollback.assert_called_once() - - @patch("events.event_handlers.update_provider_when_message_created.db") - @patch("events.event_handlers.update_provider_when_message_created.time.sleep") - def test_exponential_backoff_timing(self, mock_sleep, mock_db): - """Test that retry delays follow exponential backoff pattern.""" - # Setup mock to fail twice, succeed on third attempt - mock_query = Mock() - mock_db.session.query.return_value = mock_query - mock_query.filter.return_value = mock_query - mock_query.order_by.return_value = mock_query - mock_query.update.return_value = 1 - - mock_db.session.commit.side_effect = [ - OperationalError("deadlock detected", None, None), - OperationalError("deadlock detected", None, None), - None, # Success on third attempt - ] - - # Call the handler - handle(self.mock_message, application_generate_entity=self.mock_generate_entity) - - # Verify sleep was called twice with increasing delays - assert mock_sleep.call_count == 2 - - # First delay should be around 0.1s + jitter - first_delay = mock_sleep.call_args_list[0][0][0] - assert 0.1 <= first_delay <= 0.3 - - # Second delay should be around 0.2s + jitter - second_delay = mock_sleep.call_args_list[1][0][0] - assert 0.2 <= second_delay <= 0.4 - - def test_concurrent_handler_execution(self): - """Test that multiple handlers can run concurrently without deadlock.""" - results = [] - errors = [] - - def run_handler(): - try: - with patch( - "events.event_handlers.update_provider_when_message_created.db" - ) as mock_db: - mock_query = Mock() - mock_db.session.query.return_value = mock_query - mock_query.filter.return_value = mock_query - mock_query.order_by.return_value = mock_query - mock_query.update.return_value = 1 - - handle( - self.mock_message, - application_generate_entity=self.mock_generate_entity, - ) - results.append("success") - except Exception as e: - errors.append(str(e)) - - # Run multiple handlers concurrently - threads = [] - for _ in range(5): - thread = threading.Thread(target=run_handler) - threads.append(thread) - thread.start() - - # Wait for all threads to complete - for thread in threads: - thread.join(timeout=5) - - # Verify all handlers completed successfully - assert len(results) == 5 - assert len(errors) == 0 - - def test_performance_stats_tracking(self): - """Test that performance statistics are tracked correctly.""" - # Reset stats - stats = get_update_stats() - initial_total = stats["total_updates"] - - with patch( - "events.event_handlers.update_provider_when_message_created.db" - ) as mock_db: - mock_query = Mock() - mock_db.session.query.return_value = mock_query - mock_query.filter.return_value = mock_query - mock_query.order_by.return_value = mock_query - mock_query.update.return_value = 1 - - # Call handler - handle( - self.mock_message, application_generate_entity=self.mock_generate_entity - ) - - # Check that stats were updated - updated_stats = get_update_stats() - assert updated_stats["total_updates"] == initial_total + 1 - assert updated_stats["successful_updates"] >= initial_total + 1 - - def test_non_chat_entity_ignored(self): - """Test that non-chat entities are ignored by the handler.""" - # Create a non-chat entity - mock_non_chat_entity = Mock() - mock_non_chat_entity.__class__.__name__ = "NonChatEntity" - - with patch( - "events.event_handlers.update_provider_when_message_created.db" - ) as mock_db: - # Call handler with non-chat entity - handle(self.mock_message, application_generate_entity=mock_non_chat_entity) - - # Verify no database operations were performed - assert not mock_db.session.query.called - assert not mock_db.session.commit.called - - @patch("events.event_handlers.update_provider_when_message_created.db") - def test_quota_calculation_tokens(self, mock_db): - """Test quota calculation for token-based quotas.""" - # Setup token-based quota - self.mock_system_config.current_quota_type = QuotaUnit.TOKENS - self.mock_message.answer_tokens = 150 - - mock_query = Mock() - mock_db.session.query.return_value = mock_query - mock_query.filter.return_value = mock_query - mock_query.order_by.return_value = mock_query - mock_query.update.return_value = 1 - - # Call handler - handle(self.mock_message, application_generate_entity=self.mock_generate_entity) - - # Verify update was called with token count - update_calls = mock_query.update.call_args_list - - # Should have at least one call with quota_used update - quota_update_found = False - for call in update_calls: - values = call[0][0] # First argument to update() - if "quota_used" in values: - quota_update_found = True - break - - assert quota_update_found - - @patch("events.event_handlers.update_provider_when_message_created.db") - def test_quota_calculation_times(self, mock_db): - """Test quota calculation for times-based quotas.""" - # Setup times-based quota - self.mock_system_config.current_quota_type = QuotaUnit.TIMES - - mock_query = Mock() - mock_db.session.query.return_value = mock_query - mock_query.filter.return_value = mock_query - mock_query.order_by.return_value = mock_query - mock_query.update.return_value = 1 - - # Call handler - handle(self.mock_message, application_generate_entity=self.mock_generate_entity) - - # Verify update was called - assert mock_query.update.called - assert mock_db.session.commit.called From 60c37fe4920f2b75d0f3dbe1bb37ddd168640427 Mon Sep 17 00:00:00 2001 From: crazywoola <100913391+crazywoola@users.noreply.github.com> Date: Wed, 23 Jul 2025 13:53:27 +0800 Subject: [PATCH 03/10] Added a check to ensure the input `text` is a string before proceeding with parsing (#22809) Co-authored-by: -LAN- --- api/core/llm_generator/llm_generator.py | 3 ++- .../suggested_questions_after_answer.py | 1 - .../model_runtime/entities/message_entities.py | 17 +++++++++++++++++ api/core/workflow/nodes/tool/tool_node.py | 8 +++++++- 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/api/core/llm_generator/llm_generator.py b/api/core/llm_generator/llm_generator.py index f7fd93be4a..331ac933c8 100644 --- a/api/core/llm_generator/llm_generator.py +++ b/api/core/llm_generator/llm_generator.py @@ -114,7 +114,8 @@ class LLMGenerator: ), ) - questions = output_parser.parse(cast(str, response.message.content)) + text_content = response.message.get_text_content() + questions = output_parser.parse(text_content) if text_content else [] except InvokeError: questions = [] except Exception: diff --git a/api/core/llm_generator/output_parser/suggested_questions_after_answer.py b/api/core/llm_generator/output_parser/suggested_questions_after_answer.py index c451bf514c..98cdc4c8b7 100644 --- a/api/core/llm_generator/output_parser/suggested_questions_after_answer.py +++ b/api/core/llm_generator/output_parser/suggested_questions_after_answer.py @@ -15,5 +15,4 @@ class SuggestedQuestionsAfterAnswerOutputParser: json_obj = json.loads(action_match.group(0).strip()) else: json_obj = [] - return json_obj diff --git a/api/core/model_runtime/entities/message_entities.py b/api/core/model_runtime/entities/message_entities.py index 9d010ae28d..83dc7f0525 100644 --- a/api/core/model_runtime/entities/message_entities.py +++ b/api/core/model_runtime/entities/message_entities.py @@ -156,6 +156,23 @@ class PromptMessage(ABC, BaseModel): """ return not self.content + def get_text_content(self) -> str: + """ + Get text content from prompt message. + + :return: Text content as string, empty string if no text content + """ + if isinstance(self.content, str): + return self.content + elif isinstance(self.content, list): + text_parts = [] + for item in self.content: + if isinstance(item, TextPromptMessageContent): + text_parts.append(item.data) + return "".join(text_parts) + else: + return "" + @field_validator("content", mode="before") @classmethod def validate_content(cls, v): diff --git a/api/core/workflow/nodes/tool/tool_node.py b/api/core/workflow/nodes/tool/tool_node.py index 86d36f474d..f437ac841d 100644 --- a/api/core/workflow/nodes/tool/tool_node.py +++ b/api/core/workflow/nodes/tool/tool_node.py @@ -317,7 +317,13 @@ class ToolNode(BaseNode): elif message.type == ToolInvokeMessage.MessageType.FILE: assert message.meta is not None assert isinstance(message.meta, dict) - assert "file" in message.meta and isinstance(message.meta["file"], File) + # Validate that meta contains a 'file' key + if "file" not in message.meta: + raise ToolNodeError("File message is missing 'file' key in meta") + + # Validate that the file is an instance of File + if not isinstance(message.meta["file"], File): + raise ToolNodeError(f"Expected File object but got {type(message.meta['file']).__name__}") files.append(message.meta["file"]) elif message.type == ToolInvokeMessage.MessageType.LOG: assert isinstance(message.message, ToolInvokeMessage.LogMessage) From 6b544aa0b9f78ed06f9ac30d9790fdefb7e65fb2 Mon Sep 17 00:00:00 2001 From: -LAN- Date: Wed, 23 Jul 2025 14:56:06 +0800 Subject: [PATCH 04/10] feat: decouple WorkflowAppRunner from AppRunner (#21739) Signed-off-by: -LAN- --- api/core/app/apps/README.md | 48 -------- .../app/apps/advanced_chat/app_generator.py | 60 ++++++--- api/core/app/apps/advanced_chat/app_runner.py | 115 +++++++++++++----- api/core/app/apps/workflow/app_generator.py | 48 ++++++-- api/core/app/apps/workflow/app_runner.py | 61 ++++------ api/core/app/apps/workflow_app_runner.py | 39 ++---- 6 files changed, 199 insertions(+), 172 deletions(-) delete mode 100644 api/core/app/apps/README.md diff --git a/api/core/app/apps/README.md b/api/core/app/apps/README.md deleted file mode 100644 index 7a57bb3658..0000000000 --- a/api/core/app/apps/README.md +++ /dev/null @@ -1,48 +0,0 @@ -## Guidelines for Database Connection Management in App Runner and Task Pipeline - -Due to the presence of tasks in App Runner that require long execution times, such as LLM generation and external requests, Flask-Sqlalchemy's strategy for database connection pooling is to allocate one connection (transaction) per request. This approach keeps a connection occupied even during non-DB tasks, leading to the inability to acquire new connections during high concurrency requests due to multiple long-running tasks. - -Therefore, the database operations in App Runner and Task Pipeline must ensure connections are closed immediately after use, and it's better to pass IDs rather than Model objects to avoid detach errors. - -Examples: - -1. Creating a new record: - - ```python - app = App(id=1) - db.session.add(app) - db.session.commit() - db.session.refresh(app) # Retrieve table default values, like created_at, cached in the app object, won't affect after close - - # Handle non-long-running tasks or store the content of the App instance in memory (via variable assignment). - - db.session.close() - - return app.id - ``` - -2. Fetching a record from the table: - - ```python - app = db.session.query(App).filter(App.id == app_id).first() - - created_at = app.created_at - - db.session.close() - - # Handle tasks (include long-running). - - ``` - -3. Updating a table field: - - ```python - app = db.session.query(App).filter(App.id == app_id).first() - - app.updated_at = time.utcnow() - db.session.commit() - db.session.close() - - return app_id - ``` - diff --git a/api/core/app/apps/advanced_chat/app_generator.py b/api/core/app/apps/advanced_chat/app_generator.py index fc6556dfb5..610a5bb278 100644 --- a/api/core/app/apps/advanced_chat/app_generator.py +++ b/api/core/app/apps/advanced_chat/app_generator.py @@ -7,7 +7,8 @@ from typing import Any, Literal, Optional, Union, overload from flask import Flask, current_app from pydantic import ValidationError -from sqlalchemy.orm import sessionmaker +from sqlalchemy import select +from sqlalchemy.orm import Session, sessionmaker import contexts from configs import dify_config @@ -486,21 +487,52 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator): """ with preserve_flask_contexts(flask_app, context_vars=context): - try: - # get conversation and message - conversation = self._get_conversation(conversation_id) - message = self._get_message(message_id) - - # chatbot app - runner = AdvancedChatAppRunner( - application_generate_entity=application_generate_entity, - queue_manager=queue_manager, - conversation=conversation, - message=message, - dialogue_count=self._dialogue_count, - variable_loader=variable_loader, + # get conversation and message + conversation = self._get_conversation(conversation_id) + message = self._get_message(message_id) + + with Session(db.engine, expire_on_commit=False) as session: + workflow = session.scalar( + select(Workflow).where( + Workflow.tenant_id == application_generate_entity.app_config.tenant_id, + Workflow.app_id == application_generate_entity.app_config.app_id, + Workflow.id == application_generate_entity.app_config.workflow_id, + ) ) + if workflow is None: + raise ValueError("Workflow not found") + + # Determine system_user_id based on invocation source + is_external_api_call = application_generate_entity.invoke_from in { + InvokeFrom.WEB_APP, + InvokeFrom.SERVICE_API, + } + + if is_external_api_call: + # For external API calls, use end user's session ID + end_user = session.scalar(select(EndUser).where(EndUser.id == application_generate_entity.user_id)) + system_user_id = end_user.session_id if end_user else "" + else: + # For internal calls, use the original user ID + system_user_id = application_generate_entity.user_id + + app = session.scalar(select(App).where(App.id == application_generate_entity.app_config.app_id)) + if app is None: + raise ValueError("App not found") + + runner = AdvancedChatAppRunner( + application_generate_entity=application_generate_entity, + queue_manager=queue_manager, + conversation=conversation, + message=message, + dialogue_count=self._dialogue_count, + variable_loader=variable_loader, + workflow=workflow, + system_user_id=system_user_id, + app=app, + ) + try: runner.run() except GenerateTaskStoppedError: pass diff --git a/api/core/app/apps/advanced_chat/app_runner.py b/api/core/app/apps/advanced_chat/app_runner.py index af15324f46..80af9a3c60 100644 --- a/api/core/app/apps/advanced_chat/app_runner.py +++ b/api/core/app/apps/advanced_chat/app_runner.py @@ -1,6 +1,6 @@ import logging from collections.abc import Mapping -from typing import Any, cast +from typing import Any, Optional, cast from sqlalchemy import select from sqlalchemy.orm import Session @@ -9,13 +9,19 @@ from configs import dify_config from core.app.apps.advanced_chat.app_config_manager import AdvancedChatAppConfig from core.app.apps.base_app_queue_manager import AppQueueManager from core.app.apps.workflow_app_runner import WorkflowBasedAppRunner -from core.app.entities.app_invoke_entities import AdvancedChatAppGenerateEntity, InvokeFrom +from core.app.entities.app_invoke_entities import ( + AdvancedChatAppGenerateEntity, + AppGenerateEntity, + InvokeFrom, +) from core.app.entities.queue_entities import ( QueueAnnotationReplyEvent, QueueStopEvent, QueueTextChunkEvent, ) +from core.app.features.annotation_reply.annotation_reply import AnnotationReplyFeature from core.moderation.base import ModerationError +from core.moderation.input_moderation import InputModeration from core.variables.variables import VariableUnion from core.workflow.callbacks import WorkflowCallback, WorkflowLoggingCallback from core.workflow.entities.variable_pool import VariablePool @@ -23,8 +29,9 @@ from core.workflow.system_variable import SystemVariable from core.workflow.variable_loader import VariableLoader from core.workflow.workflow_entry import WorkflowEntry from extensions.ext_database import db +from models import Workflow from models.enums import UserFrom -from models.model import App, Conversation, EndUser, Message +from models.model import App, Conversation, Message, MessageAnnotation from models.workflow import ConversationVariable, WorkflowType logger = logging.getLogger(__name__) @@ -37,21 +44,29 @@ class AdvancedChatAppRunner(WorkflowBasedAppRunner): def __init__( self, + *, application_generate_entity: AdvancedChatAppGenerateEntity, queue_manager: AppQueueManager, conversation: Conversation, message: Message, dialogue_count: int, variable_loader: VariableLoader, + workflow: Workflow, + system_user_id: str, + app: App, ) -> None: - super().__init__(queue_manager, variable_loader) + super().__init__( + queue_manager=queue_manager, + variable_loader=variable_loader, + app_id=application_generate_entity.app_config.app_id, + ) self.application_generate_entity = application_generate_entity self.conversation = conversation self.message = message self._dialogue_count = dialogue_count - - def _get_app_id(self) -> str: - return self.application_generate_entity.app_config.app_id + self._workflow = workflow + self.system_user_id = system_user_id + self._app = app def run(self) -> None: app_config = self.application_generate_entity.app_config @@ -61,18 +76,6 @@ class AdvancedChatAppRunner(WorkflowBasedAppRunner): if not app_record: raise ValueError("App not found") - workflow = self.get_workflow(app_model=app_record, workflow_id=app_config.workflow_id) - if not workflow: - raise ValueError("Workflow not initialized") - - user_id: str | None = None - if self.application_generate_entity.invoke_from in {InvokeFrom.WEB_APP, InvokeFrom.SERVICE_API}: - end_user = db.session.query(EndUser).filter(EndUser.id == self.application_generate_entity.user_id).first() - if end_user: - user_id = end_user.session_id - else: - user_id = self.application_generate_entity.user_id - workflow_callbacks: list[WorkflowCallback] = [] if dify_config.DEBUG: workflow_callbacks.append(WorkflowLoggingCallback()) @@ -80,14 +83,14 @@ class AdvancedChatAppRunner(WorkflowBasedAppRunner): if self.application_generate_entity.single_iteration_run: # if only single iteration run is requested graph, variable_pool = self._get_graph_and_variable_pool_of_single_iteration( - workflow=workflow, + workflow=self._workflow, node_id=self.application_generate_entity.single_iteration_run.node_id, user_inputs=dict(self.application_generate_entity.single_iteration_run.inputs), ) elif self.application_generate_entity.single_loop_run: # if only single loop run is requested graph, variable_pool = self._get_graph_and_variable_pool_of_single_loop( - workflow=workflow, + workflow=self._workflow, node_id=self.application_generate_entity.single_loop_run.node_id, user_inputs=dict(self.application_generate_entity.single_loop_run.inputs), ) @@ -98,7 +101,7 @@ class AdvancedChatAppRunner(WorkflowBasedAppRunner): # moderation if self.handle_input_moderation( - app_record=app_record, + app_record=self._app, app_generate_entity=self.application_generate_entity, inputs=inputs, query=query, @@ -108,7 +111,7 @@ class AdvancedChatAppRunner(WorkflowBasedAppRunner): # annotation reply if self.handle_annotation_reply( - app_record=app_record, + app_record=self._app, message=self.message, query=query, app_generate_entity=self.application_generate_entity, @@ -128,7 +131,7 @@ class AdvancedChatAppRunner(WorkflowBasedAppRunner): ConversationVariable.from_variable( app_id=self.conversation.app_id, conversation_id=self.conversation.id, variable=variable ) - for variable in workflow.conversation_variables + for variable in self._workflow.conversation_variables ] session.add_all(db_conversation_variables) # Convert database entities to variables. @@ -141,7 +144,7 @@ class AdvancedChatAppRunner(WorkflowBasedAppRunner): query=query, files=files, conversation_id=self.conversation.id, - user_id=user_id, + user_id=self.system_user_id, dialogue_count=self._dialogue_count, app_id=app_config.app_id, workflow_id=app_config.workflow_id, @@ -152,25 +155,25 @@ class AdvancedChatAppRunner(WorkflowBasedAppRunner): variable_pool = VariablePool( system_variables=system_inputs, user_inputs=inputs, - environment_variables=workflow.environment_variables, + environment_variables=self._workflow.environment_variables, # Based on the definition of `VariableUnion`, # `list[Variable]` can be safely used as `list[VariableUnion]` since they are compatible. conversation_variables=cast(list[VariableUnion], conversation_variables), ) # init graph - graph = self._init_graph(graph_config=workflow.graph_dict) + graph = self._init_graph(graph_config=self._workflow.graph_dict) db.session.close() # RUN WORKFLOW workflow_entry = WorkflowEntry( - tenant_id=workflow.tenant_id, - app_id=workflow.app_id, - workflow_id=workflow.id, - workflow_type=WorkflowType.value_of(workflow.type), + tenant_id=self._workflow.tenant_id, + app_id=self._workflow.app_id, + workflow_id=self._workflow.id, + workflow_type=WorkflowType.value_of(self._workflow.type), graph=graph, - graph_config=workflow.graph_dict, + graph_config=self._workflow.graph_dict, user_id=self.application_generate_entity.user_id, user_from=( UserFrom.ACCOUNT @@ -241,3 +244,51 @@ class AdvancedChatAppRunner(WorkflowBasedAppRunner): self._publish_event(QueueTextChunkEvent(text=text)) self._publish_event(QueueStopEvent(stopped_by=stopped_by)) + + def query_app_annotations_to_reply( + self, app_record: App, message: Message, query: str, user_id: str, invoke_from: InvokeFrom + ) -> Optional[MessageAnnotation]: + """ + Query app annotations to reply + :param app_record: app record + :param message: message + :param query: query + :param user_id: user id + :param invoke_from: invoke from + :return: + """ + annotation_reply_feature = AnnotationReplyFeature() + return annotation_reply_feature.query( + app_record=app_record, message=message, query=query, user_id=user_id, invoke_from=invoke_from + ) + + def moderation_for_inputs( + self, + *, + app_id: str, + tenant_id: str, + app_generate_entity: AppGenerateEntity, + inputs: Mapping[str, Any], + query: str | None = None, + message_id: str, + ) -> tuple[bool, Mapping[str, Any], str]: + """ + Process sensitive_word_avoidance. + :param app_id: app id + :param tenant_id: tenant id + :param app_generate_entity: app generate entity + :param inputs: inputs + :param query: query + :param message_id: message id + :return: + """ + moderation_feature = InputModeration() + return moderation_feature.check( + app_id=app_id, + tenant_id=tenant_id, + app_config=app_generate_entity.app_config, + inputs=dict(inputs), + query=query or "", + message_id=message_id, + trace_manager=app_generate_entity.trace_manager, + ) diff --git a/api/core/app/apps/workflow/app_generator.py b/api/core/app/apps/workflow/app_generator.py index eeca9bb503..4c36f63c71 100644 --- a/api/core/app/apps/workflow/app_generator.py +++ b/api/core/app/apps/workflow/app_generator.py @@ -7,7 +7,8 @@ from typing import Any, Literal, Optional, Union, overload from flask import Flask, current_app from pydantic import ValidationError -from sqlalchemy.orm import sessionmaker +from sqlalchemy import select +from sqlalchemy.orm import Session, sessionmaker import contexts from configs import dify_config @@ -445,17 +446,44 @@ class WorkflowAppGenerator(BaseAppGenerator): """ with preserve_flask_contexts(flask_app, context_vars=context): - try: - # workflow app - runner = WorkflowAppRunner( - application_generate_entity=application_generate_entity, - queue_manager=queue_manager, - workflow_thread_pool_id=workflow_thread_pool_id, - variable_loader=variable_loader, + with Session(db.engine, expire_on_commit=False) as session: + workflow = session.scalar( + select(Workflow).where( + Workflow.tenant_id == application_generate_entity.app_config.tenant_id, + Workflow.app_id == application_generate_entity.app_config.app_id, + Workflow.id == application_generate_entity.app_config.workflow_id, + ) ) + if workflow is None: + raise ValueError("Workflow not found") + + # Determine system_user_id based on invocation source + is_external_api_call = application_generate_entity.invoke_from in { + InvokeFrom.WEB_APP, + InvokeFrom.SERVICE_API, + } + + if is_external_api_call: + # For external API calls, use end user's session ID + end_user = session.scalar(select(EndUser).where(EndUser.id == application_generate_entity.user_id)) + system_user_id = end_user.session_id if end_user else "" + else: + # For internal calls, use the original user ID + system_user_id = application_generate_entity.user_id + + runner = WorkflowAppRunner( + application_generate_entity=application_generate_entity, + queue_manager=queue_manager, + workflow_thread_pool_id=workflow_thread_pool_id, + variable_loader=variable_loader, + workflow=workflow, + system_user_id=system_user_id, + ) + try: runner.run() - except GenerateTaskStoppedError: + except GenerateTaskStoppedError as e: + logger.warning(f"Task stopped: {str(e)}") pass except InvokeAuthorizationError: queue_manager.publish_error( @@ -471,8 +499,6 @@ class WorkflowAppGenerator(BaseAppGenerator): except Exception as e: logger.exception("Unknown Error when generating") queue_manager.publish_error(e, PublishFrom.APPLICATION_MANAGER) - finally: - db.session.close() def _handle_response( self, diff --git a/api/core/app/apps/workflow/app_runner.py b/api/core/app/apps/workflow/app_runner.py index 3a66ffa578..4f4c1460ae 100644 --- a/api/core/app/apps/workflow/app_runner.py +++ b/api/core/app/apps/workflow/app_runner.py @@ -14,10 +14,8 @@ from core.workflow.entities.variable_pool import VariablePool from core.workflow.system_variable import SystemVariable from core.workflow.variable_loader import VariableLoader from core.workflow.workflow_entry import WorkflowEntry -from extensions.ext_database import db from models.enums import UserFrom -from models.model import App, EndUser -from models.workflow import WorkflowType +from models.workflow import Workflow, WorkflowType logger = logging.getLogger(__name__) @@ -29,22 +27,23 @@ class WorkflowAppRunner(WorkflowBasedAppRunner): def __init__( self, + *, application_generate_entity: WorkflowAppGenerateEntity, queue_manager: AppQueueManager, variable_loader: VariableLoader, workflow_thread_pool_id: Optional[str] = None, + workflow: Workflow, + system_user_id: str, ) -> None: - """ - :param application_generate_entity: application generate entity - :param queue_manager: application queue manager - :param workflow_thread_pool_id: workflow thread pool id - """ - super().__init__(queue_manager, variable_loader) + super().__init__( + queue_manager=queue_manager, + variable_loader=variable_loader, + app_id=application_generate_entity.app_config.app_id, + ) self.application_generate_entity = application_generate_entity self.workflow_thread_pool_id = workflow_thread_pool_id - - def _get_app_id(self) -> str: - return self.application_generate_entity.app_config.app_id + self._workflow = workflow + self._sys_user_id = system_user_id def run(self) -> None: """ @@ -53,24 +52,6 @@ class WorkflowAppRunner(WorkflowBasedAppRunner): app_config = self.application_generate_entity.app_config app_config = cast(WorkflowAppConfig, app_config) - user_id = None - if self.application_generate_entity.invoke_from in {InvokeFrom.WEB_APP, InvokeFrom.SERVICE_API}: - end_user = db.session.query(EndUser).filter(EndUser.id == self.application_generate_entity.user_id).first() - if end_user: - user_id = end_user.session_id - else: - user_id = self.application_generate_entity.user_id - - app_record = db.session.query(App).filter(App.id == app_config.app_id).first() - if not app_record: - raise ValueError("App not found") - - workflow = self.get_workflow(app_model=app_record, workflow_id=app_config.workflow_id) - if not workflow: - raise ValueError("Workflow not initialized") - - db.session.close() - workflow_callbacks: list[WorkflowCallback] = [] if dify_config.DEBUG: workflow_callbacks.append(WorkflowLoggingCallback()) @@ -79,14 +60,14 @@ class WorkflowAppRunner(WorkflowBasedAppRunner): if self.application_generate_entity.single_iteration_run: # if only single iteration run is requested graph, variable_pool = self._get_graph_and_variable_pool_of_single_iteration( - workflow=workflow, + workflow=self._workflow, node_id=self.application_generate_entity.single_iteration_run.node_id, user_inputs=self.application_generate_entity.single_iteration_run.inputs, ) elif self.application_generate_entity.single_loop_run: # if only single loop run is requested graph, variable_pool = self._get_graph_and_variable_pool_of_single_loop( - workflow=workflow, + workflow=self._workflow, node_id=self.application_generate_entity.single_loop_run.node_id, user_inputs=self.application_generate_entity.single_loop_run.inputs, ) @@ -98,7 +79,7 @@ class WorkflowAppRunner(WorkflowBasedAppRunner): system_inputs = SystemVariable( files=files, - user_id=user_id, + user_id=self._sys_user_id, app_id=app_config.app_id, workflow_id=app_config.workflow_id, workflow_execution_id=self.application_generate_entity.workflow_execution_id, @@ -107,21 +88,21 @@ class WorkflowAppRunner(WorkflowBasedAppRunner): variable_pool = VariablePool( system_variables=system_inputs, user_inputs=inputs, - environment_variables=workflow.environment_variables, + environment_variables=self._workflow.environment_variables, conversation_variables=[], ) # init graph - graph = self._init_graph(graph_config=workflow.graph_dict) + graph = self._init_graph(graph_config=self._workflow.graph_dict) # RUN WORKFLOW workflow_entry = WorkflowEntry( - tenant_id=workflow.tenant_id, - app_id=workflow.app_id, - workflow_id=workflow.id, - workflow_type=WorkflowType.value_of(workflow.type), + tenant_id=self._workflow.tenant_id, + app_id=self._workflow.app_id, + workflow_id=self._workflow.id, + workflow_type=WorkflowType.value_of(self._workflow.type), graph=graph, - graph_config=workflow.graph_dict, + graph_config=self._workflow.graph_dict, user_id=self.application_generate_entity.user_id, user_from=( UserFrom.ACCOUNT diff --git a/api/core/app/apps/workflow_app_runner.py b/api/core/app/apps/workflow_app_runner.py index 2f4d234ecd..948ea95e63 100644 --- a/api/core/app/apps/workflow_app_runner.py +++ b/api/core/app/apps/workflow_app_runner.py @@ -1,8 +1,7 @@ from collections.abc import Mapping -from typing import Any, Optional, cast +from typing import Any, cast from core.app.apps.base_app_queue_manager import AppQueueManager, PublishFrom -from core.app.apps.base_app_runner import AppRunner from core.app.entities.queue_entities import ( AppQueueEvent, QueueAgentLogEvent, @@ -65,18 +64,20 @@ from core.workflow.nodes.node_mapping import NODE_TYPE_CLASSES_MAPPING from core.workflow.system_variable import SystemVariable from core.workflow.variable_loader import DUMMY_VARIABLE_LOADER, VariableLoader, load_into_variable_pool from core.workflow.workflow_entry import WorkflowEntry -from extensions.ext_database import db -from models.model import App from models.workflow import Workflow -class WorkflowBasedAppRunner(AppRunner): - def __init__(self, queue_manager: AppQueueManager, variable_loader: VariableLoader = DUMMY_VARIABLE_LOADER) -> None: - self.queue_manager = queue_manager +class WorkflowBasedAppRunner: + def __init__( + self, + *, + queue_manager: AppQueueManager, + variable_loader: VariableLoader = DUMMY_VARIABLE_LOADER, + app_id: str, + ) -> None: + self._queue_manager = queue_manager self._variable_loader = variable_loader - - def _get_app_id(self) -> str: - raise NotImplementedError("not implemented") + self._app_id = app_id def _init_graph(self, graph_config: Mapping[str, Any]) -> Graph: """ @@ -693,21 +694,5 @@ class WorkflowBasedAppRunner(AppRunner): ) ) - def get_workflow(self, app_model: App, workflow_id: str) -> Optional[Workflow]: - """ - Get workflow - """ - # fetch workflow by workflow_id - workflow = ( - db.session.query(Workflow) - .filter( - Workflow.tenant_id == app_model.tenant_id, Workflow.app_id == app_model.id, Workflow.id == workflow_id - ) - .first() - ) - - # return workflow - return workflow - def _publish_event(self, event: AppQueueEvent) -> None: - self.queue_manager.publish(event, PublishFrom.APPLICATION_MANAGER) + self._queue_manager.publish(event, PublishFrom.APPLICATION_MANAGER) From e6913744ae2d2ec752ce7516b25cd6258d4941c7 Mon Sep 17 00:00:00 2001 From: Novice Date: Wed, 23 Jul 2025 14:58:50 +0800 Subject: [PATCH 05/10] fix: database lock timeout by separating external MCP calls from transactions (#22821) --- .../tools/mcp_tools_manage_service.py | 73 ++++++++++++------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/api/services/tools/mcp_tools_manage_service.py b/api/services/tools/mcp_tools_manage_service.py index e0e256912e..c0126a0f4f 100644 --- a/api/services/tools/mcp_tools_manage_service.py +++ b/api/services/tools/mcp_tools_manage_service.py @@ -112,19 +112,27 @@ class MCPToolManageService: @classmethod def list_mcp_tool_from_remote_server(cls, tenant_id: str, provider_id: str) -> ToolProviderApiEntity: mcp_provider = cls.get_mcp_provider_by_provider_id(provider_id, tenant_id) + server_url = mcp_provider.decrypted_server_url + authed = mcp_provider.authed + try: - with MCPClient( - mcp_provider.decrypted_server_url, provider_id, tenant_id, authed=mcp_provider.authed, for_list=True - ) as mcp_client: + with MCPClient(server_url, provider_id, tenant_id, authed=authed, for_list=True) as mcp_client: tools = mcp_client.list_tools() except MCPAuthError: raise ValueError("Please auth the tool first") except MCPError as e: raise ValueError(f"Failed to connect to MCP server: {e}") - mcp_provider.tools = json.dumps([tool.model_dump() for tool in tools]) - mcp_provider.authed = True - mcp_provider.updated_at = datetime.now() - db.session.commit() + + try: + mcp_provider = cls.get_mcp_provider_by_provider_id(provider_id, tenant_id) + mcp_provider.tools = json.dumps([tool.model_dump() for tool in tools]) + mcp_provider.authed = True + mcp_provider.updated_at = datetime.now() + db.session.commit() + except Exception: + db.session.rollback() + raise + user = mcp_provider.load_user() return ToolProviderApiEntity( id=mcp_provider.id, @@ -160,22 +168,35 @@ class MCPToolManageService: server_identifier: str, ): mcp_provider = cls.get_mcp_provider_by_provider_id(provider_id, tenant_id) - mcp_provider.updated_at = datetime.now() - mcp_provider.name = name - mcp_provider.icon = ( - json.dumps({"content": icon, "background": icon_background}) if icon_type == "emoji" else icon - ) - mcp_provider.server_identifier = server_identifier + + reconnect_result = None + encrypted_server_url = None + server_url_hash = None if UNCHANGED_SERVER_URL_PLACEHOLDER not in server_url: encrypted_server_url = encrypter.encrypt_token(tenant_id, server_url) - mcp_provider.server_url = encrypted_server_url server_url_hash = hashlib.sha256(server_url.encode()).hexdigest() if server_url_hash != mcp_provider.server_url_hash: - cls._re_connect_mcp_provider(mcp_provider, provider_id, tenant_id) - mcp_provider.server_url_hash = server_url_hash + reconnect_result = cls._re_connect_mcp_provider(server_url, provider_id, tenant_id) + try: + mcp_provider.updated_at = datetime.now() + mcp_provider.name = name + mcp_provider.icon = ( + json.dumps({"content": icon, "background": icon_background}) if icon_type == "emoji" else icon + ) + mcp_provider.server_identifier = server_identifier + + if encrypted_server_url is not None and server_url_hash is not None: + mcp_provider.server_url = encrypted_server_url + mcp_provider.server_url_hash = server_url_hash + + if reconnect_result: + mcp_provider.authed = reconnect_result["authed"] + mcp_provider.tools = reconnect_result["tools"] + mcp_provider.encrypted_credentials = reconnect_result["encrypted_credentials"] + db.session.commit() except IntegrityError as e: db.session.rollback() @@ -187,6 +208,9 @@ class MCPToolManageService: if "unique_mcp_provider_server_identifier" in error_msg: raise ValueError(f"MCP tool {server_identifier} already exists") raise + except Exception: + db.session.rollback() + raise @classmethod def update_mcp_provider_credentials( @@ -207,23 +231,22 @@ class MCPToolManageService: db.session.commit() @classmethod - def _re_connect_mcp_provider(cls, mcp_provider: MCPToolProvider, provider_id: str, tenant_id: str): - """re-connect mcp provider""" + def _re_connect_mcp_provider(cls, server_url: str, provider_id: str, tenant_id: str): try: with MCPClient( - mcp_provider.decrypted_server_url, + server_url, provider_id, tenant_id, authed=False, for_list=True, ) as mcp_client: tools = mcp_client.list_tools() - mcp_provider.authed = True - mcp_provider.tools = json.dumps([tool.model_dump() for tool in tools]) + return { + "authed": True, + "tools": json.dumps([tool.model_dump() for tool in tools]), + "encrypted_credentials": "{}", + } except MCPAuthError: - mcp_provider.authed = False - mcp_provider.tools = "[]" + return {"authed": False, "tools": "[]", "encrypted_credentials": "{}"} except MCPError as e: raise ValueError(f"Failed to re-connect MCP server: {e}") from e - # reset credentials - mcp_provider.encrypted_credentials = "{}" From eaae79a581ad761d357460f4fa4ce95f23eb805a Mon Sep 17 00:00:00 2001 From: "Junyan Qin (Chin)" Date: Wed, 23 Jul 2025 15:33:39 +0800 Subject: [PATCH 06/10] feat: plugin auto upgrade strategy (#19758) Co-authored-by: Joel Co-authored-by: crazywoola <427733928@qq.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Novice --- api/.env.example | 10 + api/README.md | 7 +- api/configs/feature/__init__.py | 36 +++ api/controllers/console/workspace/plugin.py | 115 +++++++- api/core/helper/marketplace.py | 20 ++ api/docker/entrypoint.sh | 2 +- api/extensions/ext_celery.py | 65 +++-- ...d07_add_tenant_plugin_autoupgrade_table.py | 42 +++ api/models/account.py | 40 ++- api/schedule/check_upgradable_plugin_task.py | 49 ++++ api/services/account_service.py | 12 + .../plugin/plugin_auto_upgrade_service.py | 87 +++++++ ...ss_tenant_plugin_autoupgrade_check_task.py | 166 ++++++++++++ docker/.env.example | 10 + docker/docker-compose-template.yaml | 19 ++ docker/docker-compose.yaml | 27 ++ .../common/option-list-item.tsx | 5 +- .../time-picker/header.tsx | 9 +- .../time-picker/index.tsx | 31 ++- .../time-picker/options.tsx | 4 +- .../base/date-and-time-picker/types.ts | 12 +- .../base/date-and-time-picker/utils/dayjs.ts | 12 + .../vender/line/general/search-menu.svg | 7 + .../assets/vender/system/auto-update-line.svg | 4 + web/app/components/base/icons/script.mjs | 2 +- .../icons/src/public/tracing/AliyunIcon.json | 245 +++++++++--------- .../icons/src/public/tracing/AliyunIcon.tsx | 14 +- .../src/public/tracing/AliyunIconBig.json | 184 ++++++++----- .../src/public/tracing/AliyunIconBig.tsx | 14 +- .../icons/src/public/tracing/WeaveIcon.tsx | 14 +- .../icons/src/public/tracing/WeaveIconBig.tsx | 14 +- .../base/icons/src/public/tracing/index.ts | 4 +- .../icons/src/vender/features/Citations.json | 2 +- .../vender/features/ContentModeration.json | 2 +- .../icons/src/vender/features/Document.json | 2 +- .../src/vender/features/FolderUpload.json | 2 +- .../src/vender/features/LoveMessage.json | 2 +- .../src/vender/features/MessageFast.json | 2 +- .../src/vender/features/Microphone01.json | 2 +- .../src/vender/features/TextToAudio.json | 2 +- .../src/vender/features/VirtualAssistant.json | 2 +- .../icons/src/vender/features/Vision.json | 2 +- .../line/alertsAndFeedback/AlertTriangle.json | 2 +- .../line/alertsAndFeedback/ThumbsDown.json | 2 +- .../line/alertsAndFeedback/ThumbsUp.json | 2 +- .../vender/line/arrows/ArrowNarrowLeft.json | 2 +- .../src/vender/line/arrows/ArrowUpRight.json | 2 +- .../vender/line/arrows/ChevronDownDouble.json | 2 +- .../src/vender/line/arrows/ChevronRight.json | 2 +- .../line/arrows/ChevronSelectorVertical.json | 2 +- .../src/vender/line/arrows/RefreshCcw01.json | 2 +- .../src/vender/line/arrows/RefreshCw05.json | 2 +- .../src/vender/line/arrows/ReverseLeft.json | 2 +- .../src/vender/line/communication/AiText.json | 2 +- .../vender/line/communication/ChatBot.json | 2 +- .../line/communication/ChatBotSlim.json | 2 +- .../vender/line/communication/CuteRobot.json | 2 +- .../communication/MessageCheckRemove.json | 2 +- .../line/communication/MessageFastPlus.json | 2 +- .../line/development/ArtificialBrain.json | 2 +- .../line/development/BarChartSquare02.json | 2 +- .../vender/line/development/BracketsX.json | 2 +- .../vender/line/development/CodeBrowser.json | 2 +- .../vender/line/development/Container.json | 2 +- .../vender/line/development/Database01.json | 2 +- .../vender/line/development/Database03.json | 2 +- .../vender/line/development/FileHeart02.json | 2 +- .../vender/line/development/GitBranch01.json | 2 +- .../line/development/PromptEngineering.json | 2 +- .../line/development/PuzzlePiece01.json | 2 +- .../line/development/TerminalSquare.json | 2 +- .../src/vender/line/development/Variable.json | 2 +- .../src/vender/line/development/Webhooks.json | 2 +- .../src/vender/line/editor/AlignLeft.json | 2 +- .../src/vender/line/editor/BezierCurve03.json | 2 +- .../src/vender/line/editor/Collapse.json | 2 +- .../icons/src/vender/line/editor/Colors.json | 2 +- .../vender/line/editor/ImageIndentLeft.json | 2 +- .../src/vender/line/editor/LeftIndent02.json | 2 +- .../vender/line/editor/LetterSpacing01.json | 2 +- .../src/vender/line/editor/TypeSquare.json | 2 +- .../src/vender/line/education/BookOpen01.json | 2 +- .../icons/src/vender/line/files/File02.json | 2 +- .../src/vender/line/files/FileArrow01.json | 2 +- .../src/vender/line/files/FileCheck02.json | 2 +- .../src/vender/line/files/FileDownload02.json | 2 +- .../src/vender/line/files/FilePlus01.json | 2 +- .../src/vender/line/files/FilePlus02.json | 2 +- .../icons/src/vender/line/files/FileText.json | 2 +- .../src/vender/line/files/FileUpload.json | 2 +- .../icons/src/vender/line/files/Folder.json | 2 +- .../line/financeAndECommerce/Balance.json | 2 +- .../financeAndECommerce/CoinsStacked01.json | 2 +- .../line/financeAndECommerce/GoldCoin.json | 2 +- .../line/financeAndECommerce/ReceiptList.json | 2 +- .../line/financeAndECommerce/Tag01.json | 2 +- .../line/financeAndECommerce/Tag03.json | 2 +- .../icons/src/vender/line/general/AtSign.json | 2 +- .../src/vender/line/general/Bookmark.json | 2 +- .../icons/src/vender/line/general/Check.json | 2 +- .../src/vender/line/general/CheckDone01.json | 2 +- .../vender/line/general/ChecklistSquare.json | 2 +- .../src/vender/line/general/DotsGrid.json | 2 +- .../icons/src/vender/line/general/Edit02.json | 2 +- .../icons/src/vender/line/general/Edit04.json | 2 +- .../icons/src/vender/line/general/Edit05.json | 2 +- .../icons/src/vender/line/general/Hash02.json | 2 +- .../src/vender/line/general/InfoCircle.json | 2 +- .../icons/src/vender/line/general/Link03.json | 2 +- .../vender/line/general/LinkExternal02.json | 2 +- .../src/vender/line/general/LogIn04.json | 2 +- .../src/vender/line/general/LogOut01.json | 2 +- .../src/vender/line/general/LogOut04.json | 2 +- .../icons/src/vender/line/general/Menu01.json | 2 +- .../icons/src/vender/line/general/Pin01.json | 2 +- .../icons/src/vender/line/general/Pin02.json | 2 +- .../icons/src/vender/line/general/Plus02.json | 2 +- .../src/vender/line/general/Refresh.json | 2 +- .../src/vender/line/general/SearchMenu.json | 77 ++++++ .../src/vender/line/general/SearchMenu.tsx | 20 ++ .../src/vender/line/general/Settings01.json | 2 +- .../src/vender/line/general/Settings04.json | 2 +- .../src/vender/line/general/Target04.json | 2 +- .../src/vender/line/general/Upload03.json | 2 +- .../vender/line/general/UploadCloud01.json | 2 +- .../base/icons/src/vender/line/general/X.json | 2 +- .../icons/src/vender/line/general/index.ts | 1 + .../src/vender/line/images/ImagePlus.json | 2 +- .../src/vender/line/layout/AlignLeft01.json | 2 +- .../src/vender/line/layout/AlignRight01.json | 2 +- .../icons/src/vender/line/layout/Grid01.json | 2 +- .../src/vender/line/layout/LayoutGrid02.json | 2 +- .../vender/line/mapsAndTravel/Globe01.json | 2 +- .../src/vender/line/mapsAndTravel/Route.json | 2 +- .../line/mediaAndDevices/Microphone01.json | 2 +- .../line/mediaAndDevices/PlayCircle.json | 2 +- .../vender/line/mediaAndDevices/SlidersH.json | 2 +- .../vender/line/mediaAndDevices/Speaker.json | 2 +- .../src/vender/line/mediaAndDevices/Stop.json | 2 +- .../line/mediaAndDevices/StopCircle.json | 2 +- .../icons/src/vender/line/others/Apps02.json | 2 +- .../icons/src/vender/line/others/BubbleX.json | 2 +- .../icons/src/vender/line/others/Colors.json | 2 +- .../src/vender/line/others/DragHandle.json | 2 +- .../icons/src/vender/line/others/Env.json | 2 +- .../src/vender/line/others/Exchange02.json | 2 +- .../src/vender/line/others/FileCode.json | 2 +- .../vender/line/others/GlobalVariable.json | 2 +- .../src/vender/line/others/Icon3Dots.json | 2 +- .../src/vender/line/others/LongArrowLeft.json | 2 +- .../vender/line/others/LongArrowRight.json | 2 +- .../src/vender/line/others/SearchMenu.json | 2 +- .../icons/src/vender/line/others/Tools.json | 2 +- .../src/vender/line/shapes/CubeOutline.json | 2 +- .../vender/line/time/ClockFastForward.json | 2 +- .../icons/src/vender/line/time/ClockPlay.json | 2 +- .../src/vender/line/time/ClockPlaySlim.json | 2 +- .../src/vender/line/time/ClockRefresh.json | 2 +- .../icons/src/vender/line/users/User01.json | 2 +- .../icons/src/vender/line/users/Users01.json | 2 +- .../src/vender/line/weather/Stars02.json | 2 +- .../icons/src/vender/other/AnthropicText.json | 2 +- .../icons/src/vender/other/Generator.json | 2 +- .../base/icons/src/vender/other/Group.json | 2 +- .../base/icons/src/vender/other/Mcp.json | 2 +- .../src/vender/other/NoToolPlaceholder.json | 2 +- .../base/icons/src/vender/other/Openai.json | 2 +- .../icons/src/vender/other/ReplayLine.json | 2 +- .../src/vender/plugin/BoxSparkleFill.json | 2 +- .../icons/src/vender/plugin/LeftCorner.json | 2 +- .../solid/FinanceAndECommerce/GoldCoin.json | 2 +- .../solid/FinanceAndECommerce/Scales02.json | 2 +- .../alertsAndFeedback/AlertTriangle.json | 2 +- .../src/vender/solid/arrows/ChevronDown.json | 2 +- .../src/vender/solid/arrows/HighPriority.json | 2 +- .../vender/solid/communication/AiText.json | 2 +- .../solid/communication/BubbleTextMod.json | 2 +- .../vender/solid/communication/ChatBot.json | 2 +- .../vender/solid/communication/CuteRobot.json | 2 +- .../vender/solid/communication/EditList.json | 2 +- .../solid/communication/ListSparkle.json | 2 +- .../src/vender/solid/communication/Logic.json | 2 +- .../communication/MessageDotsCircle.json | 2 +- .../solid/communication/MessageFast.json | 2 +- .../communication/MessageHeartCircle.json | 2 +- .../communication/MessageSmileSquare.json | 2 +- .../vender/solid/communication/Send03.json | 2 +- .../solid/development/ApiConnection.json | 2 +- .../solid/development/ApiConnectionMod.json | 2 +- .../solid/development/BarChartSquare02.json | 2 +- .../vender/solid/development/Container.json | 2 +- .../vender/solid/development/Database02.json | 2 +- .../vender/solid/development/Database03.json | 2 +- .../vender/solid/development/FileHeart02.json | 2 +- .../solid/development/PatternRecognition.json | 2 +- .../solid/development/PromptEngineering.json | 2 +- .../solid/development/PuzzlePiece01.json | 2 +- .../vender/solid/development/Semantic.json | 2 +- .../solid/development/TerminalSquare.json | 2 +- .../vender/solid/development/Variable02.json | 2 +- .../src/vender/solid/editor/Brush01.json | 2 +- .../src/vender/solid/editor/Citations.json | 2 +- .../icons/src/vender/solid/editor/Colors.json | 2 +- .../src/vender/solid/editor/Paragraph.json | 2 +- .../src/vender/solid/editor/TypeSquare.json | 2 +- .../src/vender/solid/education/Beaker02.json | 2 +- .../vender/solid/education/BubbleText.json | 2 +- .../src/vender/solid/education/Heart02.json | 2 +- .../src/vender/solid/education/Unblur.json | 2 +- .../icons/src/vender/solid/files/File05.json | 2 +- .../src/vender/solid/files/FileSearch02.json | 2 +- .../icons/src/vender/solid/files/FileZip.json | 2 +- .../icons/src/vender/solid/files/Folder.json | 2 +- .../vender/solid/general/AnswerTriangle.json | 2 +- .../solid/general/ArrowDownRoundFill.json | 2 +- .../src/vender/solid/general/CheckCircle.json | 2 +- .../src/vender/solid/general/CheckDone01.json | 2 +- .../src/vender/solid/general/Download02.json | 2 +- .../src/vender/solid/general/Edit03.json | 2 +- .../src/vender/solid/general/Edit04.json | 2 +- .../icons/src/vender/solid/general/Eye.json | 2 +- .../src/vender/solid/general/Github.json | 2 +- .../solid/general/MessageClockCircle.json | 2 +- .../src/vender/solid/general/PlusCircle.json | 2 +- .../solid/general/QuestionTriangle.json | 2 +- .../src/vender/solid/general/SearchMd.json | 2 +- .../src/vender/solid/general/Target04.json | 2 +- .../src/vender/solid/general/Tool03.json | 2 +- .../src/vender/solid/general/XCircle.json | 2 +- .../src/vender/solid/general/ZapFast.json | 2 +- .../src/vender/solid/general/ZapNarrow.json | 2 +- .../icons/src/vender/solid/layout/Grid01.json | 2 +- .../vender/solid/mapsAndTravel/Globe06.json | 2 +- .../src/vender/solid/mapsAndTravel/Route.json | 2 +- .../mediaAndDevices/AudioSupportIcon.json | 2 +- .../mediaAndDevices/DocumentSupportIcon.json | 2 +- .../solid/mediaAndDevices/MagicBox.json | 2 +- .../solid/mediaAndDevices/MagicEyes.json | 2 +- .../solid/mediaAndDevices/MagicWand.json | 2 +- .../solid/mediaAndDevices/Microphone01.json | 2 +- .../vender/solid/mediaAndDevices/Play.json | 2 +- .../vender/solid/mediaAndDevices/Robot.json | 2 +- .../solid/mediaAndDevices/Sliders02.json | 2 +- .../vender/solid/mediaAndDevices/Speaker.json | 2 +- .../solid/mediaAndDevices/StopCircle.json | 2 +- .../mediaAndDevices/VideoSupportIcon.json | 2 +- .../src/vender/solid/security/Lock01.json | 2 +- .../icons/src/vender/solid/shapes/Corner.json | 2 +- .../icons/src/vender/solid/shapes/Star04.json | 2 +- .../icons/src/vender/solid/shapes/Star06.json | 2 +- .../icons/src/vender/solid/users/User01.json | 2 +- .../src/vender/solid/users/UserEdit02.json | 2 +- .../icons/src/vender/solid/users/Users01.json | 2 +- .../src/vender/solid/users/UsersPlus.json | 2 +- .../src/vender/system/AutoUpdateLine.json | 37 +++ .../src/vender/system/AutoUpdateLine.tsx | 20 ++ .../base/icons/src/vender/system/index.ts | 1 + .../base/icons/src/vender/workflow/Agent.json | 2 +- .../icons/src/vender/workflow/Answer.json | 2 +- .../icons/src/vender/workflow/Assigner.json | 2 +- .../base/icons/src/vender/workflow/Code.json | 2 +- .../src/vender/workflow/DocsExtractor.json | 2 +- .../base/icons/src/vender/workflow/End.json | 2 +- .../base/icons/src/vender/workflow/Home.json | 2 +- .../base/icons/src/vender/workflow/Http.json | 2 +- .../icons/src/vender/workflow/IfElse.json | 2 +- .../icons/src/vender/workflow/Iteration.json | 2 +- .../src/vender/workflow/IterationStart.json | 2 +- .../base/icons/src/vender/workflow/Jinja.json | 2 +- .../vender/workflow/KnowledgeRetrieval.json | 2 +- .../icons/src/vender/workflow/ListFilter.json | 2 +- .../base/icons/src/vender/workflow/Llm.json | 2 +- .../base/icons/src/vender/workflow/Loop.json | 2 +- .../icons/src/vender/workflow/LoopEnd.json | 2 +- .../vender/workflow/ParameterExtractor.json | 2 +- .../vender/workflow/QuestionClassifier.json | 2 +- .../vender/workflow/TemplatingTransform.json | 2 +- .../icons/src/vender/workflow/VariableX.json | 2 +- .../src/vender/workflow/WindowCursor.json | 2 +- .../install-bundle/steps/install.tsx | 2 +- .../plugin-detail-panel/detail-header.tsx | 44 +++- .../components/plugins/plugin-page/index.tsx | 18 +- ...permission.ts => use-reference-setting.ts} | 22 +- .../auto-update-setting/config.ts | 9 + .../auto-update-setting/index.tsx | 185 +++++++++++++ .../no-data-placeholder.tsx | 31 +++ .../no-plugin-selected.tsx | 22 ++ .../auto-update-setting/plugins-picker.tsx | 69 +++++ .../auto-update-setting/plugins-selected.tsx | 29 +++ .../auto-update-setting/strategy-picker.tsx | 98 +++++++ .../auto-update-setting/tool-item.tsx | 45 ++++ .../auto-update-setting/tool-picker.tsx | 167 ++++++++++++ .../auto-update-setting/types.ts | 19 ++ .../auto-update-setting/utils.spec.ts | 14 + .../auto-update-setting/utils.ts | 37 +++ .../plugins/reference-setting-modal/label.tsx | 28 ++ .../modal.tsx | 31 ++- .../style.module.css | 0 web/app/components/plugins/types.ts | 6 + .../update-plugin/downgrade-warning.tsx | 35 +++ .../update-plugin/from-market-place.tsx | 100 ++++--- .../update-plugin/plugin-version-picker.tsx | 9 +- web/i18n/en-US/plugin.ts | 50 ++++ web/i18n/zh-Hans/plugin.ts | 50 ++++ web/service/use-plugins.ts | 65 ++++- 305 files changed, 2524 insertions(+), 581 deletions(-) create mode 100644 api/migrations/versions/2025_07_23_1508-8bcc02c9bd07_add_tenant_plugin_autoupgrade_table.py create mode 100644 api/schedule/check_upgradable_plugin_task.py create mode 100644 api/services/plugin/plugin_auto_upgrade_service.py create mode 100644 api/tasks/process_tenant_plugin_autoupgrade_check_task.py create mode 100644 web/app/components/base/icons/assets/vender/line/general/search-menu.svg create mode 100644 web/app/components/base/icons/assets/vender/system/auto-update-line.svg create mode 100644 web/app/components/base/icons/src/vender/line/general/SearchMenu.json create mode 100644 web/app/components/base/icons/src/vender/line/general/SearchMenu.tsx create mode 100644 web/app/components/base/icons/src/vender/system/AutoUpdateLine.json create mode 100644 web/app/components/base/icons/src/vender/system/AutoUpdateLine.tsx create mode 100644 web/app/components/base/icons/src/vender/system/index.ts rename web/app/components/plugins/plugin-page/{use-permission.ts => use-reference-setting.ts} (68%) create mode 100644 web/app/components/plugins/reference-setting-modal/auto-update-setting/config.ts create mode 100644 web/app/components/plugins/reference-setting-modal/auto-update-setting/index.tsx create mode 100644 web/app/components/plugins/reference-setting-modal/auto-update-setting/no-data-placeholder.tsx create mode 100644 web/app/components/plugins/reference-setting-modal/auto-update-setting/no-plugin-selected.tsx create mode 100644 web/app/components/plugins/reference-setting-modal/auto-update-setting/plugins-picker.tsx create mode 100644 web/app/components/plugins/reference-setting-modal/auto-update-setting/plugins-selected.tsx create mode 100644 web/app/components/plugins/reference-setting-modal/auto-update-setting/strategy-picker.tsx create mode 100644 web/app/components/plugins/reference-setting-modal/auto-update-setting/tool-item.tsx create mode 100644 web/app/components/plugins/reference-setting-modal/auto-update-setting/tool-picker.tsx create mode 100644 web/app/components/plugins/reference-setting-modal/auto-update-setting/types.ts create mode 100644 web/app/components/plugins/reference-setting-modal/auto-update-setting/utils.spec.ts create mode 100644 web/app/components/plugins/reference-setting-modal/auto-update-setting/utils.ts create mode 100644 web/app/components/plugins/reference-setting-modal/label.tsx rename web/app/components/plugins/{permission-setting-modal => reference-setting-modal}/modal.tsx (74%) rename web/app/components/plugins/{permission-setting-modal => reference-setting-modal}/style.module.css (100%) create mode 100644 web/app/components/plugins/update-plugin/downgrade-warning.tsx diff --git a/api/.env.example b/api/.env.example index daa0df535b..80b1c12cd8 100644 --- a/api/.env.example +++ b/api/.env.example @@ -471,6 +471,16 @@ APP_MAX_ACTIVE_REQUESTS=0 # Celery beat configuration CELERY_BEAT_SCHEDULER_TIME=1 +# Celery schedule tasks configuration +ENABLE_CLEAN_EMBEDDING_CACHE_TASK=false +ENABLE_CLEAN_UNUSED_DATASETS_TASK=false +ENABLE_CREATE_TIDB_SERVERLESS_TASK=false +ENABLE_UPDATE_TIDB_SERVERLESS_STATUS_TASK=false +ENABLE_CLEAN_MESSAGES=false +ENABLE_MAIL_CLEAN_DOCUMENT_NOTIFY_TASK=false +ENABLE_DATASETS_QUEUE_MONITOR=false +ENABLE_CHECK_UPGRADABLE_PLUGIN_TASK=true + # Position configuration POSITION_TOOL_PINS= POSITION_TOOL_INCLUDES= diff --git a/api/README.md b/api/README.md index 9308d5dc44..6ab923070e 100644 --- a/api/README.md +++ b/api/README.md @@ -74,7 +74,12 @@ 10. If you need to handle and debug the async tasks (e.g. dataset importing and documents indexing), please start the worker service. ```bash - uv run celery -A app.celery worker -P gevent -c 1 --loglevel INFO -Q dataset,generation,mail,ops_trace,app_deletion + uv run celery -A app.celery worker -P gevent -c 1 --loglevel INFO -Q dataset,generation,mail,ops_trace,app_deletion,plugin + ``` + + Addition, if you want to debug the celery scheduled tasks, you can use the following command in another terminal: + ```bash + uv run celery -A app.celery beat ``` ## Testing diff --git a/api/configs/feature/__init__.py b/api/configs/feature/__init__.py index f1d529355d..9f1646ea7d 100644 --- a/api/configs/feature/__init__.py +++ b/api/configs/feature/__init__.py @@ -832,6 +832,41 @@ class CeleryBeatConfig(BaseSettings): ) +class CeleryScheduleTasksConfig(BaseSettings): + ENABLE_CLEAN_EMBEDDING_CACHE_TASK: bool = Field( + description="Enable clean embedding cache task", + default=False, + ) + ENABLE_CLEAN_UNUSED_DATASETS_TASK: bool = Field( + description="Enable clean unused datasets task", + default=False, + ) + ENABLE_CREATE_TIDB_SERVERLESS_TASK: bool = Field( + description="Enable create tidb service job task", + default=False, + ) + ENABLE_UPDATE_TIDB_SERVERLESS_STATUS_TASK: bool = Field( + description="Enable update tidb service job status task", + default=False, + ) + ENABLE_CLEAN_MESSAGES: bool = Field( + description="Enable clean messages task", + default=False, + ) + ENABLE_MAIL_CLEAN_DOCUMENT_NOTIFY_TASK: bool = Field( + description="Enable mail clean document notify task", + default=False, + ) + ENABLE_DATASETS_QUEUE_MONITOR: bool = Field( + description="Enable queue monitor task", + default=False, + ) + ENABLE_CHECK_UPGRADABLE_PLUGIN_TASK: bool = Field( + description="Enable check upgradable plugin task", + default=True, + ) + + class PositionConfig(BaseSettings): POSITION_PROVIDER_PINS: str = Field( description="Comma-separated list of pinned model providers", @@ -961,5 +996,6 @@ class FeatureConfig( # hosted services config HostedServiceConfig, CeleryBeatConfig, + CeleryScheduleTasksConfig, ): pass diff --git a/api/controllers/console/workspace/plugin.py b/api/controllers/console/workspace/plugin.py index c0a4734828..09846d5c94 100644 --- a/api/controllers/console/workspace/plugin.py +++ b/api/controllers/console/workspace/plugin.py @@ -12,7 +12,8 @@ from controllers.console.wraps import account_initialization_required, setup_req from core.model_runtime.utils.encoders import jsonable_encoder from core.plugin.impl.exc import PluginDaemonClientSideError from libs.login import login_required -from models.account import TenantPluginPermission +from models.account import TenantPluginAutoUpgradeStrategy, TenantPluginPermission +from services.plugin.plugin_auto_upgrade_service import PluginAutoUpgradeService from services.plugin.plugin_parameter_service import PluginParameterService from services.plugin.plugin_permission_service import PluginPermissionService from services.plugin.plugin_service import PluginService @@ -534,6 +535,114 @@ class PluginFetchDynamicSelectOptionsApi(Resource): return jsonable_encoder({"options": options}) +class PluginChangePreferencesApi(Resource): + @setup_required + @login_required + @account_initialization_required + def post(self): + user = current_user + if not user.is_admin_or_owner: + raise Forbidden() + + req = reqparse.RequestParser() + req.add_argument("permission", type=dict, required=True, location="json") + req.add_argument("auto_upgrade", type=dict, required=True, location="json") + args = req.parse_args() + + tenant_id = user.current_tenant_id + + permission = args["permission"] + + install_permission = TenantPluginPermission.InstallPermission(permission.get("install_permission", "everyone")) + debug_permission = TenantPluginPermission.DebugPermission(permission.get("debug_permission", "everyone")) + + auto_upgrade = args["auto_upgrade"] + + strategy_setting = TenantPluginAutoUpgradeStrategy.StrategySetting( + auto_upgrade.get("strategy_setting", "fix_only") + ) + upgrade_time_of_day = auto_upgrade.get("upgrade_time_of_day", 0) + upgrade_mode = TenantPluginAutoUpgradeStrategy.UpgradeMode(auto_upgrade.get("upgrade_mode", "exclude")) + exclude_plugins = auto_upgrade.get("exclude_plugins", []) + include_plugins = auto_upgrade.get("include_plugins", []) + + # set permission + set_permission_result = PluginPermissionService.change_permission( + tenant_id, + install_permission, + debug_permission, + ) + if not set_permission_result: + return jsonable_encoder({"success": False, "message": "Failed to set permission"}) + + # set auto upgrade strategy + set_auto_upgrade_strategy_result = PluginAutoUpgradeService.change_strategy( + tenant_id, + strategy_setting, + upgrade_time_of_day, + upgrade_mode, + exclude_plugins, + include_plugins, + ) + if not set_auto_upgrade_strategy_result: + return jsonable_encoder({"success": False, "message": "Failed to set auto upgrade strategy"}) + + return jsonable_encoder({"success": True}) + + +class PluginFetchPreferencesApi(Resource): + @setup_required + @login_required + @account_initialization_required + def get(self): + tenant_id = current_user.current_tenant_id + + permission = PluginPermissionService.get_permission(tenant_id) + permission_dict = { + "install_permission": TenantPluginPermission.InstallPermission.EVERYONE, + "debug_permission": TenantPluginPermission.DebugPermission.EVERYONE, + } + + if permission: + permission_dict["install_permission"] = permission.install_permission + permission_dict["debug_permission"] = permission.debug_permission + + auto_upgrade = PluginAutoUpgradeService.get_strategy(tenant_id) + auto_upgrade_dict = { + "strategy_setting": TenantPluginAutoUpgradeStrategy.StrategySetting.DISABLED, + "upgrade_time_of_day": 0, + "upgrade_mode": TenantPluginAutoUpgradeStrategy.UpgradeMode.EXCLUDE, + "exclude_plugins": [], + "include_plugins": [], + } + + if auto_upgrade: + auto_upgrade_dict = { + "strategy_setting": auto_upgrade.strategy_setting, + "upgrade_time_of_day": auto_upgrade.upgrade_time_of_day, + "upgrade_mode": auto_upgrade.upgrade_mode, + "exclude_plugins": auto_upgrade.exclude_plugins, + "include_plugins": auto_upgrade.include_plugins, + } + + return jsonable_encoder({"permission": permission_dict, "auto_upgrade": auto_upgrade_dict}) + + +class PluginAutoUpgradeExcludePluginApi(Resource): + @setup_required + @login_required + @account_initialization_required + def post(self): + # exclude one single plugin + tenant_id = current_user.current_tenant_id + + req = reqparse.RequestParser() + req.add_argument("plugin_id", type=str, required=True, location="json") + args = req.parse_args() + + return jsonable_encoder({"success": PluginAutoUpgradeService.exclude_plugin(tenant_id, args["plugin_id"])}) + + api.add_resource(PluginDebuggingKeyApi, "/workspaces/current/plugin/debugging-key") api.add_resource(PluginListApi, "/workspaces/current/plugin/list") api.add_resource(PluginListLatestVersionsApi, "/workspaces/current/plugin/list/latest-versions") @@ -560,3 +669,7 @@ api.add_resource(PluginChangePermissionApi, "/workspaces/current/plugin/permissi api.add_resource(PluginFetchPermissionApi, "/workspaces/current/plugin/permission/fetch") api.add_resource(PluginFetchDynamicSelectOptionsApi, "/workspaces/current/plugin/parameters/dynamic-options") + +api.add_resource(PluginFetchPreferencesApi, "/workspaces/current/plugin/preferences/fetch") +api.add_resource(PluginChangePreferencesApi, "/workspaces/current/plugin/preferences/change") +api.add_resource(PluginAutoUpgradeExcludePluginApi, "/workspaces/current/plugin/preferences/autoupgrade/exclude") diff --git a/api/core/helper/marketplace.py b/api/core/helper/marketplace.py index 65bf4fc1db..fe3078923d 100644 --- a/api/core/helper/marketplace.py +++ b/api/core/helper/marketplace.py @@ -25,9 +25,29 @@ def batch_fetch_plugin_manifests(plugin_ids: list[str]) -> Sequence[MarketplaceP url = str(marketplace_api_url / "api/v1/plugins/batch") response = requests.post(url, json={"plugin_ids": plugin_ids}) response.raise_for_status() + return [MarketplacePluginDeclaration(**plugin) for plugin in response.json()["data"]["plugins"]] +def batch_fetch_plugin_manifests_ignore_deserialization_error( + plugin_ids: list[str], +) -> Sequence[MarketplacePluginDeclaration]: + if len(plugin_ids) == 0: + return [] + + url = str(marketplace_api_url / "api/v1/plugins/batch") + response = requests.post(url, json={"plugin_ids": plugin_ids}) + response.raise_for_status() + result: list[MarketplacePluginDeclaration] = [] + for plugin in response.json()["data"]["plugins"]: + try: + result.append(MarketplacePluginDeclaration(**plugin)) + except Exception as e: + pass + + return result + + def record_install_plugin_event(plugin_unique_identifier: str): url = str(marketplace_api_url / "api/v1/stats/plugins/install_count") response = requests.post(url, json={"unique_identifier": plugin_unique_identifier}) diff --git a/api/docker/entrypoint.sh b/api/docker/entrypoint.sh index 18d4f4885d..59d652c11b 100755 --- a/api/docker/entrypoint.sh +++ b/api/docker/entrypoint.sh @@ -22,7 +22,7 @@ if [[ "${MODE}" == "worker" ]]; then exec celery -A app.celery worker -P ${CELERY_WORKER_CLASS:-gevent} $CONCURRENCY_OPTION \ --max-tasks-per-child ${MAX_TASK_PRE_CHILD:-50} --loglevel ${LOG_LEVEL:-INFO} \ - -Q ${CELERY_QUEUES:-dataset,mail,ops_trace,app_deletion} + -Q ${CELERY_QUEUES:-dataset,mail,ops_trace,app_deletion,plugin} elif [[ "${MODE}" == "beat" ]]; then exec celery -A app.celery beat --loglevel ${LOG_LEVEL:-INFO} diff --git a/api/extensions/ext_celery.py b/api/extensions/ext_celery.py index 6279b1ad36..2c2846ba26 100644 --- a/api/extensions/ext_celery.py +++ b/api/extensions/ext_celery.py @@ -64,49 +64,62 @@ def init_app(app: DifyApp) -> Celery: celery_app.set_default() app.extensions["celery"] = celery_app - imports = [ - "schedule.clean_embedding_cache_task", - "schedule.clean_unused_datasets_task", - "schedule.create_tidb_serverless_task", - "schedule.update_tidb_serverless_status_task", - "schedule.clean_messages", - "schedule.mail_clean_document_notify_task", - "schedule.queue_monitor_task", - ] + imports = [] day = dify_config.CELERY_BEAT_SCHEDULER_TIME - beat_schedule = { - "clean_embedding_cache_task": { + + # if you add a new task, please add the switch to CeleryScheduleTasksConfig + beat_schedule = {} + if dify_config.ENABLE_CLEAN_EMBEDDING_CACHE_TASK: + imports.append("schedule.clean_embedding_cache_task") + beat_schedule["clean_embedding_cache_task"] = { "task": "schedule.clean_embedding_cache_task.clean_embedding_cache_task", "schedule": timedelta(days=day), - }, - "clean_unused_datasets_task": { + } + if dify_config.ENABLE_CLEAN_UNUSED_DATASETS_TASK: + imports.append("schedule.clean_unused_datasets_task") + beat_schedule["clean_unused_datasets_task"] = { "task": "schedule.clean_unused_datasets_task.clean_unused_datasets_task", "schedule": timedelta(days=day), - }, - "create_tidb_serverless_task": { + } + if dify_config.ENABLE_CREATE_TIDB_SERVERLESS_TASK: + imports.append("schedule.create_tidb_serverless_task") + beat_schedule["create_tidb_serverless_task"] = { "task": "schedule.create_tidb_serverless_task.create_tidb_serverless_task", "schedule": crontab(minute="0", hour="*"), - }, - "update_tidb_serverless_status_task": { + } + if dify_config.ENABLE_UPDATE_TIDB_SERVERLESS_STATUS_TASK: + imports.append("schedule.update_tidb_serverless_status_task") + beat_schedule["update_tidb_serverless_status_task"] = { "task": "schedule.update_tidb_serverless_status_task.update_tidb_serverless_status_task", "schedule": timedelta(minutes=10), - }, - "clean_messages": { + } + if dify_config.ENABLE_CLEAN_MESSAGES: + imports.append("schedule.clean_messages") + beat_schedule["clean_messages"] = { "task": "schedule.clean_messages.clean_messages", "schedule": timedelta(days=day), - }, - # every Monday - "mail_clean_document_notify_task": { + } + if dify_config.ENABLE_MAIL_CLEAN_DOCUMENT_NOTIFY_TASK: + imports.append("schedule.mail_clean_document_notify_task") + beat_schedule["mail_clean_document_notify_task"] = { "task": "schedule.mail_clean_document_notify_task.mail_clean_document_notify_task", "schedule": crontab(minute="0", hour="10", day_of_week="1"), - }, - "datasets-queue-monitor": { + } + if dify_config.ENABLE_DATASETS_QUEUE_MONITOR: + imports.append("schedule.queue_monitor_task") + beat_schedule["datasets-queue-monitor"] = { "task": "schedule.queue_monitor_task.queue_monitor_task", "schedule": timedelta( minutes=dify_config.QUEUE_MONITOR_INTERVAL if dify_config.QUEUE_MONITOR_INTERVAL else 30 ), - }, - } + } + if dify_config.ENABLE_CHECK_UPGRADABLE_PLUGIN_TASK: + imports.append("schedule.check_upgradable_plugin_task") + beat_schedule["check_upgradable_plugin_task"] = { + "task": "schedule.check_upgradable_plugin_task.check_upgradable_plugin_task", + "schedule": crontab(minute="*/15"), + } + celery_app.conf.update(beat_schedule=beat_schedule, imports=imports) return celery_app diff --git a/api/migrations/versions/2025_07_23_1508-8bcc02c9bd07_add_tenant_plugin_autoupgrade_table.py b/api/migrations/versions/2025_07_23_1508-8bcc02c9bd07_add_tenant_plugin_autoupgrade_table.py new file mode 100644 index 0000000000..4ff0402a97 --- /dev/null +++ b/api/migrations/versions/2025_07_23_1508-8bcc02c9bd07_add_tenant_plugin_autoupgrade_table.py @@ -0,0 +1,42 @@ +"""add_tenant_plugin_autoupgrade_table + +Revision ID: 8bcc02c9bd07 +Revises: 375fe79ead14 +Create Date: 2025-07-23 15:08:50.161441 + +""" +from alembic import op +import models as models +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '8bcc02c9bd07' +down_revision = '375fe79ead14' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('tenant_plugin_auto_upgrade_strategies', + sa.Column('id', models.types.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False), + sa.Column('tenant_id', models.types.StringUUID(), nullable=False), + sa.Column('strategy_setting', sa.String(length=16), server_default='fix_only', nullable=False), + sa.Column('upgrade_time_of_day', sa.Integer(), nullable=False), + sa.Column('upgrade_mode', sa.String(length=16), server_default='exclude', nullable=False), + sa.Column('exclude_plugins', sa.ARRAY(sa.String(length=255)), nullable=False), + sa.Column('include_plugins', sa.ARRAY(sa.String(length=255)), nullable=False), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False), + sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False), + sa.PrimaryKeyConstraint('id', name='tenant_plugin_auto_upgrade_strategy_pkey'), + sa.UniqueConstraint('tenant_id', name='unique_tenant_plugin_auto_upgrade_strategy') + ) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + + op.drop_table('tenant_plugin_auto_upgrade_strategies') + # ### end Alembic commands ### diff --git a/api/models/account.py b/api/models/account.py index 01bf9d5f77..01d1625dbd 100644 --- a/api/models/account.py +++ b/api/models/account.py @@ -297,6 +297,40 @@ class TenantPluginPermission(Base): ) id: Mapped[str] = mapped_column(StringUUID, server_default=db.text("uuid_generate_v4()")) - tenant_id: Mapped[str] = mapped_column(StringUUID) - install_permission: Mapped[InstallPermission] = mapped_column(db.String(16), server_default="everyone") - debug_permission: Mapped[DebugPermission] = mapped_column(db.String(16), server_default="noone") + tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) + install_permission: Mapped[InstallPermission] = mapped_column( + db.String(16), nullable=False, server_default="everyone" + ) + debug_permission: Mapped[DebugPermission] = mapped_column(db.String(16), nullable=False, server_default="noone") + + +class TenantPluginAutoUpgradeStrategy(Base): + class StrategySetting(enum.StrEnum): + DISABLED = "disabled" + FIX_ONLY = "fix_only" + LATEST = "latest" + + class UpgradeMode(enum.StrEnum): + ALL = "all" + PARTIAL = "partial" + EXCLUDE = "exclude" + + __tablename__ = "tenant_plugin_auto_upgrade_strategies" + __table_args__ = ( + db.PrimaryKeyConstraint("id", name="tenant_plugin_auto_upgrade_strategy_pkey"), + db.UniqueConstraint("tenant_id", name="unique_tenant_plugin_auto_upgrade_strategy"), + ) + + id: Mapped[str] = mapped_column(StringUUID, server_default=db.text("uuid_generate_v4()")) + tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False) + strategy_setting: Mapped[StrategySetting] = mapped_column(db.String(16), nullable=False, server_default="fix_only") + upgrade_time_of_day: Mapped[int] = mapped_column(db.Integer, nullable=False, default=0) # seconds of the day + upgrade_mode: Mapped[UpgradeMode] = mapped_column(db.String(16), nullable=False, server_default="exclude") + exclude_plugins: Mapped[list[str]] = mapped_column( + db.ARRAY(db.String(255)), nullable=False + ) # plugin_id (author/name) + include_plugins: Mapped[list[str]] = mapped_column( + db.ARRAY(db.String(255)), nullable=False + ) # plugin_id (author/name) + created_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp()) + updated_at = db.Column(db.DateTime, nullable=False, server_default=func.current_timestamp()) diff --git a/api/schedule/check_upgradable_plugin_task.py b/api/schedule/check_upgradable_plugin_task.py new file mode 100644 index 0000000000..c1d6018827 --- /dev/null +++ b/api/schedule/check_upgradable_plugin_task.py @@ -0,0 +1,49 @@ +import time + +import click + +import app +from extensions.ext_database import db +from models.account import TenantPluginAutoUpgradeStrategy +from tasks.process_tenant_plugin_autoupgrade_check_task import process_tenant_plugin_autoupgrade_check_task + +AUTO_UPGRADE_MINIMAL_CHECKING_INTERVAL = 15 * 60 # 15 minutes + + +@app.celery.task(queue="plugin") +def check_upgradable_plugin_task(): + click.echo(click.style("Start check upgradable plugin.", fg="green")) + start_at = time.perf_counter() + + now_seconds_of_day = time.time() % 86400 - 30 # we assume the tz is UTC + click.echo(click.style("Now seconds of day: {}".format(now_seconds_of_day), fg="green")) + + strategies = ( + db.session.query(TenantPluginAutoUpgradeStrategy) + .filter( + TenantPluginAutoUpgradeStrategy.upgrade_time_of_day >= now_seconds_of_day, + TenantPluginAutoUpgradeStrategy.upgrade_time_of_day + < now_seconds_of_day + AUTO_UPGRADE_MINIMAL_CHECKING_INTERVAL, + TenantPluginAutoUpgradeStrategy.strategy_setting + != TenantPluginAutoUpgradeStrategy.StrategySetting.DISABLED, + ) + .all() + ) + + for strategy in strategies: + process_tenant_plugin_autoupgrade_check_task.delay( + strategy.tenant_id, + strategy.strategy_setting, + strategy.upgrade_time_of_day, + strategy.upgrade_mode, + strategy.exclude_plugins, + strategy.include_plugins, + ) + + end_at = time.perf_counter() + click.echo( + click.style( + "Checked upgradable plugin success latency: {}".format(end_at - start_at), + fg="green", + ) + ) diff --git a/api/services/account_service.py b/api/services/account_service.py index c88e70e380..4c4510395e 100644 --- a/api/services/account_service.py +++ b/api/services/account_service.py @@ -29,6 +29,7 @@ from models.account import ( Tenant, TenantAccountJoin, TenantAccountRole, + TenantPluginAutoUpgradeStrategy, TenantStatus, ) from models.model import DifySetup @@ -828,6 +829,17 @@ class TenantService: db.session.add(tenant) db.session.commit() + plugin_upgrade_strategy = TenantPluginAutoUpgradeStrategy( + tenant_id=tenant.id, + strategy_setting=TenantPluginAutoUpgradeStrategy.StrategySetting.FIX_ONLY, + upgrade_time_of_day=0, + upgrade_mode=TenantPluginAutoUpgradeStrategy.UpgradeMode.EXCLUDE, + exclude_plugins=[], + include_plugins=[], + ) + db.session.add(plugin_upgrade_strategy) + db.session.commit() + tenant.encrypt_public_key = generate_key_pair(tenant.id) db.session.commit() return tenant diff --git a/api/services/plugin/plugin_auto_upgrade_service.py b/api/services/plugin/plugin_auto_upgrade_service.py new file mode 100644 index 0000000000..3774050445 --- /dev/null +++ b/api/services/plugin/plugin_auto_upgrade_service.py @@ -0,0 +1,87 @@ +from sqlalchemy.orm import Session + +from extensions.ext_database import db +from models.account import TenantPluginAutoUpgradeStrategy + + +class PluginAutoUpgradeService: + @staticmethod + def get_strategy(tenant_id: str) -> TenantPluginAutoUpgradeStrategy | None: + with Session(db.engine) as session: + return ( + session.query(TenantPluginAutoUpgradeStrategy) + .filter(TenantPluginAutoUpgradeStrategy.tenant_id == tenant_id) + .first() + ) + + @staticmethod + def change_strategy( + tenant_id: str, + strategy_setting: TenantPluginAutoUpgradeStrategy.StrategySetting, + upgrade_time_of_day: int, + upgrade_mode: TenantPluginAutoUpgradeStrategy.UpgradeMode, + exclude_plugins: list[str], + include_plugins: list[str], + ) -> bool: + with Session(db.engine) as session: + exist_strategy = ( + session.query(TenantPluginAutoUpgradeStrategy) + .filter(TenantPluginAutoUpgradeStrategy.tenant_id == tenant_id) + .first() + ) + if not exist_strategy: + strategy = TenantPluginAutoUpgradeStrategy( + tenant_id=tenant_id, + strategy_setting=strategy_setting, + upgrade_time_of_day=upgrade_time_of_day, + upgrade_mode=upgrade_mode, + exclude_plugins=exclude_plugins, + include_plugins=include_plugins, + ) + session.add(strategy) + else: + exist_strategy.strategy_setting = strategy_setting + exist_strategy.upgrade_time_of_day = upgrade_time_of_day + exist_strategy.upgrade_mode = upgrade_mode + exist_strategy.exclude_plugins = exclude_plugins + exist_strategy.include_plugins = include_plugins + + session.commit() + return True + + @staticmethod + def exclude_plugin(tenant_id: str, plugin_id: str) -> bool: + with Session(db.engine) as session: + exist_strategy = ( + session.query(TenantPluginAutoUpgradeStrategy) + .filter(TenantPluginAutoUpgradeStrategy.tenant_id == tenant_id) + .first() + ) + if not exist_strategy: + # create for this tenant + PluginAutoUpgradeService.change_strategy( + tenant_id, + TenantPluginAutoUpgradeStrategy.StrategySetting.FIX_ONLY, + 0, + TenantPluginAutoUpgradeStrategy.UpgradeMode.EXCLUDE, + [plugin_id], + [], + ) + return True + else: + if exist_strategy.upgrade_mode == TenantPluginAutoUpgradeStrategy.UpgradeMode.EXCLUDE: + if plugin_id not in exist_strategy.exclude_plugins: + new_exclude_plugins = exist_strategy.exclude_plugins.copy() + new_exclude_plugins.append(plugin_id) + exist_strategy.exclude_plugins = new_exclude_plugins + elif exist_strategy.upgrade_mode == TenantPluginAutoUpgradeStrategy.UpgradeMode.PARTIAL: + if plugin_id in exist_strategy.include_plugins: + new_include_plugins = exist_strategy.include_plugins.copy() + new_include_plugins.remove(plugin_id) + exist_strategy.include_plugins = new_include_plugins + elif exist_strategy.upgrade_mode == TenantPluginAutoUpgradeStrategy.UpgradeMode.ALL: + exist_strategy.upgrade_mode = TenantPluginAutoUpgradeStrategy.UpgradeMode.EXCLUDE + exist_strategy.exclude_plugins = [plugin_id] + + session.commit() + return True diff --git a/api/tasks/process_tenant_plugin_autoupgrade_check_task.py b/api/tasks/process_tenant_plugin_autoupgrade_check_task.py new file mode 100644 index 0000000000..6fcdad0525 --- /dev/null +++ b/api/tasks/process_tenant_plugin_autoupgrade_check_task.py @@ -0,0 +1,166 @@ +import traceback +import typing + +import click +from celery import shared_task # type: ignore + +from core.helper import marketplace +from core.helper.marketplace import MarketplacePluginDeclaration +from core.plugin.entities.plugin import PluginInstallationSource +from core.plugin.impl.plugin import PluginInstaller +from models.account import TenantPluginAutoUpgradeStrategy + +RETRY_TIMES_OF_ONE_PLUGIN_IN_ONE_TENANT = 3 + + +cached_plugin_manifests: dict[str, typing.Union[MarketplacePluginDeclaration, None]] = {} + + +def marketplace_batch_fetch_plugin_manifests( + plugin_ids_plain_list: list[str], +) -> list[MarketplacePluginDeclaration]: + global cached_plugin_manifests + # return marketplace.batch_fetch_plugin_manifests(plugin_ids_plain_list) + not_included_plugin_ids = [ + plugin_id for plugin_id in plugin_ids_plain_list if plugin_id not in cached_plugin_manifests + ] + if not_included_plugin_ids: + manifests = marketplace.batch_fetch_plugin_manifests_ignore_deserialization_error(not_included_plugin_ids) + for manifest in manifests: + cached_plugin_manifests[manifest.plugin_id] = manifest + + if ( + len(manifests) == 0 + ): # this indicates that the plugin not found in marketplace, should set None in cache to prevent future check + for plugin_id in not_included_plugin_ids: + cached_plugin_manifests[plugin_id] = None + + result: list[MarketplacePluginDeclaration] = [] + for plugin_id in plugin_ids_plain_list: + final_manifest = cached_plugin_manifests.get(plugin_id) + if final_manifest is not None: + result.append(final_manifest) + + return result + + +@shared_task(queue="plugin") +def process_tenant_plugin_autoupgrade_check_task( + tenant_id: str, + strategy_setting: TenantPluginAutoUpgradeStrategy.StrategySetting, + upgrade_time_of_day: int, + upgrade_mode: TenantPluginAutoUpgradeStrategy.UpgradeMode, + exclude_plugins: list[str], + include_plugins: list[str], +): + try: + manager = PluginInstaller() + + click.echo( + click.style( + "Checking upgradable plugin for tenant: {}".format(tenant_id), + fg="green", + ) + ) + + if strategy_setting == TenantPluginAutoUpgradeStrategy.StrategySetting.DISABLED: + return + + # get plugin_ids to check + plugin_ids: list[tuple[str, str, str]] = [] # plugin_id, version, unique_identifier + click.echo(click.style("Upgrade mode: {}".format(upgrade_mode), fg="green")) + + if upgrade_mode == TenantPluginAutoUpgradeStrategy.UpgradeMode.PARTIAL and include_plugins: + all_plugins = manager.list_plugins(tenant_id) + + for plugin in all_plugins: + if plugin.source == PluginInstallationSource.Marketplace and plugin.plugin_id in include_plugins: + plugin_ids.append( + ( + plugin.plugin_id, + plugin.version, + plugin.plugin_unique_identifier, + ) + ) + + elif upgrade_mode == TenantPluginAutoUpgradeStrategy.UpgradeMode.EXCLUDE: + # get all plugins and remove excluded plugins + all_plugins = manager.list_plugins(tenant_id) + plugin_ids = [ + (plugin.plugin_id, plugin.version, plugin.plugin_unique_identifier) + for plugin in all_plugins + if plugin.source == PluginInstallationSource.Marketplace and plugin.plugin_id not in exclude_plugins + ] + elif upgrade_mode == TenantPluginAutoUpgradeStrategy.UpgradeMode.ALL: + all_plugins = manager.list_plugins(tenant_id) + plugin_ids = [ + (plugin.plugin_id, plugin.version, plugin.plugin_unique_identifier) + for plugin in all_plugins + if plugin.source == PluginInstallationSource.Marketplace + ] + + if not plugin_ids: + return + + plugin_ids_plain_list = [plugin_id for plugin_id, _, _ in plugin_ids] + + manifests = marketplace_batch_fetch_plugin_manifests(plugin_ids_plain_list) + + if not manifests: + return + + for manifest in manifests: + for plugin_id, version, original_unique_identifier in plugin_ids: + if manifest.plugin_id != plugin_id: + continue + + try: + current_version = version + latest_version = manifest.latest_version + + def fix_only_checker(latest_version, current_version): + latest_version_tuple = tuple(int(val) for val in latest_version.split(".")) + current_version_tuple = tuple(int(val) for val in current_version.split(".")) + + if ( + latest_version_tuple[0] == current_version_tuple[0] + and latest_version_tuple[1] == current_version_tuple[1] + ): + return latest_version_tuple[2] != current_version_tuple[2] + return False + + version_checker = { + TenantPluginAutoUpgradeStrategy.StrategySetting.LATEST: lambda latest_version, + current_version: latest_version != current_version, + TenantPluginAutoUpgradeStrategy.StrategySetting.FIX_ONLY: fix_only_checker, + } + + if version_checker[strategy_setting](latest_version, current_version): + # execute upgrade + new_unique_identifier = manifest.latest_package_identifier + + marketplace.record_install_plugin_event(new_unique_identifier) + click.echo( + click.style( + "Upgrade plugin: {} -> {}".format(original_unique_identifier, new_unique_identifier), + fg="green", + ) + ) + task_start_resp = manager.upgrade_plugin( + tenant_id, + original_unique_identifier, + new_unique_identifier, + PluginInstallationSource.Marketplace, + { + "plugin_unique_identifier": new_unique_identifier, + }, + ) + except Exception as e: + click.echo(click.style("Error when upgrading plugin: {}".format(e), fg="red")) + traceback.print_exc() + break + + except Exception as e: + click.echo(click.style("Error when checking upgradable plugin: {}".format(e), fg="red")) + traceback.print_exc() + return diff --git a/docker/.env.example b/docker/.env.example index 6149f63165..88cc544730 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -1168,3 +1168,13 @@ QUEUE_MONITOR_THRESHOLD=200 QUEUE_MONITOR_ALERT_EMAILS= # Monitor interval in minutes, default is 30 minutes QUEUE_MONITOR_INTERVAL=30 + +# Celery schedule tasks configuration +ENABLE_CLEAN_EMBEDDING_CACHE_TASK=false +ENABLE_CLEAN_UNUSED_DATASETS_TASK=false +ENABLE_CREATE_TIDB_SERVERLESS_TASK=false +ENABLE_UPDATE_TIDB_SERVERLESS_STATUS_TASK=false +ENABLE_CLEAN_MESSAGES=false +ENABLE_MAIL_CLEAN_DOCUMENT_NOTIFY_TASK=false +ENABLE_DATASETS_QUEUE_MONITOR=false +ENABLE_CHECK_UPGRADABLE_PLUGIN_TASK=true diff --git a/docker/docker-compose-template.yaml b/docker/docker-compose-template.yaml index 7c1544acb9..878268e76b 100644 --- a/docker/docker-compose-template.yaml +++ b/docker/docker-compose-template.yaml @@ -55,6 +55,25 @@ services: - ssrf_proxy_network - default + # worker_beat service + # Celery beat for scheduling periodic tasks. + worker_beat: + image: langgenius/dify-api:1.5.0 + restart: always + environment: + # Use the shared environment variables. + <<: *shared-api-worker-env + # Startup mode, 'worker_beat' starts the Celery beat for scheduling periodic tasks. + MODE: beat + depends_on: + db: + condition: service_healthy + redis: + condition: service_started + networks: + - ssrf_proxy_network + - default + # Frontend web application. web: image: langgenius/dify-web:1.6.0 diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 1271d6d464..f914d92254 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -527,6 +527,14 @@ x-shared-env: &shared-api-worker-env QUEUE_MONITOR_THRESHOLD: ${QUEUE_MONITOR_THRESHOLD:-200} QUEUE_MONITOR_ALERT_EMAILS: ${QUEUE_MONITOR_ALERT_EMAILS:-} QUEUE_MONITOR_INTERVAL: ${QUEUE_MONITOR_INTERVAL:-30} + ENABLE_CLEAN_EMBEDDING_CACHE_TASK: ${ENABLE_CLEAN_EMBEDDING_CACHE_TASK:-false} + ENABLE_CLEAN_UNUSED_DATASETS_TASK: ${ENABLE_CLEAN_UNUSED_DATASETS_TASK:-false} + ENABLE_CREATE_TIDB_SERVERLESS_TASK: ${ENABLE_CREATE_TIDB_SERVERLESS_TASK:-false} + ENABLE_UPDATE_TIDB_SERVERLESS_STATUS_TASK: ${ENABLE_UPDATE_TIDB_SERVERLESS_STATUS_TASK:-false} + ENABLE_CLEAN_MESSAGES: ${ENABLE_CLEAN_MESSAGES:-false} + ENABLE_MAIL_CLEAN_DOCUMENT_NOTIFY_TASK: ${ENABLE_MAIL_CLEAN_DOCUMENT_NOTIFY_TASK:-false} + ENABLE_DATASETS_QUEUE_MONITOR: ${ENABLE_DATASETS_QUEUE_MONITOR:-false} + ENABLE_CHECK_UPGRADABLE_PLUGIN_TASK: ${ENABLE_CHECK_UPGRADABLE_PLUGIN_TASK:-true} services: # API service @@ -584,6 +592,25 @@ services: - ssrf_proxy_network - default + # worker_beat service + # Celery beat for scheduling periodic tasks. + worker_beat: + image: langgenius/dify-api:1.5.0 + restart: always + environment: + # Use the shared environment variables. + <<: *shared-api-worker-env + # Startup mode, 'worker_beat' starts the Celery beat for scheduling periodic tasks. + MODE: beat + depends_on: + db: + condition: service_healthy + redis: + condition: service_started + networks: + - ssrf_proxy_network + - default + # Frontend web application. web: image: langgenius/dify-web:1.6.0 diff --git a/web/app/components/base/date-and-time-picker/common/option-list-item.tsx b/web/app/components/base/date-and-time-picker/common/option-list-item.tsx index d11a6e9e86..8c2c8d82f1 100644 --- a/web/app/components/base/date-and-time-picker/common/option-list-item.tsx +++ b/web/app/components/base/date-and-time-picker/common/option-list-item.tsx @@ -4,18 +4,21 @@ import cn from '@/utils/classnames' type OptionListItemProps = { isSelected: boolean onClick: () => void + noAutoScroll?: boolean } & React.LiHTMLAttributes const OptionListItem: FC = ({ isSelected, onClick, + noAutoScroll, children, }) => { const listItemRef = useRef(null) useEffect(() => { - if (isSelected) + if (isSelected && !noAutoScroll) listItemRef.current?.scrollIntoView({ behavior: 'instant' }) + // eslint-disable-next-line react-hooks/exhaustive-deps }, []) return ( diff --git a/web/app/components/base/date-and-time-picker/time-picker/header.tsx b/web/app/components/base/date-and-time-picker/time-picker/header.tsx index 3d85b2ea40..dc6b56f744 100644 --- a/web/app/components/base/date-and-time-picker/time-picker/header.tsx +++ b/web/app/components/base/date-and-time-picker/time-picker/header.tsx @@ -1,13 +1,18 @@ import React from 'react' import { useTranslation } from 'react-i18next' -const Header = () => { +type Props = { + title?: string +} +const Header = ({ + title, +}: Props) => { const { t } = useTranslation() return (
- {t('time.title.pickTime')} + {title || t('time.title.pickTime')}
) diff --git a/web/app/components/base/date-and-time-picker/time-picker/index.tsx b/web/app/components/base/date-and-time-picker/time-picker/index.tsx index a5e666d631..d493106667 100644 --- a/web/app/components/base/date-and-time-picker/time-picker/index.tsx +++ b/web/app/components/base/date-and-time-picker/time-picker/index.tsx @@ -20,6 +20,9 @@ const TimePicker = ({ onChange, onClear, renderTrigger, + title, + minuteFilter, + popupClassName, }: TimePickerProps) => { const { t } = useTranslation() const [isOpen, setIsOpen] = useState(false) @@ -108,6 +111,15 @@ const TimePicker = ({ const displayValue = value?.format(timeFormat) || '' const placeholderDate = isOpen && selectedTime ? selectedTime.format(timeFormat) : (placeholder || t('time.defaultPlaceholder')) + const inputElem = ( + + ) return ( - {renderTrigger ? (renderTrigger()) : ( + {renderTrigger ? (renderTrigger({ + inputElem, + onClick: handleClickTrigger, + isOpen, + })) : (
- + {inputElem} )} - +
{/* Header */} -
+
{/* Time Options */} = ({ selectedTime, + minuteFilter, handleSelectHour, handleSelectMinute, handleSelectPeriod, @@ -33,7 +34,7 @@ const Options: FC = ({ {/* Minute */}
    { - minuteOptions.map((minute) => { + (minuteFilter ? minuteFilter(minuteOptions) : minuteOptions).map((minute) => { const isSelected = selectedTime?.format('mm') === minute return ( = ({ key={period} isSelected={isSelected} onClick={handleSelectPeriod.bind(null, period)} + noAutoScroll // if choose PM which would hide(scrolled) AM that may make user confused that there's no am. > {period} diff --git a/web/app/components/base/date-and-time-picker/types.ts b/web/app/components/base/date-and-time-picker/types.ts index 214c0f011b..4ac01c142a 100644 --- a/web/app/components/base/date-and-time-picker/types.ts +++ b/web/app/components/base/date-and-time-picker/types.ts @@ -28,6 +28,7 @@ export type DatePickerProps = { onClear: () => void triggerWrapClassName?: string renderTrigger?: (props: TriggerProps) => React.ReactNode + minuteFilter?: (minutes: string[]) => string[] popupZIndexClassname?: string } @@ -47,13 +48,21 @@ export type DatePickerFooterProps = { handleConfirmDate: () => void } +export type TriggerParams = { + isOpen: boolean + inputElem: React.ReactNode + onClick: (e: React.MouseEvent) => void +} export type TimePickerProps = { value: Dayjs | undefined timezone?: string placeholder?: string onChange: (date: Dayjs | undefined) => void onClear: () => void - renderTrigger?: () => React.ReactNode + renderTrigger?: (props: TriggerParams) => React.ReactNode + title?: string + minuteFilter?: (minutes: string[]) => string[] + popupClassName?: string } export type TimePickerFooterProps = { @@ -81,6 +90,7 @@ export type CalendarItemProps = { export type TimeOptionsProps = { selectedTime: Dayjs | undefined + minuteFilter?: (minutes: string[]) => string[] handleSelectHour: (hour: string) => void handleSelectMinute: (minute: string) => void handleSelectPeriod: (period: Period) => void diff --git a/web/app/components/base/date-and-time-picker/utils/dayjs.ts b/web/app/components/base/date-and-time-picker/utils/dayjs.ts index 0928fa5d58..cdc3924194 100644 --- a/web/app/components/base/date-and-time-picker/utils/dayjs.ts +++ b/web/app/components/base/date-and-time-picker/utils/dayjs.ts @@ -2,6 +2,7 @@ import dayjs, { type Dayjs } from 'dayjs' import type { Day } from '../types' import utc from 'dayjs/plugin/utc' import timezone from 'dayjs/plugin/timezone' +import tz from '@/utils/timezone.json' dayjs.extend(utc) dayjs.extend(timezone) @@ -78,3 +79,14 @@ export const getHourIn12Hour = (date: Dayjs) => { export const getDateWithTimezone = (props: { date?: Dayjs, timezone?: string }) => { return props.date ? dayjs.tz(props.date, props.timezone) : dayjs().tz(props.timezone) } + +// Asia/Shanghai -> UTC+8 +const DEFAULT_OFFSET_STR = 'UTC+0' +export const convertTimezoneToOffsetStr = (timezone?: string) => { + if (!timezone) + return DEFAULT_OFFSET_STR + const tzItem = tz.find(item => item.value === timezone) + if(!tzItem) + return DEFAULT_OFFSET_STR + return `UTC${tzItem.name.charAt(0)}${tzItem.name.charAt(2)}` +} diff --git a/web/app/components/base/icons/assets/vender/line/general/search-menu.svg b/web/app/components/base/icons/assets/vender/line/general/search-menu.svg new file mode 100644 index 0000000000..f61f69f4ba --- /dev/null +++ b/web/app/components/base/icons/assets/vender/line/general/search-menu.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/web/app/components/base/icons/assets/vender/system/auto-update-line.svg b/web/app/components/base/icons/assets/vender/system/auto-update-line.svg new file mode 100644 index 0000000000..c6bff78400 --- /dev/null +++ b/web/app/components/base/icons/assets/vender/system/auto-update-line.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web/app/components/base/icons/script.mjs b/web/app/components/base/icons/script.mjs index 7f9d7b73a0..1b5994edef 100644 --- a/web/app/components/base/icons/script.mjs +++ b/web/app/components/base/icons/script.mjs @@ -75,7 +75,7 @@ Icon.displayName = '<%= svgName %>' export default Icon `.trim()) - await writeFile(path.resolve(currentPath, `${fileName}.json`), JSON.stringify(svgData, '', '\t')) + await writeFile(path.resolve(currentPath, `${fileName}.json`), `${JSON.stringify(svgData, '', '\t')}\n`) await writeFile(path.resolve(currentPath, `${fileName}.tsx`), `${componentRender({ svgName: fileName })}\n`) const indexingRender = template(` diff --git a/web/app/components/base/icons/src/public/tracing/AliyunIcon.json b/web/app/components/base/icons/src/public/tracing/AliyunIcon.json index 5cbb52c237..9a0b89f20a 100644 --- a/web/app/components/base/icons/src/public/tracing/AliyunIcon.json +++ b/web/app/components/base/icons/src/public/tracing/AliyunIcon.json @@ -1,118 +1,131 @@ { - "icon": { - "type": "element", - "isRootNode": true, - "name": "svg", - "attributes": { - "xmlns": "http://www.w3.org/2000/svg", - "xmlns:xlink": "http://www.w3.org/1999/xlink", - "fill": "none", - "version": "1.1", - "width": "65", - "height": "16", - "viewBox": "0 0 65 16" - }, - "children": [ - { - "type": "element", - "name": "defs", - "children": [ - { - "type": "element", - "name": "clipPath", - "attributes": { - "id": "master_svg0_42_34281" - }, - "children": [ - { - "type": "element", - "name": "rect", - "attributes": { - "x": "0", - "y": "0", - "width": "19", - "height": "16", - "rx": "0" - } - } - ] - } - ] - }, - { - "type": "element", - "name": "g", - "children": [ - { - "type": "element", - "name": "g", - "attributes": { - "clip-path": "url(#master_svg0_42_34281)" - }, - "children": [ - { - "type": "element", - "name": "g", - "children": [ - { - "type": "element", - "name": "g", - "children": [ - { - "type": "element", - "name": "path", - "attributes": { - "d": "M4.06862,14.6667C3.79213,14.6667,3.45463,14.5688,3.05614,14.373C2.97908,14.3351,2.92692,14.3105,2.89968,14.2992C2.33193,14.0628,1.82911,13.7294,1.39123,13.2989C0.463742,12.3871,0,11.2874,0,10C0,8.71258,0.463742,7.61293,1.39123,6.70107C2.16172,5.94358,3.06404,5.50073,4.09819,5.37252C4.23172,3.98276,4.81755,2.77756,5.85569,1.75693C7.04708,0.585642,8.4857,0,10.1716,0C11.5256,0,12.743,0.396982,13.8239,1.19095C14.8847,1.97019,15.61,2.97855,16,4.21604L14.7045,4.61063C14.4016,3.64918,13.8374,2.86532,13.0121,2.25905C12.1719,1.64191,11.2251,1.33333,10.1716,1.33333C8.8602,1.33333,7.74124,1.7888,6.81467,2.69974C5.88811,3.61067,5.42483,4.71076,5.42483,6L5.42483,6.66667L4.74673,6.66667C3.81172,6.66667,3.01288,6.99242,2.35021,7.64393C1.68754,8.2954,1.35621,9.08076,1.35621,10C1.35621,10.9192,1.68754,11.7046,2.35021,12.3561C2.66354,12.6641,3.02298,12.9026,3.42852,13.0714C3.48193,13.0937,3.55988,13.13,3.66237,13.1803C3.87004,13.2823,4.00545,13.3333,4.06862,13.3333L4.06862,14.6667Z", - "fill-rule": "evenodd", - "fill": "#FF6A00", - "fill-opacity": "1" - } - } - ] - }, - { - "type": "element", - "name": "g", - "children": [ - { - "type": "element", - "name": "path", - "attributes": { - "d": "M13.458613505859375,7.779393492279053C12.975613505859375,7.717463492279053,12.484813505859375,7.686503492279053,11.993983505859376,7.686503492279053C11.152583505859376,7.686503492279053,10.303403505859375,7.779393492279053,9.493183505859374,7.941943492279053C8.682953505859375,8.104503492279052,7.903893505859375,8.359943492279053,7.155983505859375,8.654083492279053C6.657383505859375,8.870823492279053,6.158783505859375,9.128843492279053,5.660181505859375,9.428153492279053C5.332974751859375,9.621673492279053,5.239486705859375,10.070633492279054,5.434253505859375,10.395743492279053L7.413073505859375,13.298533492279052C7.639003505859375,13.623603492279052,8.090863505859375,13.716463492279052,8.418073505859375,13.523003492279052C8.547913505859375,13.435263492279052,8.763453505859374,13.326893492279053,9.064693505859374,13.197863492279053C9.516553505859374,13.004333492279052,9.976203505859374,12.872733492279053,10.459223505859375,12.779863492279052C10.942243505859375,12.679263492279052,11.433053505859375,12.617333492279052,11.955023505859375,12.617333492279052L13.380683505859375,7.810353492279052L13.458613505859375,7.779393492279053ZM15.273813505859374,8.135463492279053L15.016753505859375,5.333333492279053L13.458613505859375,7.787133492279053C13.817013505859375,7.818093492279052,14.144213505859375,7.880023492279053,14.494743505859375,7.949683492279053C14.494743505859375,7.944523492279053,14.754433505859375,8.006453492279054,15.273813505859374,8.135463492279053ZM12.064083505859376,12.648273492279053L11.378523505859375,14.970463492279054L12.515943505859376,16.00003349227905L14.074083505859376,15.643933492279054L14.525943505859376,13.027603492279052C14.198743505859374,12.934663492279054,13.879283505859375,12.834063492279054,13.552083505859375,12.772133492279053C13.069083505859375,12.717933492279052,12.578283505859375,12.648273492279053,12.064083505859376,12.648273492279053ZM18.327743505859374,9.428153492279053C17.829143505859374,9.128843492279053,17.330543505859374,8.870823492279053,16.831943505859375,8.654083492279053C16.348943505859374,8.460573492279053,15.826943505859376,8.267053492279054,15.305013505859375,8.135463492279053L15.305013505859375,8.267053492279054L14.463613505859374,13.043063492279053C14.596083505859376,13.105003492279053,14.759683505859375,13.135933492279053,14.884283505859376,13.205603492279053C15.185523505859376,13.334623492279052,15.401043505859375,13.443003492279052,15.530943505859375,13.530733492279053C15.858143505859376,13.724263492279054,16.341143505859375,13.623603492279052,16.535943505859375,13.306263492279053L18.514743505859375,10.403483492279053C18.779643505859376,10.039673492279054,18.686143505859377,9.621673492279053,18.327743505859374,9.428153492279053Z", - "fill": "#FF6A00", - "fill-opacity": "1" - } - } - ] - } - ] - } - ] - }, - { - "type": "element", - "name": "g", - "children": [ - { - "type": "element", - "name": "g", - "children": [ - { - "type": "element", - "name": "path", - "attributes": { - "d": "M25.044,2.668L34.676,2.668L34.676,4.04L25.044,4.04L25.044,2.668ZM29.958,7.82Q29.258,9.066,28.355,10.41Q27.451999999999998,11.754,26.92,12.3L32.506,11.782Q31.442,10.158,30.84,9.346L32.058,8.562000000000001Q32.786,9.5,33.843,11.012Q34.9,12.524,35.516,13.546L34.214,14.526Q33.891999999999996,13.966,33.346000000000004,13.098Q32.016,13.182,29.734,13.378Q27.451999999999998,13.574,25.87,13.742L25.31,13.812L24.834,13.882L24.414,12.468Q24.708,12.37,24.862000000000002,12.265Q25.016,12.16,25.121,12.069Q25.226,11.978,25.268,11.936Q25.912,11.32,26.724,10.165Q27.536,9.01,28.208,7.82L23.854,7.82L23.854,6.434L35.866,6.434L35.866,7.82L29.958,7.82ZM42.656,7.414L42.656,8.576L41.354,8.576L41.354,1.814L42.656,1.87L42.656,7.036Q43.314,5.846,43.888000000000005,4.369Q44.462,2.892,44.714,1.6600000000000001L46.086,1.981999Q45.96,2.612,45.722,3.41L49.6,3.41L49.6,4.74L45.274,4.74Q44.616,6.56,43.706,8.128L42.656,7.414ZM38.596000000000004,2.346L39.884,2.402L39.884,8.212L38.596000000000004,8.212L38.596000000000004,2.346ZM46.184,4.964Q46.688,5.356,47.5,6.175Q48.312,6.994,48.788,7.582L47.751999999999995,8.59Q47.346000000000004,8.072,46.576,7.274Q45.806,6.476,45.204,5.902L46.184,4.964ZM48.41,9.01L48.41,12.706L49.894,12.706L49.894,13.966L37.391999999999996,13.966L37.391999999999996,12.706L38.848,12.706L38.848,9.01L48.41,9.01ZM41.676,10.256L40.164,10.256L40.164,12.706L41.676,12.706L41.676,10.256ZM42.908,12.706L44.364000000000004,12.706L44.364000000000004,10.256L42.908,10.256L42.908,12.706ZM45.582,12.706L47.108000000000004,12.706L47.108000000000004,10.256L45.582,10.256L45.582,12.706ZM54.906,7.456L55.116,8.394L54.178,8.814L54.178,12.818Q54.178,13.434,54.031,13.735Q53.884,14.036,53.534,14.162Q53.184,14.288,52.456,14.358L51.867999999999995,14.414L51.476,13.084L52.162,13.028Q52.512,13,52.652,12.958Q52.792,12.916,52.841,12.797Q52.89,12.678,52.89,12.384L52.89,9.36Q51.980000000000004,9.724,51.322,9.948L51.013999999999996,8.576Q51.798,8.324,52.89,7.876L52.89,5.524L51.42,5.524L51.42,4.166L52.89,4.166L52.89,1.7579989999999999L54.178,1.814L54.178,4.166L55.214,4.166L55.214,5.524L54.178,5.524L54.178,7.316L54.808,7.022L54.906,7.456ZM56.894,4.5440000000000005L56.894,6.098L55.564,6.098L55.564,3.256L58.686,3.256Q58.42,2.346,58.266,1.9260000000000002L59.624,1.7579989999999999Q59.848,2.276,60.142,3.256L63.25,3.256L63.25,6.098L61.962,6.098L61.962,4.5440000000000005L56.894,4.5440000000000005ZM59.008,6.322Q58.392,6.938,57.685,7.512Q56.978,8.086,55.956,8.841999999999999L55.242,7.764Q56.824,6.728,58.126,5.37L59.008,6.322ZM60.422,5.37Q61.024,5.776,62.095,6.581Q63.166,7.386,63.656,7.806L62.942,8.982Q62.368,8.45,61.332,7.652Q60.296,6.854,59.666,6.434L60.422,5.37ZM62.592,10.256L60.044,10.256L60.044,12.566L63.572,12.566L63.572,13.826L55.144,13.826L55.144,12.566L58.63,12.566L58.63,10.256L56.054,10.256L56.054,8.982L62.592,8.982L62.592,10.256Z", - "fill": "#FF6A00", - "fill-opacity": "1" - } - } - ] - } - ] - } - ] - } - ] - }, - "name": "AliyunIcon" + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "xmlns": "http://www.w3.org/2000/svg", + "xmlns:xlink": "http://www.w3.org/1999/xlink", + "fill": "none", + "version": "1.1", + "width": "106", + "height": "16", + "viewBox": "0 0 106 16" + }, + "children": [ + { + "type": "element", + "name": "defs", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "clipPath", + "attributes": { + "id": "master_svg0_36_00924" + }, + "children": [ + { + "type": "element", + "name": "rect", + "attributes": { + "x": "0", + "y": "0", + "width": "19", + "height": "16", + "rx": "0" + }, + "children": [] + } + ] + } + ] + }, + { + "type": "element", + "name": "g", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "clip-path": "url(#master_svg0_36_00924)" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "g", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M4.06862,14.6667C3.79213,14.6667,3.45463,14.5688,3.05614,14.373C2.97908,14.3351,2.92692,14.3105,2.89968,14.2992C2.33193,14.0628,1.82911,13.7294,1.39123,13.2989C0.463742,12.3871,0,11.2874,0,10C0,8.71258,0.463742,7.61293,1.39123,6.70107C2.16172,5.94358,3.06404,5.50073,4.09819,5.37252C4.23172,3.98276,4.81755,2.77756,5.85569,1.75693C7.04708,0.585642,8.4857,0,10.1716,0C11.5256,0,12.743,0.396982,13.8239,1.19095C14.8847,1.97019,15.61,2.97855,16,4.21604L14.7045,4.61063C14.4016,3.64918,13.8374,2.86532,13.0121,2.25905C12.1719,1.64191,11.2251,1.33333,10.1716,1.33333C8.8602,1.33333,7.74124,1.7888,6.81467,2.69974C5.88811,3.61067,5.42483,4.71076,5.42483,6L5.42483,6.66667L4.74673,6.66667C3.81172,6.66667,3.01288,6.99242,2.35021,7.64393C1.68754,8.2954,1.35621,9.08076,1.35621,10C1.35621,10.9192,1.68754,11.7046,2.35021,12.3561C2.66354,12.6641,3.02298,12.9026,3.42852,13.0714C3.48193,13.0937,3.55988,13.13,3.66237,13.1803C3.87004,13.2823,4.00545,13.3333,4.06862,13.3333L4.06862,14.6667Z", + "fill-rule": "evenodd", + "fill": "#000000", + "fill-opacity": "1", + "style": "mix-blend-mode:passthrough" + }, + "children": [] + } + ] + }, + { + "type": "element", + "name": "g", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M13.458613505859375,7.779393492279053C12.975613505859375,7.717463492279053,12.484813505859375,7.686503492279053,11.993983505859376,7.686503492279053C11.152583505859376,7.686503492279053,10.303403505859375,7.779393492279053,9.493183505859374,7.941943492279053C8.682953505859375,8.104503492279052,7.903893505859375,8.359943492279053,7.155983505859375,8.654083492279053C6.657383505859375,8.870823492279053,6.158783505859375,9.128843492279053,5.660181505859375,9.428153492279053C5.332974751859375,9.621673492279053,5.239486705859375,10.070633492279054,5.434253505859375,10.395743492279053L7.413073505859375,13.298533492279052C7.639003505859375,13.623603492279052,8.090863505859375,13.716463492279052,8.418073505859375,13.523003492279052C8.547913505859375,13.435263492279052,8.763453505859374,13.326893492279053,9.064693505859374,13.197863492279053C9.516553505859374,13.004333492279052,9.976203505859374,12.872733492279053,10.459223505859375,12.779863492279052C10.942243505859375,12.679263492279052,11.433053505859375,12.617333492279052,11.955023505859375,12.617333492279052L13.380683505859375,7.810353492279052L13.458613505859375,7.779393492279053ZM15.273813505859374,8.135463492279053L15.016753505859375,5.333333492279053L13.458613505859375,7.787133492279053C13.817013505859375,7.818093492279052,14.144213505859375,7.880023492279053,14.494743505859375,7.949683492279053C14.494743505859375,7.944523492279053,14.754433505859375,8.006453492279054,15.273813505859374,8.135463492279053ZM12.064083505859376,12.648273492279053L11.378523505859375,14.970463492279054L12.515943505859376,16.00003349227905L14.074083505859376,15.643933492279054L14.525943505859376,13.027603492279052C14.198743505859374,12.934663492279054,13.879283505859375,12.834063492279054,13.552083505859375,12.772133492279053C13.069083505859375,12.717933492279052,12.578283505859375,12.648273492279053,12.064083505859376,12.648273492279053ZM18.327743505859374,9.428153492279053C17.829143505859374,9.128843492279053,17.330543505859374,8.870823492279053,16.831943505859375,8.654083492279053C16.348943505859374,8.460573492279053,15.826943505859376,8.267053492279054,15.305013505859375,8.135463492279053L15.305013505859375,8.267053492279054L14.463613505859374,13.043063492279053C14.596083505859376,13.105003492279053,14.759683505859375,13.135933492279053,14.884283505859376,13.205603492279053C15.185523505859376,13.334623492279052,15.401043505859375,13.443003492279052,15.530943505859375,13.530733492279053C15.858143505859376,13.724263492279054,16.341143505859375,13.623603492279052,16.535943505859375,13.306263492279053L18.514743505859375,10.403483492279053C18.779643505859376,10.039673492279054,18.686143505859377,9.621673492279053,18.327743505859374,9.428153492279053Z", + "fill": "#000000", + "fill-opacity": "1", + "style": "mix-blend-mode:passthrough" + }, + "children": [] + } + ] + } + ] + } + ] + }, + { + "type": "element", + "name": "g", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "g", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M36.174,12.958L35.278,14.358Q31.344,11.964,29.958,8.884Q29.258,10.48,27.9,11.81Q26.542,13.14,24.624,14.372L23.644,12.986Q28.642,10.186,29.034,6.378L24.12,6.378L24.12,4.95L29.076,4.95L29.076,1.743999L30.616,1.7999990000000001L30.616,4.95L35.614000000000004,4.95L35.614000000000004,6.378L30.588,6.378L30.573999999999998,6.56Q31.078,8.646,32.408,10.144Q33.738,11.642,36.174,12.958ZM44.658,4.922000000000001L43.454,4.922000000000001L43.454,4.152L41.745999999999995,4.152L41.745999999999995,2.948L43.454,2.948L43.454,1.716L44.658,1.771999L44.658,2.948L46.492000000000004,2.948L46.492000000000004,1.716L47.682,1.771999L47.682,2.948L49.586,2.948L49.586,4.152L47.682,4.152L47.682,4.922000000000001L46.492000000000004,4.922000000000001L46.492000000000004,4.152L44.658,4.152L44.658,4.922000000000001ZM46.519999999999996,11.474Q47.010000000000005,12.146,47.870999999999995,12.615Q48.732,13.084,50.104,13.364L49.726,14.624Q46.884,13.924,45.61,12.286Q45.106,13.042,44.111999999999995,13.616Q43.117999999999995,14.19,41.507999999999996,14.638L41.004000000000005,13.42Q42.488,13.098,43.349000000000004,12.615Q44.21,12.132,44.574,11.474L41.522,11.474L41.522,10.368L44.896,10.368Q44.91,10.312,44.91,10.214Q44.924,10.032,44.924,9.542L42.152,9.542L42.152,8.492L41.284,9.108Q40.989999999999995,8.464,40.5,7.708L40.5,14.358L39.282,14.358L39.282,8.268Q38.61,9.99,37.952,11.082L36.944,10.074Q37.532,9.122,38.106,7.939Q38.68,6.756,39.058,5.664L37.658,5.664L37.658,4.390000000000001L39.282,4.390000000000001L39.282,1.7579989999999999L40.5,1.814L40.5,4.390000000000001L41.816,4.390000000000001L41.816,5.664L40.5,5.664L40.5,7.134L41.116,6.658Q41.704,7.386,42.152,8.24L42.152,5.244L48.97,5.244L48.97,9.542L46.226,9.542Q46.198,10.018,46.198,10.214L46.198,10.368L49.641999999999996,10.368L49.641999999999996,11.474L46.519999999999996,11.474ZM47.85,6.952L47.85,6.28L43.314,6.28L43.314,6.952L47.85,6.952ZM47.85,7.862L43.314,7.862L43.314,8.506L47.85,8.506L47.85,7.862ZM59.904,9.388L59.512,8.114L60.548,8.030000000000001Q61.066,7.988,61.234,7.855Q61.402,7.722,61.402,7.274L61.402,2.01L62.704,2.066L62.704,7.624Q62.704,8.268,62.55,8.604Q62.396,8.940000000000001,62.025,9.094Q61.654,9.248,60.94,9.304L59.904,9.388ZM51.546,9.276Q52.274,8.52,52.596000000000004,7.988Q52.918,7.456,53.016,6.784L51.518,6.784L51.518,5.566L53.1,5.566L53.1,5.188L53.1,3.718L51.867999999999995,3.718L51.867999999999995,2.458L58.448,2.458L58.448,3.718L57.244,3.718L57.244,5.566L58.728,5.566L58.728,6.784L57.244,6.784L57.244,9.206L55.928,9.206L55.928,6.784L54.332,6.784Q54.22,7.792,53.842,8.52Q53.464,9.248,52.61,10.102L51.546,9.276ZM59.092,2.724L60.366,2.7800000000000002L60.366,7.61L59.092,7.61L59.092,2.724ZM54.402,3.718L54.402,5.202L54.402,5.566L55.928,5.566L55.928,3.718L54.402,3.718ZM58.126,11.348L58.126,12.86L63.53,12.86L63.53,14.106L51.322,14.106L51.322,12.86L56.74,12.86L56.74,11.348L52.75,11.348L52.75,10.13L56.74,10.13L56.74,9.332L58.126,9.388L58.126,10.13L62.13,10.13L62.13,11.348L58.126,11.348ZM77.39,2.528L77.39,3.9L75.64,3.9L75.64,12.272Q75.64,13.098,75.465,13.49Q75.28999999999999,13.882,74.84899999999999,14.05Q74.408,14.218,73.47,14.302L72.56,14.386L72.126,13L73.19,12.916Q73.68,12.874,73.89699999999999,12.79Q74.114,12.706,74.184,12.51Q74.25399999999999,12.314,74.25399999999999,11.88L74.25399999999999,3.9L65.042,3.9L65.042,2.528L77.39,2.528ZM66.512,5.524L72.26599999999999,5.524L72.26599999999999,11.712L66.512,11.712L66.512,5.524ZM67.842,10.354L70.95,10.354L70.95,6.896L67.842,6.896L67.842,10.354ZM88.772,3.648L85.118,3.648L85.118,10.298L83.80199999999999,10.298L83.80199999999999,2.332L90.088,2.332L90.088,10.27L88.772,10.27L88.772,3.648ZM82.668,12.65Q82.23400000000001,11.712,81.632,10.522Q80.862,12.146,79.518,14.092L78.45400000000001,13.182Q80.036,11.068,80.89,9.024Q79.7,6.728,79,5.552L80.02199999999999,4.894Q80.48400000000001,5.622,81.47800000000001,7.386Q81.87,6.042,82.122,4.2780000000000005L79.02799999999999,4.2780000000000005L79.02799999999999,2.934L83.47999999999999,2.934L83.47999999999999,4.2780000000000005Q83.144,6.784,82.318,8.940000000000001Q83.158,10.508,83.774,11.782L82.668,12.65ZM91.166,11.264Q91.124,12.104,91.04,12.636Q90.956,13.28,90.802,13.602Q90.648,13.924,90.326,14.064Q90.004,14.204,89.374,14.204L88.142,14.204Q87.344,14.204,87.029,13.868Q86.714,13.532,86.714,12.636L86.714,11.11Q86.21000000000001,12.104,85.356,12.972Q84.50200000000001,13.84,83.2,14.708L82.332,13.56Q83.886,12.608,84.691,11.705Q85.49600000000001,10.802,85.804,9.745Q86.112,8.687999999999999,86.168,7.05L86.21000000000001,4.306L87.61,4.362L87.568,7.218Q87.526,8.366,87.344,9.276L88.016,9.304L88.016,12.16Q88.016,12.608,88.128,12.734Q88.24,12.86,88.632,12.86L89.108,12.86Q89.486,12.86,89.619,12.741Q89.752,12.622,89.808,12.174Q89.892,11.362,89.892,10.788L91.166,11.264ZM93.56,1.884Q94.036,2.206,94.68,2.759Q95.324,3.312,95.702,3.704L94.904,4.795999999999999Q94.596,4.418,93.938,3.809Q93.28,3.2,92.832,2.85L93.56,1.884ZM102.1,12.93Q102.478,12.888,102.653,12.832Q102.828,12.776,102.898,12.636Q102.968,12.496,102.968,12.188L102.968,1.981999L104.06,2.0380000000000003L104.06,12.608Q104.06,13.238,103.948,13.546Q103.836,13.854,103.521,13.994Q103.206,14.134,102.534,14.19L101.75,14.246L101.372,12.986L102.1,12.93ZM95.702,10.774L95.702,2.5140000000000002L100.168,2.5140000000000002L100.168,10.732L99.006,10.732L99.006,3.732L96.836,3.732L96.836,10.774L95.702,10.774ZM101.008,11.152L101.008,3.2L102.1,3.256L102.1,11.152L101.008,11.152ZM94.652,13.364Q95.856,12.482,96.43,11.789Q97.004,11.096,97.2,10.277Q97.396,9.458,97.396,8.058L97.396,4.362L98.488,4.418L98.488,8.058Q98.488,9.738,98.201,10.809Q97.914,11.88,97.277,12.664Q96.64,13.448,95.45,14.344L94.652,13.364ZM93.07,5.034Q93.546,5.37,94.197,5.937Q94.848,6.504,95.282,6.952L94.484,8.072Q94.078,7.61,93.427,7.015Q92.776,6.42,92.258,6.028L93.07,5.034ZM92.524,13.742Q92.748,13.126,93.266,11.278Q93.784,9.43,93.896,8.814L94.498,9.01L95.072,9.206Q94.89,10.032,94.421,11.733Q93.952,13.434,93.714,14.162L92.524,13.742ZM98.74,10.858Q99.888,11.908,100.714,12.958L99.888,13.868Q99.356,13.154,98.943,12.671Q98.53,12.188,97.984,11.684L98.74,10.858Z", + "fill": "#000000", + "fill-opacity": "1" + }, + "children": [] + } + ] + } + ] + } + ] + } + ] + }, + "name": "AliyunIcon" } diff --git a/web/app/components/base/icons/src/public/tracing/AliyunIcon.tsx b/web/app/components/base/icons/src/public/tracing/AliyunIcon.tsx index 5b062b8a86..c7f785d9fb 100644 --- a/web/app/components/base/icons/src/public/tracing/AliyunIcon.tsx +++ b/web/app/components/base/icons/src/public/tracing/AliyunIcon.tsx @@ -4,12 +4,16 @@ import * as React from 'react' import data from './AliyunIcon.json' import IconBase from '@/app/components/base/icons/IconBase' -import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' +import type { IconData } from '@/app/components/base/icons/IconBase' -const Icon = React.forwardRef, Omit>(( - props, - ref, -) => ) +const Icon = ( + { + ref, + ...props + }: React.SVGProps & { + ref?: React.RefObject>; + }, +) => Icon.displayName = 'AliyunIcon' diff --git a/web/app/components/base/icons/src/public/tracing/AliyunIconBig.json b/web/app/components/base/icons/src/public/tracing/AliyunIconBig.json index ea60744daf..c8093ba660 100644 --- a/web/app/components/base/icons/src/public/tracing/AliyunIconBig.json +++ b/web/app/components/base/icons/src/public/tracing/AliyunIconBig.json @@ -1,71 +1,117 @@ { - "icon": { - "type": "element", - "isRootNode": true, - "name": "svg", - "attributes": { - "xmlns": "http://www.w3.org/2000/svg", - "xmlns:xlink": "http://www.w3.org/1999/xlink", - "fill": "none", - "version": "1.1", - "width": "96", - "height": "24", - "viewBox": "0 0 96 24" - }, - "children": [ - { - "type": "element", - "name": "g", - "children": [ - { - "type": "element", - "name": "g", - "children": [ - { - "type": "element", - "name": "path", - "attributes": { - "d": "M6.10294,22C5.68819,22,5.18195,21.8532,4.58421,21.5595C4.46861,21.5027,4.39038,21.4658,4.34951,21.4488C3.49789,21.0943,2.74367,20.5941,2.08684,19.9484C0.695613,18.5806,0,16.9311,0,15C0,13.0689,0.695612,11.4194,2.08684,10.0516C3.24259,8.91537,4.59607,8.2511,6.14728,8.05878C6.34758,5.97414,7.22633,4.16634,8.78354,2.63539C10.5706,0.878463,12.7286,0,15.2573,0C17.2884,0,19.1146,0.595472,20.7358,1.78642C22.327,2.95528,23.4151,4.46783,24,6.32406L22.0568,6.91594C21.6024,5.47377,20.7561,4.29798,19.5181,3.38858C18.2579,2.46286,16.8377,2,15.2573,2C13.2903,2,11.6119,2.6832,10.222,4.04961C8.83217,5.41601,8.13725,7.06614,8.13725,9L8.13725,10L7.12009,10C5.71758,10,4.51932,10.4886,3.52532,11.4659C2.53132,12.4431,2.03431,13.6211,2.03431,15C2.03431,16.3789,2.53132,17.5569,3.52532,18.5341C3.99531,18.9962,4.53447,19.3538,5.14278,19.6071C5.2229,19.6405,5.33983,19.695,5.49356,19.7705C5.80505,19.9235,6.00818,20,6.10294,20L6.10294,22Z", - "fill-rule": "evenodd", - "fill": "#FF6A00", - "fill-opacity": "1" - } - } - ] - }, - { - "type": "element", - "name": "g", - "children": [ - { - "type": "element", - "name": "path", - "attributes": { - "d": "M20.18796103515625,11.66909C19.46346103515625,11.5762,18.72726103515625,11.52975,17.991011035156248,11.52975C16.728921035156247,11.52975,15.45515103515625,11.66909,14.23981103515625,11.91292C13.02447103515625,12.156749999999999,11.85588103515625,12.539909999999999,10.73402103515625,12.98113C9.98612103515625,13.306239999999999,9.23822103515625,13.69327,8.49031803515625,14.14223C7.99950790415625,14.43251,7.85927603515625,15.10595,8.15142503515625,15.59361L11.11966103515625,19.9478C11.45855103515625,20.4354,12.13634103515625,20.5747,12.627151035156249,20.2845C12.821921035156251,20.152900000000002,13.14523103515625,19.990299999999998,13.59708103515625,19.796799999999998C14.27487103515625,19.506500000000003,14.964341035156249,19.3091,15.68887103515625,19.169800000000002C16.413401035156248,19.018900000000002,17.14962103515625,18.926000000000002,17.93258103515625,18.926000000000002L20.071061035156248,11.715530000000001L20.18796103515625,11.66909ZM22.91076103515625,12.20319L22.525161035156252,8L20.18796103515625,11.6807C20.72556103515625,11.72714,21.21636103515625,11.82003,21.74216103515625,11.92453C21.74216103515625,11.91679,22.13166103515625,12.00968,22.91076103515625,12.20319ZM18.09616103515625,18.9724L17.06782103515625,22.4557L18.773961035156248,24L21.11116103515625,23.465899999999998L21.788961035156248,19.5414C21.298161035156248,19.402,20.81896103515625,19.2511,20.32816103515625,19.1582C19.60366103515625,19.076900000000002,18.86746103515625,18.9724,18.09616103515625,18.9724ZM27.49166103515625,14.14223C26.74376103515625,13.69327,25.99586103515625,13.306239999999999,25.24796103515625,12.98113C24.52346103515625,12.69086,23.74046103515625,12.40058,22.95756103515625,12.20319L22.95756103515625,12.40058L21.69546103515625,19.5646C21.89416103515625,19.6575,22.139561035156248,19.7039,22.32646103515625,19.8084C22.77836103515625,20.0019,23.101661035156248,20.1645,23.29646103515625,20.2961C23.78726103515625,20.586399999999998,24.51176103515625,20.4354,24.80396103515625,19.959400000000002L27.77216103515625,15.605229999999999C28.16946103515625,15.05951,28.02926103515625,14.43251,27.49166103515625,14.14223Z", - "fill": "#FF6A00", - "fill-opacity": "1" - } - } - ] - }, - { - "type": "element", - "name": "g", - "children": [ - { - "type": "element", - "name": "path", - "attributes": { - "d": "M35.785,3.8624638671875L50.233000000000004,3.8624638671875L50.233000000000004,5.9204638671875L35.785,5.9204638671875L35.785,3.8624638671875ZM43.156,11.5904638671875Q42.106,13.4594638671875,40.7515,15.4754638671875Q39.397,17.4914638671875,38.599000000000004,18.3104638671875L46.978,17.5334638671875Q45.382,15.0974638671875,44.479,13.8794638671875L46.306,12.7034638671875Q47.397999999999996,14.1104638671875,48.9835,16.3784638671875Q50.569,18.6464638671875,51.492999999999995,20.1794638671875L49.54,21.6494638671875Q49.057,20.8094638671875,48.238,19.5074638671875Q46.243,19.6334638671875,42.82,19.9274638671875Q39.397,20.2214638671875,37.024,20.4734638671875L36.184,20.5784638671875L35.47,20.6834638671875L34.84,18.5624638671875Q35.281,18.4154638671875,35.512,18.2579638671875Q35.743,18.1004638671875,35.9005,17.963963867187502Q36.058,17.8274638671875,36.121,17.7644638671875Q37.087,16.840463867187502,38.305,15.1079638671875Q39.522999999999996,13.3754638671875,40.531,11.5904638671875L34,11.5904638671875L34,9.5114638671875L52.018,9.5114638671875L52.018,11.5904638671875L43.156,11.5904638671875ZM62.203,10.9814638671875L62.203,12.7244638671875L60.25,12.7244638671875L60.25,2.5814638671875L62.203,2.6654638671875L62.203,10.4144638671875Q63.19,8.6294638671875,64.051,6.4139638671875Q64.912,4.1984638671875,65.28999999999999,2.3504638671875L67.348,2.8334628671875Q67.15899999999999,3.7784638671875,66.80199999999999,4.9754638671875L72.619,4.9754638671875L72.619,6.9704638671875L66.13,6.9704638671875Q65.143,9.7004638671875,63.778,12.0524638671875L62.203,10.9814638671875ZM56.113,3.3794638671875L58.045,3.4634638671875L58.045,12.1784638671875L56.113,12.1784638671875L56.113,3.3794638671875ZM67.495,7.3064638671875Q68.251,7.8944638671875,69.469,9.1229638671875Q70.687,10.3514638671875,71.40100000000001,11.2334638671875L69.84700000000001,12.7454638671875Q69.238,11.9684638671875,68.083,10.7714638671875Q66.928,9.5744638671875,66.025,8.7134638671875L67.495,7.3064638671875ZM70.834,13.3754638671875L70.834,18.9194638671875L73.06,18.9194638671875L73.06,20.8094638671875L54.307,20.8094638671875L54.307,18.9194638671875L56.491,18.9194638671875L56.491,13.3754638671875L70.834,13.3754638671875ZM60.733000000000004,15.2444638671875L58.465,15.2444638671875L58.465,18.9194638671875L60.733000000000004,18.9194638671875L60.733000000000004,15.2444638671875ZM62.581,18.9194638671875L64.765,18.9194638671875L64.765,15.2444638671875L62.581,15.2444638671875L62.581,18.9194638671875ZM66.592,18.9194638671875L68.881,18.9194638671875L68.881,15.2444638671875L66.592,15.2444638671875L66.592,18.9194638671875ZM80.578,11.0444638671875L80.893,12.4514638671875L79.48599999999999,13.0814638671875L79.48599999999999,19.0874638671875Q79.48599999999999,20.0114638671875,79.2655,20.4629638671875Q79.045,20.9144638671875,78.52000000000001,21.1034638671875Q77.995,21.2924638671875,76.90299999999999,21.3974638671875L76.021,21.4814638671875L75.43299999999999,19.4864638671875L76.462,19.4024638671875Q76.987,19.3604638671875,77.197,19.2974638671875Q77.407,19.2344638671875,77.4805,19.0559638671875Q77.554,18.8774638671875,77.554,18.4364638671875L77.554,13.9004638671875Q76.189,14.4464638671875,75.202,14.7824638671875L74.74000000000001,12.7244638671875Q75.916,12.3464638671875,77.554,11.6744638671875L77.554,8.1464638671875L75.34899999999999,8.1464638671875L75.34899999999999,6.1094638671875L77.554,6.1094638671875L77.554,2.4974628671875L79.48599999999999,2.5814638671875L79.48599999999999,6.1094638671875L81.03999999999999,6.1094638671875L81.03999999999999,8.1464638671875L79.48599999999999,8.1464638671875L79.48599999999999,10.8344638671875L80.431,10.3934638671875L80.578,11.0444638671875ZM83.56,6.6764638671875L83.56,9.0074638671875L81.565,9.0074638671875L81.565,4.7444638671875L86.24799999999999,4.7444638671875Q85.84899999999999,3.3794638671875,85.618,2.7494638671875L87.655,2.4974628671875Q87.991,3.2744638671875,88.432,4.7444638671875L93.094,4.7444638671875L93.094,9.0074638671875L91.162,9.0074638671875L91.162,6.6764638671875L83.56,6.6764638671875ZM86.731,9.3434638671875Q85.807,10.2674638671875,84.7465,11.1284638671875Q83.686,11.9894638671875,82.15299999999999,13.1234638671875L81.082,11.5064638671875Q83.455,9.9524638671875,85.408,7.9154638671875L86.731,9.3434638671875ZM88.852,7.9154638671875Q89.755,8.5244638671875,91.3615,9.731963867187499Q92.968,10.9394638671875,93.703,11.5694638671875L92.632,13.3334638671875Q91.771,12.5354638671875,90.217,11.3384638671875Q88.663,10.1414638671875,87.718,9.5114638671875L88.852,7.9154638671875ZM92.107,15.2444638671875L88.285,15.2444638671875L88.285,18.7094638671875L93.577,18.7094638671875L93.577,20.5994638671875L80.935,20.5994638671875L80.935,18.7094638671875L86.164,18.7094638671875L86.164,15.2444638671875L82.3,15.2444638671875L82.3,13.3334638671875L92.107,13.3334638671875L92.107,15.2444638671875Z", - "fill": "#FF6A00", - "fill-opacity": "1" - } - } - ] - } - ] - } - ] - }, - "name": "AliyunBigIcon" + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "xmlns": "http://www.w3.org/2000/svg", + "xmlns:xlink": "http://www.w3.org/1999/xlink", + "fill": "none", + "version": "1.1", + "width": "159", + "height": "24", + "viewBox": "0 0 159 24" + }, + "children": [ + { + "type": "element", + "name": "defs", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "clipPath", + "attributes": { + "id": "master_svg0_42_18775" + }, + "children": [ + { + "type": "element", + "name": "rect", + "attributes": { + "x": "0", + "y": "0", + "width": "28.5", + "height": "24", + "rx": "0" + }, + "children": [] + } + ] + } + ] + }, + { + "type": "element", + "name": "g", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "g", + "attributes": { + "clip-path": "url(#master_svg0_42_18775)" + }, + "children": [ + { + "type": "element", + "name": "g", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M6.10294,22C5.68819,22,5.18195,21.8532,4.58421,21.5595C4.46861,21.5027,4.39038,21.4658,4.34951,21.4488C3.49789,21.0943,2.74367,20.5941,2.08684,19.9484C0.695613,18.5806,0,16.9311,0,15C0,13.0689,0.695612,11.4194,2.08684,10.0516C3.24259,8.91537,4.59607,8.2511,6.14728,8.05878C6.34758,5.97414,7.22633,4.16634,8.78354,2.63539C10.5706,0.878463,12.7286,0,15.2573,0C17.2884,0,19.1146,0.595472,20.7358,1.78642C22.327,2.95528,23.4151,4.46783,24,6.32406L22.0568,6.91594C21.6024,5.47377,20.7561,4.29798,19.5181,3.38858C18.2579,2.46286,16.8377,2,15.2573,2C13.2903,2,11.6119,2.6832,10.222,4.04961C8.83217,5.41601,8.13725,7.06614,8.13725,9L8.13725,10L7.12009,10C5.71758,10,4.51932,10.4886,3.52532,11.4659C2.53132,12.4431,2.03431,13.6211,2.03431,15C2.03431,16.3789,2.53132,17.5569,3.52532,18.5341C3.99531,18.9962,4.53447,19.3538,5.14278,19.6071C5.2229,19.6405,5.33983,19.695,5.49356,19.7705C5.80505,19.9235,6.00818,20,6.10294,20L6.10294,22Z", + "fill-rule": "evenodd", + "fill": "#000000", + "fill-opacity": "1", + "style": "mix-blend-mode:passthrough" + }, + "children": [] + } + ] + }, + { + "type": "element", + "name": "g", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M20.18796103515625,11.66909C19.46346103515625,11.5762,18.72726103515625,11.52975,17.991011035156248,11.52975C16.728921035156247,11.52975,15.45515103515625,11.66909,14.23981103515625,11.91292C13.02447103515625,12.156749999999999,11.85588103515625,12.539909999999999,10.73402103515625,12.98113C9.98612103515625,13.306239999999999,9.23822103515625,13.69327,8.49031803515625,14.14223C7.99950790415625,14.43251,7.85927603515625,15.10595,8.15142503515625,15.59361L11.11966103515625,19.9478C11.45855103515625,20.4354,12.13634103515625,20.5747,12.627151035156249,20.2845C12.821921035156251,20.152900000000002,13.14523103515625,19.990299999999998,13.59708103515625,19.796799999999998C14.27487103515625,19.506500000000003,14.964341035156249,19.3091,15.68887103515625,19.169800000000002C16.413401035156248,19.018900000000002,17.14962103515625,18.926000000000002,17.93258103515625,18.926000000000002L20.071061035156248,11.715530000000001L20.18796103515625,11.66909ZM22.91076103515625,12.20319L22.525161035156252,8L20.18796103515625,11.6807C20.72556103515625,11.72714,21.21636103515625,11.82003,21.74216103515625,11.92453C21.74216103515625,11.91679,22.13166103515625,12.00968,22.91076103515625,12.20319ZM18.09616103515625,18.9724L17.06782103515625,22.4557L18.773961035156248,24L21.11116103515625,23.465899999999998L21.788961035156248,19.5414C21.298161035156248,19.402,20.81896103515625,19.2511,20.32816103515625,19.1582C19.60366103515625,19.076900000000002,18.86746103515625,18.9724,18.09616103515625,18.9724ZM27.49166103515625,14.14223C26.74376103515625,13.69327,25.99586103515625,13.306239999999999,25.24796103515625,12.98113C24.52346103515625,12.69086,23.74046103515625,12.40058,22.95756103515625,12.20319L22.95756103515625,12.40058L21.69546103515625,19.5646C21.89416103515625,19.6575,22.139561035156248,19.7039,22.32646103515625,19.8084C22.77836103515625,20.0019,23.101661035156248,20.1645,23.29646103515625,20.2961C23.78726103515625,20.586399999999998,24.51176103515625,20.4354,24.80396103515625,19.959400000000002L27.77216103515625,15.605229999999999C28.16946103515625,15.05951,28.02926103515625,14.43251,27.49166103515625,14.14223Z", + "fill": "#000000", + "fill-opacity": "1", + "style": "mix-blend-mode:passthrough" + }, + "children": [] + } + ] + } + ] + }, + { + "type": "element", + "name": "g", + "attributes": {}, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M53.295,19.1189814453125L51.951,21.2189814453125Q46.05,17.6279814453125,43.971000000000004,13.0079814453125Q42.921,15.4019814453125,40.884,17.3969814453125Q38.847,19.3919814453125,35.97,21.2399814453125L34.5,19.1609814453125Q41.997,14.9609814453125,42.585,9.2489814453125L35.214,9.2489814453125L35.214,7.1069814453125L42.647999999999996,7.1069814453125L42.647999999999996,2.2979812453125L44.958,2.3819804453125L44.958,7.1069814453125L52.455,7.1069814453125L52.455,9.2489814453125L44.916,9.2489814453125L44.894999999999996,9.5219814453125Q45.650999999999996,12.6509814453125,47.646,14.8979814453125Q49.641,17.1449814453125,53.295,19.1189814453125ZM66.021,7.0649814453125L64.215,7.0649814453125L64.215,5.9099814453125L61.653,5.9099814453125L61.653,4.1039814453125L64.215,4.1039814453125L64.215,2.2559814453125L66.021,2.3399810453125L66.021,4.1039814453125L68.77199999999999,4.1039814453125L68.77199999999999,2.2559814453125L70.557,2.3399810453125L70.557,4.1039814453125L73.413,4.1039814453125L73.413,5.9099814453125L70.557,5.9099814453125L70.557,7.0649814453125L68.77199999999999,7.0649814453125L68.77199999999999,5.9099814453125L66.021,5.9099814453125L66.021,7.0649814453125ZM68.814,16.8929814453125Q69.549,17.9009814453125,70.84049999999999,18.6044814453125Q72.132,19.3079814453125,74.19,19.7279814453125L73.62299999999999,21.6179814453125Q69.36,20.5679814453125,67.449,18.1109814453125Q66.693,19.2449814453125,65.202,20.1059814453125Q63.711,20.9669814453125,61.296,21.6389814453125L60.54,19.8119814453125Q62.766,19.3289814453125,64.0575,18.6044814453125Q65.349,17.879981445312502,65.895,16.8929814453125L61.317,16.8929814453125L61.317,15.2339814453125L66.378,15.2339814453125Q66.399,15.1499814453125,66.399,15.0029814453125Q66.42,14.7299814453125,66.42,13.9949814453125L62.262,13.9949814453125L62.262,12.4199814453125L60.96,13.3439814453125Q60.519,12.3779814453125,59.784,11.2439814453125L59.784,21.2189814453125L57.957,21.2189814453125L57.957,12.0839814453125Q56.949,14.6669814453125,55.962,16.3049814453125L54.45,14.7929814453125Q55.332,13.3649814453125,56.193,11.5904814453125Q57.054,9.815981445312499,57.620999999999995,8.1779814453125L55.521,8.1779814453125L55.521,6.2669814453125L57.957,6.2669814453125L57.957,2.3189811453125L59.784,2.4029824453125L59.784,6.2669814453125L61.757999999999996,6.2669814453125L61.757999999999996,8.1779814453125L59.784,8.1779814453125L59.784,10.3829814453125L60.708,9.6689814453125Q61.59,10.7609814453125,62.262,12.0419814453125L62.262,7.5479814453125L72.489,7.5479814453125L72.489,13.9949814453125L68.37299999999999,13.9949814453125Q68.331,14.7089814453125,68.331,15.0029814453125L68.331,15.2339814453125L73.497,15.2339814453125L73.497,16.8929814453125L68.814,16.8929814453125ZM70.809,10.1099814453125L70.809,9.1019814453125L64.005,9.1019814453125L64.005,10.1099814453125L70.809,10.1099814453125ZM70.809,11.4749814453125L64.005,11.4749814453125L64.005,12.4409814453125L70.809,12.4409814453125L70.809,11.4749814453125ZM88.89,13.7639814453125L88.30199999999999,11.8529814453125L89.856,11.7269814453125Q90.63300000000001,11.6639814453125,90.88499999999999,11.4644814453125Q91.137,11.2649814453125,91.137,10.5929814453125L91.137,2.6969814453125L93.09,2.7809824453125L93.09,11.1179814453125Q93.09,12.0839814453125,92.85900000000001,12.5879814453125Q92.628,13.0919814453125,92.0715,13.3229814453125Q91.515,13.5539814453125,90.444,13.6379814453125L88.89,13.7639814453125ZM76.35300000000001,13.5959814453125Q77.445,12.4619814453125,77.928,11.6639814453125Q78.411,10.8659814453125,78.55799999999999,9.8579814453125L76.311,9.8579814453125L76.311,8.0309814453125L78.684,8.0309814453125L78.684,7.4639814453125L78.684,5.2589814453125L76.836,5.2589814453125L76.836,3.3689814453125L86.706,3.3689814453125L86.706,5.2589814453125L84.9,5.2589814453125L84.9,8.0309814453125L87.126,8.0309814453125L87.126,9.8579814453125L84.9,9.8579814453125L84.9,13.4909814453125L82.926,13.4909814453125L82.926,9.8579814453125L80.532,9.8579814453125Q80.364,11.3699814453125,79.797,12.4619814453125Q79.22999999999999,13.5539814453125,77.949,14.8349814453125L76.35300000000001,13.5959814453125ZM87.672,3.7679814453125L89.583,3.8519814453125L89.583,11.0969814453125L87.672,11.0969814453125L87.672,3.7679814453125ZM80.637,5.2589814453125L80.637,7.4849814453125L80.637,8.0309814453125L82.926,8.0309814453125L82.926,5.2589814453125L80.637,5.2589814453125ZM86.223,16.7039814453125L86.223,18.9719814453125L94.32900000000001,18.9719814453125L94.32900000000001,20.8409814453125L76.017,20.8409814453125L76.017,18.9719814453125L84.144,18.9719814453125L84.144,16.7039814453125L78.15899999999999,16.7039814453125L78.15899999999999,14.8769814453125L84.144,14.8769814453125L84.144,13.6799814453125L86.223,13.7639814453125L86.223,14.8769814453125L92.229,14.8769814453125L92.229,16.7039814453125L86.223,16.7039814453125ZM115.119,3.4739814453125L115.119,5.5319814453125L112.494,5.5319814453125L112.494,18.0899814453125Q112.494,19.3289814453125,112.2315,19.9169814453125Q111.969,20.5049814453125,111.3075,20.7569814453125Q110.646,21.0089814453125,109.239,21.1349814453125L107.874,21.2609814453125L107.223,19.1819814453125L108.819,19.0559814453125Q109.554,18.9929814453125,109.8795,18.8669814453125Q110.205,18.7409814453125,110.31,18.4469814453125Q110.415,18.1529814453125,110.415,17.501981445312502L110.415,5.5319814453125L96.59700000000001,5.5319814453125L96.59700000000001,3.4739814453125L115.119,3.4739814453125ZM98.802,7.9679814453125L107.433,7.9679814453125L107.433,17.2499814453125L98.802,17.2499814453125L98.802,7.9679814453125ZM100.797,15.2129814453125L105.459,15.2129814453125L105.459,10.0259814453125L100.797,10.0259814453125L100.797,15.2129814453125ZM132.192,5.1539814453125L126.711,5.1539814453125L126.711,15.1289814453125L124.737,15.1289814453125L124.737,3.1799814453125L134.166,3.1799814453125L134.166,15.0869814453125L132.192,15.0869814453125L132.192,5.1539814453125ZM123.036,18.6569814453125Q122.385,17.2499814453125,121.482,15.4649814453125Q120.327,17.9009814453125,118.311,20.8199814453125L116.715,19.4549814453125Q119.088,16.2839814453125,120.369,13.2179814453125Q118.584,9.7739814453125,117.534,8.0099814453125L119.067,7.0229814453125Q119.76,8.1149814453125,121.251,10.7609814453125Q121.839,8.7449814453125,122.217,6.0989814453125L117.576,6.0989814453125L117.576,4.0829814453125L124.254,4.0829814453125L124.254,6.0989814453125Q123.75,9.8579814453125,122.511,13.0919814453125Q123.771,15.4439814453125,124.695,17.3549814453125L123.036,18.6569814453125ZM135.78300000000002,16.5779814453125Q135.72,17.8379814453125,135.594,18.6359814453125Q135.46800000000002,19.6019814453125,135.237,20.0849814453125Q135.006,20.5679814453125,134.523,20.7779814453125Q134.04000000000002,20.9879814453125,133.095,20.9879814453125L131.247,20.9879814453125Q130.05,20.9879814453125,129.5775,20.4839814453125Q129.10500000000002,19.9799814453125,129.10500000000002,18.6359814453125L129.10500000000002,16.3469814453125Q128.349,17.8379814453125,127.068,19.1399814453125Q125.787,20.4419814453125,123.834,21.7439814453125L122.532,20.0219814453125Q124.863,18.5939814453125,126.0705,17.2394814453125Q127.278,15.8849814453125,127.74,14.2994814453125Q128.202,12.7139814453125,128.286,10.2569814453125L128.349,6.1409814453125L130.449,6.224981445312499L130.386,10.5089814453125Q130.32299999999998,12.2309814453125,130.05,13.5959814453125L131.058,13.6379814453125L131.058,17.9219814453125Q131.058,18.5939814453125,131.226,18.7829814453125Q131.394,18.9719814453125,131.982,18.9719814453125L132.696,18.9719814453125Q133.263,18.9719814453125,133.4625,18.7934814453125Q133.662,18.6149814453125,133.74599999999998,17.942981445312498Q133.872,16.7249814453125,133.872,15.8639814453125L135.78300000000002,16.5779814453125ZM139.374,2.5079814453125Q140.088,2.9909814453125,141.054,3.8204814453125Q142.01999999999998,4.6499814453125,142.587,5.2379814453125L141.39,6.8759814453125Q140.928,6.3089814453125,139.941,5.3954814453125Q138.954,4.4819814453125,138.28199999999998,3.9569814453125L139.374,2.5079814453125ZM152.184,19.0769814453125Q152.751,19.0139814453125,153.014,18.9299814453125Q153.276,18.8459814453125,153.381,18.6359814453125Q153.486,18.4259814453125,153.486,17.9639814453125L153.486,2.6549814453125L155.124,2.7389824453125L155.124,18.5939814453125Q155.124,19.5389814453125,154.95600000000002,20.0009814453125Q154.788,20.4629814453125,154.315,20.6729814453125Q153.84300000000002,20.8829814453125,152.83499999999998,20.9669814453125L151.659,21.0509814453125L151.09199999999998,19.1609814453125L152.184,19.0769814453125ZM142.587,15.8429814453125L142.587,3.4529814453125L149.286,3.4529814453125L149.286,15.7799814453125L147.543,15.7799814453125L147.543,5.2799814453125L144.288,5.2799814453125L144.288,15.8429814453125L142.587,15.8429814453125ZM150.546,16.4099814453125L150.546,4.4819814453125L152.184,4.5659814453125005L152.184,16.4099814453125L150.546,16.4099814453125ZM141.012,19.7279814453125Q142.81799999999998,18.4049814453125,143.679,17.3654814453125Q144.54000000000002,16.3259814453125,144.834,15.0974814453125Q145.128,13.8689814453125,145.128,11.7689814453125L145.128,6.224981445312499L146.76600000000002,6.3089814453125L146.76600000000002,11.7689814453125Q146.76600000000002,14.2889814453125,146.33499999999998,15.8954814453125Q145.905,17.501981445312502,144.95,18.6779814453125Q143.994,19.8539814453125,142.209,21.1979814453125L141.012,19.7279814453125ZM138.639,7.2329814453125Q139.353,7.7369814453125,140.329,8.5874814453125Q141.30599999999998,9.4379814453125,141.957,10.1099814453125L140.76,11.7899814453125Q140.151,11.0969814453125,139.174,10.2044814453125Q138.19799999999998,9.311981445312501,137.421,8.7239814453125L138.639,7.2329814453125ZM137.82,20.2949814453125Q138.156,19.3709814453125,138.933,16.5989814453125Q139.70999999999998,13.8269814453125,139.878,12.9029814453125L140.781,13.1969814453125L141.642,13.4909814453125Q141.369,14.7299814453125,140.66500000000002,17.2814814453125Q139.962,19.8329814453125,139.60500000000002,20.9249814453125L137.82,20.2949814453125ZM147.144,15.9689814453125Q148.86599999999999,17.5439814453125,150.10500000000002,19.1189814453125L148.86599999999999,20.4839814453125Q148.06799999999998,19.4129814453125,147.449,18.6884814453125Q146.829,17.9639814453125,146.01,17.207981445312498L147.144,15.9689814453125Z", + "fill": "#000000", + "fill-opacity": "1" + }, + "children": [] + } + ] + } + ] + } + ] + }, + "name": "AliyunIconBig" } diff --git a/web/app/components/base/icons/src/public/tracing/AliyunIconBig.tsx b/web/app/components/base/icons/src/public/tracing/AliyunIconBig.tsx index 0924f70fbd..703ea1d37f 100644 --- a/web/app/components/base/icons/src/public/tracing/AliyunIconBig.tsx +++ b/web/app/components/base/icons/src/public/tracing/AliyunIconBig.tsx @@ -4,12 +4,16 @@ import * as React from 'react' import data from './AliyunIconBig.json' import IconBase from '@/app/components/base/icons/IconBase' -import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' +import type { IconData } from '@/app/components/base/icons/IconBase' -const Icon = React.forwardRef, Omit>(( - props, - ref, -) => ) +const Icon = ( + { + ref, + ...props + }: React.SVGProps & { + ref?: React.RefObject>; + }, +) => Icon.displayName = 'AliyunIconBig' diff --git a/web/app/components/base/icons/src/public/tracing/WeaveIcon.tsx b/web/app/components/base/icons/src/public/tracing/WeaveIcon.tsx index fd66bd79ae..9261604bfe 100644 --- a/web/app/components/base/icons/src/public/tracing/WeaveIcon.tsx +++ b/web/app/components/base/icons/src/public/tracing/WeaveIcon.tsx @@ -4,12 +4,16 @@ import * as React from 'react' import data from './WeaveIcon.json' import IconBase from '@/app/components/base/icons/IconBase' -import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' +import type { IconData } from '@/app/components/base/icons/IconBase' -const Icon = React.forwardRef, Omit>(( - props, - ref, -) => ) +const Icon = ( + { + ref, + ...props + }: React.SVGProps & { + ref?: React.RefObject>; + }, +) => Icon.displayName = 'WeaveIcon' diff --git a/web/app/components/base/icons/src/public/tracing/WeaveIconBig.tsx b/web/app/components/base/icons/src/public/tracing/WeaveIconBig.tsx index 1d2bb9fcc2..79267467db 100644 --- a/web/app/components/base/icons/src/public/tracing/WeaveIconBig.tsx +++ b/web/app/components/base/icons/src/public/tracing/WeaveIconBig.tsx @@ -4,12 +4,16 @@ import * as React from 'react' import data from './WeaveIconBig.json' import IconBase from '@/app/components/base/icons/IconBase' -import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase' +import type { IconData } from '@/app/components/base/icons/IconBase' -const Icon = React.forwardRef, Omit>(( - props, - ref, -) => ) +const Icon = ( + { + ref, + ...props + }: React.SVGProps & { + ref?: React.RefObject>; + }, +) => Icon.displayName = 'WeaveIconBig' diff --git a/web/app/components/base/icons/src/public/tracing/index.ts b/web/app/components/base/icons/src/public/tracing/index.ts index 07e3385f46..2d9e7ff0a5 100644 --- a/web/app/components/base/icons/src/public/tracing/index.ts +++ b/web/app/components/base/icons/src/public/tracing/index.ts @@ -1,3 +1,5 @@ +export { default as AliyunIconBig } from './AliyunIconBig' +export { default as AliyunIcon } from './AliyunIcon' export { default as ArizeIconBig } from './ArizeIconBig' export { default as ArizeIcon } from './ArizeIcon' export { default as LangfuseIconBig } from './LangfuseIconBig' @@ -11,5 +13,3 @@ export { default as PhoenixIcon } from './PhoenixIcon' export { default as TracingIcon } from './TracingIcon' export { default as WeaveIconBig } from './WeaveIconBig' export { default as WeaveIcon } from './WeaveIcon' -export { default as AliyunIconBig } from './AliyunIconBig' -export { default as AliyunIcon } from './AliyunIcon' diff --git a/web/app/components/base/icons/src/vender/features/Citations.json b/web/app/components/base/icons/src/vender/features/Citations.json index 1b0b6250de..24a77db601 100644 --- a/web/app/components/base/icons/src/vender/features/Citations.json +++ b/web/app/components/base/icons/src/vender/features/Citations.json @@ -23,4 +23,4 @@ ] }, "name": "Citations" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/features/ContentModeration.json b/web/app/components/base/icons/src/vender/features/ContentModeration.json index 4f5c47acd2..fc609e0434 100644 --- a/web/app/components/base/icons/src/vender/features/ContentModeration.json +++ b/web/app/components/base/icons/src/vender/features/ContentModeration.json @@ -25,4 +25,4 @@ ] }, "name": "ContentModeration" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/features/Document.json b/web/app/components/base/icons/src/vender/features/Document.json index fdd08d5254..f0638eecf7 100644 --- a/web/app/components/base/icons/src/vender/features/Document.json +++ b/web/app/components/base/icons/src/vender/features/Document.json @@ -20,4 +20,4 @@ ] }, "name": "Document" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/features/FolderUpload.json b/web/app/components/base/icons/src/vender/features/FolderUpload.json index 2180127e3d..c113da043b 100644 --- a/web/app/components/base/icons/src/vender/features/FolderUpload.json +++ b/web/app/components/base/icons/src/vender/features/FolderUpload.json @@ -23,4 +23,4 @@ ] }, "name": "FolderUpload" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/features/LoveMessage.json b/web/app/components/base/icons/src/vender/features/LoveMessage.json index 7dbc062662..4874b94944 100644 --- a/web/app/components/base/icons/src/vender/features/LoveMessage.json +++ b/web/app/components/base/icons/src/vender/features/LoveMessage.json @@ -23,4 +23,4 @@ ] }, "name": "LoveMessage" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/features/MessageFast.json b/web/app/components/base/icons/src/vender/features/MessageFast.json index 4580398f31..b859b1f3f0 100644 --- a/web/app/components/base/icons/src/vender/features/MessageFast.json +++ b/web/app/components/base/icons/src/vender/features/MessageFast.json @@ -25,4 +25,4 @@ ] }, "name": "MessageFast" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/features/Microphone01.json b/web/app/components/base/icons/src/vender/features/Microphone01.json index a4ba1bc23f..57545716cf 100644 --- a/web/app/components/base/icons/src/vender/features/Microphone01.json +++ b/web/app/components/base/icons/src/vender/features/Microphone01.json @@ -34,4 +34,4 @@ ] }, "name": "Microphone01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/features/TextToAudio.json b/web/app/components/base/icons/src/vender/features/TextToAudio.json index 1d824f72cc..4369e0b6f1 100644 --- a/web/app/components/base/icons/src/vender/features/TextToAudio.json +++ b/web/app/components/base/icons/src/vender/features/TextToAudio.json @@ -74,4 +74,4 @@ ] }, "name": "TextToAudio" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/features/VirtualAssistant.json b/web/app/components/base/icons/src/vender/features/VirtualAssistant.json index b426eb4b0b..3cbeba0ea5 100644 --- a/web/app/components/base/icons/src/vender/features/VirtualAssistant.json +++ b/web/app/components/base/icons/src/vender/features/VirtualAssistant.json @@ -32,4 +32,4 @@ ] }, "name": "VirtualAssistant" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/features/Vision.json b/web/app/components/base/icons/src/vender/features/Vision.json index e9b5b4df85..6d60e32a29 100644 --- a/web/app/components/base/icons/src/vender/features/Vision.json +++ b/web/app/components/base/icons/src/vender/features/Vision.json @@ -25,4 +25,4 @@ ] }, "name": "Vision" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/alertsAndFeedback/AlertTriangle.json b/web/app/components/base/icons/src/vender/line/alertsAndFeedback/AlertTriangle.json index a200e6035e..057ecbdfc2 100644 --- a/web/app/components/base/icons/src/vender/line/alertsAndFeedback/AlertTriangle.json +++ b/web/app/components/base/icons/src/vender/line/alertsAndFeedback/AlertTriangle.json @@ -36,4 +36,4 @@ ] }, "name": "AlertTriangle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsDown.json b/web/app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsDown.json index b9ccbef3ec..41877c74bd 100644 --- a/web/app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsDown.json +++ b/web/app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsDown.json @@ -63,4 +63,4 @@ ] }, "name": "ThumbsDown" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsUp.json b/web/app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsUp.json index 674516b1c5..0ee442871f 100644 --- a/web/app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsUp.json +++ b/web/app/components/base/icons/src/vender/line/alertsAndFeedback/ThumbsUp.json @@ -63,4 +63,4 @@ ] }, "name": "ThumbsUp" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/arrows/ArrowNarrowLeft.json b/web/app/components/base/icons/src/vender/line/arrows/ArrowNarrowLeft.json index 73d6708c51..e3f7b5c674 100644 --- a/web/app/components/base/icons/src/vender/line/arrows/ArrowNarrowLeft.json +++ b/web/app/components/base/icons/src/vender/line/arrows/ArrowNarrowLeft.json @@ -26,4 +26,4 @@ ] }, "name": "ArrowNarrowLeft" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/arrows/ArrowUpRight.json b/web/app/components/base/icons/src/vender/line/arrows/ArrowUpRight.json index 9ab1e6e0d0..621a37afdf 100644 --- a/web/app/components/base/icons/src/vender/line/arrows/ArrowUpRight.json +++ b/web/app/components/base/icons/src/vender/line/arrows/ArrowUpRight.json @@ -36,4 +36,4 @@ ] }, "name": "ArrowUpRight" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/arrows/ChevronDownDouble.json b/web/app/components/base/icons/src/vender/line/arrows/ChevronDownDouble.json index cfae43931c..706e13533c 100644 --- a/web/app/components/base/icons/src/vender/line/arrows/ChevronDownDouble.json +++ b/web/app/components/base/icons/src/vender/line/arrows/ChevronDownDouble.json @@ -36,4 +36,4 @@ ] }, "name": "ChevronDownDouble" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/arrows/ChevronRight.json b/web/app/components/base/icons/src/vender/line/arrows/ChevronRight.json index c144e678bb..e03a2c8dd0 100644 --- a/web/app/components/base/icons/src/vender/line/arrows/ChevronRight.json +++ b/web/app/components/base/icons/src/vender/line/arrows/ChevronRight.json @@ -36,4 +36,4 @@ ] }, "name": "ChevronRight" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/arrows/ChevronSelectorVertical.json b/web/app/components/base/icons/src/vender/line/arrows/ChevronSelectorVertical.json index 84da1f3dbb..67ff40298d 100644 --- a/web/app/components/base/icons/src/vender/line/arrows/ChevronSelectorVertical.json +++ b/web/app/components/base/icons/src/vender/line/arrows/ChevronSelectorVertical.json @@ -26,4 +26,4 @@ ] }, "name": "ChevronSelectorVertical" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/arrows/RefreshCcw01.json b/web/app/components/base/icons/src/vender/line/arrows/RefreshCcw01.json index 30033b41bd..8b3cb0d5a7 100644 --- a/web/app/components/base/icons/src/vender/line/arrows/RefreshCcw01.json +++ b/web/app/components/base/icons/src/vender/line/arrows/RefreshCcw01.json @@ -26,4 +26,4 @@ ] }, "name": "RefreshCcw01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/arrows/RefreshCw05.json b/web/app/components/base/icons/src/vender/line/arrows/RefreshCw05.json index 5468171fe0..1ba0cedfd3 100644 --- a/web/app/components/base/icons/src/vender/line/arrows/RefreshCw05.json +++ b/web/app/components/base/icons/src/vender/line/arrows/RefreshCw05.json @@ -26,4 +26,4 @@ ] }, "name": "RefreshCw05" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/arrows/ReverseLeft.json b/web/app/components/base/icons/src/vender/line/arrows/ReverseLeft.json index 48c6d1fbd6..b5173968c8 100644 --- a/web/app/components/base/icons/src/vender/line/arrows/ReverseLeft.json +++ b/web/app/components/base/icons/src/vender/line/arrows/ReverseLeft.json @@ -36,4 +36,4 @@ ] }, "name": "ReverseLeft" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/communication/AiText.json b/web/app/components/base/icons/src/vender/line/communication/AiText.json index 0f5ff57837..2473c64c22 100644 --- a/web/app/components/base/icons/src/vender/line/communication/AiText.json +++ b/web/app/components/base/icons/src/vender/line/communication/AiText.json @@ -36,4 +36,4 @@ ] }, "name": "AiText" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/communication/ChatBot.json b/web/app/components/base/icons/src/vender/line/communication/ChatBot.json index 69547f9353..0e7382d741 100644 --- a/web/app/components/base/icons/src/vender/line/communication/ChatBot.json +++ b/web/app/components/base/icons/src/vender/line/communication/ChatBot.json @@ -90,4 +90,4 @@ ] }, "name": "ChatBot" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/communication/ChatBotSlim.json b/web/app/components/base/icons/src/vender/line/communication/ChatBotSlim.json index 07f6cda56b..9be716acd6 100644 --- a/web/app/components/base/icons/src/vender/line/communication/ChatBotSlim.json +++ b/web/app/components/base/icons/src/vender/line/communication/ChatBotSlim.json @@ -65,4 +65,4 @@ ] }, "name": "ChatBotSlim" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/communication/CuteRobot.json b/web/app/components/base/icons/src/vender/line/communication/CuteRobot.json index 4ae74d2a77..35596bac9a 100644 --- a/web/app/components/base/icons/src/vender/line/communication/CuteRobot.json +++ b/web/app/components/base/icons/src/vender/line/communication/CuteRobot.json @@ -36,4 +36,4 @@ ] }, "name": "CuteRobot" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/communication/MessageCheckRemove.json b/web/app/components/base/icons/src/vender/line/communication/MessageCheckRemove.json index a536c9f341..5d4202b2e1 100644 --- a/web/app/components/base/icons/src/vender/line/communication/MessageCheckRemove.json +++ b/web/app/components/base/icons/src/vender/line/communication/MessageCheckRemove.json @@ -36,4 +36,4 @@ ] }, "name": "MessageCheckRemove" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/communication/MessageFastPlus.json b/web/app/components/base/icons/src/vender/line/communication/MessageFastPlus.json index 7d40cc7425..988e278325 100644 --- a/web/app/components/base/icons/src/vender/line/communication/MessageFastPlus.json +++ b/web/app/components/base/icons/src/vender/line/communication/MessageFastPlus.json @@ -26,4 +26,4 @@ ] }, "name": "MessageFastPlus" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/ArtificialBrain.json b/web/app/components/base/icons/src/vender/line/development/ArtificialBrain.json index 7015ee281a..8bc500ea9b 100644 --- a/web/app/components/base/icons/src/vender/line/development/ArtificialBrain.json +++ b/web/app/components/base/icons/src/vender/line/development/ArtificialBrain.json @@ -26,4 +26,4 @@ ] }, "name": "ArtificialBrain" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/BarChartSquare02.json b/web/app/components/base/icons/src/vender/line/development/BarChartSquare02.json index 5b695a7e79..ef51cbec7f 100644 --- a/web/app/components/base/icons/src/vender/line/development/BarChartSquare02.json +++ b/web/app/components/base/icons/src/vender/line/development/BarChartSquare02.json @@ -36,4 +36,4 @@ ] }, "name": "BarChartSquare02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/BracketsX.json b/web/app/components/base/icons/src/vender/line/development/BracketsX.json index 08935cc7ff..2287a51073 100644 --- a/web/app/components/base/icons/src/vender/line/development/BracketsX.json +++ b/web/app/components/base/icons/src/vender/line/development/BracketsX.json @@ -26,4 +26,4 @@ ] }, "name": "BracketsX" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/CodeBrowser.json b/web/app/components/base/icons/src/vender/line/development/CodeBrowser.json index 1d0254d846..7234b42cea 100644 --- a/web/app/components/base/icons/src/vender/line/development/CodeBrowser.json +++ b/web/app/components/base/icons/src/vender/line/development/CodeBrowser.json @@ -36,4 +36,4 @@ ] }, "name": "CodeBrowser" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/Container.json b/web/app/components/base/icons/src/vender/line/development/Container.json index 3b15cd8f88..dbedb8aff3 100644 --- a/web/app/components/base/icons/src/vender/line/development/Container.json +++ b/web/app/components/base/icons/src/vender/line/development/Container.json @@ -26,4 +26,4 @@ ] }, "name": "Container" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/Database01.json b/web/app/components/base/icons/src/vender/line/development/Database01.json index e25b3e7cef..2be1974840 100644 --- a/web/app/components/base/icons/src/vender/line/development/Database01.json +++ b/web/app/components/base/icons/src/vender/line/development/Database01.json @@ -26,4 +26,4 @@ ] }, "name": "Database01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/Database03.json b/web/app/components/base/icons/src/vender/line/development/Database03.json index 5acf4bf1f9..24a004afed 100644 --- a/web/app/components/base/icons/src/vender/line/development/Database03.json +++ b/web/app/components/base/icons/src/vender/line/development/Database03.json @@ -26,4 +26,4 @@ ] }, "name": "Database03" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/FileHeart02.json b/web/app/components/base/icons/src/vender/line/development/FileHeart02.json index ef9343dfc0..163e64b570 100644 --- a/web/app/components/base/icons/src/vender/line/development/FileHeart02.json +++ b/web/app/components/base/icons/src/vender/line/development/FileHeart02.json @@ -49,4 +49,4 @@ ] }, "name": "FileHeart02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/GitBranch01.json b/web/app/components/base/icons/src/vender/line/development/GitBranch01.json index 04205e57c6..f9d9d00e59 100644 --- a/web/app/components/base/icons/src/vender/line/development/GitBranch01.json +++ b/web/app/components/base/icons/src/vender/line/development/GitBranch01.json @@ -36,4 +36,4 @@ ] }, "name": "GitBranch01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/PromptEngineering.json b/web/app/components/base/icons/src/vender/line/development/PromptEngineering.json index c55bde8f57..97ca2e9353 100644 --- a/web/app/components/base/icons/src/vender/line/development/PromptEngineering.json +++ b/web/app/components/base/icons/src/vender/line/development/PromptEngineering.json @@ -62,4 +62,4 @@ ] }, "name": "PromptEngineering" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/PuzzlePiece01.json b/web/app/components/base/icons/src/vender/line/development/PuzzlePiece01.json index ce06d6125f..672e405ffa 100644 --- a/web/app/components/base/icons/src/vender/line/development/PuzzlePiece01.json +++ b/web/app/components/base/icons/src/vender/line/development/PuzzlePiece01.json @@ -63,4 +63,4 @@ ] }, "name": "PuzzlePiece01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/TerminalSquare.json b/web/app/components/base/icons/src/vender/line/development/TerminalSquare.json index 7a78b7b934..48fb6ce248 100644 --- a/web/app/components/base/icons/src/vender/line/development/TerminalSquare.json +++ b/web/app/components/base/icons/src/vender/line/development/TerminalSquare.json @@ -36,4 +36,4 @@ ] }, "name": "TerminalSquare" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/Variable.json b/web/app/components/base/icons/src/vender/line/development/Variable.json index b7545fe8ae..b366f11a06 100644 --- a/web/app/components/base/icons/src/vender/line/development/Variable.json +++ b/web/app/components/base/icons/src/vender/line/development/Variable.json @@ -59,4 +59,4 @@ ] }, "name": "Variable" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/development/Webhooks.json b/web/app/components/base/icons/src/vender/line/development/Webhooks.json index 452194deb3..bb9ccf1059 100644 --- a/web/app/components/base/icons/src/vender/line/development/Webhooks.json +++ b/web/app/components/base/icons/src/vender/line/development/Webhooks.json @@ -86,4 +86,4 @@ ] }, "name": "Webhooks" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/editor/AlignLeft.json b/web/app/components/base/icons/src/vender/line/editor/AlignLeft.json index ae8b150447..7ddf4d24c1 100644 --- a/web/app/components/base/icons/src/vender/line/editor/AlignLeft.json +++ b/web/app/components/base/icons/src/vender/line/editor/AlignLeft.json @@ -36,4 +36,4 @@ ] }, "name": "AlignLeft" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/editor/BezierCurve03.json b/web/app/components/base/icons/src/vender/line/editor/BezierCurve03.json index bc87f9b00d..5f76ff1ac3 100644 --- a/web/app/components/base/icons/src/vender/line/editor/BezierCurve03.json +++ b/web/app/components/base/icons/src/vender/line/editor/BezierCurve03.json @@ -35,4 +35,4 @@ ] }, "name": "BezierCurve03" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/editor/Collapse.json b/web/app/components/base/icons/src/vender/line/editor/Collapse.json index 5e3cf08ce0..224133e0b6 100644 --- a/web/app/components/base/icons/src/vender/line/editor/Collapse.json +++ b/web/app/components/base/icons/src/vender/line/editor/Collapse.json @@ -59,4 +59,4 @@ ] }, "name": "Collapse" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/editor/Colors.json b/web/app/components/base/icons/src/vender/line/editor/Colors.json index baee8ee347..0508092598 100644 --- a/web/app/components/base/icons/src/vender/line/editor/Colors.json +++ b/web/app/components/base/icons/src/vender/line/editor/Colors.json @@ -36,4 +36,4 @@ ] }, "name": "Colors" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/editor/ImageIndentLeft.json b/web/app/components/base/icons/src/vender/line/editor/ImageIndentLeft.json index 603696d969..33ba61f1c7 100644 --- a/web/app/components/base/icons/src/vender/line/editor/ImageIndentLeft.json +++ b/web/app/components/base/icons/src/vender/line/editor/ImageIndentLeft.json @@ -36,4 +36,4 @@ ] }, "name": "ImageIndentLeft" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/editor/LeftIndent02.json b/web/app/components/base/icons/src/vender/line/editor/LeftIndent02.json index 447ae887a9..cb77ee97ea 100644 --- a/web/app/components/base/icons/src/vender/line/editor/LeftIndent02.json +++ b/web/app/components/base/icons/src/vender/line/editor/LeftIndent02.json @@ -26,4 +26,4 @@ ] }, "name": "LeftIndent02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/editor/LetterSpacing01.json b/web/app/components/base/icons/src/vender/line/editor/LetterSpacing01.json index 98b3cd6617..e322926aa0 100644 --- a/web/app/components/base/icons/src/vender/line/editor/LetterSpacing01.json +++ b/web/app/components/base/icons/src/vender/line/editor/LetterSpacing01.json @@ -36,4 +36,4 @@ ] }, "name": "LetterSpacing01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/editor/TypeSquare.json b/web/app/components/base/icons/src/vender/line/editor/TypeSquare.json index 195b047746..b381c51420 100644 --- a/web/app/components/base/icons/src/vender/line/editor/TypeSquare.json +++ b/web/app/components/base/icons/src/vender/line/editor/TypeSquare.json @@ -35,4 +35,4 @@ ] }, "name": "TypeSquare" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/education/BookOpen01.json b/web/app/components/base/icons/src/vender/line/education/BookOpen01.json index bfa7941345..1c6f46b700 100644 --- a/web/app/components/base/icons/src/vender/line/education/BookOpen01.json +++ b/web/app/components/base/icons/src/vender/line/education/BookOpen01.json @@ -46,4 +46,4 @@ ] }, "name": "BookOpen01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/files/File02.json b/web/app/components/base/icons/src/vender/line/files/File02.json index 110765adeb..6c0cf176c1 100644 --- a/web/app/components/base/icons/src/vender/line/files/File02.json +++ b/web/app/components/base/icons/src/vender/line/files/File02.json @@ -36,4 +36,4 @@ ] }, "name": "File02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/files/FileArrow01.json b/web/app/components/base/icons/src/vender/line/files/FileArrow01.json index 189f0814df..ce13dd0f5e 100644 --- a/web/app/components/base/icons/src/vender/line/files/FileArrow01.json +++ b/web/app/components/base/icons/src/vender/line/files/FileArrow01.json @@ -36,4 +36,4 @@ ] }, "name": "FileArrow01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/files/FileCheck02.json b/web/app/components/base/icons/src/vender/line/files/FileCheck02.json index 9a2e063c0a..0b08e61b30 100644 --- a/web/app/components/base/icons/src/vender/line/files/FileCheck02.json +++ b/web/app/components/base/icons/src/vender/line/files/FileCheck02.json @@ -36,4 +36,4 @@ ] }, "name": "FileCheck02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/files/FileDownload02.json b/web/app/components/base/icons/src/vender/line/files/FileDownload02.json index a0dccc280f..2c439adb31 100644 --- a/web/app/components/base/icons/src/vender/line/files/FileDownload02.json +++ b/web/app/components/base/icons/src/vender/line/files/FileDownload02.json @@ -26,4 +26,4 @@ ] }, "name": "FileDownload02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/files/FilePlus01.json b/web/app/components/base/icons/src/vender/line/files/FilePlus01.json index 67d8784494..470703abe1 100644 --- a/web/app/components/base/icons/src/vender/line/files/FilePlus01.json +++ b/web/app/components/base/icons/src/vender/line/files/FilePlus01.json @@ -36,4 +36,4 @@ ] }, "name": "FilePlus01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/files/FilePlus02.json b/web/app/components/base/icons/src/vender/line/files/FilePlus02.json index 447b1e91ba..cd55cad950 100644 --- a/web/app/components/base/icons/src/vender/line/files/FilePlus02.json +++ b/web/app/components/base/icons/src/vender/line/files/FilePlus02.json @@ -26,4 +26,4 @@ ] }, "name": "FilePlus02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/files/FileText.json b/web/app/components/base/icons/src/vender/line/files/FileText.json index 536bc45852..12335ec1c2 100644 --- a/web/app/components/base/icons/src/vender/line/files/FileText.json +++ b/web/app/components/base/icons/src/vender/line/files/FileText.json @@ -36,4 +36,4 @@ ] }, "name": "FileText" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/files/FileUpload.json b/web/app/components/base/icons/src/vender/line/files/FileUpload.json index 5dc2ec115e..6dfa30a350 100644 --- a/web/app/components/base/icons/src/vender/line/files/FileUpload.json +++ b/web/app/components/base/icons/src/vender/line/files/FileUpload.json @@ -49,4 +49,4 @@ ] }, "name": "FileUpload" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/files/Folder.json b/web/app/components/base/icons/src/vender/line/files/Folder.json index 6bbc4380ae..84e3cb9763 100644 --- a/web/app/components/base/icons/src/vender/line/files/Folder.json +++ b/web/app/components/base/icons/src/vender/line/files/Folder.json @@ -36,4 +36,4 @@ ] }, "name": "Folder" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/financeAndECommerce/Balance.json b/web/app/components/base/icons/src/vender/line/financeAndECommerce/Balance.json index c04fcda517..79bdc7024d 100644 --- a/web/app/components/base/icons/src/vender/line/financeAndECommerce/Balance.json +++ b/web/app/components/base/icons/src/vender/line/financeAndECommerce/Balance.json @@ -26,4 +26,4 @@ ] }, "name": "Balance" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/financeAndECommerce/CoinsStacked01.json b/web/app/components/base/icons/src/vender/line/financeAndECommerce/CoinsStacked01.json index 8a971909c8..328e38a1ce 100644 --- a/web/app/components/base/icons/src/vender/line/financeAndECommerce/CoinsStacked01.json +++ b/web/app/components/base/icons/src/vender/line/financeAndECommerce/CoinsStacked01.json @@ -36,4 +36,4 @@ ] }, "name": "CoinsStacked01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/financeAndECommerce/GoldCoin.json b/web/app/components/base/icons/src/vender/line/financeAndECommerce/GoldCoin.json index f10b5fa7cf..7a748bda5a 100644 --- a/web/app/components/base/icons/src/vender/line/financeAndECommerce/GoldCoin.json +++ b/web/app/components/base/icons/src/vender/line/financeAndECommerce/GoldCoin.json @@ -117,4 +117,4 @@ ] }, "name": "GoldCoin" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/financeAndECommerce/ReceiptList.json b/web/app/components/base/icons/src/vender/line/financeAndECommerce/ReceiptList.json index 8e9c070875..ac3d3bdfe2 100644 --- a/web/app/components/base/icons/src/vender/line/financeAndECommerce/ReceiptList.json +++ b/web/app/components/base/icons/src/vender/line/financeAndECommerce/ReceiptList.json @@ -26,4 +26,4 @@ ] }, "name": "ReceiptList" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/financeAndECommerce/Tag01.json b/web/app/components/base/icons/src/vender/line/financeAndECommerce/Tag01.json index b6f838d72f..82cd5af5f9 100644 --- a/web/app/components/base/icons/src/vender/line/financeAndECommerce/Tag01.json +++ b/web/app/components/base/icons/src/vender/line/financeAndECommerce/Tag01.json @@ -63,4 +63,4 @@ ] }, "name": "Tag01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/financeAndECommerce/Tag03.json b/web/app/components/base/icons/src/vender/line/financeAndECommerce/Tag03.json index ef0753b8d3..2fa00f62f7 100644 --- a/web/app/components/base/icons/src/vender/line/financeAndECommerce/Tag03.json +++ b/web/app/components/base/icons/src/vender/line/financeAndECommerce/Tag03.json @@ -36,4 +36,4 @@ ] }, "name": "Tag03" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/AtSign.json b/web/app/components/base/icons/src/vender/line/general/AtSign.json index 0722d8ff34..dd6d9cbbc7 100644 --- a/web/app/components/base/icons/src/vender/line/general/AtSign.json +++ b/web/app/components/base/icons/src/vender/line/general/AtSign.json @@ -63,4 +63,4 @@ ] }, "name": "AtSign" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Bookmark.json b/web/app/components/base/icons/src/vender/line/general/Bookmark.json index 1b6e517be7..378bc76be5 100644 --- a/web/app/components/base/icons/src/vender/line/general/Bookmark.json +++ b/web/app/components/base/icons/src/vender/line/general/Bookmark.json @@ -26,4 +26,4 @@ ] }, "name": "Bookmark" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Check.json b/web/app/components/base/icons/src/vender/line/general/Check.json index eae343816a..e3265f8138 100644 --- a/web/app/components/base/icons/src/vender/line/general/Check.json +++ b/web/app/components/base/icons/src/vender/line/general/Check.json @@ -36,4 +36,4 @@ ] }, "name": "Check" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/CheckDone01.json b/web/app/components/base/icons/src/vender/line/general/CheckDone01.json index 85355f93fd..ec3894aa00 100644 --- a/web/app/components/base/icons/src/vender/line/general/CheckDone01.json +++ b/web/app/components/base/icons/src/vender/line/general/CheckDone01.json @@ -36,4 +36,4 @@ ] }, "name": "CheckDone01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/ChecklistSquare.json b/web/app/components/base/icons/src/vender/line/general/ChecklistSquare.json index 737c69623d..6cf330994a 100644 --- a/web/app/components/base/icons/src/vender/line/general/ChecklistSquare.json +++ b/web/app/components/base/icons/src/vender/line/general/ChecklistSquare.json @@ -33,4 +33,4 @@ ] }, "name": "ChecklistSquare" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/DotsGrid.json b/web/app/components/base/icons/src/vender/line/general/DotsGrid.json index 9aafed2f7b..85a24bb14c 100644 --- a/web/app/components/base/icons/src/vender/line/general/DotsGrid.json +++ b/web/app/components/base/icons/src/vender/line/general/DotsGrid.json @@ -131,4 +131,4 @@ ] }, "name": "DotsGrid" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Edit02.json b/web/app/components/base/icons/src/vender/line/general/Edit02.json index 38798fecf1..2d32d1da94 100644 --- a/web/app/components/base/icons/src/vender/line/general/Edit02.json +++ b/web/app/components/base/icons/src/vender/line/general/Edit02.json @@ -63,4 +63,4 @@ ] }, "name": "Edit02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Edit04.json b/web/app/components/base/icons/src/vender/line/general/Edit04.json index 73f275b732..34be957072 100644 --- a/web/app/components/base/icons/src/vender/line/general/Edit04.json +++ b/web/app/components/base/icons/src/vender/line/general/Edit04.json @@ -26,4 +26,4 @@ ] }, "name": "Edit04" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Edit05.json b/web/app/components/base/icons/src/vender/line/general/Edit05.json index 321336bc2f..f1bbf7138e 100644 --- a/web/app/components/base/icons/src/vender/line/general/Edit05.json +++ b/web/app/components/base/icons/src/vender/line/general/Edit05.json @@ -63,4 +63,4 @@ ] }, "name": "Edit05" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Hash02.json b/web/app/components/base/icons/src/vender/line/general/Hash02.json index 41b639f938..bd140198a1 100644 --- a/web/app/components/base/icons/src/vender/line/general/Hash02.json +++ b/web/app/components/base/icons/src/vender/line/general/Hash02.json @@ -35,4 +35,4 @@ ] }, "name": "Hash02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/InfoCircle.json b/web/app/components/base/icons/src/vender/line/general/InfoCircle.json index 4017e85ce1..6bc285c86b 100644 --- a/web/app/components/base/icons/src/vender/line/general/InfoCircle.json +++ b/web/app/components/base/icons/src/vender/line/general/InfoCircle.json @@ -63,4 +63,4 @@ ] }, "name": "InfoCircle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Link03.json b/web/app/components/base/icons/src/vender/line/general/Link03.json index ccd608f643..4728221b60 100644 --- a/web/app/components/base/icons/src/vender/line/general/Link03.json +++ b/web/app/components/base/icons/src/vender/line/general/Link03.json @@ -54,4 +54,4 @@ ] }, "name": "Link03" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/LinkExternal02.json b/web/app/components/base/icons/src/vender/line/general/LinkExternal02.json index af445595c8..7016dd896f 100644 --- a/web/app/components/base/icons/src/vender/line/general/LinkExternal02.json +++ b/web/app/components/base/icons/src/vender/line/general/LinkExternal02.json @@ -35,4 +35,4 @@ ] }, "name": "LinkExternal02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/LogIn04.json b/web/app/components/base/icons/src/vender/line/general/LogIn04.json index a8316e9c27..27808a36a9 100644 --- a/web/app/components/base/icons/src/vender/line/general/LogIn04.json +++ b/web/app/components/base/icons/src/vender/line/general/LogIn04.json @@ -50,4 +50,4 @@ ] }, "name": "LogIn04" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/LogOut01.json b/web/app/components/base/icons/src/vender/line/general/LogOut01.json index bd2cb3e18c..d5c89394ef 100644 --- a/web/app/components/base/icons/src/vender/line/general/LogOut01.json +++ b/web/app/components/base/icons/src/vender/line/general/LogOut01.json @@ -36,4 +36,4 @@ ] }, "name": "LogOut01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/LogOut04.json b/web/app/components/base/icons/src/vender/line/general/LogOut04.json index a19bedfe4c..80a27ecf31 100644 --- a/web/app/components/base/icons/src/vender/line/general/LogOut04.json +++ b/web/app/components/base/icons/src/vender/line/general/LogOut04.json @@ -50,4 +50,4 @@ ] }, "name": "LogOut04" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Menu01.json b/web/app/components/base/icons/src/vender/line/general/Menu01.json index 5b32928738..5dfdebf7cc 100644 --- a/web/app/components/base/icons/src/vender/line/general/Menu01.json +++ b/web/app/components/base/icons/src/vender/line/general/Menu01.json @@ -36,4 +36,4 @@ ] }, "name": "Menu01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Pin01.json b/web/app/components/base/icons/src/vender/line/general/Pin01.json index b0e61a2373..3ad6bd8799 100644 --- a/web/app/components/base/icons/src/vender/line/general/Pin01.json +++ b/web/app/components/base/icons/src/vender/line/general/Pin01.json @@ -36,4 +36,4 @@ ] }, "name": "Pin01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Pin02.json b/web/app/components/base/icons/src/vender/line/general/Pin02.json index c5b51a5f33..474e7e102f 100644 --- a/web/app/components/base/icons/src/vender/line/general/Pin02.json +++ b/web/app/components/base/icons/src/vender/line/general/Pin02.json @@ -26,4 +26,4 @@ ] }, "name": "Pin02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Plus02.json b/web/app/components/base/icons/src/vender/line/general/Plus02.json index 8a9516f1ae..84b07b4251 100644 --- a/web/app/components/base/icons/src/vender/line/general/Plus02.json +++ b/web/app/components/base/icons/src/vender/line/general/Plus02.json @@ -36,4 +36,4 @@ ] }, "name": "Plus02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Refresh.json b/web/app/components/base/icons/src/vender/line/general/Refresh.json index 128dcb7d4d..693b9ab4f0 100644 --- a/web/app/components/base/icons/src/vender/line/general/Refresh.json +++ b/web/app/components/base/icons/src/vender/line/general/Refresh.json @@ -20,4 +20,4 @@ ] }, "name": "Refresh" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/SearchMenu.json b/web/app/components/base/icons/src/vender/line/general/SearchMenu.json new file mode 100644 index 0000000000..5854f25339 --- /dev/null +++ b/web/app/components/base/icons/src/vender/line/general/SearchMenu.json @@ -0,0 +1,77 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "32", + "height": "32", + "viewBox": "0 0 32 32", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M28.0049 16C28.0049 20.4183 24.4231 24 20.0049 24C15.5866 24 12.0049 20.4183 12.0049 16C12.0049 11.5817 15.5866 8 20.0049 8C24.4231 8 28.0049 11.5817 28.0049 16Z", + "stroke": "currentColor", + "stroke-width": "2", + "stroke-linecap": "round", + "stroke-linejoin": "round" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M4.00488 16H6.67155", + "stroke": "currentColor", + "stroke-width": "2", + "stroke-linecap": "round", + "stroke-linejoin": "round" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M4.00488 9.33334H8.00488", + "stroke": "currentColor", + "stroke-width": "2", + "stroke-linecap": "round", + "stroke-linejoin": "round" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M4.00488 22.6667H8.00488", + "stroke": "currentColor", + "stroke-width": "2", + "stroke-linecap": "round", + "stroke-linejoin": "round" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "d": "M26 22L29.3333 25.3333", + "stroke": "currentColor", + "stroke-width": "2", + "stroke-linecap": "round", + "stroke-linejoin": "round" + }, + "children": [] + } + ] + }, + "name": "SearchMenu" +} diff --git a/web/app/components/base/icons/src/vender/line/general/SearchMenu.tsx b/web/app/components/base/icons/src/vender/line/general/SearchMenu.tsx new file mode 100644 index 0000000000..4826abb20f --- /dev/null +++ b/web/app/components/base/icons/src/vender/line/general/SearchMenu.tsx @@ -0,0 +1,20 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './SearchMenu.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconData } from '@/app/components/base/icons/IconBase' + +const Icon = ( + { + ref, + ...props + }: React.SVGProps & { + ref?: React.RefObject>; + }, +) => + +Icon.displayName = 'SearchMenu' + +export default Icon diff --git a/web/app/components/base/icons/src/vender/line/general/Settings01.json b/web/app/components/base/icons/src/vender/line/general/Settings01.json index 8734e9f947..ca337d9b20 100644 --- a/web/app/components/base/icons/src/vender/line/general/Settings01.json +++ b/web/app/components/base/icons/src/vender/line/general/Settings01.json @@ -83,4 +83,4 @@ ] }, "name": "Settings01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Settings04.json b/web/app/components/base/icons/src/vender/line/general/Settings04.json index e46a0548ed..4dd34e68a4 100644 --- a/web/app/components/base/icons/src/vender/line/general/Settings04.json +++ b/web/app/components/base/icons/src/vender/line/general/Settings04.json @@ -36,4 +36,4 @@ ] }, "name": "Settings04" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Target04.json b/web/app/components/base/icons/src/vender/line/general/Target04.json index 5c07628bae..731fcc208c 100644 --- a/web/app/components/base/icons/src/vender/line/general/Target04.json +++ b/web/app/components/base/icons/src/vender/line/general/Target04.json @@ -62,4 +62,4 @@ ] }, "name": "Target04" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/Upload03.json b/web/app/components/base/icons/src/vender/line/general/Upload03.json index c3490f3cff..bda73041a9 100644 --- a/web/app/components/base/icons/src/vender/line/general/Upload03.json +++ b/web/app/components/base/icons/src/vender/line/general/Upload03.json @@ -63,4 +63,4 @@ ] }, "name": "Upload03" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/UploadCloud01.json b/web/app/components/base/icons/src/vender/line/general/UploadCloud01.json index 03e448d7ad..5e5411c1cf 100644 --- a/web/app/components/base/icons/src/vender/line/general/UploadCloud01.json +++ b/web/app/components/base/icons/src/vender/line/general/UploadCloud01.json @@ -39,4 +39,4 @@ ] }, "name": "UploadCloud01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/X.json b/web/app/components/base/icons/src/vender/line/general/X.json index 5c2fde5df6..9c482caa25 100644 --- a/web/app/components/base/icons/src/vender/line/general/X.json +++ b/web/app/components/base/icons/src/vender/line/general/X.json @@ -36,4 +36,4 @@ ] }, "name": "X" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/general/index.ts b/web/app/components/base/icons/src/vender/line/general/index.ts index b5c7a7bbc1..1b6c7e7303 100644 --- a/web/app/components/base/icons/src/vender/line/general/index.ts +++ b/web/app/components/base/icons/src/vender/line/general/index.ts @@ -19,6 +19,7 @@ export { default as Pin01 } from './Pin01' export { default as Pin02 } from './Pin02' export { default as Plus02 } from './Plus02' export { default as Refresh } from './Refresh' +export { default as SearchMenu } from './SearchMenu' export { default as Settings01 } from './Settings01' export { default as Settings04 } from './Settings04' export { default as Target04 } from './Target04' diff --git a/web/app/components/base/icons/src/vender/line/images/ImagePlus.json b/web/app/components/base/icons/src/vender/line/images/ImagePlus.json index 127b04659a..ce3073f1c3 100644 --- a/web/app/components/base/icons/src/vender/line/images/ImagePlus.json +++ b/web/app/components/base/icons/src/vender/line/images/ImagePlus.json @@ -36,4 +36,4 @@ ] }, "name": "ImagePlus" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/layout/AlignLeft01.json b/web/app/components/base/icons/src/vender/line/layout/AlignLeft01.json index 5ed5add0d7..9450fd2403 100644 --- a/web/app/components/base/icons/src/vender/line/layout/AlignLeft01.json +++ b/web/app/components/base/icons/src/vender/line/layout/AlignLeft01.json @@ -36,4 +36,4 @@ ] }, "name": "AlignLeft01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/layout/AlignRight01.json b/web/app/components/base/icons/src/vender/line/layout/AlignRight01.json index 6690e6d474..05ecc93716 100644 --- a/web/app/components/base/icons/src/vender/line/layout/AlignRight01.json +++ b/web/app/components/base/icons/src/vender/line/layout/AlignRight01.json @@ -36,4 +36,4 @@ ] }, "name": "AlignRight01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/layout/Grid01.json b/web/app/components/base/icons/src/vender/line/layout/Grid01.json index 43a385c770..edc374a9cc 100644 --- a/web/app/components/base/icons/src/vender/line/layout/Grid01.json +++ b/web/app/components/base/icons/src/vender/line/layout/Grid01.json @@ -80,4 +80,4 @@ ] }, "name": "Grid01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/layout/LayoutGrid02.json b/web/app/components/base/icons/src/vender/line/layout/LayoutGrid02.json index d71e981723..a5e5b2479d 100644 --- a/web/app/components/base/icons/src/vender/line/layout/LayoutGrid02.json +++ b/web/app/components/base/icons/src/vender/line/layout/LayoutGrid02.json @@ -26,4 +26,4 @@ ] }, "name": "LayoutGrid02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/mapsAndTravel/Globe01.json b/web/app/components/base/icons/src/vender/line/mapsAndTravel/Globe01.json index 1e0896672b..9ccee71b02 100644 --- a/web/app/components/base/icons/src/vender/line/mapsAndTravel/Globe01.json +++ b/web/app/components/base/icons/src/vender/line/mapsAndTravel/Globe01.json @@ -63,4 +63,4 @@ ] }, "name": "Globe01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/mapsAndTravel/Route.json b/web/app/components/base/icons/src/vender/line/mapsAndTravel/Route.json index 19cb837362..cb0b7f01a9 100644 --- a/web/app/components/base/icons/src/vender/line/mapsAndTravel/Route.json +++ b/web/app/components/base/icons/src/vender/line/mapsAndTravel/Route.json @@ -63,4 +63,4 @@ ] }, "name": "Route" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/mediaAndDevices/Microphone01.json b/web/app/components/base/icons/src/vender/line/mediaAndDevices/Microphone01.json index 8f273d0a75..193aee5c3b 100644 --- a/web/app/components/base/icons/src/vender/line/mediaAndDevices/Microphone01.json +++ b/web/app/components/base/icons/src/vender/line/mediaAndDevices/Microphone01.json @@ -36,4 +36,4 @@ ] }, "name": "Microphone01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/mediaAndDevices/PlayCircle.json b/web/app/components/base/icons/src/vender/line/mediaAndDevices/PlayCircle.json index 278512534f..db313deb88 100644 --- a/web/app/components/base/icons/src/vender/line/mediaAndDevices/PlayCircle.json +++ b/web/app/components/base/icons/src/vender/line/mediaAndDevices/PlayCircle.json @@ -83,4 +83,4 @@ ] }, "name": "PlayCircle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/mediaAndDevices/SlidersH.json b/web/app/components/base/icons/src/vender/line/mediaAndDevices/SlidersH.json index fc138eecbc..4620cb9178 100644 --- a/web/app/components/base/icons/src/vender/line/mediaAndDevices/SlidersH.json +++ b/web/app/components/base/icons/src/vender/line/mediaAndDevices/SlidersH.json @@ -26,4 +26,4 @@ ] }, "name": "SlidersH" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/mediaAndDevices/Speaker.json b/web/app/components/base/icons/src/vender/line/mediaAndDevices/Speaker.json index 3e5cbe171b..2cb1df48f8 100644 --- a/web/app/components/base/icons/src/vender/line/mediaAndDevices/Speaker.json +++ b/web/app/components/base/icons/src/vender/line/mediaAndDevices/Speaker.json @@ -109,4 +109,4 @@ ] }, "name": "Speaker" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/mediaAndDevices/Stop.json b/web/app/components/base/icons/src/vender/line/mediaAndDevices/Stop.json index 7d25397087..b0860433ee 100644 --- a/web/app/components/base/icons/src/vender/line/mediaAndDevices/Stop.json +++ b/web/app/components/base/icons/src/vender/line/mediaAndDevices/Stop.json @@ -63,4 +63,4 @@ ] }, "name": "Stop" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/mediaAndDevices/StopCircle.json b/web/app/components/base/icons/src/vender/line/mediaAndDevices/StopCircle.json index 2d456014b8..3a211c78ce 100644 --- a/web/app/components/base/icons/src/vender/line/mediaAndDevices/StopCircle.json +++ b/web/app/components/base/icons/src/vender/line/mediaAndDevices/StopCircle.json @@ -56,4 +56,4 @@ ] }, "name": "StopCircle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/others/Apps02.json b/web/app/components/base/icons/src/vender/line/others/Apps02.json index 2ff128f24c..31378e175d 100644 --- a/web/app/components/base/icons/src/vender/line/others/Apps02.json +++ b/web/app/components/base/icons/src/vender/line/others/Apps02.json @@ -33,4 +33,4 @@ ] }, "name": "Apps02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/others/BubbleX.json b/web/app/components/base/icons/src/vender/line/others/BubbleX.json index 0cb5702c1f..7991ed4981 100644 --- a/web/app/components/base/icons/src/vender/line/others/BubbleX.json +++ b/web/app/components/base/icons/src/vender/line/others/BubbleX.json @@ -54,4 +54,4 @@ ] }, "name": "BubbleX" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/others/Colors.json b/web/app/components/base/icons/src/vender/line/others/Colors.json index b1832c2fe8..904e39fd18 100644 --- a/web/app/components/base/icons/src/vender/line/others/Colors.json +++ b/web/app/components/base/icons/src/vender/line/others/Colors.json @@ -63,4 +63,4 @@ ] }, "name": "Colors" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/others/DragHandle.json b/web/app/components/base/icons/src/vender/line/others/DragHandle.json index c1364aff18..ee1803c15c 100644 --- a/web/app/components/base/icons/src/vender/line/others/DragHandle.json +++ b/web/app/components/base/icons/src/vender/line/others/DragHandle.json @@ -35,4 +35,4 @@ ] }, "name": "DragHandle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/others/Env.json b/web/app/components/base/icons/src/vender/line/others/Env.json index 87a88edf3f..0cca4da4c4 100644 --- a/web/app/components/base/icons/src/vender/line/others/Env.json +++ b/web/app/components/base/icons/src/vender/line/others/Env.json @@ -87,4 +87,4 @@ ] }, "name": "Env" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/others/Exchange02.json b/web/app/components/base/icons/src/vender/line/others/Exchange02.json index 808a9ff644..3672d8b88b 100644 --- a/web/app/components/base/icons/src/vender/line/others/Exchange02.json +++ b/web/app/components/base/icons/src/vender/line/others/Exchange02.json @@ -23,4 +23,4 @@ ] }, "name": "Exchange02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/others/FileCode.json b/web/app/components/base/icons/src/vender/line/others/FileCode.json index 41050a559b..d61af3fdb3 100644 --- a/web/app/components/base/icons/src/vender/line/others/FileCode.json +++ b/web/app/components/base/icons/src/vender/line/others/FileCode.json @@ -23,4 +23,4 @@ ] }, "name": "FileCode" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/others/GlobalVariable.json b/web/app/components/base/icons/src/vender/line/others/GlobalVariable.json index d5fce59b4a..600c803f32 100644 --- a/web/app/components/base/icons/src/vender/line/others/GlobalVariable.json +++ b/web/app/components/base/icons/src/vender/line/others/GlobalVariable.json @@ -25,4 +25,4 @@ ] }, "name": "GlobalVariable" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/others/Icon3Dots.json b/web/app/components/base/icons/src/vender/line/others/Icon3Dots.json index 0942222f39..cd56eea903 100644 --- a/web/app/components/base/icons/src/vender/line/others/Icon3Dots.json +++ b/web/app/components/base/icons/src/vender/line/others/Icon3Dots.json @@ -36,4 +36,4 @@ ] }, "name": "Icon3Dots" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/others/LongArrowLeft.json b/web/app/components/base/icons/src/vender/line/others/LongArrowLeft.json index d2646b1090..43074803fe 100644 --- a/web/app/components/base/icons/src/vender/line/others/LongArrowLeft.json +++ b/web/app/components/base/icons/src/vender/line/others/LongArrowLeft.json @@ -24,4 +24,4 @@ ] }, "name": "LongArrowLeft" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/others/LongArrowRight.json b/web/app/components/base/icons/src/vender/line/others/LongArrowRight.json index 7582b81568..df05126c9a 100644 --- a/web/app/components/base/icons/src/vender/line/others/LongArrowRight.json +++ b/web/app/components/base/icons/src/vender/line/others/LongArrowRight.json @@ -24,4 +24,4 @@ ] }, "name": "LongArrowRight" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/others/SearchMenu.json b/web/app/components/base/icons/src/vender/line/others/SearchMenu.json index 5222574040..5854f25339 100644 --- a/web/app/components/base/icons/src/vender/line/others/SearchMenu.json +++ b/web/app/components/base/icons/src/vender/line/others/SearchMenu.json @@ -74,4 +74,4 @@ ] }, "name": "SearchMenu" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/others/Tools.json b/web/app/components/base/icons/src/vender/line/others/Tools.json index 0ab6857b09..12068ada07 100644 --- a/web/app/components/base/icons/src/vender/line/others/Tools.json +++ b/web/app/components/base/icons/src/vender/line/others/Tools.json @@ -116,4 +116,4 @@ ] }, "name": "Tools" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/shapes/CubeOutline.json b/web/app/components/base/icons/src/vender/line/shapes/CubeOutline.json index 4091004b72..bfeea58e92 100644 --- a/web/app/components/base/icons/src/vender/line/shapes/CubeOutline.json +++ b/web/app/components/base/icons/src/vender/line/shapes/CubeOutline.json @@ -95,4 +95,4 @@ ] }, "name": "CubeOutline" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/time/ClockFastForward.json b/web/app/components/base/icons/src/vender/line/time/ClockFastForward.json index 26b72084bf..72f2478958 100644 --- a/web/app/components/base/icons/src/vender/line/time/ClockFastForward.json +++ b/web/app/components/base/icons/src/vender/line/time/ClockFastForward.json @@ -26,4 +26,4 @@ ] }, "name": "ClockFastForward" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/time/ClockPlay.json b/web/app/components/base/icons/src/vender/line/time/ClockPlay.json index 7d3cc48b09..4f6739241c 100644 --- a/web/app/components/base/icons/src/vender/line/time/ClockPlay.json +++ b/web/app/components/base/icons/src/vender/line/time/ClockPlay.json @@ -63,4 +63,4 @@ ] }, "name": "ClockPlay" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/time/ClockPlaySlim.json b/web/app/components/base/icons/src/vender/line/time/ClockPlaySlim.json index 348694eeee..6790781864 100644 --- a/web/app/components/base/icons/src/vender/line/time/ClockPlaySlim.json +++ b/web/app/components/base/icons/src/vender/line/time/ClockPlaySlim.json @@ -36,4 +36,4 @@ ] }, "name": "ClockPlaySlim" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/time/ClockRefresh.json b/web/app/components/base/icons/src/vender/line/time/ClockRefresh.json index 925907ab8c..f0fda2c829 100644 --- a/web/app/components/base/icons/src/vender/line/time/ClockRefresh.json +++ b/web/app/components/base/icons/src/vender/line/time/ClockRefresh.json @@ -59,4 +59,4 @@ ] }, "name": "ClockRefresh" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/users/User01.json b/web/app/components/base/icons/src/vender/line/users/User01.json index 55353030f9..5b878f8deb 100644 --- a/web/app/components/base/icons/src/vender/line/users/User01.json +++ b/web/app/components/base/icons/src/vender/line/users/User01.json @@ -36,4 +36,4 @@ ] }, "name": "User01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/users/Users01.json b/web/app/components/base/icons/src/vender/line/users/Users01.json index 96dbeb30ec..497c258bc5 100644 --- a/web/app/components/base/icons/src/vender/line/users/Users01.json +++ b/web/app/components/base/icons/src/vender/line/users/Users01.json @@ -36,4 +36,4 @@ ] }, "name": "Users01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/line/weather/Stars02.json b/web/app/components/base/icons/src/vender/line/weather/Stars02.json index 54f6a42ecf..fdb25e6238 100644 --- a/web/app/components/base/icons/src/vender/line/weather/Stars02.json +++ b/web/app/components/base/icons/src/vender/line/weather/Stars02.json @@ -26,4 +26,4 @@ ] }, "name": "Stars02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/other/AnthropicText.json b/web/app/components/base/icons/src/vender/other/AnthropicText.json index a65ef47747..df844dec27 100644 --- a/web/app/components/base/icons/src/vender/other/AnthropicText.json +++ b/web/app/components/base/icons/src/vender/other/AnthropicText.json @@ -536,4 +536,4 @@ ] }, "name": "AnthropicText" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/other/Generator.json b/web/app/components/base/icons/src/vender/other/Generator.json index 3f24cfe18b..a72489d190 100644 --- a/web/app/components/base/icons/src/vender/other/Generator.json +++ b/web/app/components/base/icons/src/vender/other/Generator.json @@ -34,4 +34,4 @@ ] }, "name": "Generator" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/other/Group.json b/web/app/components/base/icons/src/vender/other/Group.json index 078febbc80..5f95dfc364 100644 --- a/web/app/components/base/icons/src/vender/other/Group.json +++ b/web/app/components/base/icons/src/vender/other/Group.json @@ -63,4 +63,4 @@ ] }, "name": "Group" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/other/Mcp.json b/web/app/components/base/icons/src/vender/other/Mcp.json index 7caa70b16b..c1162e64a1 100644 --- a/web/app/components/base/icons/src/vender/other/Mcp.json +++ b/web/app/components/base/icons/src/vender/other/Mcp.json @@ -32,4 +32,4 @@ ] }, "name": "Mcp" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/other/NoToolPlaceholder.json b/web/app/components/base/icons/src/vender/other/NoToolPlaceholder.json index d33d62d344..db2c952b1d 100644 --- a/web/app/components/base/icons/src/vender/other/NoToolPlaceholder.json +++ b/web/app/components/base/icons/src/vender/other/NoToolPlaceholder.json @@ -276,4 +276,4 @@ ] }, "name": "NoToolPlaceholder" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/other/Openai.json b/web/app/components/base/icons/src/vender/other/Openai.json index 236f66fcf2..ddf1243254 100644 --- a/web/app/components/base/icons/src/vender/other/Openai.json +++ b/web/app/components/base/icons/src/vender/other/Openai.json @@ -77,4 +77,4 @@ ] }, "name": "Openai" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/other/ReplayLine.json b/web/app/components/base/icons/src/vender/other/ReplayLine.json index 0fffbc98f5..2cc78753fd 100644 --- a/web/app/components/base/icons/src/vender/other/ReplayLine.json +++ b/web/app/components/base/icons/src/vender/other/ReplayLine.json @@ -33,4 +33,4 @@ ] }, "name": "ReplayLine" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/plugin/BoxSparkleFill.json b/web/app/components/base/icons/src/vender/plugin/BoxSparkleFill.json index 3733f98afd..55d7c64620 100644 --- a/web/app/components/base/icons/src/vender/plugin/BoxSparkleFill.json +++ b/web/app/components/base/icons/src/vender/plugin/BoxSparkleFill.json @@ -63,4 +63,4 @@ ] }, "name": "BoxSparkleFill" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/plugin/LeftCorner.json b/web/app/components/base/icons/src/vender/plugin/LeftCorner.json index d4cd0cd0ec..2374b1cfd8 100644 --- a/web/app/components/base/icons/src/vender/plugin/LeftCorner.json +++ b/web/app/components/base/icons/src/vender/plugin/LeftCorner.json @@ -24,4 +24,4 @@ ] }, "name": "LeftCorner" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/FinanceAndECommerce/GoldCoin.json b/web/app/components/base/icons/src/vender/solid/FinanceAndECommerce/GoldCoin.json index dac0e567f6..878c1f9f1f 100644 --- a/web/app/components/base/icons/src/vender/solid/FinanceAndECommerce/GoldCoin.json +++ b/web/app/components/base/icons/src/vender/solid/FinanceAndECommerce/GoldCoin.json @@ -23,4 +23,4 @@ ] }, "name": "GoldCoin" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/FinanceAndECommerce/Scales02.json b/web/app/components/base/icons/src/vender/solid/FinanceAndECommerce/Scales02.json index 9a781bd62d..3dd4e8908c 100644 --- a/web/app/components/base/icons/src/vender/solid/FinanceAndECommerce/Scales02.json +++ b/web/app/components/base/icons/src/vender/solid/FinanceAndECommerce/Scales02.json @@ -45,4 +45,4 @@ ] }, "name": "Scales02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/alertsAndFeedback/AlertTriangle.json b/web/app/components/base/icons/src/vender/solid/alertsAndFeedback/AlertTriangle.json index c73fbc5855..1aa7089b6d 100644 --- a/web/app/components/base/icons/src/vender/solid/alertsAndFeedback/AlertTriangle.json +++ b/web/app/components/base/icons/src/vender/solid/alertsAndFeedback/AlertTriangle.json @@ -35,4 +35,4 @@ ] }, "name": "AlertTriangle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/arrows/ChevronDown.json b/web/app/components/base/icons/src/vender/solid/arrows/ChevronDown.json index ef9a33dc03..b4b6429d9c 100644 --- a/web/app/components/base/icons/src/vender/solid/arrows/ChevronDown.json +++ b/web/app/components/base/icons/src/vender/solid/arrows/ChevronDown.json @@ -36,4 +36,4 @@ ] }, "name": "ChevronDown" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/arrows/HighPriority.json b/web/app/components/base/icons/src/vender/solid/arrows/HighPriority.json index 6710fd8109..5b66153647 100644 --- a/web/app/components/base/icons/src/vender/solid/arrows/HighPriority.json +++ b/web/app/components/base/icons/src/vender/solid/arrows/HighPriority.json @@ -50,4 +50,4 @@ ] }, "name": "HighPriority" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/communication/AiText.json b/web/app/components/base/icons/src/vender/solid/communication/AiText.json index c6e30fbf01..65860e58b9 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/AiText.json +++ b/web/app/components/base/icons/src/vender/solid/communication/AiText.json @@ -50,4 +50,4 @@ ] }, "name": "AiText" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/communication/BubbleTextMod.json b/web/app/components/base/icons/src/vender/solid/communication/BubbleTextMod.json index fceddcc729..7b2e964a61 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/BubbleTextMod.json +++ b/web/app/components/base/icons/src/vender/solid/communication/BubbleTextMod.json @@ -25,4 +25,4 @@ ] }, "name": "BubbleTextMod" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/communication/ChatBot.json b/web/app/components/base/icons/src/vender/solid/communication/ChatBot.json index 024b0edbeb..0378d60a53 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/ChatBot.json +++ b/web/app/components/base/icons/src/vender/solid/communication/ChatBot.json @@ -55,4 +55,4 @@ ] }, "name": "ChatBot" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.json b/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.json index 5b36575f56..fa9786473c 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.json +++ b/web/app/components/base/icons/src/vender/solid/communication/CuteRobot.json @@ -35,4 +35,4 @@ ] }, "name": "CuteRobot" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/communication/EditList.json b/web/app/components/base/icons/src/vender/solid/communication/EditList.json index 436f0be9f3..51278466c5 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/EditList.json +++ b/web/app/components/base/icons/src/vender/solid/communication/EditList.json @@ -50,4 +50,4 @@ ] }, "name": "EditList" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/communication/ListSparkle.json b/web/app/components/base/icons/src/vender/solid/communication/ListSparkle.json index 2e348e4b8f..160172c88c 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/ListSparkle.json +++ b/web/app/components/base/icons/src/vender/solid/communication/ListSparkle.json @@ -50,4 +50,4 @@ ] }, "name": "ListSparkle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/communication/Logic.json b/web/app/components/base/icons/src/vender/solid/communication/Logic.json index 57f86f4dd8..fa55d1c35b 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/Logic.json +++ b/web/app/components/base/icons/src/vender/solid/communication/Logic.json @@ -50,4 +50,4 @@ ] }, "name": "Logic" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/communication/MessageDotsCircle.json b/web/app/components/base/icons/src/vender/solid/communication/MessageDotsCircle.json index dca92bf5d9..e4f41f22b4 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/MessageDotsCircle.json +++ b/web/app/components/base/icons/src/vender/solid/communication/MessageDotsCircle.json @@ -35,4 +35,4 @@ ] }, "name": "MessageDotsCircle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/communication/MessageFast.json b/web/app/components/base/icons/src/vender/solid/communication/MessageFast.json index 4580398f31..b859b1f3f0 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/MessageFast.json +++ b/web/app/components/base/icons/src/vender/solid/communication/MessageFast.json @@ -25,4 +25,4 @@ ] }, "name": "MessageFast" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/communication/MessageHeartCircle.json b/web/app/components/base/icons/src/vender/solid/communication/MessageHeartCircle.json index 84769ba909..ede7ecdb8b 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/MessageHeartCircle.json +++ b/web/app/components/base/icons/src/vender/solid/communication/MessageHeartCircle.json @@ -35,4 +35,4 @@ ] }, "name": "MessageHeartCircle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/communication/MessageSmileSquare.json b/web/app/components/base/icons/src/vender/solid/communication/MessageSmileSquare.json index 7810d9043b..466f1d0207 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/MessageSmileSquare.json +++ b/web/app/components/base/icons/src/vender/solid/communication/MessageSmileSquare.json @@ -35,4 +35,4 @@ ] }, "name": "MessageSmileSquare" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/communication/Send03.json b/web/app/components/base/icons/src/vender/solid/communication/Send03.json index c6ff534838..8d0373ba7a 100644 --- a/web/app/components/base/icons/src/vender/solid/communication/Send03.json +++ b/web/app/components/base/icons/src/vender/solid/communication/Send03.json @@ -33,4 +33,4 @@ ] }, "name": "Send03" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/development/ApiConnection.json b/web/app/components/base/icons/src/vender/solid/development/ApiConnection.json index 6aafba9630..54a052241c 100644 --- a/web/app/components/base/icons/src/vender/solid/development/ApiConnection.json +++ b/web/app/components/base/icons/src/vender/solid/development/ApiConnection.json @@ -50,4 +50,4 @@ ] }, "name": "ApiConnection" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/development/ApiConnectionMod.json b/web/app/components/base/icons/src/vender/solid/development/ApiConnectionMod.json index e8ebcc7448..21efdaa13e 100644 --- a/web/app/components/base/icons/src/vender/solid/development/ApiConnectionMod.json +++ b/web/app/components/base/icons/src/vender/solid/development/ApiConnectionMod.json @@ -35,4 +35,4 @@ ] }, "name": "ApiConnectionMod" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/development/BarChartSquare02.json b/web/app/components/base/icons/src/vender/solid/development/BarChartSquare02.json index 14b274eef7..8ae42ed951 100644 --- a/web/app/components/base/icons/src/vender/solid/development/BarChartSquare02.json +++ b/web/app/components/base/icons/src/vender/solid/development/BarChartSquare02.json @@ -35,4 +35,4 @@ ] }, "name": "BarChartSquare02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/development/Container.json b/web/app/components/base/icons/src/vender/solid/development/Container.json index c2c3701b4c..b0d23fef72 100644 --- a/web/app/components/base/icons/src/vender/solid/development/Container.json +++ b/web/app/components/base/icons/src/vender/solid/development/Container.json @@ -41,4 +41,4 @@ ] }, "name": "Container" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/development/Database02.json b/web/app/components/base/icons/src/vender/solid/development/Database02.json index a1c5230612..b18d20eaea 100644 --- a/web/app/components/base/icons/src/vender/solid/development/Database02.json +++ b/web/app/components/base/icons/src/vender/solid/development/Database02.json @@ -43,4 +43,4 @@ ] }, "name": "Database02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/development/Database03.json b/web/app/components/base/icons/src/vender/solid/development/Database03.json index fa0c7ce94f..b00726139c 100644 --- a/web/app/components/base/icons/src/vender/solid/development/Database03.json +++ b/web/app/components/base/icons/src/vender/solid/development/Database03.json @@ -25,4 +25,4 @@ ] }, "name": "Database03" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/development/FileHeart02.json b/web/app/components/base/icons/src/vender/solid/development/FileHeart02.json index 08df0f27dd..681806b16f 100644 --- a/web/app/components/base/icons/src/vender/solid/development/FileHeart02.json +++ b/web/app/components/base/icons/src/vender/solid/development/FileHeart02.json @@ -47,4 +47,4 @@ ] }, "name": "FileHeart02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/development/PatternRecognition.json b/web/app/components/base/icons/src/vender/solid/development/PatternRecognition.json index 3d13c32b87..3b05d5ba8c 100644 --- a/web/app/components/base/icons/src/vender/solid/development/PatternRecognition.json +++ b/web/app/components/base/icons/src/vender/solid/development/PatternRecognition.json @@ -95,4 +95,4 @@ ] }, "name": "PatternRecognition" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/development/PromptEngineering.json b/web/app/components/base/icons/src/vender/solid/development/PromptEngineering.json index 01fbac5e93..a34a3f4fe8 100644 --- a/web/app/components/base/icons/src/vender/solid/development/PromptEngineering.json +++ b/web/app/components/base/icons/src/vender/solid/development/PromptEngineering.json @@ -50,4 +50,4 @@ ] }, "name": "PromptEngineering" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/development/PuzzlePiece01.json b/web/app/components/base/icons/src/vender/solid/development/PuzzlePiece01.json index f4008c81e2..20e6719fbe 100644 --- a/web/app/components/base/icons/src/vender/solid/development/PuzzlePiece01.json +++ b/web/app/components/base/icons/src/vender/solid/development/PuzzlePiece01.json @@ -35,4 +35,4 @@ ] }, "name": "PuzzlePiece01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/development/Semantic.json b/web/app/components/base/icons/src/vender/solid/development/Semantic.json index 333b3fa1c1..d9f6eeeb7e 100644 --- a/web/app/components/base/icons/src/vender/solid/development/Semantic.json +++ b/web/app/components/base/icons/src/vender/solid/development/Semantic.json @@ -50,4 +50,4 @@ ] }, "name": "Semantic" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/development/TerminalSquare.json b/web/app/components/base/icons/src/vender/solid/development/TerminalSquare.json index 7716cfd242..bf3c05a3b9 100644 --- a/web/app/components/base/icons/src/vender/solid/development/TerminalSquare.json +++ b/web/app/components/base/icons/src/vender/solid/development/TerminalSquare.json @@ -35,4 +35,4 @@ ] }, "name": "TerminalSquare" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/development/Variable02.json b/web/app/components/base/icons/src/vender/solid/development/Variable02.json index f506afd8bb..d957d38d4e 100644 --- a/web/app/components/base/icons/src/vender/solid/development/Variable02.json +++ b/web/app/components/base/icons/src/vender/solid/development/Variable02.json @@ -59,4 +59,4 @@ ] }, "name": "Variable02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/editor/Brush01.json b/web/app/components/base/icons/src/vender/solid/editor/Brush01.json index 049e5f2924..4087091bc0 100644 --- a/web/app/components/base/icons/src/vender/solid/editor/Brush01.json +++ b/web/app/components/base/icons/src/vender/solid/editor/Brush01.json @@ -32,4 +32,4 @@ ] }, "name": "Brush01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/editor/Citations.json b/web/app/components/base/icons/src/vender/solid/editor/Citations.json index 79d56b1a6c..1f7aa93794 100644 --- a/web/app/components/base/icons/src/vender/solid/editor/Citations.json +++ b/web/app/components/base/icons/src/vender/solid/editor/Citations.json @@ -33,4 +33,4 @@ ] }, "name": "Citations" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/editor/Colors.json b/web/app/components/base/icons/src/vender/solid/editor/Colors.json index 6e5dc69049..6fc4010c27 100644 --- a/web/app/components/base/icons/src/vender/solid/editor/Colors.json +++ b/web/app/components/base/icons/src/vender/solid/editor/Colors.json @@ -59,4 +59,4 @@ ] }, "name": "Colors" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/editor/Paragraph.json b/web/app/components/base/icons/src/vender/solid/editor/Paragraph.json index a16f076073..747f8e50b7 100644 --- a/web/app/components/base/icons/src/vender/solid/editor/Paragraph.json +++ b/web/app/components/base/icons/src/vender/solid/editor/Paragraph.json @@ -41,4 +41,4 @@ ] }, "name": "Paragraph" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/editor/TypeSquare.json b/web/app/components/base/icons/src/vender/solid/editor/TypeSquare.json index f901b0737f..9e6c72cf67 100644 --- a/web/app/components/base/icons/src/vender/solid/editor/TypeSquare.json +++ b/web/app/components/base/icons/src/vender/solid/editor/TypeSquare.json @@ -25,4 +25,4 @@ ] }, "name": "TypeSquare" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/education/Beaker02.json b/web/app/components/base/icons/src/vender/solid/education/Beaker02.json index 2f7830084e..b6dfd318ef 100644 --- a/web/app/components/base/icons/src/vender/solid/education/Beaker02.json +++ b/web/app/components/base/icons/src/vender/solid/education/Beaker02.json @@ -35,4 +35,4 @@ ] }, "name": "Beaker02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/education/BubbleText.json b/web/app/components/base/icons/src/vender/solid/education/BubbleText.json index 999f0db97e..e1b4b54fd2 100644 --- a/web/app/components/base/icons/src/vender/solid/education/BubbleText.json +++ b/web/app/components/base/icons/src/vender/solid/education/BubbleText.json @@ -35,4 +35,4 @@ ] }, "name": "BubbleText" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/education/Heart02.json b/web/app/components/base/icons/src/vender/solid/education/Heart02.json index 8cecaaee84..58ffe0c6f7 100644 --- a/web/app/components/base/icons/src/vender/solid/education/Heart02.json +++ b/web/app/components/base/icons/src/vender/solid/education/Heart02.json @@ -23,4 +23,4 @@ ] }, "name": "Heart02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/education/Unblur.json b/web/app/components/base/icons/src/vender/solid/education/Unblur.json index 13b8bb36f5..33c43170fe 100644 --- a/web/app/components/base/icons/src/vender/solid/education/Unblur.json +++ b/web/app/components/base/icons/src/vender/solid/education/Unblur.json @@ -149,4 +149,4 @@ ] }, "name": "Unblur" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/files/File05.json b/web/app/components/base/icons/src/vender/solid/files/File05.json index 17b9629741..ead7649bcf 100644 --- a/web/app/components/base/icons/src/vender/solid/files/File05.json +++ b/web/app/components/base/icons/src/vender/solid/files/File05.json @@ -52,4 +52,4 @@ ] }, "name": "File05" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/files/FileSearch02.json b/web/app/components/base/icons/src/vender/solid/files/FileSearch02.json index 7f8b0e8c78..e1decb16ac 100644 --- a/web/app/components/base/icons/src/vender/solid/files/FileSearch02.json +++ b/web/app/components/base/icons/src/vender/solid/files/FileSearch02.json @@ -54,4 +54,4 @@ ] }, "name": "FileSearch02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/files/FileZip.json b/web/app/components/base/icons/src/vender/solid/files/FileZip.json index 11fe823916..3d58745fa8 100644 --- a/web/app/components/base/icons/src/vender/solid/files/FileZip.json +++ b/web/app/components/base/icons/src/vender/solid/files/FileZip.json @@ -44,4 +44,4 @@ ] }, "name": "FileZip" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/files/Folder.json b/web/app/components/base/icons/src/vender/solid/files/Folder.json index 4fc5e5f51f..50c483bc92 100644 --- a/web/app/components/base/icons/src/vender/solid/files/Folder.json +++ b/web/app/components/base/icons/src/vender/solid/files/Folder.json @@ -35,4 +35,4 @@ ] }, "name": "Folder" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/AnswerTriangle.json b/web/app/components/base/icons/src/vender/solid/general/AnswerTriangle.json index a4b6283830..030e1efedf 100644 --- a/web/app/components/base/icons/src/vender/solid/general/AnswerTriangle.json +++ b/web/app/components/base/icons/src/vender/solid/general/AnswerTriangle.json @@ -24,4 +24,4 @@ ] }, "name": "AnswerTriangle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/ArrowDownRoundFill.json b/web/app/components/base/icons/src/vender/solid/general/ArrowDownRoundFill.json index 4e7da3c801..8367c942cb 100644 --- a/web/app/components/base/icons/src/vender/solid/general/ArrowDownRoundFill.json +++ b/web/app/components/base/icons/src/vender/solid/general/ArrowDownRoundFill.json @@ -33,4 +33,4 @@ ] }, "name": "ArrowDownRoundFill" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/CheckCircle.json b/web/app/components/base/icons/src/vender/solid/general/CheckCircle.json index 1b567e859e..403a5fe1c4 100644 --- a/web/app/components/base/icons/src/vender/solid/general/CheckCircle.json +++ b/web/app/components/base/icons/src/vender/solid/general/CheckCircle.json @@ -35,4 +35,4 @@ ] }, "name": "CheckCircle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/CheckDone01.json b/web/app/components/base/icons/src/vender/solid/general/CheckDone01.json index b4d5530b06..57a48650f1 100644 --- a/web/app/components/base/icons/src/vender/solid/general/CheckDone01.json +++ b/web/app/components/base/icons/src/vender/solid/general/CheckDone01.json @@ -34,4 +34,4 @@ ] }, "name": "CheckDone01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/Download02.json b/web/app/components/base/icons/src/vender/solid/general/Download02.json index 5854e64301..8afe46c93e 100644 --- a/web/app/components/base/icons/src/vender/solid/general/Download02.json +++ b/web/app/components/base/icons/src/vender/solid/general/Download02.json @@ -26,4 +26,4 @@ ] }, "name": "Download02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/Edit03.json b/web/app/components/base/icons/src/vender/solid/general/Edit03.json index f736ef56dd..ddf3a0d234 100644 --- a/web/app/components/base/icons/src/vender/solid/general/Edit03.json +++ b/web/app/components/base/icons/src/vender/solid/general/Edit03.json @@ -54,4 +54,4 @@ ] }, "name": "Edit03" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/Edit04.json b/web/app/components/base/icons/src/vender/solid/general/Edit04.json index aa923c2862..c254f600a4 100644 --- a/web/app/components/base/icons/src/vender/solid/general/Edit04.json +++ b/web/app/components/base/icons/src/vender/solid/general/Edit04.json @@ -36,4 +36,4 @@ ] }, "name": "Edit04" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/Eye.json b/web/app/components/base/icons/src/vender/solid/general/Eye.json index a7e63484da..a76bb81725 100644 --- a/web/app/components/base/icons/src/vender/solid/general/Eye.json +++ b/web/app/components/base/icons/src/vender/solid/general/Eye.json @@ -34,4 +34,4 @@ ] }, "name": "Eye" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/Github.json b/web/app/components/base/icons/src/vender/solid/general/Github.json index 46e694215b..a46c81bfef 100644 --- a/web/app/components/base/icons/src/vender/solid/general/Github.json +++ b/web/app/components/base/icons/src/vender/solid/general/Github.json @@ -33,4 +33,4 @@ ] }, "name": "Github" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/MessageClockCircle.json b/web/app/components/base/icons/src/vender/solid/general/MessageClockCircle.json index 4307f82ef8..d52347f6d9 100644 --- a/web/app/components/base/icons/src/vender/solid/general/MessageClockCircle.json +++ b/web/app/components/base/icons/src/vender/solid/general/MessageClockCircle.json @@ -33,4 +33,4 @@ ] }, "name": "MessageClockCircle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/PlusCircle.json b/web/app/components/base/icons/src/vender/solid/general/PlusCircle.json index 005a7ba5bf..e3a86132ec 100644 --- a/web/app/components/base/icons/src/vender/solid/general/PlusCircle.json +++ b/web/app/components/base/icons/src/vender/solid/general/PlusCircle.json @@ -35,4 +35,4 @@ ] }, "name": "PlusCircle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/QuestionTriangle.json b/web/app/components/base/icons/src/vender/solid/general/QuestionTriangle.json index 8830ee5837..32df4b0cd5 100644 --- a/web/app/components/base/icons/src/vender/solid/general/QuestionTriangle.json +++ b/web/app/components/base/icons/src/vender/solid/general/QuestionTriangle.json @@ -42,4 +42,4 @@ ] }, "name": "QuestionTriangle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/SearchMd.json b/web/app/components/base/icons/src/vender/solid/general/SearchMd.json index 808195f1fa..89cf471ca5 100644 --- a/web/app/components/base/icons/src/vender/solid/general/SearchMd.json +++ b/web/app/components/base/icons/src/vender/solid/general/SearchMd.json @@ -35,4 +35,4 @@ ] }, "name": "SearchMd" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/Target04.json b/web/app/components/base/icons/src/vender/solid/general/Target04.json index 6b22fab885..70895ccc00 100644 --- a/web/app/components/base/icons/src/vender/solid/general/Target04.json +++ b/web/app/components/base/icons/src/vender/solid/general/Target04.json @@ -43,4 +43,4 @@ ] }, "name": "Target04" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/Tool03.json b/web/app/components/base/icons/src/vender/solid/general/Tool03.json index 0a7f1ab96c..843fb36fba 100644 --- a/web/app/components/base/icons/src/vender/solid/general/Tool03.json +++ b/web/app/components/base/icons/src/vender/solid/general/Tool03.json @@ -59,4 +59,4 @@ ] }, "name": "Tool03" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/XCircle.json b/web/app/components/base/icons/src/vender/solid/general/XCircle.json index dd269fafcc..5e09c5a9e1 100644 --- a/web/app/components/base/icons/src/vender/solid/general/XCircle.json +++ b/web/app/components/base/icons/src/vender/solid/general/XCircle.json @@ -26,4 +26,4 @@ ] }, "name": "XCircle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/ZapFast.json b/web/app/components/base/icons/src/vender/solid/general/ZapFast.json index 865a48ee65..418a5c0019 100644 --- a/web/app/components/base/icons/src/vender/solid/general/ZapFast.json +++ b/web/app/components/base/icons/src/vender/solid/general/ZapFast.json @@ -76,4 +76,4 @@ ] }, "name": "ZapFast" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/general/ZapNarrow.json b/web/app/components/base/icons/src/vender/solid/general/ZapNarrow.json index 740c823f6e..27a8059fc8 100644 --- a/web/app/components/base/icons/src/vender/solid/general/ZapNarrow.json +++ b/web/app/components/base/icons/src/vender/solid/general/ZapNarrow.json @@ -35,4 +35,4 @@ ] }, "name": "ZapNarrow" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/layout/Grid01.json b/web/app/components/base/icons/src/vender/solid/layout/Grid01.json index 722cdecef6..35d4190237 100644 --- a/web/app/components/base/icons/src/vender/solid/layout/Grid01.json +++ b/web/app/components/base/icons/src/vender/solid/layout/Grid01.json @@ -76,4 +76,4 @@ ] }, "name": "Grid01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mapsAndTravel/Globe06.json b/web/app/components/base/icons/src/vender/solid/mapsAndTravel/Globe06.json index 6cc565ffdf..b86197ae7e 100644 --- a/web/app/components/base/icons/src/vender/solid/mapsAndTravel/Globe06.json +++ b/web/app/components/base/icons/src/vender/solid/mapsAndTravel/Globe06.json @@ -54,4 +54,4 @@ ] }, "name": "Globe06" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mapsAndTravel/Route.json b/web/app/components/base/icons/src/vender/solid/mapsAndTravel/Route.json index 24d3f35954..ac94bf2109 100644 --- a/web/app/components/base/icons/src/vender/solid/mapsAndTravel/Route.json +++ b/web/app/components/base/icons/src/vender/solid/mapsAndTravel/Route.json @@ -55,4 +55,4 @@ ] }, "name": "Route" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/AudioSupportIcon.json b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/AudioSupportIcon.json index cd3006b76d..aaab128672 100644 --- a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/AudioSupportIcon.json +++ b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/AudioSupportIcon.json @@ -23,4 +23,4 @@ ] }, "name": "AudioSupportIcon" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/DocumentSupportIcon.json b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/DocumentSupportIcon.json index 49cb6a521c..1047de09e0 100644 --- a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/DocumentSupportIcon.json +++ b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/DocumentSupportIcon.json @@ -23,4 +23,4 @@ ] }, "name": "DocumentSupportIcon" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/MagicBox.json b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/MagicBox.json index 4668e9eba8..ee079108c6 100644 --- a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/MagicBox.json +++ b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/MagicBox.json @@ -61,4 +61,4 @@ ] }, "name": "MagicBox" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/MagicEyes.json b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/MagicEyes.json index 00e16960a6..e7c0b53bf2 100644 --- a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/MagicEyes.json +++ b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/MagicEyes.json @@ -35,4 +35,4 @@ ] }, "name": "MagicEyes" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/MagicWand.json b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/MagicWand.json index bf13ab9e00..d9852c839f 100644 --- a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/MagicWand.json +++ b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/MagicWand.json @@ -70,4 +70,4 @@ ] }, "name": "MagicWand" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Microphone01.json b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Microphone01.json index 36aad43649..95ff504b07 100644 --- a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Microphone01.json +++ b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Microphone01.json @@ -52,4 +52,4 @@ ] }, "name": "Microphone01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Play.json b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Play.json index b32d786e4e..dc3cb6b4c0 100644 --- a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Play.json +++ b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Play.json @@ -35,4 +35,4 @@ ] }, "name": "Play" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Robot.json b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Robot.json index 650ca36528..616821956e 100644 --- a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Robot.json +++ b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Robot.json @@ -35,4 +35,4 @@ ] }, "name": "Robot" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Sliders02.json b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Sliders02.json index d72b99aa57..015509fca5 100644 --- a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Sliders02.json +++ b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Sliders02.json @@ -74,4 +74,4 @@ ] }, "name": "Sliders02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Speaker.json b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Speaker.json index 3e5cbe171b..2cb1df48f8 100644 --- a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Speaker.json +++ b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/Speaker.json @@ -109,4 +109,4 @@ ] }, "name": "Speaker" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/StopCircle.json b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/StopCircle.json index 67e02fca63..62ae331783 100644 --- a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/StopCircle.json +++ b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/StopCircle.json @@ -35,4 +35,4 @@ ] }, "name": "StopCircle" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/VideoSupportIcon.json b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/VideoSupportIcon.json index 4bc6881a5d..c801c12c4a 100644 --- a/web/app/components/base/icons/src/vender/solid/mediaAndDevices/VideoSupportIcon.json +++ b/web/app/components/base/icons/src/vender/solid/mediaAndDevices/VideoSupportIcon.json @@ -23,4 +23,4 @@ ] }, "name": "VideoSupportIcon" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/security/Lock01.json b/web/app/components/base/icons/src/vender/solid/security/Lock01.json index aa01bc574f..080a309f4d 100644 --- a/web/app/components/base/icons/src/vender/solid/security/Lock01.json +++ b/web/app/components/base/icons/src/vender/solid/security/Lock01.json @@ -35,4 +35,4 @@ ] }, "name": "Lock01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/shapes/Corner.json b/web/app/components/base/icons/src/vender/solid/shapes/Corner.json index 2f35483a66..23e1194c73 100644 --- a/web/app/components/base/icons/src/vender/solid/shapes/Corner.json +++ b/web/app/components/base/icons/src/vender/solid/shapes/Corner.json @@ -24,4 +24,4 @@ ] }, "name": "Corner" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/shapes/Star04.json b/web/app/components/base/icons/src/vender/solid/shapes/Star04.json index 5e5393a9a4..eba208cca0 100644 --- a/web/app/components/base/icons/src/vender/solid/shapes/Star04.json +++ b/web/app/components/base/icons/src/vender/solid/shapes/Star04.json @@ -33,4 +33,4 @@ ] }, "name": "Star04" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/shapes/Star06.json b/web/app/components/base/icons/src/vender/solid/shapes/Star06.json index 0466602376..5baa4d9a02 100644 --- a/web/app/components/base/icons/src/vender/solid/shapes/Star06.json +++ b/web/app/components/base/icons/src/vender/solid/shapes/Star06.json @@ -59,4 +59,4 @@ ] }, "name": "Star06" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/users/User01.json b/web/app/components/base/icons/src/vender/solid/users/User01.json index c9b8ea90d2..110cb2c020 100644 --- a/web/app/components/base/icons/src/vender/solid/users/User01.json +++ b/web/app/components/base/icons/src/vender/solid/users/User01.json @@ -54,4 +54,4 @@ ] }, "name": "User01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/users/UserEdit02.json b/web/app/components/base/icons/src/vender/solid/users/UserEdit02.json index f4451ea16f..7040d17ccb 100644 --- a/web/app/components/base/icons/src/vender/solid/users/UserEdit02.json +++ b/web/app/components/base/icons/src/vender/solid/users/UserEdit02.json @@ -89,4 +89,4 @@ ] }, "name": "UserEdit02" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/users/Users01.json b/web/app/components/base/icons/src/vender/solid/users/Users01.json index c18d59a00f..9c78dd5a09 100644 --- a/web/app/components/base/icons/src/vender/solid/users/Users01.json +++ b/web/app/components/base/icons/src/vender/solid/users/Users01.json @@ -76,4 +76,4 @@ ] }, "name": "Users01" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/solid/users/UsersPlus.json b/web/app/components/base/icons/src/vender/solid/users/UsersPlus.json index a70117f655..af8c22709f 100644 --- a/web/app/components/base/icons/src/vender/solid/users/UsersPlus.json +++ b/web/app/components/base/icons/src/vender/solid/users/UsersPlus.json @@ -74,4 +74,4 @@ ] }, "name": "UsersPlus" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/system/AutoUpdateLine.json b/web/app/components/base/icons/src/vender/system/AutoUpdateLine.json new file mode 100644 index 0000000000..5acc316bdd --- /dev/null +++ b/web/app/components/base/icons/src/vender/system/AutoUpdateLine.json @@ -0,0 +1,37 @@ +{ + "icon": { + "type": "element", + "isRootNode": true, + "name": "svg", + "attributes": { + "width": "24", + "height": "24", + "viewBox": "0 0 24 24", + "fill": "none", + "xmlns": "http://www.w3.org/2000/svg" + }, + "children": [ + { + "type": "element", + "name": "path", + "attributes": { + "d": "M5.46257 4.43262C7.21556 2.91688 9.5007 2 12 2C17.5228 2 22 6.47715 22 12C22 14.1361 21.3302 16.1158 20.1892 17.7406L17 12H20C20 7.58172 16.4183 4 12 4C9.84982 4 7.89777 4.84827 6.46023 6.22842L5.46257 4.43262ZM18.5374 19.5674C16.7844 21.0831 14.4993 22 12 22C6.47715 22 2 17.5228 2 12C2 9.86386 2.66979 7.88416 3.8108 6.25944L7 12H4C4 16.4183 7.58172 20 12 20C14.1502 20 16.1022 19.1517 17.5398 17.7716L18.5374 19.5674Z", + "fill": "currentColor" + }, + "children": [] + }, + { + "type": "element", + "name": "path", + "attributes": { + "fill-rule": "evenodd", + "clip-rule": "evenodd", + "d": "M16.3308 16H14.2915L13.6249 13.9476H10.3761L9.70846 16H7.66918L10.7759 7H13.2281L16.3308 16ZM10.8595 12.4622H13.1435L12.0378 9.05639H11.9673L10.8595 12.4622Z", + "fill": "currentColor" + }, + "children": [] + } + ] + }, + "name": "AutoUpdateLine" +} diff --git a/web/app/components/base/icons/src/vender/system/AutoUpdateLine.tsx b/web/app/components/base/icons/src/vender/system/AutoUpdateLine.tsx new file mode 100644 index 0000000000..d162edaa5a --- /dev/null +++ b/web/app/components/base/icons/src/vender/system/AutoUpdateLine.tsx @@ -0,0 +1,20 @@ +// GENERATE BY script +// DON NOT EDIT IT MANUALLY + +import * as React from 'react' +import data from './AutoUpdateLine.json' +import IconBase from '@/app/components/base/icons/IconBase' +import type { IconData } from '@/app/components/base/icons/IconBase' + +const Icon = ( + { + ref, + ...props + }: React.SVGProps & { + ref?: React.RefObject>; + }, +) => + +Icon.displayName = 'AutoUpdateLine' + +export default Icon diff --git a/web/app/components/base/icons/src/vender/system/index.ts b/web/app/components/base/icons/src/vender/system/index.ts new file mode 100644 index 0000000000..01553789b8 --- /dev/null +++ b/web/app/components/base/icons/src/vender/system/index.ts @@ -0,0 +1 @@ +export { default as AutoUpdateLine } from './AutoUpdateLine' diff --git a/web/app/components/base/icons/src/vender/workflow/Agent.json b/web/app/components/base/icons/src/vender/workflow/Agent.json index e7ed19369b..200475fc44 100644 --- a/web/app/components/base/icons/src/vender/workflow/Agent.json +++ b/web/app/components/base/icons/src/vender/workflow/Agent.json @@ -50,4 +50,4 @@ ] }, "name": "Agent" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/Answer.json b/web/app/components/base/icons/src/vender/workflow/Answer.json index 4f15b339bb..b0ad3f87ea 100644 --- a/web/app/components/base/icons/src/vender/workflow/Answer.json +++ b/web/app/components/base/icons/src/vender/workflow/Answer.json @@ -35,4 +35,4 @@ ] }, "name": "Answer" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/Assigner.json b/web/app/components/base/icons/src/vender/workflow/Assigner.json index 7106e5ad43..89e76a9cbe 100644 --- a/web/app/components/base/icons/src/vender/workflow/Assigner.json +++ b/web/app/components/base/icons/src/vender/workflow/Assigner.json @@ -65,4 +65,4 @@ ] }, "name": "Assigner" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/Code.json b/web/app/components/base/icons/src/vender/workflow/Code.json index d94f12ab3a..d72f02e289 100644 --- a/web/app/components/base/icons/src/vender/workflow/Code.json +++ b/web/app/components/base/icons/src/vender/workflow/Code.json @@ -35,4 +35,4 @@ ] }, "name": "Code" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/DocsExtractor.json b/web/app/components/base/icons/src/vender/workflow/DocsExtractor.json index 5b454590be..4e43c6c208 100644 --- a/web/app/components/base/icons/src/vender/workflow/DocsExtractor.json +++ b/web/app/components/base/icons/src/vender/workflow/DocsExtractor.json @@ -61,4 +61,4 @@ ] }, "name": "DocsExtractor" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/End.json b/web/app/components/base/icons/src/vender/workflow/End.json index 3e281cb575..56336efad1 100644 --- a/web/app/components/base/icons/src/vender/workflow/End.json +++ b/web/app/components/base/icons/src/vender/workflow/End.json @@ -35,4 +35,4 @@ ] }, "name": "End" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/Home.json b/web/app/components/base/icons/src/vender/workflow/Home.json index fd3096f658..982a9db222 100644 --- a/web/app/components/base/icons/src/vender/workflow/Home.json +++ b/web/app/components/base/icons/src/vender/workflow/Home.json @@ -35,4 +35,4 @@ ] }, "name": "Home" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/Http.json b/web/app/components/base/icons/src/vender/workflow/Http.json index 53b5c3a9fd..4affe7a5b0 100644 --- a/web/app/components/base/icons/src/vender/workflow/Http.json +++ b/web/app/components/base/icons/src/vender/workflow/Http.json @@ -68,4 +68,4 @@ ] }, "name": "Http" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/IfElse.json b/web/app/components/base/icons/src/vender/workflow/IfElse.json index 0ff778bc24..359f695c26 100644 --- a/web/app/components/base/icons/src/vender/workflow/IfElse.json +++ b/web/app/components/base/icons/src/vender/workflow/IfElse.json @@ -35,4 +35,4 @@ ] }, "name": "IfElse" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/Iteration.json b/web/app/components/base/icons/src/vender/workflow/Iteration.json index ee5748d1f1..84148e7bac 100644 --- a/web/app/components/base/icons/src/vender/workflow/Iteration.json +++ b/web/app/components/base/icons/src/vender/workflow/Iteration.json @@ -33,4 +33,4 @@ ] }, "name": "Iteration" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/IterationStart.json b/web/app/components/base/icons/src/vender/workflow/IterationStart.json index 2941cdb65d..cb574b7ea5 100644 --- a/web/app/components/base/icons/src/vender/workflow/IterationStart.json +++ b/web/app/components/base/icons/src/vender/workflow/IterationStart.json @@ -33,4 +33,4 @@ ] }, "name": "IterationStart" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/Jinja.json b/web/app/components/base/icons/src/vender/workflow/Jinja.json index ba46cb9ca6..91eee1534b 100644 --- a/web/app/components/base/icons/src/vender/workflow/Jinja.json +++ b/web/app/components/base/icons/src/vender/workflow/Jinja.json @@ -95,4 +95,4 @@ ] }, "name": "Jinja" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/KnowledgeRetrieval.json b/web/app/components/base/icons/src/vender/workflow/KnowledgeRetrieval.json index 4bdc83f868..69eb10eb83 100644 --- a/web/app/components/base/icons/src/vender/workflow/KnowledgeRetrieval.json +++ b/web/app/components/base/icons/src/vender/workflow/KnowledgeRetrieval.json @@ -35,4 +35,4 @@ ] }, "name": "KnowledgeRetrieval" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/ListFilter.json b/web/app/components/base/icons/src/vender/workflow/ListFilter.json index 568020f4a6..6ed383c315 100644 --- a/web/app/components/base/icons/src/vender/workflow/ListFilter.json +++ b/web/app/components/base/icons/src/vender/workflow/ListFilter.json @@ -35,4 +35,4 @@ ] }, "name": "ListFilter" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/Llm.json b/web/app/components/base/icons/src/vender/workflow/Llm.json index d900a67041..cdf114a490 100644 --- a/web/app/components/base/icons/src/vender/workflow/Llm.json +++ b/web/app/components/base/icons/src/vender/workflow/Llm.json @@ -35,4 +35,4 @@ ] }, "name": "Llm" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/Loop.json b/web/app/components/base/icons/src/vender/workflow/Loop.json index 65a70d82a1..b6abd13dfa 100644 --- a/web/app/components/base/icons/src/vender/workflow/Loop.json +++ b/web/app/components/base/icons/src/vender/workflow/Loop.json @@ -35,4 +35,4 @@ ] }, "name": "Loop" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/LoopEnd.json b/web/app/components/base/icons/src/vender/workflow/LoopEnd.json index 1427dfdcc5..eea9e717ca 100644 --- a/web/app/components/base/icons/src/vender/workflow/LoopEnd.json +++ b/web/app/components/base/icons/src/vender/workflow/LoopEnd.json @@ -35,4 +35,4 @@ ] }, "name": "LoopEnd" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/ParameterExtractor.json b/web/app/components/base/icons/src/vender/workflow/ParameterExtractor.json index 7d4fa6424a..eb66f4846b 100644 --- a/web/app/components/base/icons/src/vender/workflow/ParameterExtractor.json +++ b/web/app/components/base/icons/src/vender/workflow/ParameterExtractor.json @@ -263,4 +263,4 @@ ] }, "name": "ParameterExtractor" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/QuestionClassifier.json b/web/app/components/base/icons/src/vender/workflow/QuestionClassifier.json index a50ee6c410..6bd3dbf096 100644 --- a/web/app/components/base/icons/src/vender/workflow/QuestionClassifier.json +++ b/web/app/components/base/icons/src/vender/workflow/QuestionClassifier.json @@ -35,4 +35,4 @@ ] }, "name": "QuestionClassifier" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/TemplatingTransform.json b/web/app/components/base/icons/src/vender/workflow/TemplatingTransform.json index 69ee236611..6399208a2d 100644 --- a/web/app/components/base/icons/src/vender/workflow/TemplatingTransform.json +++ b/web/app/components/base/icons/src/vender/workflow/TemplatingTransform.json @@ -151,4 +151,4 @@ ] }, "name": "TemplatingTransform" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/VariableX.json b/web/app/components/base/icons/src/vender/workflow/VariableX.json index 1560684e55..a87b000587 100644 --- a/web/app/components/base/icons/src/vender/workflow/VariableX.json +++ b/web/app/components/base/icons/src/vender/workflow/VariableX.json @@ -35,4 +35,4 @@ ] }, "name": "VariableX" -} \ No newline at end of file +} diff --git a/web/app/components/base/icons/src/vender/workflow/WindowCursor.json b/web/app/components/base/icons/src/vender/workflow/WindowCursor.json index b64ba912bb..66591c1116 100644 --- a/web/app/components/base/icons/src/vender/workflow/WindowCursor.json +++ b/web/app/components/base/icons/src/vender/workflow/WindowCursor.json @@ -59,4 +59,4 @@ ] }, "name": "WindowCursor" -} \ No newline at end of file +} diff --git a/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx index 2d8bdcd3d9..fabad62397 100644 --- a/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx +++ b/web/app/components/plugins/install-plugin/install-bundle/steps/install.tsx @@ -10,7 +10,7 @@ import type { ExposeRefs } from './install-multi' import InstallMulti from './install-multi' import { useInstallOrUpdate } from '@/service/use-plugins' import useRefreshPluginList from '../../hooks/use-refresh-plugin-list' -import { useCanInstallPluginFromMarketplace } from '@/app/components/plugins/plugin-page/use-permission' +import { useCanInstallPluginFromMarketplace } from '@/app/components/plugins/plugin-page/use-reference-setting' import { useMittContextSelector } from '@/context/mitt-context' import Checkbox from '@/app/components/base/checkbox' const i18nPrefix = 'plugin.installModal' diff --git a/web/app/components/plugins/plugin-detail-panel/detail-header.tsx b/web/app/components/plugins/plugin-detail-panel/detail-header.tsx index 9c31a0b8e1..e5d1458140 100644 --- a/web/app/components/plugins/plugin-detail-panel/detail-header.tsx +++ b/web/app/components/plugins/plugin-detail-panel/detail-header.tsx @@ -40,6 +40,11 @@ import { PluginAuth } from '@/app/components/plugins/plugin-auth' import { AuthCategory } from '@/app/components/plugins/plugin-auth' import { useAllToolProviders } from '@/service/use-tools' import DeprecationNotice from '../base/deprecation-notice' +import { AutoUpdateLine } from '../../base/icons/src/vender/system' +import { convertUTCDaySecondsToLocalSeconds, timeOfDayToDayjs } from '../reference-setting-modal/auto-update-setting/utils' +import useReferenceSetting from '../plugin-page/use-reference-setting' +import { AUTO_UPDATE_MODE } from '../reference-setting-modal/auto-update-setting/types' +import { useAppContext } from '@/context/app-context' const i18nPrefix = 'plugin.action' @@ -55,6 +60,8 @@ const DetailHeader = ({ onUpdate, }: Props) => { const { t } = useTranslation() + const { userProfile: { timezone } } = useAppContext() + const { theme } = useTheme() const locale = useGetLanguage() const { locale: currentLocale } = useI18N() @@ -112,8 +119,24 @@ const DetailHeader = ({ setFalse: hideUpdateModal, }] = useBoolean(false) - const handleUpdate = async () => { + const { referenceSetting } = useReferenceSetting() + const { auto_upgrade: autoUpgradeInfo } = referenceSetting || {} + const isAutoUpgradeEnabled = useMemo(() => { + if (!autoUpgradeInfo || !isFromMarketplace) + return false + if(autoUpgradeInfo.upgrade_mode === AUTO_UPDATE_MODE.update_all) + return true + if(autoUpgradeInfo.upgrade_mode === AUTO_UPDATE_MODE.partial && autoUpgradeInfo.include_plugins.includes(plugin_id)) + return true + if(autoUpgradeInfo.upgrade_mode === AUTO_UPDATE_MODE.exclude && !autoUpgradeInfo.exclude_plugins.includes(plugin_id)) + return true + return false + }, [autoUpgradeInfo, plugin_id, isFromMarketplace]) + + const [isDowngrade, setIsDowngrade] = useState(false) + const handleUpdate = async (isDowngrade?: boolean) => { if (isFromMarketplace) { + setIsDowngrade(!!isDowngrade) showUpdateModal() return } @@ -180,9 +203,6 @@ const DetailHeader = ({ } }, [showDeleting, installation_id, hideDeleting, hideDeleteConfirm, onUpdate, category, refreshModelProviders, invalidateAllToolProviders]) - // #plugin TODO# used in apps - // const usedInApps = 3 - return (
    @@ -201,7 +221,7 @@ const DetailHeader = ({ currentVersion={version} onSelect={(state) => { setTargetVersion(state) - handleUpdate() + handleUpdate(state.isDowngrade) }} trigger={ } /> + {/* Auto update info */} + {isAutoUpgradeEnabled && ( + + {/* add a a div to fix tooltip hover not show problem */} +
    + + + +
    +
    + )} + {(hasNewVersion || isFromGitHub) && ( + } + value={value} + onChange={onChange} + isShow={isShowToolPicker} + onShowChange={setToolPicker} + /> +
    + ) +} +export default React.memo(PluginsPicker) diff --git a/web/app/components/plugins/reference-setting-modal/auto-update-setting/plugins-selected.tsx b/web/app/components/plugins/reference-setting-modal/auto-update-setting/plugins-selected.tsx new file mode 100644 index 0000000000..42c2a34ee8 --- /dev/null +++ b/web/app/components/plugins/reference-setting-modal/auto-update-setting/plugins-selected.tsx @@ -0,0 +1,29 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import cn from '@/utils/classnames' +import { MARKETPLACE_API_PREFIX } from '@/config' +import Icon from '@/app/components/plugins/card/base/card-icon' + +const MAX_DISPLAY_COUNT = 14 +type Props = { + className?: string + plugins: string[] +} + +const PluginsSelected: FC = ({ + className, + plugins, +}) => { + const isShowAll = plugins.length < MAX_DISPLAY_COUNT + const displayPlugins = plugins.slice(0, MAX_DISPLAY_COUNT) + return ( +
    + {displayPlugins.map(plugin => ( + + ))} + {!isShowAll &&
    +{plugins.length - MAX_DISPLAY_COUNT}
    } +
    + ) +} +export default React.memo(PluginsSelected) diff --git a/web/app/components/plugins/reference-setting-modal/auto-update-setting/strategy-picker.tsx b/web/app/components/plugins/reference-setting-modal/auto-update-setting/strategy-picker.tsx new file mode 100644 index 0000000000..c8227520f3 --- /dev/null +++ b/web/app/components/plugins/reference-setting-modal/auto-update-setting/strategy-picker.tsx @@ -0,0 +1,98 @@ +import { useState } from 'react' +import { useTranslation } from 'react-i18next' +import { + RiArrowDownSLine, + RiCheckLine, +} from '@remixicon/react' +import { AUTO_UPDATE_STRATEGY } from './types' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' +import Button from '@/app/components/base/button' +const i18nPrefix = 'plugin.autoUpdate.strategy' + +type Props = { + value: AUTO_UPDATE_STRATEGY + onChange: (value: AUTO_UPDATE_STRATEGY) => void +} +const StrategyPicker = ({ + value, + onChange, +}: Props) => { + const { t } = useTranslation() + const [open, setOpen] = useState(false) + const options = [ + { + value: AUTO_UPDATE_STRATEGY.disabled, + label: t(`${i18nPrefix}.disabled.name`), + description: t(`${i18nPrefix}.disabled.description`), + }, + { + value: AUTO_UPDATE_STRATEGY.fixOnly, + label: t(`${i18nPrefix}.fixOnly.name`), + description: t(`${i18nPrefix}.fixOnly.description`), + }, + { + value: AUTO_UPDATE_STRATEGY.latest, + label: t(`${i18nPrefix}.latest.name`), + description: t(`${i18nPrefix}.latest.description`), + }, + ] + const selectedOption = options.find(option => option.value === value) + + return ( + + { + e.stopPropagation() + e.nativeEvent.stopImmediatePropagation() + setOpen(v => !v) + }}> + + + +
    + { + options.map(option => ( +
    { + e.stopPropagation() + e.nativeEvent.stopImmediatePropagation() + onChange(option.value) + setOpen(false) + }} + > +
    + { + value === option.value && ( + + ) + } +
    +
    +
    {option.label}
    +
    {option.description}
    +
    +
    + )) + } +
    +
    +
    + ) +} + +export default StrategyPicker diff --git a/web/app/components/plugins/reference-setting-modal/auto-update-setting/tool-item.tsx b/web/app/components/plugins/reference-setting-modal/auto-update-setting/tool-item.tsx new file mode 100644 index 0000000000..99a01bcd0f --- /dev/null +++ b/web/app/components/plugins/reference-setting-modal/auto-update-setting/tool-item.tsx @@ -0,0 +1,45 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import type { PluginDetail } from '@/app/components/plugins/types' +import Icon from '@/app/components/plugins/card/base/card-icon' +import { renderI18nObject } from '@/i18n' +import { useGetLanguage } from '@/context/i18n' +import { MARKETPLACE_API_PREFIX } from '@/config' +import Checkbox from '@/app/components/base/checkbox' + +type Props = { + payload: PluginDetail + isChecked?: boolean + onCheckChange: () => void +} + +const ToolItem: FC = ({ + payload, + isChecked, + onCheckChange, +}) => { + const language = useGetLanguage() + + const { plugin_id, declaration } = payload + const { label, author: org } = declaration + return ( +
    +
    +
    + +
    {renderI18nObject(label, language)}
    +
    {org}
    +
    + +
    +
    + ) +} +export default React.memo(ToolItem) diff --git a/web/app/components/plugins/reference-setting-modal/auto-update-setting/tool-picker.tsx b/web/app/components/plugins/reference-setting-modal/auto-update-setting/tool-picker.tsx new file mode 100644 index 0000000000..02c1ecaf35 --- /dev/null +++ b/web/app/components/plugins/reference-setting-modal/auto-update-setting/tool-picker.tsx @@ -0,0 +1,167 @@ +'use client' +import type { FC } from 'react' +import React, { useCallback, useMemo, useState } from 'react' +import { + PortalToFollowElem, + PortalToFollowElemContent, + PortalToFollowElemTrigger, +} from '@/app/components/base/portal-to-follow-elem' +import { useInstalledPluginList } from '@/service/use-plugins' +import { PLUGIN_TYPE_SEARCH_MAP } from '../../marketplace/plugin-type-switch' +import SearchBox from '@/app/components/plugins/marketplace/search-box' +import { useTranslation } from 'react-i18next' +import cn from '@/utils/classnames' +import ToolItem from './tool-item' +import Loading from '@/app/components/base/loading' +import NoDataPlaceholder from './no-data-placeholder' +import { PluginSource } from '../../types' + +type Props = { + trigger: React.ReactNode + value: string[] + onChange: (value: string[]) => void + isShow: boolean + onShowChange: (isShow: boolean) => void + +} + +const ToolPicker: FC = ({ + trigger, + value, + onChange, + isShow, + onShowChange, +}) => { + const { t } = useTranslation() + const toggleShowPopup = useCallback(() => { + onShowChange(!isShow) + }, [onShowChange, isShow]) + + const tabs = [ + { + key: PLUGIN_TYPE_SEARCH_MAP.all, + name: t('plugin.category.all'), + }, + { + key: PLUGIN_TYPE_SEARCH_MAP.model, + name: t('plugin.category.models'), + }, + { + key: PLUGIN_TYPE_SEARCH_MAP.tool, + name: t('plugin.category.tools'), + }, + { + key: PLUGIN_TYPE_SEARCH_MAP.agent, + name: t('plugin.category.agents'), + }, + { + key: PLUGIN_TYPE_SEARCH_MAP.extension, + name: t('plugin.category.extensions'), + }, + { + key: PLUGIN_TYPE_SEARCH_MAP.bundle, + name: t('plugin.category.bundles'), + }, + ] + + const [pluginType, setPluginType] = useState(PLUGIN_TYPE_SEARCH_MAP.all) + const [query, setQuery] = useState('') + const [tags, setTags] = useState([]) + const { data, isLoading } = useInstalledPluginList() + const filteredList = useMemo(() => { + const list = data ? data.plugins : [] + return list.filter((plugin) => { + const isFromMarketPlace = plugin.source === PluginSource.marketplace + return ( + isFromMarketPlace && (pluginType === PLUGIN_TYPE_SEARCH_MAP.all || plugin.declaration.category === pluginType) + && (tags.length === 0 || tags.some(tag => plugin.declaration.tags.includes(tag))) + && (query === '' || plugin.plugin_id.toLowerCase().includes(query.toLowerCase())) + ) + }) + }, [data, pluginType, query, tags]) + const handleCheckChange = useCallback((pluginId: string) => { + return () => { + const newValue = value.includes(pluginId) + ? value.filter(id => id !== pluginId) + : [...value, pluginId] + onChange(newValue) + } + }, [onChange, value]) + + const listContent = ( +
    + {filteredList.map(item => ( + + ))} +
    + ) + + const loadingContent = ( +
    + +
    + ) + + const noData = ( + + ) + + return ( + + + {trigger} + + +
    +
    + +
    +
    +
    + { + tabs.map(tab => ( +
    setPluginType(tab.key)} + > + {tab.name} +
    + )) + } +
    +
    + {!isLoading && filteredList.length > 0 && listContent} + {!isLoading && filteredList.length === 0 && noData} + {isLoading && loadingContent} +
    +
    +
    + ) +} + +export default React.memo(ToolPicker) diff --git a/web/app/components/plugins/reference-setting-modal/auto-update-setting/types.ts b/web/app/components/plugins/reference-setting-modal/auto-update-setting/types.ts new file mode 100644 index 0000000000..b734150b49 --- /dev/null +++ b/web/app/components/plugins/reference-setting-modal/auto-update-setting/types.ts @@ -0,0 +1,19 @@ +export enum AUTO_UPDATE_STRATEGY { + fixOnly = 'fix_only', + disabled = 'disabled', + latest = 'latest', +} + +export enum AUTO_UPDATE_MODE { + partial = 'partial', + exclude = 'exclude', + update_all = 'all', +} + +export type AutoUpdateConfig = { + strategy_setting: AUTO_UPDATE_STRATEGY + upgrade_time_of_day: number + upgrade_mode: AUTO_UPDATE_MODE + exclude_plugins: string[] + include_plugins: string[] +} diff --git a/web/app/components/plugins/reference-setting-modal/auto-update-setting/utils.spec.ts b/web/app/components/plugins/reference-setting-modal/auto-update-setting/utils.spec.ts new file mode 100644 index 0000000000..f813338c98 --- /dev/null +++ b/web/app/components/plugins/reference-setting-modal/auto-update-setting/utils.spec.ts @@ -0,0 +1,14 @@ +import { convertLocalSecondsToUTCDaySeconds, convertUTCDaySecondsToLocalSeconds } from './utils' + +describe('convertLocalSecondsToUTCDaySeconds', () => { + it('should convert local seconds to UTC day seconds correctly', () => { + const localTimezone = 'Asia/Shanghai' + const utcSeconds = convertLocalSecondsToUTCDaySeconds(0, localTimezone) + expect(utcSeconds).toBe((24 - 8) * 3600) + }) + + it('should convert local seconds to UTC day seconds for a specific time', () => { + const localTimezone = 'Asia/Shanghai' + expect(convertUTCDaySecondsToLocalSeconds(convertLocalSecondsToUTCDaySeconds(0, localTimezone), localTimezone)).toBe(0) + }) +}) diff --git a/web/app/components/plugins/reference-setting-modal/auto-update-setting/utils.ts b/web/app/components/plugins/reference-setting-modal/auto-update-setting/utils.ts new file mode 100644 index 0000000000..23c067285f --- /dev/null +++ b/web/app/components/plugins/reference-setting-modal/auto-update-setting/utils.ts @@ -0,0 +1,37 @@ +import type { Dayjs } from 'dayjs' +import dayjs from 'dayjs' +import utc from 'dayjs/plugin/utc' +import timezone from 'dayjs/plugin/timezone' + +dayjs.extend(utc) +dayjs.extend(timezone) + +export const timeOfDayToDayjs = (timeOfDay: number): Dayjs => { + const hours = Math.floor(timeOfDay / 3600) + const minutes = (timeOfDay - hours * 3600) / 60 + const res = dayjs().startOf('day').hour(hours).minute(minutes) + return res +} + +export const convertLocalSecondsToUTCDaySeconds = (secondsInDay: number, localTimezone: string): number => { + const localDayStart = dayjs().tz(localTimezone).startOf('day') + const localTargetTime = localDayStart.add(secondsInDay, 'second') + const utcTargetTime = localTargetTime.utc() + const utcDayStart = utcTargetTime.startOf('day') + const secondsFromUTCMidnight = utcTargetTime.diff(utcDayStart, 'second') + return secondsFromUTCMidnight +} + +export const dayjsToTimeOfDay = (date?: Dayjs): number => { + if (!date) return 0 + return date.hour() * 3600 + date.minute() * 60 +} + +export const convertUTCDaySecondsToLocalSeconds = (utcDaySeconds: number, localTimezone: string): number => { + const utcDayStart = dayjs().utc().startOf('day') + const utcTargetTime = utcDayStart.add(utcDaySeconds, 'second') + const localTargetTime = utcTargetTime.tz(localTimezone) + const localDayStart = localTargetTime.startOf('day') + const secondsInLocalDay = localTargetTime.diff(localDayStart, 'second') + return secondsInLocalDay +} diff --git a/web/app/components/plugins/reference-setting-modal/label.tsx b/web/app/components/plugins/reference-setting-modal/label.tsx new file mode 100644 index 0000000000..6444bf801d --- /dev/null +++ b/web/app/components/plugins/reference-setting-modal/label.tsx @@ -0,0 +1,28 @@ +'use client' +import type { FC } from 'react' +import React from 'react' +import cn from '@/utils/classnames' + +type Props = { + label: string + description?: string +} + +const Label: FC = ({ + label, + description, +}) => { + return ( +
    +
    + {label} +
    + {description && ( +
    + {description} +
    + )} +
    + ) +} +export default React.memo(Label) diff --git a/web/app/components/plugins/permission-setting-modal/modal.tsx b/web/app/components/plugins/reference-setting-modal/modal.tsx similarity index 74% rename from web/app/components/plugins/permission-setting-modal/modal.tsx rename to web/app/components/plugins/reference-setting-modal/modal.tsx index 6fd4d8c2dc..9fefbdbb55 100644 --- a/web/app/components/plugins/permission-setting-modal/modal.tsx +++ b/web/app/components/plugins/reference-setting-modal/modal.tsx @@ -5,14 +5,18 @@ import { useTranslation } from 'react-i18next' import Modal from '@/app/components/base/modal' import OptionCard from '@/app/components/workflow/nodes/_base/components/option-card' import Button from '@/app/components/base/button' -import type { Permissions } from '@/app/components/plugins/types' +import type { Permissions, ReferenceSetting } from '@/app/components/plugins/types' import { PermissionType } from '@/app/components/plugins/types' +import type { AutoUpdateConfig } from './auto-update-setting/types' +import AutoUpdateSetting from './auto-update-setting' +import { defaultValue as autoUpdateDefaultValue } from './auto-update-setting/config' +import Label from './label' const i18nPrefix = 'plugin.privilege' type Props = { - payload: Permissions + payload: ReferenceSetting onHide: () => void - onSave: (payload: Permissions) => void + onSave: (payload: ReferenceSetting) => void } const PluginSettingModal: FC = ({ @@ -21,7 +25,9 @@ const PluginSettingModal: FC = ({ onSave, }) => { const { t } = useTranslation() - const [tempPrivilege, setTempPrivilege] = useState(payload) + const { auto_upgrade: autoUpdateConfig, permission: privilege } = payload || {} + const [tempPrivilege, setTempPrivilege] = useState(privilege) + const [tempAutoUpdateConfig, setTempAutoUpdateConfig] = useState(autoUpdateConfig || autoUpdateDefaultValue) const handlePrivilegeChange = useCallback((key: string) => { return (value: PermissionType) => { setTempPrivilege({ @@ -32,18 +38,21 @@ const PluginSettingModal: FC = ({ }, [tempPrivilege]) const handleSave = useCallback(async () => { - await onSave(tempPrivilege) + await onSave({ + permission: tempPrivilege, + auto_upgrade: tempAutoUpdateConfig, + }) onHide() - }, [onHide, onSave, tempPrivilege]) + }, [onHide, onSave, tempAutoUpdateConfig, tempPrivilege]) return ( -
    +
    {t(`${i18nPrefix}.title`)}
    @@ -53,9 +62,7 @@ const PluginSettingModal: FC = ({ { title: t(`${i18nPrefix}.whoCanDebug`), key: 'debug_permission', value: tempPrivilege?.debug_permission || PermissionType.noOne }, ].map(({ title, key, value }) => (
    -
    - {title} -
    +
    + +
    + + +
    + + ) +} + +export default DowngradeWarningModal diff --git a/web/app/components/plugins/update-plugin/from-market-place.tsx b/web/app/components/plugins/update-plugin/from-market-place.tsx index 98994d9b9c..70bc7399f5 100644 --- a/web/app/components/plugins/update-plugin/from-market-place.tsx +++ b/web/app/components/plugins/update-plugin/from-market-place.tsx @@ -13,13 +13,18 @@ import { updateFromMarketPlace } from '@/service/plugins' import checkTaskStatus from '@/app/components/plugins/install-plugin/base/check-task-status' import { usePluginTaskList } from '@/service/use-plugins' import Toast from '../../base/toast' +import DowngradeWarningModal from './downgrade-warning' +import { useInvalidateReferenceSettings, useRemoveAutoUpgrade } from '@/service/use-plugins' +import cn from '@/utils/classnames' const i18nPrefix = 'plugin.upgrade' type Props = { payload: UpdateFromMarketPlacePayload + pluginId: string onSave: () => void onCancel: () => void + isShowDowngradeWarningModal?: boolean } enum UploadStep { @@ -30,8 +35,10 @@ enum UploadStep { const UpdatePluginModal: FC = ({ payload, + pluginId, onSave, onCancel, + isShowDowngradeWarningModal, }) => { const { originalPackageInfo, @@ -103,51 +110,74 @@ const UpdatePluginModal: FC = ({ onSave() }, [onSave, uploadStep, check, originalPackageInfo.id, handleRefetch, targetPackageInfo.id]) + const { mutateAsync } = useRemoveAutoUpgrade() + const invalidateReferenceSettings = useInvalidateReferenceSettings() + const handleExcludeAndDownload = async () => { + await mutateAsync({ + plugin_id: pluginId, + }) + invalidateReferenceSettings() + handleConfirm() + } + const doShowDowngradeWarningModal = isShowDowngradeWarningModal && uploadStep === UploadStep.notStarted + return ( -
    - {t(`${i18nPrefix}.description`)} -
    -
    - - - {`${originalPackageInfo.payload.version} -> ${targetPackageInfo.version}`} - - - } + {doShowDowngradeWarningModal && ( + -
    -
    - {uploadStep === UploadStep.notStarted && ( + )} + {!doShowDowngradeWarningModal && ( + <> +
    + {t(`${i18nPrefix}.description`)} +
    +
    + + + {`${originalPackageInfo.payload.version} -> ${targetPackageInfo.version}`} + + + } + /> +
    +
    + {uploadStep === UploadStep.notStarted && ( + + )} - )} - -
    +
    + + )} +
    ) } diff --git a/web/app/components/plugins/update-plugin/plugin-version-picker.tsx b/web/app/components/plugins/update-plugin/plugin-version-picker.tsx index 424f76d790..36a4faace1 100644 --- a/web/app/components/plugins/update-plugin/plugin-version-picker.tsx +++ b/web/app/components/plugins/update-plugin/plugin-version-picker.tsx @@ -15,6 +15,7 @@ import type { import { useVersionListOfPlugin } from '@/service/use-plugins' import useTimestamp from '@/hooks/use-timestamp' import cn from '@/utils/classnames' +import { lt } from 'semver' type Props = { disabled?: boolean @@ -28,9 +29,11 @@ type Props = { onSelect: ({ version, unique_identifier, + isDowngrade, }: { version: string unique_identifier: string + isDowngrade: boolean }) => void } @@ -59,13 +62,14 @@ const PluginVersionPicker: FC = ({ const { data: res } = useVersionListOfPlugin(pluginID) - const handleSelect = useCallback(({ version, unique_identifier }: { + const handleSelect = useCallback(({ version, unique_identifier, isDowngrade }: { version: string unique_identifier: string + isDowngrade: boolean }) => { if (currentVersion === version) return - onSelect({ version, unique_identifier }) + onSelect({ version, unique_identifier, isDowngrade }) onShowChange(false) }, [currentVersion, onSelect, onShowChange]) @@ -99,6 +103,7 @@ const PluginVersionPicker: FC = ({ onClick={() => handleSelect({ version: version.version, unique_identifier: version.unique_identifier, + isDowngrade: lt(version.version, currentVersion), })} >
    diff --git a/web/i18n/en-US/plugin.ts b/web/i18n/en-US/plugin.ts index 3258144132..aa127eaf13 100644 --- a/web/i18n/en-US/plugin.ts +++ b/web/i18n/en-US/plugin.ts @@ -125,6 +125,56 @@ const translation = { admins: 'Admins', noone: 'No one', }, + autoUpdate: { + automaticUpdates: 'Automatic updates', + updateTime: 'Update time', + specifyPluginsToUpdate: 'Specify plugins to update', + strategy: { + disabled: { + name: 'Disabled', + description: 'Plugins will not auto-update', + }, + fixOnly: { + name: 'Fix Only', + description: 'Auto-update for patch versions only (e.g., 1.0.1 → 1.0.2). Minor version changes won\'t trigger updates.', + selectedDescription: 'Auto-update for patch versions only', + }, + latest: { + name: 'Latest', + description: 'Always update to latest version', + selectedDescription: 'Always update to latest version', + }, + }, + updateTimeTitle: 'Update time', + upgradeMode: { + all: 'Update all', + exclude: 'Exclude selected', + partial: 'Only selected', + }, + upgradeModePlaceholder: { + exclude: 'Selected plugins will not auto-update', + partial: 'Only selected plugins will auto-update. No plugins are currently selected, so no plugins will auto-update.', + }, + excludeUpdate: 'The following {{num}} plugins will not auto-update', + partialUPdate: 'Only the following {{num}} plugins will auto-update', + operation: { + clearAll: 'Clear all', + select: 'Select plugins', + }, + nextUpdateTime: 'Next auto-update: {{time}}', + pluginDowngradeWarning: { + title: 'Plugin Downgrade', + description: 'Auto-update is currently enabled for this plugin. Downgrading the version may cause your changes to be overwritten during the next automatic update.', + downgrade: 'Downgrade anyway', + exclude: 'Exclude from auto-update', + }, + noPluginPlaceholder: { + noFound: 'No plugins were found', + noInstalled: 'No plugins installed', + }, + updateSettings: 'Update Settings', + changeTimezone: 'To change time zone, go to Settings', + }, pluginInfoModal: { title: 'Plugin info', repository: 'Repository', diff --git a/web/i18n/zh-Hans/plugin.ts b/web/i18n/zh-Hans/plugin.ts index 4c95101592..a080a26a8c 100644 --- a/web/i18n/zh-Hans/plugin.ts +++ b/web/i18n/zh-Hans/plugin.ts @@ -125,6 +125,56 @@ const translation = { admins: '管理员', noone: '无人', }, + autoUpdate: { + automaticUpdates: '自动更新', + updateTime: '更新时间', + specifyPluginsToUpdate: '指定要更新的插件', + strategy: { + disabled: { + name: '禁用', + description: '插件将不会自动更新', + }, + fixOnly: { + name: '仅修复', + description: '仅自动更新补丁版本(例如,1.0.1 → 1.0.2)。次要版本更改不会触发更新。', + selectedDescription: '仅自动更新补丁版本', + }, + latest: { + name: '最新', + description: '始终更新到最新版本', + selectedDescription: '始终更新到最新版本', + }, + }, + updateTimeTitle: '更新时间', + upgradeMode: { + all: '更新全部', + exclude: '排除选定', + partial: '仅选定', + }, + upgradeModePlaceholder: { + exclude: '选定的插件将不会自动更新', + partial: '仅选定的插件将自动更新。目前未选择任何插件,因此不会自动更新任何插件。', + }, + excludeUpdate: '以下 {{num}} 个插件将不会自动更新', + partialUPdate: '仅以下 {{num}} 个插件将自动更新', + operation: { + clearAll: '清除所有', + select: '选择插件', + }, + nextUpdateTime: '下次自动更新时间: {{time}}', + pluginDowngradeWarning: { + title: '插件降级', + description: '此插件目前已启用自动更新。降级版本可能会导致您的更改在下次自动更新时被覆盖。', + downgrade: '仍然降级', + exclude: '从自动更新中排除', + }, + noPluginPlaceholder: { + noFound: '未找到插件', + noInstalled: '未安装插件', + }, + updateSettings: '更新设置', + changeTimezone: '要更改时区,请前往设置', + }, pluginInfoModal: { title: '插件信息', repository: '仓库', diff --git a/web/service/use-plugins.ts b/web/service/use-plugins.ts index ff092bb037..86f8134a5d 100644 --- a/web/service/use-plugins.ts +++ b/web/service/use-plugins.ts @@ -13,7 +13,6 @@ import type { InstalledLatestVersionResponse, InstalledPluginListWithTotalResponse, PackageDependency, - Permissions, Plugin, PluginDeclaration, PluginDetail, @@ -22,6 +21,7 @@ import type { PluginType, PluginsFromMarketplaceByInfoResponse, PluginsFromMarketplaceResponse, + ReferenceSetting, VersionInfo, VersionListResponse, uploadGitHubResponse, @@ -40,7 +40,7 @@ import { useQueryClient, } from '@tanstack/react-query' import { useInvalidateAllBuiltInTools } from './use-tools' -import usePermission from '@/app/components/plugins/plugin-page/use-permission' +import useReferenceSetting from '@/app/components/plugins/plugin-page/use-reference-setting' import { uninstallPlugin } from '@/service/plugins' import useRefreshPluginList from '@/app/components/plugins/install-plugin/hooks/use-refresh-plugin-list' import { cloneDeep } from 'lodash-es' @@ -350,37 +350,45 @@ export const useDebugKey = () => { }) } -const usePermissionsKey = [NAME_SPACE, 'permissions'] -export const usePermissions = () => { +const useReferenceSettingKey = [NAME_SPACE, 'referenceSettings'] +export const useReferenceSettings = () => { return useQuery({ - queryKey: usePermissionsKey, - queryFn: () => get('/workspaces/current/plugin/permission/fetch'), + queryKey: useReferenceSettingKey, + queryFn: () => get('/workspaces/current/plugin/preferences/fetch'), }) } -export const useInvalidatePermissions = () => { +export const useInvalidateReferenceSettings = () => { const queryClient = useQueryClient() return () => { queryClient.invalidateQueries( { - queryKey: usePermissionsKey, + queryKey: useReferenceSettingKey, }) } } -export const useMutationPermissions = ({ +export const useMutationReferenceSettings = ({ onSuccess, }: { onSuccess?: () => void }) => { return useMutation({ - mutationFn: (payload: Permissions) => { - return post('/workspaces/current/plugin/permission/change', { body: payload }) + mutationFn: (payload: ReferenceSetting) => { + return post('/workspaces/current/plugin/preferences/change', { body: payload }) }, onSuccess, }) } +export const useRemoveAutoUpgrade = () => { + return useMutation({ + mutationFn: (payload: { plugin_id: string }) => { + return post('/workspaces/current/plugin/preferences/autoupgrade/exclude', { body: payload }) + }, + }) +} + export const useMutationPluginsFromMarketplace = () => { return useMutation({ mutationFn: (pluginsSearchParams: PluginsSearchParams) => { @@ -427,6 +435,39 @@ export const useFetchPluginsInMarketPlaceByIds = (unique_identifiers: string[], }) } +export const useFetchPluginListOrBundleList = (pluginsSearchParams: PluginsSearchParams) => { + return useQuery({ + queryKey: [NAME_SPACE, 'fetchPluginListOrBundleList', pluginsSearchParams], + queryFn: () => { + const { + query, + sortBy, + sortOrder, + category, + tags, + exclude, + type, + page = 1, + pageSize = 40, + } = pluginsSearchParams + const pluginOrBundle = type === 'bundle' ? 'bundles' : 'plugins' + return postMarketplace<{ data: PluginsFromMarketplaceResponse }>(`/${pluginOrBundle}/search/advanced`, { + body: { + page, + page_size: pageSize, + query, + sort_by: sortBy, + sort_order: sortOrder, + category: category !== 'all' ? category : '', + tags, + exclude, + type, + }, + }) + }, + }) +} + export const useFetchPluginsInMarketPlaceByInfo = (infos: Record[]) => { return useQuery({ queryKey: [NAME_SPACE, 'fetchPluginsInMarketPlaceByInfo', infos], @@ -448,7 +489,7 @@ const usePluginTaskListKey = [NAME_SPACE, 'pluginTaskList'] export const usePluginTaskList = (category?: PluginType) => { const { canManagement, - } = usePermission() + } = useReferenceSetting() const { refreshPluginList } = useRefreshPluginList() const { data, From b4e152f7752979850bc8a566c20d94bffeba1904 Mon Sep 17 00:00:00 2001 From: wlleiiwang <1025164922@qq.com> Date: Wed, 23 Jul 2025 15:38:31 +0800 Subject: [PATCH 07/10] FEAT: Tencent Vector search supports backward compatibility with the previous score calculation approach. (#22820) Co-authored-by: wlleiiwang --- api/core/rag/datasource/vdb/tencent/tencent_vector.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/api/core/rag/datasource/vdb/tencent/tencent_vector.py b/api/core/rag/datasource/vdb/tencent/tencent_vector.py index 84746d23ea..23ed8a3344 100644 --- a/api/core/rag/datasource/vdb/tencent/tencent_vector.py +++ b/api/core/rag/datasource/vdb/tencent/tencent_vector.py @@ -284,7 +284,8 @@ class TencentVector(BaseVector): # Compatible with version 1.1.3 and below. meta = json.loads(meta) score = 1 - result.get("score", 0.0) - score = result.get("score", 0.0) + else: + score = result.get("score", 0.0) if score > score_threshold: meta["score"] = score doc = Document(page_content=result.get(self.field_text), metadata=meta) From cf07189bd2f99ff26289247a9c998b8958f62cc6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 23 Jul 2025 15:42:59 +0800 Subject: [PATCH 08/10] chore: translate i18n files (#22824) Co-authored-by: Nov1c444 <66365942+Nov1c444@users.noreply.github.com> --- web/i18n/de-DE/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/es-ES/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/fa-IR/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/fr-FR/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/hi-IN/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/it-IT/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/ja-JP/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/ko-KR/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/pl-PL/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/pt-BR/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/ro-RO/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/ru-RU/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/sl-SI/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/th-TH/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/tr-TR/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/uk-UA/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/vi-VN/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ web/i18n/zh-Hant/plugin.ts | 49 ++++++++++++++++++++++++++++++++++++++ 18 files changed, 882 insertions(+) diff --git a/web/i18n/de-DE/plugin.ts b/web/i18n/de-DE/plugin.ts index e416e4c9cb..6fa6999ae5 100644 --- a/web/i18n/de-DE/plugin.ts +++ b/web/i18n/de-DE/plugin.ts @@ -248,6 +248,55 @@ const translation = { authRemoved: 'Die Authentifizierung wurde entfernt.', }, deprecated: 'Abgelehnt', + autoUpdate: { + strategy: { + disabled: { + description: 'Plugins werden nicht automatisch aktualisiert', + name: 'Behindert', + }, + fixOnly: { + name: 'Nur fixieren', + selectedDescription: 'Auto-Update nur für Patch-Versionen', + }, + latest: { + description: 'Immer auf die neueste Version aktualisieren', + selectedDescription: 'Immer auf die neueste Version aktualisieren', + name: 'Neueste', + }, + }, + upgradeMode: { + exclude: 'Ausgewählte ausschließen', + partial: 'Nur ausgewählt', + all: 'Alle aktualisieren', + }, + upgradeModePlaceholder: { + exclude: 'Ausgewählte Plugins werden nicht automatisch aktualisiert', + partial: 'Nur ausgewählte Plugins werden automatisch aktualisiert. Derzeit sind keine Plugins ausgewählt, daher werden keine Plugins automatisch aktualisiert.', + }, + operation: { + clearAll: 'Alles löschen', + select: 'Plugins auswählen', + }, + pluginDowngradeWarning: { + downgrade: 'Trotzdem downgraden', + title: 'Plugin Downgrade', + exclude: 'Von der automatischen Aktualisierung ausschließen', + description: 'Die automatische Aktualisierung ist derzeit für dieses Plugin aktiviert. Ein Downgrade der Version kann dazu führen, dass Ihre Änderungen während des nächsten automatischen Updates überschrieben werden.', + }, + noPluginPlaceholder: { + noInstalled: 'Keine Plugins installiert', + noFound: 'Keine Plugins gefunden.', + }, + automaticUpdates: 'Automatische Updates', + updateTimeTitle: 'Aktualisierungszeit', + updateTime: 'Aktualisierungszeit', + excludeUpdate: 'Die folgenden {{num}} Plugins werden nicht automatisch aktualisiert.', + changeTimezone: 'Um die Zeitzone zu ändern, gehen Sie zu Einstellungen ', + nextUpdateTime: 'Nächstes automatisches Update: {{time}}', + partialUPdate: 'Nur die folgenden {{num}} Plugins werden automatisch aktualisiert', + specifyPluginsToUpdate: 'Geben Sie die zu aktualisierenden Plugins an', + updateSettings: 'Einstellungen aktualisieren', + }, } export default translation diff --git a/web/i18n/es-ES/plugin.ts b/web/i18n/es-ES/plugin.ts index e4506e09e2..6299684851 100644 --- a/web/i18n/es-ES/plugin.ts +++ b/web/i18n/es-ES/plugin.ts @@ -248,6 +248,55 @@ const translation = { default: 'Predeterminado', }, deprecated: 'Obsoleto', + autoUpdate: { + strategy: { + disabled: { + description: 'Los plugins no se actualizarán automáticamente', + name: 'Discapacitado', + }, + fixOnly: { + name: 'Arreglar Solo', + selectedDescription: 'Actualización automática solo para versiones de parches', + }, + latest: { + selectedDescription: 'Siempre actualiza a la última versión', + description: 'Siempre actualiza a la última versión', + name: 'último', + }, + }, + upgradeMode: { + partial: 'Solo seleccionado', + all: 'Actualizar todo', + exclude: 'Excluir seleccionado', + }, + upgradeModePlaceholder: { + exclude: 'Los plugins seleccionados no se actualizarán automáticamente', + partial: 'Solo los plugins seleccionados se actualizarán automáticamente. Actualmente no hay plugins seleccionados, por lo que no se actualizarán automáticamente.', + }, + operation: { + clearAll: 'Borrar todo', + select: 'Seleccionar complementos', + }, + pluginDowngradeWarning: { + title: 'Degradar plugin', + exclude: 'Excluir de la actualización automática', + downgrade: 'De todas formas, degradar', + description: 'La actualización automática está actualmente habilitada para este complemento. Downgradear la versión puede hacer que tus cambios se sobrescriban durante la próxima actualización automática.', + }, + noPluginPlaceholder: { + noFound: 'No se encontraron complementos', + noInstalled: 'No hay plugins instalados', + }, + updateTimeTitle: 'Hora de actualización', + nextUpdateTime: 'Próxima autoactualización: {{time}}', + specifyPluginsToUpdate: 'Especifique qué complementos actualizar', + updateTime: 'Actualizar tiempo', + updateSettings: 'Actualizar configuraciones', + excludeUpdate: 'Los siguientes {{num}} complementos no se actualizarán automáticamente', + partialUPdate: 'Solo los siguientes {{num}} complementos se actualizarán automáticamente', + changeTimezone: 'Para cambiar la zona horaria, ve a Configuración.', + automaticUpdates: 'Actualizaciones automáticas', + }, } export default translation diff --git a/web/i18n/fa-IR/plugin.ts b/web/i18n/fa-IR/plugin.ts index a9fba512e6..5e1cbe02bf 100644 --- a/web/i18n/fa-IR/plugin.ts +++ b/web/i18n/fa-IR/plugin.ts @@ -248,6 +248,55 @@ const translation = { useApiAuthDesc: 'پس از پیکربندی اعتبارنامه‌ها، تمامی اعضای درون فضای کاری می‌توانند از این ابزار هنگام نظم‌دهی به برنامه‌ها استفاده کنند.', }, deprecated: 'منسوخ شده', + autoUpdate: { + strategy: { + disabled: { + name: 'ناتوان', + description: 'پلاگین‌ها به‌طور خودکار به‌روزرسانی نخواهند شد', + }, + fixOnly: { + name: 'فقط تعمیر کنید', + selectedDescription: 'به‌روزرسانی خودکار تنها برای نسخه‌های وصله', + }, + latest: { + name: 'جدیدترین', + selectedDescription: 'همیشه به آخرین نسخه بروزرسانی کنید', + description: 'همیشه به آخرین نسخه بروزرسانی کنید', + }, + }, + upgradeMode: { + all: 'همه را بروزرسانی کن', + partial: 'فقط انتخاب شده', + exclude: 'انتخاب شده را استثنا کن', + }, + upgradeModePlaceholder: { + exclude: 'افزونه‌های انتخاب شده به‌صورت خودکار به‌روزرسانی نخواهند شد', + partial: 'فقط پلاگین‌های انتخاب شده به‌روزرسانی خودکار خواهند داشت. در حال حاضر هیچ پلاگینی انتخاب نشده است، بنابراین هیچ پلاگینی به‌روزرسانی خودکار نخواهد شد.', + }, + operation: { + select: 'افزونه‌ها را انتخاب کنید', + clearAll: 'همه را پاک کن', + }, + pluginDowngradeWarning: { + title: 'کاهش نسخه افزونه', + downgrade: 'به هر حال تنزل دهید', + exclude: 'از بروزرسانی خودکار مستثنی شود', + description: 'به‌روزرسانی خودکار برای این افزونه در حال حاضر فعال است. کاهش نسخه ممکن است باعث شود تغییرات شما در حین به‌روزرسانی خودکار بعدی نادیده گرفته شود.', + }, + noPluginPlaceholder: { + noFound: 'هیچ افزونه‌ای یافت نشد', + noInstalled: 'هیچ افزونه‌ای نصب نشده است', + }, + updateTimeTitle: 'زمان به‌روزرسانی', + specifyPluginsToUpdate: 'ماژول‌هایی را برای به‌روزرسانی مشخص کنید', + updateTime: 'زمان به‌روزرسانی', + automaticUpdates: 'بروز رسانی خودکار', + updateSettings: 'تنظیمات را به‌روزرسانی کنید', + changeTimezone: 'برای تغییر منطقه زمانی، به تنظیمات بروید', + excludeUpdate: 'پلاگین‌های زیر {{num}} به‌طور خودکار به‌روزرسانی نخواهند شد', + nextUpdateTime: 'به‌روزرسانی خودکار بعدی: {{time}}', + partialUPdate: 'تنها {{num}} پلاگین زیر به‌طور خودکار به‌روزرسانی خواهد شد.', + }, } export default translation diff --git a/web/i18n/fr-FR/plugin.ts b/web/i18n/fr-FR/plugin.ts index 2f85e26244..255171058a 100644 --- a/web/i18n/fr-FR/plugin.ts +++ b/web/i18n/fr-FR/plugin.ts @@ -248,6 +248,55 @@ const translation = { useApi: 'Utilisez la clé API', }, deprecated: 'Obsolète', + autoUpdate: { + strategy: { + disabled: { + description: 'Les plugins ne se mettront pas à jour automatiquement', + name: 'désactivé', + }, + fixOnly: { + selectedDescription: 'Mise à jour automatique uniquement pour les versions de correctif', + name: 'Réparer seulement', + }, + latest: { + name: 'Dernier', + selectedDescription: 'Mettez toujours à jour vers la dernière version', + description: 'Mettez toujours à jour vers la dernière version', + }, + }, + upgradeMode: { + exclude: 'Exclure sélectionné', + all: 'Mettre à jour tout', + partial: 'Seulement sélectionné', + }, + upgradeModePlaceholder: { + partial: 'Seuls les plugins sélectionnés se mettront à jour automatiquement. Aucun plugin n\'est actuellement sélectionné, donc aucun plugin ne se mettra à jour automatiquement.', + exclude: 'Les plugins sélectionnés ne se mettront pas à jour automatiquement.', + }, + operation: { + clearAll: 'Tout effacer', + select: 'Sélectionner des plugins', + }, + pluginDowngradeWarning: { + title: 'Baisse de version du plugin', + exclude: 'Exclure de la mise à jour automatique', + downgrade: 'Dégradez de toute façon', + description: 'La mise à jour automatique est actuellement activée pour ce plugin. Le fait de rétrograder la version peut entraîner la perte de vos modifications lors de la prochaine mise à jour automatique.', + }, + noPluginPlaceholder: { + noInstalled: 'Aucun plugin installé', + noFound: 'Aucun plugin n\'a été trouvé', + }, + updateTime: 'Temps de mise à jour', + specifyPluginsToUpdate: 'Spécifiez les plugins à mettre à jour', + updateTimeTitle: 'Temps de mise à jour', + changeTimezone: 'Pour changer de fuseau horaire, allez dans Paramètres', + automaticUpdates: 'Mises à jour automatiques', + updateSettings: 'Mettre à jour les paramètres', + excludeUpdate: 'Les {{num}} plugins suivants ne se mettront pas à jour automatiquement', + partialUPdate: 'Seuls les {{num}} plugins suivants se mettront à jour automatiquement', + nextUpdateTime: 'Prochaine mise à jour automatique : {{time}}', + }, } export default translation diff --git a/web/i18n/hi-IN/plugin.ts b/web/i18n/hi-IN/plugin.ts index b1349b149b..ae4547421c 100644 --- a/web/i18n/hi-IN/plugin.ts +++ b/web/i18n/hi-IN/plugin.ts @@ -248,6 +248,55 @@ const translation = { clientInfo: 'चूंकि इस टूल प्रदाता के लिए कोई सिस्टम क्लाइंट रहस्य नहीं पाए गए हैं, इसलिए इसे मैन्युअल रूप से सेटअप करना आवश्यक है, कृपया redirect_uri का उपयोग करें', }, deprecated: 'अनुशंसित नहीं', + autoUpdate: { + strategy: { + disabled: { + name: 'अक्षम', + description: 'प्लगइन्स स्वचालित रूप से अपडेट नहीं होंगे', + }, + fixOnly: { + name: 'केवल ठीक करें', + selectedDescription: 'केवल पैच संस्करणों के लिए स्वचालित अपडेट', + }, + latest: { + name: 'नवीनतम', + selectedDescription: 'हमेशा नवीनतम संस्करण पर अद्यतन करें', + description: 'हमेशा नवीनतम संस्करण पर अद्यतन करें', + }, + }, + upgradeMode: { + all: 'सभी अपडेट करें', + partial: 'केवल चयनित', + exclude: 'चुने हुए को बाहर करें', + }, + upgradeModePlaceholder: { + partial: 'केवल चयनित प्लगइन्स स्वतः अपडेट होंगे। वर्तमान में कोई प्लगइन चयनित नहीं है, इसलिए कोई प्लगइन स्वतः अपडेट नहीं होगा।', + exclude: 'चुने हुए प्लगइन्स अपने आप अपडेट नहीं होंगे', + }, + operation: { + clearAll: 'सभी हटाएं', + select: 'प्लगइन्स चुनें', + }, + pluginDowngradeWarning: { + downgrade: 'फिर भी डाउनग्रेड करें', + title: 'प्लगइन डाउनग्रेड', + exclude: 'स्वतः अपडेट से बाहर करें', + description: 'इस प्लगइन के लिए ऑटो-अपडेट वर्तमान में सक्षम है। संस्करण को डाउनग्रेड करने से आपके परिवर्तनों को अगली स्वचालित अद्यतन के दौरान ओवरराइट किया जा सकता है।', + }, + noPluginPlaceholder: { + noFound: 'कोई प्लगइन्स नहीं मिले', + noInstalled: 'कोई प्लगइन स्थापित नहीं है', + }, + updateTimeTitle: 'अद्यतन समय', + updateSettings: 'सेटिंग्स अपडेट करें', + automaticUpdates: 'स्वचालित अपडेट', + partialUPdate: 'केवल निम्नलिखित {{num}} प्लगइन्स स्वचालित रूप से अपडेट होंगे', + nextUpdateTime: 'अगली ऑटो-अपडेट: {{time}}', + updateTime: 'अद्यतन समय', + specifyPluginsToUpdate: 'अपडेट करने के लिए प्लगइन्स निर्दिष्ट करें', + changeTimezone: 'समय क्षेत्र बदलने के लिए, सेटिंग्स पर जाएं', + excludeUpdate: 'निम्नलिखित {{num}} प्लगइन्स स्वचालित रूप से अपडेट नहीं होंगे', + }, } export default translation diff --git a/web/i18n/it-IT/plugin.ts b/web/i18n/it-IT/plugin.ts index 52c05ae40c..e7b6b147fa 100644 --- a/web/i18n/it-IT/plugin.ts +++ b/web/i18n/it-IT/plugin.ts @@ -248,6 +248,55 @@ const translation = { clientInfo: 'Poiché non sono stati trovati segreti client di sistema per questo fornitore di strumenti, è necessario configurarlo manualmente. Per redirect_uri, si prega di utilizzare', }, deprecated: 'Deprecato', + autoUpdate: { + strategy: { + disabled: { + name: 'Disabile', + description: 'I plugin non si aggiorneranno automaticamente', + }, + fixOnly: { + name: 'Ripara solo', + selectedDescription: 'Aggiornamento automatico solo per versioni patch', + }, + latest: { + selectedDescription: 'Aggiorna sempre all\'ultima versione', + description: 'Aggiorna sempre all\'ultima versione', + name: 'Ultimo', + }, + }, + upgradeMode: { + exclude: 'Escludi selezionato', + all: 'Aggiorna tutto', + partial: 'Solo selezionati', + }, + upgradeModePlaceholder: { + exclude: 'I plugin selezionati non verranno aggiornati automaticamente', + partial: 'Solo i plugin selezionati si aggiorneranno automaticamente. Attualmente non ci sono plugin selezionati, quindi nessun plugin si aggiornerà automaticamente.', + }, + operation: { + clearAll: 'Cancella tutto', + select: 'Seleziona i plugin', + }, + pluginDowngradeWarning: { + title: 'Downgrade del plugin', + downgrade: 'Comunque esegui il downgrade', + exclude: 'Escludi dall\'aggiornamento automatico', + description: 'L\'aggiornamento automatico è attualmente abilitato per questo plugin. Il downgrade della versione potrebbe causare la sovrascrittura delle tue modifiche durante il prossimo aggiornamento automatico.', + }, + noPluginPlaceholder: { + noFound: 'Nessun plugin trovato', + noInstalled: 'Nessun plugin installato', + }, + specifyPluginsToUpdate: 'Specifica i plugin da aggiornare', + updateTime: 'Tempo di aggiornamento', + automaticUpdates: 'Aggiornamenti automatici', + updateSettings: 'Aggiorna impostazioni', + nextUpdateTime: 'Prossimo aggiornamento automatico: {{time}}', + partialUPdate: 'Solo i seguenti {{num}} plugin si aggiorneranno automaticamente', + changeTimezone: 'Per cambiare il fuso orario, vai su Impostazioni', + excludeUpdate: 'I seguenti {{num}} plugin non si aggiorneranno automaticamente', + updateTimeTitle: 'Tempo di aggiornamento', + }, } export default translation diff --git a/web/i18n/ja-JP/plugin.ts b/web/i18n/ja-JP/plugin.ts index a80cde7e38..38b73a847e 100644 --- a/web/i18n/ja-JP/plugin.ts +++ b/web/i18n/ja-JP/plugin.ts @@ -248,6 +248,55 @@ const translation = { useApiAuthDesc: '認証情報を設定した後、ワークスペース内のすべてのメンバーは、アプリケーションをオーケストレーションする際にこのツールを使用できます。', clientInfo: 'このツールプロバイダーにシステムクライアントシークレットが見つからないため、手動で設定する必要があります。redirect_uriには、次を使用してください。', }, + autoUpdate: { + strategy: { + disabled: { + name: '無効', + description: 'プラグインは自動更新されません', + }, + fixOnly: { + name: '修正のみ', + selectedDescription: 'パッチバージョンのみの自動更新', + }, + latest: { + name: '最新', + selectedDescription: '常に最新バージョンに更新してください', + description: '常に最新バージョンに更新してください', + }, + }, + upgradeMode: { + partial: '選択されたもののみ', + exclude: '選択したものを除外する', + all: 'すべてを更新する', + }, + upgradeModePlaceholder: { + exclude: '選択されたプラグインは自動更新されません', + partial: '選択されたプラグインのみが自動更新されます。現在選択されているプラグインはないため、プラグインは自動更新されません。', + }, + operation: { + clearAll: 'すべてクリア', + select: 'プラグインを選択する', + }, + pluginDowngradeWarning: { + title: 'プラグインのダウングレード', + downgrade: 'とにかくダウングレードする', + exclude: '自動更新から除外する', + description: 'このプラグインは現在、自動更新が有効です。バージョンをダウングレードすると、次回の自動更新中に変更が上書きされる可能性があります。', + }, + noPluginPlaceholder: { + noInstalled: 'プラグインがインストールされていません', + noFound: 'プラグインが見つかりませんでした', + }, + updateTimeTitle: '更新時刻', + automaticUpdates: '自動更新', + updateTime: '更新時刻', + updateSettings: '設定を更新する', + nextUpdateTime: '次の自動更新: {{time}}', + excludeUpdate: '以下の{{num}}プラグインは自動更新されません', + changeTimezone: 'タイムゾーンを変更するには、設定に移動してください。', + specifyPluginsToUpdate: '更新するプラグインを指定してください', + partialUPdate: '以下の{{num}}プラグインのみが自動更新されます', + }, } export default translation diff --git a/web/i18n/ko-KR/plugin.ts b/web/i18n/ko-KR/plugin.ts index 5ed122c3f1..1f60f1365b 100644 --- a/web/i18n/ko-KR/plugin.ts +++ b/web/i18n/ko-KR/plugin.ts @@ -248,6 +248,55 @@ const translation = { clientInfo: '이 도구 공급자에 대한 시스템 클라이언트 비밀이 발견되지 않았으므로 수동으로 설정해야 하며, redirect_uri는 다음을 사용하십시오.', }, deprecated: '사용 중단됨', + autoUpdate: { + strategy: { + disabled: { + name: '장애인', + description: '플러그인이 자동으로 업데이트되지 않습니다.', + }, + fixOnly: { + name: '수정만 하기', + selectedDescription: '패치 버전만 자동 업데이트', + }, + latest: { + name: '최신', + description: '항상 최신 버전으로 업데이트하세요.', + selectedDescription: '항상 최신 버전으로 업데이트하세요.', + }, + }, + upgradeMode: { + partial: '선택된 것만', + all: '모두 업데이트하기', + exclude: '선택한 항목 제외', + }, + upgradeModePlaceholder: { + partial: '선택된 플러그인만 자동 업데이트됩니다. 현재 선택된 플러그인이 없으므로 자동 업데이트되는 플러그인은 없습니다.', + exclude: '선택한 플러그인은 자동으로 업데이트되지 않습니다.', + }, + operation: { + clearAll: '모두 지우기', + select: '플러그인을 선택하세요', + }, + pluginDowngradeWarning: { + exclude: '자동 업데이트에서 제외', + title: '플러그인 다운그레이드', + downgrade: '어쨌든 다운그레이드', + description: '이 플러그인은 현재 자동 업데이트가 활성화되어 있습니다. 버전을 다운그레이드하면 다음 자동 업데이트 중에 변경 사항이 덮어써질 수 있습니다.', + }, + noPluginPlaceholder: { + noFound: '플러그인이 없습니다.', + noInstalled: '설치된 플러그인이 없습니다.', + }, + updateTimeTitle: '업데이트 시간', + automaticUpdates: '자동 업데이트', + updateTime: '업데이트 시간', + nextUpdateTime: '다음 자동 업데이트: {{time}}', + updateSettings: '설정 업데이트', + partialUPdate: '다음 {{num}} 플러그인만 자동 업데이트됩니다.', + changeTimezone: '시간대를 변경하려면 설정으로 이동하세요.', + specifyPluginsToUpdate: '업데이트할 플러그인을 지정하십시오.', + excludeUpdate: '다음 {{num}} 플러그인은 자동 업데이트되지 않습니다.', + }, } export default translation diff --git a/web/i18n/pl-PL/plugin.ts b/web/i18n/pl-PL/plugin.ts index 3349fac4da..10944a339b 100644 --- a/web/i18n/pl-PL/plugin.ts +++ b/web/i18n/pl-PL/plugin.ts @@ -248,6 +248,55 @@ const translation = { clientInfo: 'Ponieważ nie znaleziono tajemnic klientów systemu dla tego dostawcy narzędzi, wymagane jest ręczne skonfigurowanie, dla redirect_uri proszę użyć', }, deprecated: 'Nieaktualny', + autoUpdate: { + strategy: { + disabled: { + description: 'Wtyczki nie będą się automatycznie aktualizować', + name: 'Niepełnosprawny', + }, + fixOnly: { + selectedDescription: 'Automatyczna aktualizacja tylko dla wersji poprawek', + name: 'Napraw tylko', + }, + latest: { + name: 'Najświeższy', + description: 'Zawsze aktualizuj do najnowszej wersji', + selectedDescription: 'Zawsze aktualizuj do najnowszej wersji', + }, + }, + upgradeMode: { + all: 'Zaktualizuj wszystko', + partial: 'Tylko wybrane', + exclude: 'Wyłącz wybrane', + }, + upgradeModePlaceholder: { + exclude: 'Wybrane wtyczki nie będą aktualizować się automatycznie.', + partial: 'Tylko wybrane wtyczki będą się aktualizować automatycznie. Obecnie nie wybrano żadnych wtyczek, więc żadna wtyczka nie będzie się automatycznie aktualizować.', + }, + operation: { + clearAll: 'Wyczyść wszystko', + select: 'Wybierz wtyczki', + }, + pluginDowngradeWarning: { + exclude: 'Wyłącz z automatycznej aktualizacji', + downgrade: 'Zrób downgrade tak czy inaczej', + title: 'Obniżenie wersji wtyczki', + description: 'Automatyczna aktualizacja jest obecnie włączona dla tej wtyczki. Obniżenie wersji może spowodować, że twoje zmiany zostaną nadpisane podczas następnej automatycznej aktualizacji.', + }, + noPluginPlaceholder: { + noInstalled: 'Brak zainstalowanych wtyczek', + noFound: 'Nie znaleziono wtyczek', + }, + updateTime: 'Czas aktualizacji', + updateSettings: 'Zaktualizuj ustawienia', + updateTimeTitle: 'Czas aktualizacji', + specifyPluginsToUpdate: 'Określ wtyczki do zaktualizowania', + nextUpdateTime: 'Następna automatyczna aktualizacja: {{time}}', + automaticUpdates: 'Automatyczne aktualizacje', + excludeUpdate: 'Następujące {{num}} wtyczki nie będą aktualizować się automatycznie', + changeTimezone: 'Aby zmienić strefę czasową, przejdź do Ustawienia', + partialUPdate: 'Tylko następujące {{num}} wtyczki będą się automatycznie aktualizować', + }, } export default translation diff --git a/web/i18n/pt-BR/plugin.ts b/web/i18n/pt-BR/plugin.ts index 4527f5ff03..47490d218c 100644 --- a/web/i18n/pt-BR/plugin.ts +++ b/web/i18n/pt-BR/plugin.ts @@ -248,6 +248,55 @@ const translation = { clientInfo: 'Como não foram encontrados segredos de cliente do sistema para este provedor de ferramentas, é necessário configurá-lo manualmente. Para redirect_uri, use', }, deprecated: 'Obsoleto', + autoUpdate: { + strategy: { + disabled: { + name: 'Desativado', + description: 'Os plugins não atualizarão automaticamente', + }, + fixOnly: { + selectedDescription: 'Atualização automática apenas para versões de patch', + name: 'Reparar Apenas', + }, + latest: { + description: 'Sempre atualize para a versão mais recente', + selectedDescription: 'Sempre atualize para a versão mais recente', + name: 'Último', + }, + }, + upgradeMode: { + all: 'Atualizar tudo', + exclude: 'Excluir selecionados', + partial: 'Somente selecionado', + }, + upgradeModePlaceholder: { + exclude: 'Plugins selecionados não serão atualizados automaticamente', + partial: 'Apenas plugins selecionados serão atualizados automaticamente. Nenhum plugin está atualmente selecionado, então nenhum plugin será atualizado automaticamente.', + }, + operation: { + select: 'Selecionar plugins', + clearAll: 'Limpar tudo', + }, + pluginDowngradeWarning: { + downgrade: 'Descer de nível de qualquer forma', + exclude: 'Excluir da atualização automática', + title: 'Rebaixamento do Plugin', + description: 'A atualização automática está atualmente habilitada para este plugin. Reverter a versão pode causar a sobrescrição de suas alterações durante a próxima atualização automática.', + }, + noPluginPlaceholder: { + noFound: 'Nenhum plugin foi encontrado.', + noInstalled: 'Nenhum plugin instalado', + }, + updateTime: 'Atualizar hora', + automaticUpdates: 'Atualizações automáticas', + excludeUpdate: 'Os seguintes {{num}} plugins não serão atualizados automaticamente', + updateTimeTitle: 'Atualizar hora', + specifyPluginsToUpdate: 'Especifique os plugins a serem atualizados', + changeTimezone: 'Para mudar o fuso horário, vá para Configurações', + nextUpdateTime: 'Próxima atualização automática: {{time}}', + partialUPdate: 'Apenas os seguintes {{num}} plugins serão atualizados automaticamente', + updateSettings: 'Atualizar Configurações', + }, } export default translation diff --git a/web/i18n/ro-RO/plugin.ts b/web/i18n/ro-RO/plugin.ts index 3b5e4da843..8c3ba06bbc 100644 --- a/web/i18n/ro-RO/plugin.ts +++ b/web/i18n/ro-RO/plugin.ts @@ -248,6 +248,55 @@ const translation = { clientInfo: 'Deoarece nu s-au găsit secretele clientului sistemului pentru acest furnizor de instrumente, este necesară configurarea manuală; pentru redirect_uri, vă rugăm să folosiți', }, deprecated: 'Încetat de a mai fi utilizat', + autoUpdate: { + strategy: { + disabled: { + description: 'Pluginurile nu se vor actualiza automat', + name: 'Dezactivat', + }, + fixOnly: { + selectedDescription: 'Actualizare automată doar pentru versiuni patch', + name: 'Fix doar', + }, + latest: { + name: 'Ultimul', + selectedDescription: 'Actualizați întotdeauna la cea mai recentă versiune', + description: 'Actualizați întotdeauna la cea mai recentă versiune', + }, + }, + upgradeMode: { + exclude: 'Excluzi selecția', + all: 'Actualizează tot', + partial: 'Numai selectat', + }, + upgradeModePlaceholder: { + exclude: 'Pluginurile selectate nu se vor actualiza automat.', + partial: 'Numai pluginurile selectate se vor actualiza automat. Nu există pluginuri selectate în prezent, așa că niciun plugin nu se va actualiza automat.', + }, + operation: { + select: 'Selectați plugin-uri', + clearAll: 'Șterge tot', + }, + pluginDowngradeWarning: { + title: 'Scădere a pluginului', + exclude: 'Exclude de la actualizarea automată', + downgrade: 'Oricum, downgradează', + description: 'Actualizarea automată este în prezent activată pentru acest plugin. Revenirea la o versiune anterioară poate provoca suprascrierea modificărilor tale în timpul următoarei actualizări automate.', + }, + noPluginPlaceholder: { + noFound: 'Nu au fost găsite plugin-uri', + noInstalled: 'Niciun plugin instalat', + }, + excludeUpdate: 'Următoarele {{num}} pluginuri nu se vor actualiza automat', + updateTimeTitle: 'Timp de actualizare', + updateSettings: 'Actualizează setările', + changeTimezone: 'Pentru a schimba fusul orar, mergi la Setări', + automaticUpdates: 'Actualizări automate', + specifyPluginsToUpdate: 'Specificați plugin-urile de actualizat', + partialUPdate: 'Numai următoarele {{num}} pluginuri se vor actualiza automat', + updateTime: 'Timp de actualizare', + nextUpdateTime: 'Următoarea actualizare automată: {{time}}', + }, } export default translation diff --git a/web/i18n/ru-RU/plugin.ts b/web/i18n/ru-RU/plugin.ts index e82963c3f1..f39139aa05 100644 --- a/web/i18n/ru-RU/plugin.ts +++ b/web/i18n/ru-RU/plugin.ts @@ -248,6 +248,55 @@ const translation = { clientInfo: 'Поскольку не найдены секреты клиентской системы для этого поставщика инструментов, необходимо настроить его вручную, для redirect_uri, пожалуйста, используйте', }, deprecated: 'Устаревший', + autoUpdate: { + strategy: { + disabled: { + name: 'Отключен', + description: 'Плагины не будут автоматически обновляться', + }, + fixOnly: { + name: 'Только исправить', + selectedDescription: 'Автообновление только для версий патчей', + }, + latest: { + name: 'Новости', + selectedDescription: 'Всегда обновляйте до последней версии', + description: 'Всегда обновляйте до последней версии', + }, + }, + upgradeMode: { + partial: 'Только выбрано', + all: 'Обновить все', + exclude: 'Исключить выбранное', + }, + upgradeModePlaceholder: { + partial: 'Только выбранные плагины будут автоматически обновляться. В данный момент плагины не выбраны, поэтому никакие плагины не будут автоматически обновляться.', + exclude: 'Выбранные плагины не будут обновляться автоматически', + }, + operation: { + select: 'Выберите плагины', + clearAll: 'Очистить все', + }, + pluginDowngradeWarning: { + exclude: 'Исключить из автообновления', + title: 'Понижение версии плагина', + downgrade: 'Все равно понизьте версию', + description: 'Автообновление в данный момент включено для этого плагина. Понижение версии может привести к тому, что ваши изменения будут перезаписаны во время следующего автоматического обновления.', + }, + noPluginPlaceholder: { + noFound: 'Плагины не найдены', + noInstalled: 'Нет установленных плагинов', + }, + updateTimeTitle: 'Время обновления', + updateTime: 'Время обновления', + automaticUpdates: 'Автоматические обновления', + updateSettings: 'Обновить настройки', + nextUpdateTime: 'Следующее автообновление: {{time}}', + specifyPluginsToUpdate: 'Укажите плагины для обновления', + excludeUpdate: 'Следующие {{num}} плагины не будут обновляться автоматически', + partialUPdate: 'Только следующие {{num}} плагины будут обновляться автоматически', + changeTimezone: 'Чтобы изменить часовой пояс, перейдите в Настройки', + }, } export default translation diff --git a/web/i18n/sl-SI/plugin.ts b/web/i18n/sl-SI/plugin.ts index 5ed6d9c0a7..049a80f859 100644 --- a/web/i18n/sl-SI/plugin.ts +++ b/web/i18n/sl-SI/plugin.ts @@ -248,6 +248,55 @@ const translation = { useApiAuthDesc: 'Po konfiguraciji poverilnic lahko vsi člani v delovnem prostoru uporabljajo to orodje pri orkestraciji aplikacij.', }, deprecated: 'Zastaran', + autoUpdate: { + strategy: { + disabled: { + name: 'Onemogočeno', + description: 'Vtičniki se ne bodo samodejno posodobili', + }, + fixOnly: { + name: 'Popravi samo', + selectedDescription: 'Samodejno posodabljanje samo za različice popravkov', + }, + latest: { + selectedDescription: 'Vedno posodobite na najnovejšo različico', + name: 'Najnovejši', + description: 'Vedno posodobite na najnovejšo različico', + }, + }, + upgradeMode: { + partial: 'Samo izbrano', + exclude: 'Izključi izbrano', + all: 'Posodobi vse', + }, + upgradeModePlaceholder: { + exclude: 'Izbrani vtičniki se ne bodo samodejno posodabljali.', + partial: 'Samo izbrani vtičniki se bodo samodejno posodabljali. Trenutno ni izbranih nobenih vtičnikov, zato se nobeni vtičniki ne bodo samodejno posodobili.', + }, + operation: { + select: 'Izberi vtičnike', + clearAll: 'Počisti vse', + }, + pluginDowngradeWarning: { + downgrade: 'Kljub temu narediti nižjo različico', + exclude: 'Izključi iz samodejnega posodabljanja', + title: 'Zmanjšanje različice vtičnika', + description: 'Samodejno posodabljanje je trenutno omogočeno za ta vtičnik. Zmanjšanje različice lahko povzroči, da bodo vaše spremembe prepisane med naslednjim samodejnim posodabljanjem.', + }, + noPluginPlaceholder: { + noFound: 'Nobeni vtičniki niso bili najdeni', + noInstalled: 'Nobenih vtičnikov ni nameščenih', + }, + updateTimeTitle: 'Čas posodobitve', + specifyPluginsToUpdate: 'Določite vtičnike za posodobitev', + updateTime: 'Čas posodobitve', + nextUpdateTime: 'Naslednje samodejno posodabljanje: {{time}}', + automaticUpdates: 'Samodejna posodobitev', + excludeUpdate: 'Naslednjih {{num}} razširitev ne bo samodejno posodobljenih', + changeTimezone: 'Za spremembo časovnega pasu pojdite v Nastavitve', + partialUPdate: 'Samo naslednjih {{num}} vtičnikov se bo samodejno posodabljalo.', + updateSettings: 'Posodobi nastavitve', + }, } export default translation diff --git a/web/i18n/th-TH/plugin.ts b/web/i18n/th-TH/plugin.ts index b152f5848f..6a53350cad 100644 --- a/web/i18n/th-TH/plugin.ts +++ b/web/i18n/th-TH/plugin.ts @@ -248,6 +248,55 @@ const translation = { clientInfo: 'เนื่องจากไม่พบความลับของลูกค้าสำหรับผู้ให้บริการเครื่องมือนี้ จำเป็นต้องตั้งค่าแบบแมนนวล สำหรับ redirect_uri กรุณาใช้', }, deprecated: 'เลิกใช้', + autoUpdate: { + strategy: { + disabled: { + name: 'ผู้พิการ', + description: 'ปลั๊กอินจะไม่อัปเดตอัตโนมัติ', + }, + fixOnly: { + name: 'ซ่อมเฉพาะ', + selectedDescription: 'อัปเดตอัตโนมัติเฉพาะเวอร์ชันแพตช์เท่านั้น', + }, + latest: { + name: 'ล่าสุด', + selectedDescription: 'อัปเดตเป็นเวอร์ชันล่าสุดเสมอ', + description: 'อัปเดตเป็นเวอร์ชันล่าสุดเสมอ', + }, + }, + upgradeMode: { + partial: 'เฉพาะที่เลือกไว้', + exclude: 'ยกเว้นที่เลือกไว้', + all: 'อัปเดตทั้งหมด', + }, + upgradeModePlaceholder: { + exclude: 'ปลั๊กอินที่เลือกจะไม่อัปเดตอัตโนมัติ', + partial: 'เฉพาะปลั๊กอินที่เลือกจะอัปเดตโดยอัตโนมัติ ขณะนี้ไม่มีปลั๊กอินใดที่ถูกเลือก ดังนั้นจะไม่มีปลั๊กอินใดที่อัปเดตโดยอัตโนมัติ', + }, + operation: { + clearAll: 'ล้างทั้งหมด', + select: 'เลือกปลั๊กอิน', + }, + pluginDowngradeWarning: { + title: 'การลดเวอร์ชันปลั๊กอิน', + downgrade: 'ลดระดับอยู่ดี', + exclude: 'ไม่รวมในการอัปเดตอัตโนมัติ', + description: 'ฟีเจอร์การอัปเดตอัตโนมัติเปิดใช้งานอยู่สำหรับปลั๊กอินนี้ การลดระดับเวอร์ชันอาจทำให้การเปลี่ยนแปลงของคุณหายไปในระหว่างการอัปเดตอัตโนมัติต่อไป', + }, + noPluginPlaceholder: { + noInstalled: 'ไม่มีปลั๊กอินติดตั้ง', + noFound: 'ไม่พบปลั๊กอิน', + }, + specifyPluginsToUpdate: 'ระบุปลั๊กอินที่จะแ atualizar', + updateTime: 'เวลาที่อัปเดต', + updateTimeTitle: 'เวลาที่อัปเดต', + updateSettings: 'อัปเดตการตั้งค่า', + nextUpdateTime: 'การอัปเดตอัตโนมัติครั้งถัดไป: {{time}}', + automaticUpdates: 'การอัปเดตอัตโนมัติ', + excludeUpdate: 'ปลั๊กอิน {{num}} ต่อไปนี้จะไม่อัพเดตอัตโนมัติ', + partialUPdate: 'ปลั๊กอิน {{num}} ตัวต่อไปนี้จะอัปเดตให้อัตโนมัติเท่านั้น', + changeTimezone: 'ในการเปลี่ยนเขตเวลา ให้ไปที่ การตั้งค่า', + }, } export default translation diff --git a/web/i18n/tr-TR/plugin.ts b/web/i18n/tr-TR/plugin.ts index 40799328e6..4c2b5510d2 100644 --- a/web/i18n/tr-TR/plugin.ts +++ b/web/i18n/tr-TR/plugin.ts @@ -248,6 +248,55 @@ const translation = { clientInfo: 'Bu araç sağlayıcı için sistem istemci gizlilikleri bulunmadığından, manuel olarak ayar yapılması gerekmektedir. redirect_uri için lütfen şu adresi kullanın', }, deprecated: 'Kaldırılmış', + autoUpdate: { + strategy: { + disabled: { + name: 'Engelli', + description: 'Eklentiler otomatik olarak güncellenmeyecek', + }, + fixOnly: { + selectedDescription: 'Sadece yamanın versiyonları için otomatik güncelleme', + name: 'Sadece Düzelt', + }, + latest: { + name: 'Son', + selectedDescription: 'Her zaman en son sürüme güncelle', + description: 'Her zaman en son sürüme güncelle', + }, + }, + upgradeMode: { + partial: 'Sadece seçilen', + all: 'Hepsini güncelle', + exclude: 'Seçilenleri hariç tut', + }, + upgradeModePlaceholder: { + exclude: 'Seçilen eklentiler otomatik olarak güncellenmeyecek.', + partial: 'Sadece seçilen eklentiler otomatik olarak güncellenecek. Şu anda hiçbir eklenti seçilmedi, bu yüzden hiçbir eklenti otomatik olarak güncellenmeyecek.', + }, + operation: { + select: 'Eklentileri seçin', + clearAll: 'Hepsini temizle', + }, + pluginDowngradeWarning: { + downgrade: 'Her durumda düşürme', + title: 'Eklenti Düşürme', + exclude: 'Otomatik güncellemeden hariç tut', + description: 'Bu eklenti için otomatik güncelleme şu anda etkin. Sürümün düşürülmesi, bir sonraki otomatik güncelleme sırasında değişikliklerinizin üzerine yazılmasına neden olabilir.', + }, + noPluginPlaceholder: { + noInstalled: 'Hiçbir eklenti yüklenmemiş', + noFound: 'Hiçbir eklenti bulunamadı', + }, + automaticUpdates: 'Otomatik güncellemeler', + updateTime: 'Güncelleme zamanı', + updateTimeTitle: 'Güncelleme zamanı', + updateSettings: 'Ayarları Güncelle', + nextUpdateTime: 'Sonraki otomatik güncelleme: {{time}}', + specifyPluginsToUpdate: 'Güncellemek için eklentileri belirtin', + excludeUpdate: 'Aşağıdaki {{num}} eklenti otomatik olarak güncellenmeyecek', + changeTimezone: 'Zaman dilimini değiştirmek için Ayarlar sekmesine gidin', + partialUPdate: 'Sadece aşağıdaki {{num}} eklenti otomatik olarak güncellenecek', + }, } export default translation diff --git a/web/i18n/uk-UA/plugin.ts b/web/i18n/uk-UA/plugin.ts index 76c717cd47..877d7843ff 100644 --- a/web/i18n/uk-UA/plugin.ts +++ b/web/i18n/uk-UA/plugin.ts @@ -248,6 +248,55 @@ const translation = { useApiAuthDesc: 'Після налаштування облікових даних усі учасники робочого простору можуть використовувати цей інструмент під час оркестрації додатків.', }, deprecated: 'Застарілий', + autoUpdate: { + strategy: { + disabled: { + name: 'Вимкнено', + description: 'Плагіни не будуть автоматично оновлюватися', + }, + fixOnly: { + name: 'Виправити тільки', + selectedDescription: 'Автоматичне оновлення лише для версій патчів', + }, + latest: { + name: 'Останні', + selectedDescription: 'Завжди оновлюйте до останньої версії', + description: 'Завжди оновлюйте до останньої версії', + }, + }, + upgradeMode: { + all: 'Оновити все', + partial: 'Тільки вибрані', + exclude: 'Виключити вибране', + }, + upgradeModePlaceholder: { + exclude: 'Вибрані плагіни не будуть оновлюватися автоматично', + partial: 'Тільки вибрані плагіни будуть автоматично оновлюватись. Наразі жоден з плагінів не вибрано, тому жоден плагін не буде автоматично оновлений.', + }, + operation: { + clearAll: 'Очистити все', + select: 'Виберіть плагіни', + }, + pluginDowngradeWarning: { + downgrade: 'Все одно знизити версію', + title: 'Пониження плагіна', + exclude: 'Виключити з автоматичного оновлення', + description: 'Автоматичне оновлення наразі увімкнене для цього плагіна. Пониження версії може призвести до того, що ваші зміни будуть перезаписані під час наступного автоматичного оновлення.', + }, + noPluginPlaceholder: { + noFound: 'Плагіни не були знайдені', + noInstalled: 'Жодних плагінів не встановлено', + }, + updateTime: 'Час оновлення', + automaticUpdates: 'Автоматичні оновлення', + updateTimeTitle: 'Час оновлення', + nextUpdateTime: 'Наступне автоматичне оновлення: {{time}}', + specifyPluginsToUpdate: 'Вкажіть плагіни для оновлення', + excludeUpdate: 'Наступні {{num}} плагіни не будуть автоматично оновлюватися', + updateSettings: 'Оновити налаштування', + changeTimezone: 'Щоб змінити часовий пояс, перейдіть до Налаштування', + partialUPdate: 'Тільки наступні {{num}} плагіни будуть автоматично оновлюватися', + }, } export default translation diff --git a/web/i18n/vi-VN/plugin.ts b/web/i18n/vi-VN/plugin.ts index 9760eafd0c..677d90e6a7 100644 --- a/web/i18n/vi-VN/plugin.ts +++ b/web/i18n/vi-VN/plugin.ts @@ -248,6 +248,55 @@ const translation = { clientInfo: 'Vì không tìm thấy bí mật khách hàng hệ thống cho nhà cung cấp công cụ này, cần thiết lập thủ công, đối với redirect_uri, vui lòng sử dụng', }, deprecated: 'Đã bị ngưng sử dụng', + autoUpdate: { + strategy: { + disabled: { + name: 'Khuyết tật', + description: 'Các plugin sẽ không tự động cập nhật', + }, + fixOnly: { + name: 'Chỉ sửa chữa', + selectedDescription: 'Tự động cập nhật chỉ cho các phiên bản bản vá', + }, + latest: { + name: 'Mới nhất', + description: 'Luôn cập nhật lên phiên bản mới nhất', + selectedDescription: 'Luôn cập nhật lên phiên bản mới nhất', + }, + }, + upgradeMode: { + partial: 'Chỉ được chọn', + exclude: 'Loại trừ đã chọn', + all: 'Cập nhật tất cả', + }, + upgradeModePlaceholder: { + exclude: 'Các plugin được chọn sẽ không tự động cập nhật', + partial: 'Chỉ những plugin được chọn mới tự động cập nhật. Hiện tại không có plugin nào được chọn, vì vậy sẽ không có plugin nào tự động cập nhật.', + }, + operation: { + clearAll: 'Xóa tất cả', + select: 'Chọn plugin', + }, + pluginDowngradeWarning: { + exclude: 'Loại trừ khỏi cập nhật tự động', + downgrade: 'Giảm cấp vẫn vậy', + description: 'Chức năng tự động cập nhật hiện đang được bật cho plugin này. Việc hạ cấp phiên bản có thể khiến các thay đổi của bạn bị ghi đè trong lần cập nhật tự động tiếp theo.', + title: 'Hạ cấp Plugin', + }, + noPluginPlaceholder: { + noInstalled: 'Không có plugin nào được cài đặt', + noFound: 'Không tìm thấy plugin nào', + }, + updateTimeTitle: 'Thời gian cập nhật', + updateTime: 'Thời gian cập nhật', + automaticUpdates: 'Cập nhật tự động', + nextUpdateTime: 'Cập nhật tự động tiếp theo: {{time}}', + specifyPluginsToUpdate: 'Chỉ định các plugin để cập nhật', + excludeUpdate: 'Các plugin {{num}} sau đây sẽ không tự động cập nhật', + updateSettings: 'Cập nhật cài đặt', + partialUPdate: 'Chỉ có {{num}} plugin sau đây sẽ tự động cập nhật', + changeTimezone: 'Để thay đổi múi giờ, hãy vào Cài đặt', + }, } export default translation diff --git a/web/i18n/zh-Hant/plugin.ts b/web/i18n/zh-Hant/plugin.ts index 24b0ef997e..0d0e1f8782 100644 --- a/web/i18n/zh-Hant/plugin.ts +++ b/web/i18n/zh-Hant/plugin.ts @@ -248,6 +248,55 @@ const translation = { useApiAuthDesc: '配置完憑證後,工作區內的所有成員在協調應用程式時都可以使用此工具。', }, deprecated: '不推薦使用的', + autoUpdate: { + strategy: { + disabled: { + description: '插件將不會自動更新', + name: '殘疾的', + }, + fixOnly: { + name: '僅修理', + selectedDescription: '僅限於修補版本的自動更新', + }, + latest: { + description: '始終更新至最新版本', + name: '最新', + selectedDescription: '始終更新至最新版本', + }, + }, + upgradeMode: { + all: '更新所有', + exclude: '排除選定的', + partial: '僅選擇', + }, + upgradeModePlaceholder: { + partial: '只有選定的插件會自動更新。目前未選定任何插件,因此不會自動更新任何插件。', + exclude: '選定的插件將不會自動更新', + }, + operation: { + select: '選擇插件', + clearAll: '清除所有', + }, + pluginDowngradeWarning: { + downgrade: '無論如何降級', + title: '插件降級', + exclude: '排除自動更新', + description: '這個插件目前已啟用自動更新。降級版本可能會導致您的更改在下一次自動更新時被覆蓋。', + }, + noPluginPlaceholder: { + noInstalled: '沒有安裝插件', + noFound: '未找到任何外掛', + }, + automaticUpdates: '自動更新', + updateTime: '更新時間', + updateTimeTitle: '更新時間', + updateSettings: '更新設定', + partialUPdate: '只有以下 {{num}} 個插件將自動更新', + excludeUpdate: '以下 {{num}} 個插件將不會自動更新', + nextUpdateTime: '下次自動更新:{{time}}', + specifyPluginsToUpdate: '指定要更新的插件', + changeTimezone: '要更改時區,請前往設定', + }, } export default translation From a366de26c4dae386438141f177fb48e95a24bc0b Mon Sep 17 00:00:00 2001 From: Wu Tianwei <30284043+WTW0313@users.noreply.github.com> Date: Wed, 23 Jul 2025 16:04:46 +0800 Subject: [PATCH 09/10] feat: performance optimization (#22810) --- .../[appId]/overview/tracing/panel.tsx | 66 ++++++++----- web/app/components/i18n.tsx | 19 +++- .../plugins/base/deprecation-notice.tsx | 4 +- web/app/dev-only/i18n-checker/page.tsx | 19 +++- web/app/signin/invite-settings/page.tsx | 2 +- web/context/i18n.ts | 6 +- web/i18n/README.md | 2 +- web/i18n/de-DE/{share-app.ts => share.ts} | 0 web/i18n/en-US/{share-app.ts => share.ts} | 0 web/i18n/es-ES/{share-app.ts => share.ts} | 0 web/i18n/fa-IR/{share-app.ts => share.ts} | 0 web/i18n/fr-FR/{share-app.ts => share.ts} | 0 web/i18n/hi-IN/{share-app.ts => share.ts} | 0 web/i18n/i18next-config.ts | 95 ++++++++++--------- web/i18n/index.ts | 4 +- web/i18n/it-IT/{share-app.ts => share.ts} | 0 web/i18n/ja-JP/{share-app.ts => share.ts} | 0 web/i18n/ko-KR/{share-app.ts => share.ts} | 0 web/i18n/pl-PL/{share-app.ts => share.ts} | 0 web/i18n/pt-BR/{share-app.ts => share.ts} | 0 web/i18n/ro-RO/{share-app.ts => share.ts} | 0 web/i18n/ru-RU/{share-app.ts => share.ts} | 0 web/i18n/sl-SI/{share-app.ts => share.ts} | 0 web/i18n/th-TH/{share-app.ts => share.ts} | 0 web/i18n/tr-TR/{share-app.ts => share.ts} | 0 web/i18n/uk-UA/{share-app.ts => share.ts} | 0 web/i18n/vi-VN/{share-app.ts => share.ts} | 0 web/i18n/zh-Hans/{share-app.ts => share.ts} | 0 web/i18n/zh-Hant/{share-app.ts => share.ts} | 0 web/utils/format.ts | 4 - 30 files changed, 138 insertions(+), 83 deletions(-) rename web/i18n/de-DE/{share-app.ts => share.ts} (100%) rename web/i18n/en-US/{share-app.ts => share.ts} (100%) rename web/i18n/es-ES/{share-app.ts => share.ts} (100%) rename web/i18n/fa-IR/{share-app.ts => share.ts} (100%) rename web/i18n/fr-FR/{share-app.ts => share.ts} (100%) rename web/i18n/hi-IN/{share-app.ts => share.ts} (100%) rename web/i18n/it-IT/{share-app.ts => share.ts} (100%) rename web/i18n/ja-JP/{share-app.ts => share.ts} (100%) rename web/i18n/ko-KR/{share-app.ts => share.ts} (100%) rename web/i18n/pl-PL/{share-app.ts => share.ts} (100%) rename web/i18n/pt-BR/{share-app.ts => share.ts} (100%) rename web/i18n/ro-RO/{share-app.ts => share.ts} (100%) rename web/i18n/ru-RU/{share-app.ts => share.ts} (100%) rename web/i18n/sl-SI/{share-app.ts => share.ts} (100%) rename web/i18n/th-TH/{share-app.ts => share.ts} (100%) rename web/i18n/tr-TR/{share-app.ts => share.ts} (100%) rename web/i18n/uk-UA/{share-app.ts => share.ts} (100%) rename web/i18n/vi-VN/{share-app.ts => share.ts} (100%) rename web/i18n/zh-Hans/{share-app.ts => share.ts} (100%) rename web/i18n/zh-Hant/{share-app.ts => share.ts} (100%) diff --git a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/panel.tsx b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/panel.tsx index 8bf18904be..d082523222 100644 --- a/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/panel.tsx +++ b/web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/panel.tsx @@ -83,27 +83,50 @@ const Panel: FC = () => { const hasConfiguredTracing = !!(langSmithConfig || langFuseConfig || opikConfig || weaveConfig || arizeConfig || phoenixConfig || aliyunConfig) const fetchTracingConfig = async () => { - const { tracing_config: arizeConfig, has_not_configured: arizeHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.arize }) - if (!arizeHasNotConfig) - setArizeConfig(arizeConfig as ArizeConfig) - const { tracing_config: phoenixConfig, has_not_configured: phoenixHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.phoenix }) - if (!phoenixHasNotConfig) - setPhoenixConfig(phoenixConfig as PhoenixConfig) - const { tracing_config: langSmithConfig, has_not_configured: langSmithHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.langSmith }) - if (!langSmithHasNotConfig) - setLangSmithConfig(langSmithConfig as LangSmithConfig) - const { tracing_config: langFuseConfig, has_not_configured: langFuseHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.langfuse }) - if (!langFuseHasNotConfig) - setLangFuseConfig(langFuseConfig as LangFuseConfig) - const { tracing_config: opikConfig, has_not_configured: OpikHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.opik }) - if (!OpikHasNotConfig) - setOpikConfig(opikConfig as OpikConfig) - const { tracing_config: weaveConfig, has_not_configured: weaveHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.weave }) - if (!weaveHasNotConfig) - setWeaveConfig(weaveConfig as WeaveConfig) - const { tracing_config: aliyunConfig, has_not_configured: aliyunHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.aliyun }) - if (!aliyunHasNotConfig) - setAliyunConfig(aliyunConfig as AliyunConfig) + const getArizeConfig = async () => { + const { tracing_config: arizeConfig, has_not_configured: arizeHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.arize }) + if (!arizeHasNotConfig) + setArizeConfig(arizeConfig as ArizeConfig) + } + const getPhoenixConfig = async () => { + const { tracing_config: phoenixConfig, has_not_configured: phoenixHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.phoenix }) + if (!phoenixHasNotConfig) + setPhoenixConfig(phoenixConfig as PhoenixConfig) + } + const getLangSmithConfig = async () => { + const { tracing_config: langSmithConfig, has_not_configured: langSmithHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.langSmith }) + if (!langSmithHasNotConfig) + setLangSmithConfig(langSmithConfig as LangSmithConfig) + } + const getLangFuseConfig = async () => { + const { tracing_config: langFuseConfig, has_not_configured: langFuseHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.langfuse }) + if (!langFuseHasNotConfig) + setLangFuseConfig(langFuseConfig as LangFuseConfig) + } + const getOpikConfig = async () => { + const { tracing_config: opikConfig, has_not_configured: OpikHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.opik }) + if (!OpikHasNotConfig) + setOpikConfig(opikConfig as OpikConfig) + } + const getWeaveConfig = async () => { + const { tracing_config: weaveConfig, has_not_configured: weaveHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.weave }) + if (!weaveHasNotConfig) + setWeaveConfig(weaveConfig as WeaveConfig) + } + const getAliyunConfig = async () => { + const { tracing_config: aliyunConfig, has_not_configured: aliyunHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.aliyun }) + if (!aliyunHasNotConfig) + setAliyunConfig(aliyunConfig as AliyunConfig) + } + Promise.all([ + getArizeConfig(), + getPhoenixConfig(), + getLangSmithConfig(), + getLangFuseConfig(), + getOpikConfig(), + getWeaveConfig(), + getAliyunConfig(), + ]) } const handleTracingConfigUpdated = async (provider: TracingProvider) => { @@ -155,7 +178,6 @@ const Panel: FC = () => { await fetchTracingConfig() setLoaded() })() - // eslint-disable-next-line react-hooks/exhaustive-deps }, []) const [controlShowPopup, setControlShowPopup] = useState(0) diff --git a/web/app/components/i18n.tsx b/web/app/components/i18n.tsx index f04f8d6cbe..374b1f608f 100644 --- a/web/app/components/i18n.tsx +++ b/web/app/components/i18n.tsx @@ -1,10 +1,13 @@ 'use client' import type { FC } from 'react' -import React, { useEffect } from 'react' +import React, { useEffect, useState } from 'react' import I18NContext from '@/context/i18n' import type { Locale } from '@/i18n' import { setLocaleOnClient } from '@/i18n' +import Loading from './base/loading' +import { usePrefetchQuery } from '@tanstack/react-query' +import { getSystemFeatures } from '@/service/common' export type II18nProps = { locale: Locale @@ -14,10 +17,22 @@ const I18n: FC = ({ locale, children, }) => { + const [loading, setLoading] = useState(true) + + usePrefetchQuery({ + queryKey: ['systemFeatures'], + queryFn: getSystemFeatures, + }) + useEffect(() => { - setLocaleOnClient(locale, false) + setLocaleOnClient(locale, false).then(() => { + setLoading(false) + }) }, [locale]) + if (loading) + return
    + return ( = ({ const deprecatedReasonKey = useMemo(() => { if (!deprecatedReason) return '' - return snakeCase2CamelCase(deprecatedReason) + return camelCase(deprecatedReason) }, [deprecatedReason]) // Check if the deprecatedReasonKey exists in i18n diff --git a/web/app/dev-only/i18n-checker/page.tsx b/web/app/dev-only/i18n-checker/page.tsx index 5ed0c86b82..d821979bb9 100644 --- a/web/app/dev-only/i18n-checker/page.tsx +++ b/web/app/dev-only/i18n-checker/page.tsx @@ -1,13 +1,19 @@ 'use client' -import { resources } from '@/i18n/i18next-config' -import { useEffect, useState } from 'react' +import { loadLangResources } from '@/i18n/i18next-config' +import { useCallback, useEffect, useState } from 'react' import cn from '@/utils/classnames' +import { LanguagesSupported } from '@/i18n/language' export default function I18nTest() { const [langs, setLangs] = useState([]) + const getLangs = useCallback(async () => { + const langs = await genLangs() + setLangs(langs) + }, []) + useEffect(() => { - setLangs(genLangs()) + getLangs() }, []) return ( @@ -107,10 +113,15 @@ export default function I18nTest() { ) } -function genLangs() { +async function genLangs() { const langs_: Lang[] = [] let en!: Lang + const resources: Record = {} + // Initialize empty resource object + for (const lang of LanguagesSupported) + resources[lang] = await loadLangResources(lang) + for (const [key, value] of Object.entries(resources)) { const keys = getNestedKeys(value.translation) const lang: Lang = { diff --git a/web/app/signin/invite-settings/page.tsx b/web/app/signin/invite-settings/page.tsx index 1ff1c7d671..ea35900968 100644 --- a/web/app/signin/invite-settings/page.tsx +++ b/web/app/signin/invite-settings/page.tsx @@ -57,7 +57,7 @@ export default function InviteSettingsPage() { if (res.result === 'success') { localStorage.setItem('console_token', res.data.access_token) localStorage.setItem('refresh_token', res.data.refresh_token) - setLocaleOnClient(language, false) + await setLocaleOnClient(language, false) router.replace('/apps') } } diff --git a/web/context/i18n.ts b/web/context/i18n.ts index ef53a4b481..932beb9936 100644 --- a/web/context/i18n.ts +++ b/web/context/i18n.ts @@ -9,13 +9,15 @@ import { noop } from 'lodash-es' type II18NContext = { locale: Locale i18n: Record - setLocaleOnClient: (_lang: Locale, _reloadPage?: boolean) => void + setLocaleOnClient: (_lang: Locale, _reloadPage?: boolean) => Promise } const I18NContext = createContext({ locale: 'en-US', i18n: {}, - setLocaleOnClient: noop, + setLocaleOnClient: async (_lang: Locale, _reloadPage?: boolean) => { + noop() + }, }) export const useI18N = () => useContext(I18NContext) diff --git a/web/i18n/README.md b/web/i18n/README.md index b81ffbf4c3..5e7058d829 100644 --- a/web/i18n/README.md +++ b/web/i18n/README.md @@ -28,7 +28,7 @@ This directory contains the internationalization (i18n) files for this project. │   ├── [ 52] layout.ts │   ├── [2.3K] login.ts │   ├── [ 52] register.ts -│   ├── [2.5K] share-app.ts +│   ├── [2.5K] share.ts │   └── [2.8K] tools.ts ├── [1.6K] i18next-config.ts ├── [ 634] index.ts diff --git a/web/i18n/de-DE/share-app.ts b/web/i18n/de-DE/share.ts similarity index 100% rename from web/i18n/de-DE/share-app.ts rename to web/i18n/de-DE/share.ts diff --git a/web/i18n/en-US/share-app.ts b/web/i18n/en-US/share.ts similarity index 100% rename from web/i18n/en-US/share-app.ts rename to web/i18n/en-US/share.ts diff --git a/web/i18n/es-ES/share-app.ts b/web/i18n/es-ES/share.ts similarity index 100% rename from web/i18n/es-ES/share-app.ts rename to web/i18n/es-ES/share.ts diff --git a/web/i18n/fa-IR/share-app.ts b/web/i18n/fa-IR/share.ts similarity index 100% rename from web/i18n/fa-IR/share-app.ts rename to web/i18n/fa-IR/share.ts diff --git a/web/i18n/fr-FR/share-app.ts b/web/i18n/fr-FR/share.ts similarity index 100% rename from web/i18n/fr-FR/share-app.ts rename to web/i18n/fr-FR/share.ts diff --git a/web/i18n/hi-IN/share-app.ts b/web/i18n/hi-IN/share.ts similarity index 100% rename from web/i18n/hi-IN/share-app.ts rename to web/i18n/hi-IN/share.ts diff --git a/web/i18n/i18next-config.ts b/web/i18n/i18next-config.ts index 8c5583bf9a..8c5bd375a7 100644 --- a/web/i18n/i18next-config.ts +++ b/web/i18n/i18next-config.ts @@ -1,65 +1,74 @@ 'use client' import i18n from 'i18next' +import { camelCase } from 'lodash-es' import { initReactI18next } from 'react-i18next' -import { LanguagesSupported } from '@/i18n/language' - -const requireSilent = (lang: string) => { +const requireSilent = async (lang: string, namespace: string) => { let res try { - res = require(`./${lang}/education`).default + res = (await import(`./${lang}/${namespace}`)).default } catch { - res = require('./en-US/education').default + res = (await import(`./en-US/${namespace}`)).default } return res } -const loadLangResources = (lang: string) => ({ - translation: { - common: require(`./${lang}/common`).default, - layout: require(`./${lang}/layout`).default, - login: require(`./${lang}/login`).default, - register: require(`./${lang}/register`).default, - app: require(`./${lang}/app`).default, - appOverview: require(`./${lang}/app-overview`).default, - appDebug: require(`./${lang}/app-debug`).default, - appApi: require(`./${lang}/app-api`).default, - appLog: require(`./${lang}/app-log`).default, - appAnnotation: require(`./${lang}/app-annotation`).default, - share: require(`./${lang}/share-app`).default, - dataset: require(`./${lang}/dataset`).default, - datasetDocuments: require(`./${lang}/dataset-documents`).default, - datasetHitTesting: require(`./${lang}/dataset-hit-testing`).default, - datasetSettings: require(`./${lang}/dataset-settings`).default, - datasetCreation: require(`./${lang}/dataset-creation`).default, - explore: require(`./${lang}/explore`).default, - billing: require(`./${lang}/billing`).default, - custom: require(`./${lang}/custom`).default, - tools: require(`./${lang}/tools`).default, - workflow: require(`./${lang}/workflow`).default, - runLog: require(`./${lang}/run-log`).default, - plugin: require(`./${lang}/plugin`).default, - pluginTags: require(`./${lang}/plugin-tags`).default, - time: require(`./${lang}/time`).default, - education: requireSilent(lang), - }, -}) +const NAMESPACES = [ + 'app-annotation', + 'app-api', + 'app-debug', + 'app-log', + 'app-overview', + 'app', + 'billing', + 'common', + 'custom', + 'dataset-creation', + 'dataset-documents', + 'dataset-hit-testing', + 'dataset-settings', + 'dataset', + 'education', + 'explore', + 'layout', + 'login', + 'plugin-tags', + 'plugin', + 'register', + 'run-log', + 'share', + 'time', + 'tools', + 'workflow', +] -type Resource = Record> -// Automatically generate the resources object -export const resources = LanguagesSupported.reduce((acc, lang) => { - acc[lang] = loadLangResources(lang) - return acc -}, {}) +export const loadLangResources = async (lang: string) => { + const modules = await Promise.all(NAMESPACES.map(ns => requireSilent(lang, ns))) + const resources = modules.reduce((acc, mod, index) => { + acc[camelCase(NAMESPACES[index])] = mod + return acc + }, {} as Record) + return { + translation: resources, + } +} i18n.use(initReactI18next) .init({ lng: undefined, fallbackLng: 'en-US', - resources, }) -export const changeLanguage = i18n.changeLanguage +export const changeLanguage = async (lng?: string) => { + const resolvedLng = lng ?? 'en-US' + const resources = { + [resolvedLng]: await loadLangResources(resolvedLng), + } + if (!i18n.hasResourceBundle(resolvedLng, 'translation')) + i18n.addResourceBundle(resolvedLng, 'translation', resources[resolvedLng].translation, true, true) + await i18n.changeLanguage(resolvedLng) +} + export default i18n diff --git a/web/i18n/index.ts b/web/i18n/index.ts index eb49759097..27ed3022ad 100644 --- a/web/i18n/index.ts +++ b/web/i18n/index.ts @@ -11,9 +11,9 @@ export const i18n = { export type Locale = typeof i18n['locales'][number] -export const setLocaleOnClient = (locale: Locale, reloadPage = true) => { +export const setLocaleOnClient = async (locale: Locale, reloadPage = true) => { Cookies.set(LOCALE_COOKIE_NAME, locale, { expires: 365 }) - changeLanguage(locale) + await changeLanguage(locale) reloadPage && location.reload() } diff --git a/web/i18n/it-IT/share-app.ts b/web/i18n/it-IT/share.ts similarity index 100% rename from web/i18n/it-IT/share-app.ts rename to web/i18n/it-IT/share.ts diff --git a/web/i18n/ja-JP/share-app.ts b/web/i18n/ja-JP/share.ts similarity index 100% rename from web/i18n/ja-JP/share-app.ts rename to web/i18n/ja-JP/share.ts diff --git a/web/i18n/ko-KR/share-app.ts b/web/i18n/ko-KR/share.ts similarity index 100% rename from web/i18n/ko-KR/share-app.ts rename to web/i18n/ko-KR/share.ts diff --git a/web/i18n/pl-PL/share-app.ts b/web/i18n/pl-PL/share.ts similarity index 100% rename from web/i18n/pl-PL/share-app.ts rename to web/i18n/pl-PL/share.ts diff --git a/web/i18n/pt-BR/share-app.ts b/web/i18n/pt-BR/share.ts similarity index 100% rename from web/i18n/pt-BR/share-app.ts rename to web/i18n/pt-BR/share.ts diff --git a/web/i18n/ro-RO/share-app.ts b/web/i18n/ro-RO/share.ts similarity index 100% rename from web/i18n/ro-RO/share-app.ts rename to web/i18n/ro-RO/share.ts diff --git a/web/i18n/ru-RU/share-app.ts b/web/i18n/ru-RU/share.ts similarity index 100% rename from web/i18n/ru-RU/share-app.ts rename to web/i18n/ru-RU/share.ts diff --git a/web/i18n/sl-SI/share-app.ts b/web/i18n/sl-SI/share.ts similarity index 100% rename from web/i18n/sl-SI/share-app.ts rename to web/i18n/sl-SI/share.ts diff --git a/web/i18n/th-TH/share-app.ts b/web/i18n/th-TH/share.ts similarity index 100% rename from web/i18n/th-TH/share-app.ts rename to web/i18n/th-TH/share.ts diff --git a/web/i18n/tr-TR/share-app.ts b/web/i18n/tr-TR/share.ts similarity index 100% rename from web/i18n/tr-TR/share-app.ts rename to web/i18n/tr-TR/share.ts diff --git a/web/i18n/uk-UA/share-app.ts b/web/i18n/uk-UA/share.ts similarity index 100% rename from web/i18n/uk-UA/share-app.ts rename to web/i18n/uk-UA/share.ts diff --git a/web/i18n/vi-VN/share-app.ts b/web/i18n/vi-VN/share.ts similarity index 100% rename from web/i18n/vi-VN/share-app.ts rename to web/i18n/vi-VN/share.ts diff --git a/web/i18n/zh-Hans/share-app.ts b/web/i18n/zh-Hans/share.ts similarity index 100% rename from web/i18n/zh-Hans/share-app.ts rename to web/i18n/zh-Hans/share.ts diff --git a/web/i18n/zh-Hant/share-app.ts b/web/i18n/zh-Hant/share.ts similarity index 100% rename from web/i18n/zh-Hant/share-app.ts rename to web/i18n/zh-Hant/share.ts diff --git a/web/utils/format.ts b/web/utils/format.ts index 781ec90815..720c8f6762 100644 --- a/web/utils/format.ts +++ b/web/utils/format.ts @@ -56,7 +56,3 @@ export const downloadFile = ({ data, fileName }: { data: Blob; fileName: string a.remove() window.URL.revokeObjectURL(url) } - -export const snakeCase2CamelCase = (input: string): string => { - return input.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()) -} From 882f8bdd2cc95d1e4f4e224dad122c27b995ed56 Mon Sep 17 00:00:00 2001 From: Wu Tianwei <30284043+WTW0313@users.noreply.github.com> Date: Wed, 23 Jul 2025 17:29:03 +0800 Subject: [PATCH 10/10] fix: update @headlessui/react to version 2.2.1 (#22839) --- web/package.json | 2 +- web/pnpm-lock.yaml | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/web/package.json b/web/package.json index 4bd21e6d86..768be417ec 100644 --- a/web/package.json +++ b/web/package.json @@ -46,7 +46,7 @@ "@eslint/compat": "^1.2.4", "@floating-ui/react": "^0.26.25", "@formatjs/intl-localematcher": "^0.5.6", - "@headlessui/react": "^2.2.0", + "@headlessui/react": "2.2.1", "@heroicons/react": "^2.0.16", "@hookform/resolvers": "^3.9.0", "@lexical/code": "^0.30.0", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml index 40825aec01..eaff8c8504 100644 --- a/web/pnpm-lock.yaml +++ b/web/pnpm-lock.yaml @@ -66,8 +66,8 @@ importers: specifier: ^0.5.6 version: 0.5.10 '@headlessui/react': - specifier: ^2.2.0 - version: 2.2.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + specifier: 2.2.1 + version: 2.2.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@heroicons/react': specifier: ^2.0.16 version: 2.2.0(react@19.1.0) @@ -1634,8 +1634,8 @@ packages: resolution: {integrity: sha512-HXuHKvpHLo9/GQ/yKMmKFyS1AYL2t9pL67+GfpYZfOAb29qD80EMozi50zRZk82KmNRBcA2A0/ErjpOwUxJrNg==} engines: {node: '>=20.0.0'} - '@headlessui/react@2.2.4': - resolution: {integrity: sha512-lz+OGcAH1dK93rgSMzXmm1qKOJkBUqZf1L4M8TWLNplftQD3IkoEDdUFNfAn4ylsN6WOTVtWaLmvmaHOUk1dTA==} + '@headlessui/react@2.2.1': + resolution: {integrity: sha512-daiUqVLae8CKVjEVT19P/izW0aGK0GNhMSAeMlrDebKmoVZHcRRwbxzgtnEadUVDXyBsWo9/UH4KHeniO+0tMg==} engines: {node: '>=10'} peerDependencies: react: ^18 || ^19 || ^19.0.0-rc @@ -9496,7 +9496,7 @@ snapshots: jest-mock: 29.7.0 jest-util: 29.7.0 - '@headlessui/react@2.2.4(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + '@headlessui/react@2.2.1(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': dependencies: '@floating-ui/react': 0.26.28(react-dom@19.1.0(react@19.1.0))(react@19.1.0) '@react-aria/focus': 3.20.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0) @@ -9504,7 +9504,6 @@ snapshots: '@tanstack/react-virtual': 3.13.12(react-dom@19.1.0(react@19.1.0))(react@19.1.0) react: 19.1.0 react-dom: 19.1.0(react@19.1.0) - use-sync-external-store: 1.5.0(react@19.1.0) '@heroicons/react@2.2.0(react@19.1.0)': dependencies: