diff --git a/client/packages/lowcoder/src/i18n/locales/en.ts b/client/packages/lowcoder/src/i18n/locales/en.ts index 1f91cd585..e60828cfd 100644 --- a/client/packages/lowcoder/src/i18n/locales/en.ts +++ b/client/packages/lowcoder/src/i18n/locales/en.ts @@ -2499,7 +2499,7 @@ export const en = { "API100k": "100,000 API Calls — $100", "API1M": "1,000,000 API Calls — $1,000", "API10M": "10,000,000 API Calls — $10,000", - "UsageOverrunDesc": "When your API package runs low, we’ll alert you. Once the package is consumed, your instance remains functional but will operate at a reduced speed to prevent abuse and maintain fairness.", + "UsageOverrunDesc": "When your API package runs low, we'll alert you. Once the package is consumed, your instance remains functional but will operate at a reduced speed to prevent abuse and maintain fairness.", "UsageTopUpInfo": "You can seamlessly add additional packages anytime to ensure continuous, fast access — no service interruptions.", "AppUsageTitle": "App Usage Logs", "AppUsageIntroTitle": "Understand how your apps are used", @@ -2531,7 +2531,7 @@ export const en = { "BrandingPagesIntro2": "These touchpoints help deliver a fully branded experience even during unexpected scenarios or account transitions.", "BrandingMetaIntro": "Define standard metadata like page title and description to improve your SEO presence and brand messaging.", "BrandingHelpLinksIntro": "Add context-sensitive documentation links directly inside the app, providing just-in-time help to your users.", - "BrandingWhatsNewIntro": "Activate the 'What’s New' section to highlight updates and product announcements in a branded and visible manner.", + "BrandingWhatsNewIntro": "Activate the 'What's New' section to highlight updates and product announcements in a branded and visible manner.", "EnvironmentsIntroTitle": "Lowcoder Staging", "EnvironmentsTitle" : "Multi-Environment Infrastructure", @@ -2552,11 +2552,425 @@ export const en = { "EnvironmentsFeature2": "Deployment of applications, data sources, and configurations between environments, directly from the UI without the need for Additional CI/CD tools.", "EnvironmentsFeature3": "Environment-specific access controls and visibility rules.", "EnvironmentsFeature5": "Clear separation of concerns for staging, sandbox, and production operations.", - "apiUsage" : "API Calls.", "loadingApiUsage" : "Loading API usage data..." }, + // Environments page translations + "environments": { + "title": "Environments", + "search": "Search", + "refresh": "Refresh", + "addEnvironment": "Add Environment", + "errorLoadingEnvironments": "Error loading environments", + "noEnvironmentsFoundMatching": "No environments found matching \"{searchText}\"", + "noEnvironmentsFound": "No environments found. Create your first environment to get started.", + "environmentsTypeLabel": "{type} Environments", + "showingAllEnvironments": "Showing all {count} environments", + "unnamedEnvironment": "Unnamed Environment", + "masterEnvironment": "Master Environment", + "viewAuditLogs": "View Audit Logs", + "id": "ID", + "domain": "Domain", + "master": "Master", + "license": "License", + "apiCalls": "API Calls", + "yes": "Yes", + "no": "No", + "copyId": "Copy ID", + "copied": "Copied!", + "percentUsed": "{percent}% used", + "licenseStatus": { + "checking": "Checking...", + "licensed": "Licensed", + "unlicensed": "License Required", + "error": "Setup Required", + "unknown": "Unknown" + }, + "detail": { + "environmentNotFound": "Environment Not Found", + "returnToEnvironmentsList": "Return to Environments List", + "environmentDetail": "Environment Detail", + "environmentOverview": "Environment Overview", + "noDomainSet": "No domain set", + "environmentId": "Environment ID", + "licenseStatus": "License Status", + "licenseNeeded": "License Needed", + "setupRequired": "Setup Required", + "created": "Created", + "unknown": "Unknown", + "licenseDetails": "License Details", + "apiCallsRemaining": "API Calls Remaining", + "totalApiCallsLimit": "Total API Calls Limit", + "enterpriseEdition": "Enterprise Edition", + "active": "Active", + "inactive": "Inactive", + "licenseInformation": "License Information", + "calls": "calls", + "licenses": "Licenses", + "license": "License", + "workspaces": "Workspaces", + "userGroups": "User Groups", + "type": "Type", + "status": "Status", + "licensed": "Licensed", + "unlicensed": "Unlicensed", + "apiKey": "API Key", + "configured": "Configured", + "notSet": "Not Set", + "masterEnv": "Master Env" + }, + "unlicensed": { + "unlicensedDescription": "This environment needs a valid license to unlock its full capabilities and features. Please make sure your API Service URL is correctly configured and Plugin is installed.", + "errorDescription": "We encountered an issue while checking the license. Please review the configuration settings.", + "defaultDescription": "This environment requires license configuration to proceed.", + "contactLowcoderTeam": "Contact Lowcoder Team", + "editEnvironment": "Edit Environment", + "backToEnvironments": "Back to Environments", + "helpText": "Need assistance? Contact our team for licensing support or edit the environment configuration to resolve this issue.", + "type": "Type", + "status": "Status", + "masterEnv": "Master Env", + "licenseIssue": "License Issue", + "error": "Error", + "missing": "Missing" + }, + "error": { + "itemNotFound": "The item you're looking for doesn't exist or you don't have permission to view it." + }, + "modal": { + "createNewEnvironment": "Create New Environment", + "editEnvironment": "Edit Environment", + "cancel": "Cancel", + "createEnvironment": "Create Environment", + "saveChanges": "Save Changes", + "environmentName": "Environment Name", + "pleaseEnterName": "Please enter a name", + "nameMinLength": "Name must be at least 2 characters", + "enterEnvironmentName": "Enter environment name", + "description": "Description", + "enterDescription": "Enter description", + "stage": "Stage", + "pleaseSelectStage": "Please select a stage", + "selectStage": "Select stage", + "development": "Development (DEV)", + "testing": "Testing (TEST)", + "preProduction": "Pre-Production (PREPROD)", + "production": "Production (PROD)", + "frontendUrl": "Frontend URL", + "pleaseEnterValidUrl": "Please enter a valid URL", + "apiServiceUrl": "API Service URL", + "nodeServiceUrl": "Node Service URL", + "apiKey": "API Key", + "enterApiKey": "Enter API key", + "masterEnvironment": "Master Environment", + "alreadyMasterEnvironment": "{name} is already the Master environment", + "willBeMaster": "Will be Master", + "currentlyMaster": "Currently Master", + "configurationRequirements": "Configuration Requirements", + "configurationRequirementsDesc": "Ensure that the API Service URL is configured and correct, the API key is valid, and for license verification make sure you have both the license and plugin properly installed." + }, + "workspaces": { + "title": "Workspaces", + "subtitle": "Manage workspaces in this environment", + "refresh": "Refresh", + "errorLoadingWorkspaces": "Error loading workspaces", + "configurationIssue": "Configuration Issue", + "missingConfiguration": "Missing required configuration: API key or API service URL", + "totalWorkspaces": "Total Workspaces", + "managedWorkspaces": "Managed Workspaces", + "unmanagedWorkspaces": "Unmanaged Workspaces", + "workspace": "Workspace", + "role": "Role", + "status": "Status", + "managed": "Managed", + "unmanaged": "Unmanaged", + "actions": "Actions", + "viewAuditLogs": "View Audit Logs", + "audit": "Audit", + "searchWorkspaces": "Search workspaces by name or ID", + "showAll": "Show All", + "managedOnly": "Managed Only", + "showingResults": "Showing {count} of {total} workspaces", + "paginationTotal": "{start}-{end} of {total} workspaces", + "noWorkspacesFound": "No workspaces found in this environment" + }, + "userGroups": { + "title": "User Groups", + "subtitle": "Manage user groups in this environment", + "refresh": "Refresh", + "errorLoadingUserGroups": "Error loading user groups", + "configurationIssue": "Configuration Issue", + "missingConfiguration": "Missing required configuration: API key or API service URL", + "totalGroups": "Total Groups", + "allUsersGroups": "All Users Groups", + "developerGroups": "Developer Groups", + "customGroups": "Custom Groups", + "userGroup": "User Group", + "type": "Type", + "allUsers": "All Users", + "developers": "Developers", + "custom": "Custom", + "members": "Members", + "adminMembers": "Admin Members", + "created": "Created", + "totalMembersTooltip": "Total number of members in this group", + "adminMembersTooltip": "Number of admin users in this group", + "searchUserGroups": "Search user groups by name or ID", + "showingResults": "Showing {count} of {total} user groups", + "paginationTotal": "{start}-{end} of {total} user groups", + "noUserGroupsFound": "No user groups found in this environment" + }, + "apps": { + "title": "Apps", + "subtitle": "Manage workspace applications", + "refresh": "Refresh", + "errorLoadingApps": "Error loading apps", + "configurationIssue": "Configuration Issue", + "missingConfiguration": "Missing required configuration: API key or API service URL", + "totalApps": "Total Apps", + "publishedApps": "Published Apps", + "managedApps": "Managed Apps", + "unmanagedApps": "Unmanaged Apps", + "app": "App", + "status": "Status", + "published": "Published", + "draft": "Draft", + "managed": "Managed", + "unmanaged": "Unmanaged", + "deploy": "Deploy", + "audit": "Audit", + "appMustBeManagedToDeploy": "App must be managed before it can be deployed", + "deployThisApp": "Deploy this app to another environment", + "viewAuditLogs": "View Audit Logs", + "searchApps": "Search apps by name or ID", + "showAll": "Show All", + "managedOnly": "Managed Only", + "showingResults": "Showing {count} of {total} apps", + "paginationTotal": "{start}-{end} of {total} apps", + "noAppsFound": "No apps found in this workspace", + "appRecycled": "This app has been moved to recycle bin", + "managedSuccess": "{name} is now Managed", + "unmanagedSuccess": "{name} is now Unmanaged", + "managedError": "Failed to change managed status for {name}" + }, + "dataSources": { + "title": "Data Sources", + "subtitle": "Manage workspace data connections", + "refresh": "Refresh", + "errorLoadingDataSources": "Error loading data sources", + "configurationIssue": "Configuration Issue", + "missingConfiguration": "Missing required configuration: API key or API service URL", + "totalDataSources": "Total Data Sources", + "availableTypes": "Available Types", + "managed": "Managed", + "unmanaged": "Unmanaged", + "dataSource": "Data Source", + "type": "Type", + "status": "Status", + "deploy": "Deploy", + "audit": "Audit", + "dataSourceMustBeManagedToDeploy": "Data source must be managed before it can be deployed", + "deployThisDataSource": "Deploy this data source to another environment", + "viewAuditLogs": "View Audit Logs", + "searchDataSources": "Search data sources by name or ID", + "showAll": "Show All", + "managedOnly": "Managed Only", + "showingResults": "Showing {count} of {total} data sources", + "paginationTotal": "{start}-{end} of {total} data sources", + "noDataSourcesFound": "No data sources found in this workspace", + "managedSuccess": "{name} is now Managed", + "unmanagedSuccess": "{name} is now Unmanaged", + "managedError": "Failed to change managed status for {name}" + }, + "queries": { + "title": "Queries", + "subtitle": "Manage workspace API queries", + "refresh": "Refresh", + "errorLoadingQueries": "Error loading queries", + "configurationIssue": "Configuration Issue", + "missingConfiguration": "Missing required configuration: API key or API service URL", + "totalQueries": "Total Queries", + "managed": "Managed", + "unmanaged": "Unmanaged", + "query": "Query", + "creator": "Creator", + "status": "Status", + "deploy": "Deploy", + "audit": "Audit", + "queryMustBeManagedToDeploy": "Query must be managed before it can be deployed", + "deployThisQuery": "Deploy this query to another environment", + "viewAuditLogs": "View Audit Logs", + "searchQueries": "Search queries by name or ID", + "showAll": "Show All", + "managedOnly": "Managed Only", + "showingResults": "Showing {count} of {total} queries", + "paginationTotal": "{start}-{end} of {total} queries", + "noQueriesFound": "No queries found in this workspace", + "managedSuccess": "{name} is now Managed", + "unmanagedSuccess": "{name} is now Unmanaged", + "managedError": "Failed to change managed status for {name}" + }, + + // Deploy Modal and Credential Confirmations + "deployModal": { + "deployTitle": "Deploy {singularLabel}: {name}", + "loadingEnvironments": "Loading environments...", + "sourceEnvironment": "Source Environment", + "targetEnvironment": "Target Environment", + "selectTargetEnvironment": "Select target environment", + "selectTargetEnvironmentValidation": "Please select a target environment", + "confirmed": "Confirmed", + "cancel": "Cancel", + "deploy": "Deploy", + "targetEnvironmentNotFound": "Target environment not found", + "confirmCredentialOverwrite": "Please confirm credential overwrite before deploying", + "deploySuccess": "Successfully deployed {name} to target environment", + "deployFailed": "Failed to deploy {singularLabel}", + "selectFieldValidation": "Please select {label}", + "selectFieldPlaceholder": "Select {label}", + "inputFieldValidation": "Please input {label}", + "inputFieldPlaceholder": "Enter {label}" + }, + // Add contact lowcoder modal + "contactLowcoder": { + "title": "Contact Lowcoder Team", + "environmentLabel": "Environment:", + "environmentIdLabel": "Environment ID:", + "deploymentIdLabel": "Deployment ID:", + "loading": "Loading...", + "notAvailable": "Not available", + "unnamedEnvironment": "Unnamed Environment", + "fetchingDeploymentInfo": "Fetching deployment information...", + "unableToLoadContactForm": "Unable to Load Contact Form", + "apiConfigurationError": "Environment API service URL or API key not configured", + "failedToFetchDeploymentId": "Failed to fetch deployment ID", + "ensureProperConfiguration": "Please ensure the environment is properly configured to contact support." + }, + + "credentialConfirmations": { + "firstConfirmation": { + "title": "Overwrite Credentials Warning", + "message": "This action will overwrite existing credentials in the target environment.", + "description": "This is a serious operation that may affect other applications and users.", + "question": "Are you sure you want to proceed?", + "continueButton": "Continue", + "cancelButton": "Cancel" + }, + "secondConfirmation": { + "title": "Final Confirmation Required", + "message": "Final Warning: Credential Overwrite", + "description": "You are about to overwrite credentials in the target environment. This action cannot be undone and may break existing integrations.", + "confirmOnceMore": "Please confirm one more time.", + "finalQuestion": "Are you absolutely certain you want to overwrite the credentials?", + "confirmButton": "Yes, Overwrite Credentials", + "cancelButton": "Cancel" + } + }, + + "config": { + "singularLabels": { + "app": "App", + "dataSource": "Data Source", + "query": "Query", + "workspace": "Workspace" + }, + "fields": { + "updateDependenciesIfNeeded": "Update Dependencies If Needed", + "publishOnTarget": "Publish On Target", + "publicToAll": "Public To All", + "publicToMarketplace": "Public To Marketplace", + "overwriteCredentials": "Overwrite Credentials" + } + }, + + // Service error messages + "services": { + "environments": { + "missingEnvironmentId": "Missing environment ID", + "failedToUpdateEnvironment": "Failed to update environment", + "environmentCreatedSuccessfully": "Environment created successfully", + "failedToCreateEnvironment": "Failed to create environment", + "failedToFetchEnvironments": "Failed to fetch environments", + "failedToFetchEnvironment": "Failed to fetch environment", + "environmentIdRequired": "Environment ID is required", + "apiKeyRequiredForWorkspaces": "API key is required to fetch workspaces", + "apiServiceUrlRequiredForWorkspaces": "API service URL is required to fetch workspaces", + "failedToFetchWorkspaces": "Failed to fetch workspaces", + "apiKeyRequiredForUserGroups": "API key is required to fetch user groups", + "apiServiceUrlRequiredForUserGroups": "API service URL is required to fetch user groups", + "failedToFetchUserGroups": "Failed to fetch user groups", + "workspaceIdRequired": "Workspace ID is required", + "apiKeyRequiredForApps": "API key is required to fetch apps", + "apiServiceUrlRequiredForApps": "API service URL is required to fetch apps", + "failedToFetchWorkspaceApps": "Failed to fetch workspace apps", + "apiKeyRequiredForDataSources": "API key is required to fetch data sources", + "apiServiceUrlRequiredForDataSources": "API service URL is required to fetch data sources", + "failedToFetchWorkspaceDataSources": "Failed to fetch workspace data sources", + "apiKeyRequiredForQueries": "API key is required to fetch queries", + "apiServiceUrlRequiredForQueries": "API service URL is required to fetch queries", + "failedToFetchWorkspaceQueries": "Failed to fetch workspace queries", + "apiServiceUrlNotConfigured": "API service URL not configured", + "licenseCheckFailed": "License check failed", + "apiKeyRequiredForDeploymentId": "API key is required to fetch deployment ID", + "failedToFetchDeploymentId": "Failed to fetch deployment ID" + }, + "enterprise": { + "missingEnvironmentId": "Missing environment ID", + "failedToFetchManagedWorkspaces": "Failed to fetch managed workspaces", + "missingRequiredParamsToConnectOrg": "Missing required params to connect workspace", + "failedToConnectOrg": "Failed to connect workspace", + "missingOrgGidToUnconnectWorkspace": "Missing workspace GID to unconnect workspace", + "failedToUnconnectOrg": "Failed to unconnect workspace", + "failedToConnectApp": "Failed to connect app", + "failedToUnconnectApp": "Failed to unconnect app", + "failedToFetchDataSources": "Failed to fetch data sources", + "failedToDeployDataSource": "Failed to deploy data source", + "failedToDisconnectManagedDataSource": "Failed to disconnect managed data source", + "environmentIdRequired": "Environment ID is required", + "failedToFetchQueries": "Failed to fetch queries", + "environmentIdAndQueryGidRequired": "Environment ID and Query GID are required", + "failedToDeployQuery": "Failed to deploy query", + "queryGidRequired": "Query GID is required", + "failedToDisconnectQuery": "Failed to disconnect query" + }, + "apps": { + "failedToFetchApps": "Failed to fetch apps", + "failedToDeployApp": "Failed to deploy app" + }, + "datasources": { + "workspaceIdRequired": "Workspace ID is required", + "apiKeyRequiredToFetchDataSources": "API key is required to fetch data sources", + "apiServiceUrlRequiredToFetchDataSources": "API service URL is required to fetch data sources", + "failedToFetchDataSources": "Failed to fetch data sources", + "failedToDeployDataSource": "Failed to deploy data source" + }, + "workspace": { + "failedToFetchWorkspaces": "Failed to fetch workspaces", + "failedToDeployWorkspace": "Failed to deploy workspace" + }, + "managedObjects": { + "missingRequiredParameters": "Missing required parameters", + "failedToCheckManagedStatus": "Failed to check managed status", + "failedToSetAsManaged": "Failed to set {{objType}} as managed", + "failedToRemoveFromManaged": "Failed to remove {{objType}} from managed", + "missingEnvironmentId": "Missing environment ID", + "failedToFetchManagedObjects": "Failed to fetch managed objects", + "failedToFetchManagedObject": "Failed to fetch managed object", + "managedObjectNotFound": "Managed object not found for objGid: {{objGid}}" + }, + "license": { + "apiServiceUrlRequired": "API service URL is required", + "licenseInformationUnavailable": "License information unavailable", + "licenseCheckTookTooLong": "License check took too long", + "licenseServiceNotAvailable": "License service not available", + "authenticationRequired": "Authentication required - please check API key", + "licenseServiceTemporarilyUnavailable": "License service temporarily unavailable", + "remainingAPICalls": "{{remaining}} remaining ({{used}}/{{total}} used, {{percentage}}%)", + } + } + } + }, "subscription": { "details": "Subscription Details", "productDetails": "Product Details", diff --git a/client/packages/lowcoder/src/pages/setting/environments/EnvironmentDetail.tsx b/client/packages/lowcoder/src/pages/setting/environments/EnvironmentDetail.tsx index 2a52b1826..f9495a05d 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/EnvironmentDetail.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/EnvironmentDetail.tsx @@ -46,6 +46,7 @@ import { getEnvironmentTagColor } from "./utils/environmentUtils"; import { formatAPICalls, getAPICallsStatusColor } from "./services/license.service"; import ErrorComponent from './components/ErrorComponent'; import { Level1SettingPageContent } from "../styled"; +import { trans } from "i18n"; /** * Environment Detail Page Component @@ -105,9 +106,9 @@ const EnvironmentDetail: React.FC = () => { if (error || !environment) { return ( ); } @@ -138,26 +139,26 @@ const EnvironmentDetail: React.FC = () => { // Stats data for the cards const statsData = [ { - title: "Type", - value: environment.environmentType || "Unknown", + title: trans("enterprise.environments.detail.type"), + value: environment.environmentType || trans("enterprise.environments.detail.unknown"), icon: , color: getEnvironmentTagColor(environment.environmentType) }, { - title: "Status", - value: environment.isLicensed ? "Licensed" : "Unlicensed", + title: trans("enterprise.environments.detail.status"), + value: environment.isLicensed ? trans("enterprise.environments.detail.licensed") : trans("enterprise.environments.detail.unlicensed"), icon: environment.isLicensed ? : , color: environment.isLicensed ? "#52c41a" : "#ff4d4f" }, { - title: "API Key", - value: environment.environmentApikey ? "Configured" : "Not Set", + title: trans("enterprise.environments.detail.apiKey"), + value: environment.environmentApikey ? trans("enterprise.environments.detail.configured") : trans("enterprise.environments.detail.notSet"), icon: , color: environment.environmentApikey ? "#1890ff" : "#faad14" }, { - title: "Master Env", - value: environment.isMaster ? "Yes" : "No", + title: trans("enterprise.environments.detail.masterEnv"), + value: environment.isMaster ? trans("enterprise.environments.yes") : trans("enterprise.environments.no"), icon: , color: environment.isMaster ? "#722ed1" : "#8c8c8c" } @@ -168,7 +169,7 @@ const EnvironmentDetail: React.FC = () => { key: 'workspaces', label: ( - Workspaces + {trans("enterprise.environments.detail.workspaces")} ), children: @@ -177,7 +178,7 @@ const EnvironmentDetail: React.FC = () => { key: 'userGroups', label: ( - User Groups + {trans("enterprise.environments.detail.userGroups")} ), children: @@ -192,12 +193,12 @@ const EnvironmentDetail: React.FC = () => { items={[ { key: 'environments', - title: 'Environments', + title: trans("enterprise.environments.title"), onClick: () => history.push('/setting/environments') }, { key: 'current', - title: environment.environmentName || "Environment Detail" + title: environment.environmentName || trans("enterprise.environments.detail.environmentDetail") } ]} /> @@ -224,7 +225,7 @@ const EnvironmentDetail: React.FC = () => { {/* Basic Environment Information Card */} { column={{ xxl: 4, xl: 3, lg: 3, md: 2, sm: 1, xs: 1 }} size="small" > - + {environment.environmentFrontendUrl ? ( { {environment.environmentFrontendUrl} ) : ( - "No domain set" + trans("enterprise.environments.detail.noDomainSet") )} - + {environment.environmentId} - + {(() => { switch (environment.licenseStatus) { case 'checking': - return } color="blue" style={{ borderRadius: '4px' }}>Checking...; + return } color="blue" style={{ borderRadius: '4px' }}>{trans("enterprise.environments.licenseStatus.checking")}; case 'licensed': - return } color="green" style={{ borderRadius: '4px' }}>Licensed; + return } color="green" style={{ borderRadius: '4px' }}>{trans("enterprise.environments.licenseStatus.licensed")}; case 'unlicensed': - return } color="orange" style={{ borderRadius: '4px' }}>License Needed; + return } color="orange" style={{ borderRadius: '4px' }}>{trans("enterprise.environments.detail.licenseNeeded")}; case 'error': - return } color="orange" style={{ borderRadius: '4px' }}>Setup Required; + return } color="orange" style={{ borderRadius: '4px' }}>{trans("enterprise.environments.detail.setupRequired")}; default: - return Unknown; + return {trans("enterprise.environments.detail.unknown")}; } })()} - - {environment.createdAt ? new Date(environment.createdAt).toLocaleDateString() : "Unknown"} + + {environment.createdAt ? new Date(environment.createdAt).toLocaleDateString() : trans("enterprise.environments.detail.unknown")} @@ -285,7 +286,7 @@ const EnvironmentDetail: React.FC = () => { title={ - License Details + {trans("enterprise.environments.detail.licenseDetails")} } style={{ @@ -304,7 +305,7 @@ const EnvironmentDetail: React.FC = () => { styles={{ body: { padding: '16px' } }} > ( { color: '#8c8c8c', marginTop: '4px' }}> - {environment.licenseDetails.apiCallsUsage || 0}% used + {trans("enterprise.environments.percentUsed", { percent: environment.licenseDetails.apiCallsUsage || 0 })} @@ -347,7 +348,7 @@ const EnvironmentDetail: React.FC = () => { styles={{ body: { padding: '16px' } }} > value?.toLocaleString()} prefix={} @@ -356,7 +357,7 @@ const EnvironmentDetail: React.FC = () => { color="blue" style={{ marginTop: '12px' }} > - {environment.licenseDetails.eeLicenses.length} License{environment.licenseDetails.eeLicenses.length !== 1 ? 's' : ''} + {environment.licenseDetails.eeLicenses.length} {environment.licenseDetails.eeLicenses.length !== 1 ? trans("enterprise.environments.detail.licenses") : trans("enterprise.environments.detail.license")} @@ -369,8 +370,8 @@ const EnvironmentDetail: React.FC = () => { styles={{ body: { padding: '16px' } }} > ( {
- License Information + {trans("enterprise.environments.detail.licenseInformation")} @@ -408,13 +409,13 @@ const EnvironmentDetail: React.FC = () => {
- ID: {license.customerId} + {trans("enterprise.environments.id")}: {license.customerId}
UUID: {license.uuid.substring(0, 8)}...
- {license.apiCallsLimit.toLocaleString()} calls + {license.apiCallsLimit.toLocaleString()} {trans("enterprise.environments.detail.calls")} diff --git a/client/packages/lowcoder/src/pages/setting/environments/EnvironmentsList.tsx b/client/packages/lowcoder/src/pages/setting/environments/EnvironmentsList.tsx index 36be33166..b46381511 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/EnvironmentsList.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/EnvironmentsList.tsx @@ -13,6 +13,7 @@ import StatsCard from "./components/StatsCard"; import { buildEnvironmentId } from "@lowcoder-ee/constants/routesURL"; import { createEnvironment } from "./services/environments.service"; import { getEnvironmentTagColor } from "./utils/environmentUtils"; +import { trans } from "i18n"; import styled from "styled-components"; const EnvironmentsWrapper = styled.div` @@ -157,9 +158,9 @@ const EnvironmentsList: React.FC = () => { return ( - Environments + {trans("enterprise.environments.title")} setSearchText(e.target.value)} style={{ width: "192px", height: "32px", margin: "0 12px 0 0" }} @@ -169,14 +170,14 @@ const EnvironmentsList: React.FC = () => { icon={} onClick={handleRefresh} > - Refresh + {trans("enterprise.environments.refresh")} } onClick={() => setIsCreateModalVisible(true)} > - Add Environment + {trans("enterprise.environments.addEnvironment")} @@ -187,7 +188,7 @@ const EnvironmentsList: React.FC = () => { {environmentStats.map(([type, count]) => ( { {error && ( { {!isLoading && !error && filteredEnvironments.length === 0 && searchText && ( )} {!isLoading && !error && environments.length === 0 && !searchText && ( )} diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/AppsTab.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/AppsTab.tsx index 150b17242..f63bc3071 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/components/AppsTab.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/components/AppsTab.tsx @@ -11,6 +11,7 @@ import { useDeployModal } from '../context/DeployModalContext'; import { appsConfig } from '../config/apps.config'; import history from "@lowcoder-ee/util/history"; import { messageInstance } from 'lowcoder-design/src/components/GlobalInstances'; +import { trans } from 'i18n'; const { Search } = Input; @@ -117,10 +118,10 @@ const AppsTab: React.FC = ({ environment, workspaceId }) => { unmanaged: prev.total - managed })); - messageInstance.success(`${app.name} is now ${checked ? 'Managed' : 'Unmanaged'}`); + messageInstance.success(trans(checked ? "enterprise.environments.apps.managedSuccess" : "enterprise.environments.apps.unmanagedSuccess", { name: app.name })); return true; } catch (error) { - messageInstance.error(`Failed to change managed status for ${app.name}`); + messageInstance.error(trans("enterprise.environments.apps.managedError", { name: app.name })); return false; } finally { setRefreshing(false); @@ -141,7 +142,7 @@ const AppsTab: React.FC = ({ environment, workspaceId }) => { // Table columns const columns = [ { - title: 'App', + title: trans("enterprise.environments.apps.app"), key: 'app', render: (app: App) => (
@@ -158,7 +159,7 @@ const AppsTab: React.FC = ({ environment, workspaceId }) => {
{app.name} {app.applicationStatus === 'RECYCLED' && ( - + = ({ environment, workspaceId }) => { ), }, { - title: 'Status', + title: trans("enterprise.environments.apps.status"), key: 'status', render: (app: App) => ( - {app.published ? : null} {app.published ? 'Published' : 'Draft'} + {app.published ? : null} {app.published ? trans("enterprise.environments.apps.published") : trans("enterprise.environments.apps.draft")} - {app.managed ? : } {app.managed ? 'Managed' : 'Unmanaged'} + {app.managed ? : } {app.managed ? trans("enterprise.environments.apps.managed") : trans("enterprise.environments.apps.unmanaged")} ), }, { - title: 'Managed', + title: trans("enterprise.environments.apps.managed"), key: 'managed', render: (_: any, app: App) => ( = ({ environment, workspaceId }) => { ), }, { - title: 'Actions', + title: trans("enterprise.environments.workspaces.actions"), key: 'actions', render: (_: any, app: App) => ( e.stopPropagation()}> - + - + @@ -289,10 +290,10 @@ const AppsTab: React.FC = ({ environment, workspaceId }) => { }}>
- <AppstoreOutlined style={{ marginRight: 8 }} /> Apps + <AppstoreOutlined style={{ marginRight: 8 }} /> {trans("enterprise.environments.apps.title")}

- Manage workspace applications + {trans("enterprise.environments.apps.subtitle")}

{/* Error display */} {error && ( = ({ environment, workspaceId }) => { {/* Configuration warnings */} {(!environment.environmentApikey || !environment.environmentApiServiceUrl) && !error && ( = ({ environment, workspaceId }) => { } /> } /> } /> } /> @@ -371,7 +372,7 @@ const AppsTab: React.FC = ({ environment, workspaceId }) => {
) : apps.length === 0 ? ( ) : ( @@ -379,7 +380,7 @@ const AppsTab: React.FC = ({ environment, workspaceId }) => { {/* Search and Filter Bar */}
setSearchText(value)} onChange={e => setSearchText(e.target.value)} @@ -391,13 +392,13 @@ const AppsTab: React.FC = ({ environment, workspaceId }) => { icon={} style={{ marginLeft: '8px' }} > - {showManagedOnly ? 'Show All' : 'Managed Only'} + {showManagedOnly ? trans("enterprise.environments.apps.showAll") : trans("enterprise.environments.apps.managedOnly")}
{searchText && displayedApps.length !== apps.length && (
- Showing {displayedApps.length} of {apps.length} apps + {trans("enterprise.environments.apps.showingResults", { count: displayedApps.length, total: apps.length })}
)} @@ -407,7 +408,7 @@ const AppsTab: React.FC = ({ environment, workspaceId }) => { rowKey="applicationId" pagination={{ pageSize: 10, - showTotal: (total, range) => `${range[0]}-${range[1]} of ${total} apps`, + showTotal: (total, range) => trans("enterprise.environments.apps.paginationTotal", { start: range[0], end: range[1], total }), size: 'small' }} size="middle" diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/ContactLowcoderModal.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/ContactLowcoderModal.tsx index 34ab0526f..7362d35ee 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/components/ContactLowcoderModal.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/components/ContactLowcoderModal.tsx @@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react'; import { Modal, Card, Row, Col, Typography, Divider, Spin, Alert } from 'antd'; import { CustomerServiceOutlined, CloudServerOutlined } from '@ant-design/icons'; import { useSelector } from 'react-redux'; +import { trans } from 'i18n'; import { Environment } from '../types/environment.types'; import { getEnvironmentDeploymentId } from '../services/environments.service'; import { HubspotModal } from '../../hubspotModal'; @@ -34,7 +35,7 @@ const ContactLowcoderModal: React.FC = ({ const fetchDeploymentId = async () => { if (!visible || !environment.environmentApiServiceUrl || !environment.environmentApikey) { if (visible) { - setError('Environment API service URL or API key not configured'); + setError(trans('enterprise.environments.contactLowcoder.apiConfigurationError')); } return; } @@ -51,7 +52,7 @@ const ContactLowcoderModal: React.FC = ({ setShowHubspotModal(true); } catch (err) { console.error('Failed to fetch deployment ID:', err); - setError(err instanceof Error ? err.message : 'Failed to fetch deployment ID'); + setError(err instanceof Error ? err.message : trans('enterprise.environments.contactLowcoder.failedToFetchDeploymentId')); } finally { setIsLoading(false); } @@ -91,7 +92,7 @@ const ContactLowcoderModal: React.FC = ({ title={
- Contact Lowcoder Team + {trans('enterprise.environments.contactLowcoder.title')}
} open={visible} @@ -119,15 +120,15 @@ const ContactLowcoderModal: React.FC = ({
- Environment: {environment.environmentName || 'Unnamed Environment'} + {trans('enterprise.environments.contactLowcoder.environmentLabel')} {environment.environmentName || trans('enterprise.environments.contactLowcoder.unnamedEnvironment')}
- Environment ID: {environment.environmentId} + {trans('enterprise.environments.contactLowcoder.environmentIdLabel')} {environment.environmentId}
- Deployment ID: {isLoading ? 'Loading...' : deploymentId || 'Not available'} + {trans('enterprise.environments.contactLowcoder.deploymentIdLabel')} {isLoading ? trans('enterprise.environments.contactLowcoder.loading') : deploymentId || trans('enterprise.environments.contactLowcoder.notAvailable')}
@@ -148,14 +149,14 @@ const ContactLowcoderModal: React.FC = ({ }}> - Fetching deployment information... + {trans('enterprise.environments.contactLowcoder.fetchingDeploymentInfo')} )} {error && ( = ({ fontSize: '14px' }}> -
Please ensure the environment is properly configured to contact support.
+
{trans('enterprise.environments.contactLowcoder.ensureProperConfiguration')}
)} diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/CreateEnvironmentModal.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/CreateEnvironmentModal.tsx index 8a6132c0a..170128f7a 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/components/CreateEnvironmentModal.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/components/CreateEnvironmentModal.tsx @@ -3,6 +3,7 @@ import { Modal, Form, Input, Select, Switch, Button, Alert, Tooltip } from 'antd import { useSelector } from 'react-redux'; import { selectMasterEnvironment, selectHasMasterEnvironment } from 'redux/selectors/enterpriseSelectors'; import { Environment } from '../types/environment.types'; +import { trans } from 'i18n'; const { Option } = Select; @@ -66,14 +67,14 @@ const CreateEnvironmentModal: React.FC = ({ return ( - Cancel + {trans("enterprise.environments.modal.cancel")} , ]} > @@ -95,43 +96,43 @@ const CreateEnvironmentModal: React.FC = ({ > - + - + + + + @@ -139,9 +140,9 @@ const CreateEnvironmentModal: React.FC = ({ @@ -149,9 +150,9 @@ const CreateEnvironmentModal: React.FC = ({ @@ -159,20 +160,20 @@ const CreateEnvironmentModal: React.FC = ({ - +
@@ -185,15 +186,15 @@ const CreateEnvironmentModal: React.FC = ({ {isMaster && ( - Will be Master + {trans("enterprise.environments.modal.willBeMaster")} )}
= ({ environment, workspaceI unmanaged: prev.total - managed })); - messageInstance.success(`${dataSource.name} is now ${checked ? 'Managed' : 'Unmanaged'}`); + messageInstance.success(trans(checked ? "enterprise.environments.dataSources.managedSuccess" : "enterprise.environments.dataSources.unmanagedSuccess", { name: dataSource.name })); return true; } catch (error) { - messageInstance.error(`Failed to change managed status for ${dataSource.name}`); + messageInstance.error(trans("enterprise.environments.dataSources.managedError", { name: dataSource.name })); return false; } finally { setRefreshing(false); @@ -139,7 +140,7 @@ const DataSourcesTab: React.FC = ({ environment, workspaceI // Table columns const columns = [ { - title: 'Data Source', + title: trans("enterprise.environments.dataSources.dataSource"), key: 'datasource', render: (dataSource: DataSource) => (
@@ -161,7 +162,7 @@ const DataSourcesTab: React.FC = ({ environment, workspaceI ), }, { - title: 'Type', + title: trans("enterprise.environments.dataSources.type"), dataIndex: 'type', key: 'type', render: (type: string) => ( @@ -171,19 +172,19 @@ const DataSourcesTab: React.FC = ({ environment, workspaceI ), }, { - title: 'Status', + title: trans("enterprise.environments.dataSources.status"), key: 'status', render: (dataSource: DataSource) => ( - {dataSource.managed ? : } {dataSource.managed ? 'Managed' : 'Unmanaged'} + {dataSource.managed ? : } {dataSource.managed ? trans("enterprise.environments.dataSources.managed") : trans("enterprise.environments.dataSources.unmanaged")} ), }, { - title: 'Managed', + title: trans("enterprise.environments.dataSources.managed"), key: 'managed', render: (_: any, dataSource: DataSource) => ( = ({ environment, workspaceI ), }, { - title: 'Actions', + title: trans("enterprise.environments.workspaces.actions"), key: 'actions', render: (_: any, dataSource: DataSource) => ( e.stopPropagation()}> - + - + @@ -286,10 +287,10 @@ const DataSourcesTab: React.FC = ({ environment, workspaceI }}>
- <DatabaseOutlined style={{ marginRight: 8 }} /> Data Sources + <DatabaseOutlined style={{ marginRight: 8 }} /> {trans("enterprise.environments.dataSources.title")}

- Manage workspace data connections + {trans("enterprise.environments.dataSources.subtitle")}

{/* Error display */} {error && ( = ({ environment, workspaceI {/* Configuration warnings */} {(!environment.environmentApikey || !environment.environmentApiServiceUrl) && !error && ( = ({ environment, workspaceI } /> } /> } /> } /> @@ -368,7 +369,7 @@ const DataSourcesTab: React.FC = ({ environment, workspaceI ) : dataSources.length === 0 ? ( ) : ( @@ -376,7 +377,7 @@ const DataSourcesTab: React.FC = ({ environment, workspaceI {/* Search and Filter Bar */}
setSearchText(value)} onChange={e => setSearchText(e.target.value)} @@ -388,13 +389,13 @@ const DataSourcesTab: React.FC = ({ environment, workspaceI icon={} style={{ marginLeft: '8px' }} > - {showManagedOnly ? 'Show All' : 'Managed Only'} + {showManagedOnly ? trans("enterprise.environments.dataSources.showAll") : trans("enterprise.environments.dataSources.managedOnly")}
{searchText && displayedDataSources.length !== dataSources.length && (
- Showing {displayedDataSources.length} of {dataSources.length} data sources + {trans("enterprise.environments.dataSources.showingResults", { count: displayedDataSources.length, total: dataSources.length })}
)} @@ -404,7 +405,7 @@ const DataSourcesTab: React.FC = ({ environment, workspaceI rowKey="id" pagination={{ pageSize: 10, - showTotal: (total, range) => `${range[0]}-${range[1]} of ${total} data sources`, + showTotal: (total, range) => trans("enterprise.environments.dataSources.paginationTotal", { start: range[0], end: range[1], total }), size: 'small' }} size="middle" diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/DeployItemModal.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/DeployItemModal.tsx index b7051185c..757f55153 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/components/DeployItemModal.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/components/DeployItemModal.tsx @@ -2,6 +2,7 @@ import React, { useState, useEffect } from 'react'; import { Modal, Form, Select, Checkbox, Button, Spin, Input, Tag, Space, Alert } from 'antd'; import { messageInstance } from 'lowcoder-design/src/components/GlobalInstances'; +import { trans } from "i18n"; import { useSelector } from 'react-redux'; import { selectLicensedEnvironments, selectEnvironmentsLoading } from 'redux/selectors/enterpriseSelectors'; import { Environment } from '../types/environment.types'; @@ -87,13 +88,13 @@ function DeployItemModal({ const targetEnv = licensedEnvironments.find(env => env.environmentId === values.targetEnvId); if (!targetEnv) { - messageInstance.error('Target environment not found'); + messageInstance.error(trans("enterprise.environments.deployModal.targetEnvironmentNotFound")); return; } // Additional check for credential overwrite if (values.deployCredential && credentialConfirmationStep !== 2) { - messageInstance.error('Please confirm credential overwrite before deploying'); + messageInstance.error(trans("enterprise.environments.deployModal.confirmCredentialOverwrite")); return; } @@ -105,12 +106,12 @@ function DeployItemModal({ // Execute deployment await config.deploy.execute(params); - messageInstance.success(`Successfully deployed ${item.name} to target environment`); + messageInstance.success(trans("enterprise.environments.deployModal.deploySuccess", { name: item.name })); if (onSuccess) onSuccess(); onClose(); } catch (error) { console.error('Deployment error:', error); - messageInstance.error(`Failed to deploy ${config.deploy.singularLabel.toLowerCase()}`); + messageInstance.error(trans("enterprise.environments.deployModal.deployFailed", { singularLabel: config.deploy.singularLabel.toLowerCase() })); } finally { setDeploying(false); } @@ -118,7 +119,10 @@ function DeployItemModal({ return ( {isLoading ? (
- +
) : (
{/* Source environment display */} - + {sourceEnvironment.environmentName} {sourceEnvironment.environmentType && ( @@ -147,10 +151,10 @@ function DeployItemModal({ - {targetEnvironments.map((env) => ( @@ -196,7 +200,7 @@ function DeployItemModal({ style={{ marginLeft: 8 }} icon={} > - Confirmed + {trans("enterprise.environments.deployModal.confirmed")} )} @@ -209,9 +213,9 @@ function DeployItemModal({ name={field.name} label={field.label} initialValue={field.defaultValue} - rules={field.required ? [{ required: true, message: `Please select ${field.label}` }] : undefined} + rules={field.required ? [{ required: true, message: trans("enterprise.environments.deployModal.selectFieldValidation", { label: field.label }) }] : undefined} > - {field.options?.map(option => ( {option.label} @@ -227,9 +231,9 @@ function DeployItemModal({ name={field.name} label={field.label} initialValue={field.defaultValue} - rules={field.required ? [{ required: true, message: `Please input ${field.label}` }] : undefined} + rules={field.required ? [{ required: true, message: trans("enterprise.environments.deployModal.inputFieldValidation", { label: field.label }) }] : undefined} > - + ); default: @@ -239,10 +243,10 @@ function DeployItemModal({ diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/EditEnvironmentModal.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/EditEnvironmentModal.tsx index 3b90bc826..37d1b0946 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/components/EditEnvironmentModal.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/components/EditEnvironmentModal.tsx @@ -3,6 +3,7 @@ import { Modal, Form, Input, Select, Switch, Button, Alert, Tooltip } from 'antd import { useSelector } from 'react-redux'; import { selectMasterEnvironment, selectHasMasterEnvironment } from 'redux/selectors/enterpriseSelectors'; import { Environment } from '../types/environment.types'; +import { trans } from 'i18n'; const { Option } = Select; @@ -81,14 +82,14 @@ const EditEnvironmentModal: React.FC = ({ return ( - Cancel + {trans("enterprise.environments.modal.cancel")} , ]} > @@ -107,72 +108,72 @@ const EditEnvironmentModal: React.FC = ({ > - + - + + + + - +
@@ -185,15 +186,15 @@ const EditEnvironmentModal: React.FC = ({ {isMaster && ( - Currently Master + {trans("enterprise.environments.modal.currentlyMaster")} )}
= ({
- {environment.environmentName || "Unnamed Environment"} + {environment.environmentName || trans("enterprise.environments.unnamedEnvironment")}
= ({ fontSize: '14px', fontFamily: 'monospace' }}> - ID: {environment.environmentId} + {trans("enterprise.environments.id")}: {environment.environmentId} = ({ {environment.isMaster && ( - Master + {trans("enterprise.environments.master")} )} {environment.isLicensed === false && ( - Unlicensed + {trans("enterprise.environments.detail.unlicensed")} )}
@@ -93,7 +94,7 @@ const EnvironmentHeader: React.FC = ({ borderRadius: '4px' }} > - Edit Environment + {trans("enterprise.environments.unlicensed.editEnvironment")} diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/EnvironmentsTable.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/EnvironmentsTable.tsx index 2336c8d5d..81f777188 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/components/EnvironmentsTable.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/components/EnvironmentsTable.tsx @@ -4,6 +4,7 @@ import { EditOutlined, AuditOutlined, LinkOutlined, EnvironmentOutlined, StarFil import { Environment } from '../types/environment.types'; import { getEnvironmentTagColor, formatEnvironmentType } from '../utils/environmentUtils'; import { getAPICallsStatusColor } from '../services/license.service'; +import { trans } from 'i18n'; const { Text, Title } = Typography; @@ -56,35 +57,35 @@ const EnvironmentsTable: React.FC = ({ return { icon: , color: '#40a9ff', - text: 'Checking...', + text: trans("enterprise.environments.licenseStatus.checking"), status: 'processing' as const }; case 'licensed': return { icon: , color: '#73d13d', - text: 'Licensed', + text: trans("enterprise.environments.licenseStatus.licensed"), status: 'success' as const }; case 'unlicensed': return { icon: , color: '#ff7875', - text: 'License Required', + text: trans("enterprise.environments.licenseStatus.unlicensed"), status: 'warning' as const }; case 'error': return { icon: , color: '#ffc53d', - text: 'Setup Required', + text: trans("enterprise.environments.licenseStatus.error"), status: 'warning' as const }; default: return { icon: , color: '#d9d9d9', - text: 'Unknown', + text: trans("enterprise.environments.licenseStatus.unknown"), status: 'default' as const }; } @@ -163,9 +164,9 @@ const EnvironmentsTable: React.FC = ({ />
- {env.environmentName || 'Unnamed Environment'} + {env.environmentName || trans("enterprise.environments.unnamedEnvironment")} {env.isMaster && ( - <Tooltip title="Master Environment"> + <Tooltip title={trans("enterprise.environments.masterEnvironment")}> <StarFilled style={{ color: '#faad14', marginLeft: '6px', fontSize: '12px' }} /> </Tooltip> )} @@ -192,7 +193,7 @@ const EnvironmentsTable: React.FC<EnvironmentsTableProps> = ({ {/* Only show audit button for licensed environments */} {isAccessible && ( <div> - <Tooltip title="View Audit Logs" placement="top"> + <Tooltip title={trans("enterprise.environments.viewAuditLogs")} placement="top"> <Button type="text" icon={<AuditOutlined />} @@ -214,9 +215,9 @@ const EnvironmentsTable: React.FC<EnvironmentsTableProps> = ({ <div style={{ padding: '8px 0', borderTop: '1px solid #f5f5f5' }}> <div style={{ display: 'flex', flexDirection: 'column', gap: '6px' }}> <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> - <Text type="secondary" style={{ fontSize: '12px' }}>ID:</Text> + <Text type="secondary" style={{ fontSize: '12px' }}>{trans("enterprise.environments.id")}:</Text> {isAccessible ? ( - <Text style={{ fontSize: '12px', fontFamily: 'monospace' }} copyable={{ tooltips: ['Copy ID', 'Copied!'] }}> + <Text style={{ fontSize: '12px', fontFamily: 'monospace' }} copyable={{ tooltips: [trans("enterprise.environments.copyId"), trans("enterprise.environments.copied")] }}> {env.environmentId} </Text> ) : ( @@ -227,7 +228,7 @@ const EnvironmentsTable: React.FC<EnvironmentsTableProps> = ({ </div> <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> - <Text type="secondary" style={{ fontSize: '12px' }}>Domain:</Text> + <Text type="secondary" style={{ fontSize: '12px' }}>{trans("enterprise.environments.domain")}:</Text> {env.environmentFrontendUrl ? ( isAccessible ? ( <a @@ -251,14 +252,14 @@ const EnvironmentsTable: React.FC<EnvironmentsTableProps> = ({ </div> <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> - <Text type="secondary" style={{ fontSize: '12px' }}>Master:</Text> + <Text type="secondary" style={{ fontSize: '12px' }}>{trans("enterprise.environments.master")}:</Text> <Text style={{ fontSize: '12px' }}> - {env.isMaster ? 'Yes' : 'No'} + {env.isMaster ? trans("enterprise.environments.yes") : trans("enterprise.environments.no")} </Text> </div> <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> - <Text type="secondary" style={{ fontSize: '12px' }}>License:</Text> + <Text type="secondary" style={{ fontSize: '12px' }}>{trans("enterprise.environments.license")}:</Text> <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}> <span style={{ color: licenseDisplay.color, fontSize: '12px' }}> {licenseDisplay.icon} @@ -275,7 +276,7 @@ const EnvironmentsTable: React.FC<EnvironmentsTableProps> = ({ <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '6px' }}> <Text type="secondary" style={{ fontSize: '11px' }}> <ApiOutlined style={{ marginRight: '4px' }} /> - API Calls + {trans("enterprise.environments.apiCalls")} </Text> </div> @@ -295,7 +296,7 @@ const EnvironmentsTable: React.FC<EnvironmentsTableProps> = ({ fontSize: '10px', color: '#8c8c8c' }}> - <span>{env.licenseDetails.apiCallsUsage || 0}% used</span> + <span>{trans("enterprise.environments.percentUsed", { percent: env.licenseDetails.apiCallsUsage || 0 })}</span> </div> </div> )} @@ -310,7 +311,7 @@ const EnvironmentsTable: React.FC<EnvironmentsTableProps> = ({ {environments.length > 10 && ( <div style={{ textAlign: 'center', margin: '16px 0' }}> <Text type="secondary" style={{ fontSize: '13px' }}> - Showing all {environments.length} environments + {trans("enterprise.environments.showingAllEnvironments", { count: environments.length })} </Text> </div> )} diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/ErrorComponent.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/ErrorComponent.tsx index 2f4d5fbac..e2015059d 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/components/ErrorComponent.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/components/ErrorComponent.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { Card, Button, Typography } from 'antd'; import { HomeOutlined } from '@ant-design/icons'; import history from '@lowcoder-ee/util/history'; +import { trans } from 'i18n'; const { Title, Text } = Typography; @@ -20,7 +21,7 @@ const ErrorComponent: React.FC<ErrorComponentProps> = ({ errorMessage, returnPat {errorMessage} - The item you're looking for doesn't exist or you don't have permission to view it. + {trans("enterprise.environments.error.itemNotFound")} - + @@ -286,10 +287,10 @@ const QueriesTab: React.FC = ({ environment, workspaceId }) => }}>
- <ThunderboltOutlined style={{ marginRight: 8 }} /> Queries + <ThunderboltOutlined style={{ marginRight: 8 }} /> {trans("enterprise.environments.queries.title")}

- Manage workspace API queries + {trans("enterprise.environments.queries.subtitle")}

{/* Error display */} {error && ( = ({ environment, workspaceId }) => {/* Configuration warnings */} {(!environment.environmentApikey || !environment.environmentApiServiceUrl) && !error && ( = ({ environment, workspaceId }) => } /> } /> } /> @@ -361,7 +362,7 @@ const QueriesTab: React.FC = ({ environment, workspaceId }) =>
) : queries.length === 0 ? ( ) : ( @@ -369,7 +370,7 @@ const QueriesTab: React.FC = ({ environment, workspaceId }) => {/* Search and Filter Bar */}
setSearchText(value)} onChange={e => setSearchText(e.target.value)} @@ -381,13 +382,13 @@ const QueriesTab: React.FC = ({ environment, workspaceId }) => icon={} style={{ marginLeft: '8px' }} > - {showManagedOnly ? 'Show All' : 'Managed Only'} + {showManagedOnly ? trans("enterprise.environments.queries.showAll") : trans("enterprise.environments.queries.managedOnly")}
{searchText && displayedQueries.length !== queries.length && (
- Showing {displayedQueries.length} of {queries.length} queries + {trans("enterprise.environments.queries.showingResults", { count: displayedQueries.length, total: queries.length })}
)} @@ -397,7 +398,7 @@ const QueriesTab: React.FC = ({ environment, workspaceId }) => rowKey="id" pagination={{ pageSize: 10, - showTotal: (total, range) => `${range[0]}-${range[1]} of ${total} queries`, + showTotal: (total, range) => trans("enterprise.environments.queries.paginationTotal", { start: range[0], end: range[1], total }), size: 'small' }} size="middle" diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/UnlicensedEnvironmentView.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/UnlicensedEnvironmentView.tsx index 75d33ebda..1473c013a 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/components/UnlicensedEnvironmentView.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/components/UnlicensedEnvironmentView.tsx @@ -16,6 +16,7 @@ import EnvironmentHeader from './EnvironmentHeader'; import StatsCard from './StatsCard'; import { Level1SettingPageContent } from "../../styled"; import history from "@lowcoder-ee/util/history"; +import { trans } from 'i18n'; const { Title, Text } = Typography; @@ -54,37 +55,37 @@ const UnlicensedEnvironmentView: React.FC = ({ switch (environment.licenseStatus) { case 'unlicensed': - return 'This environment needs a valid license to unlock its full capabilities and features. Please make sure your API Service URL is correctly configured and Plugin is installed.'; + return trans("enterprise.environments.unlicensed.unlicensedDescription"); case 'error': - return 'We encountered an issue while checking the license. Please review the configuration settings.'; + return trans("enterprise.environments.unlicensed.errorDescription"); default: - return 'This environment requires license configuration to proceed.'; + return trans("enterprise.environments.unlicensed.defaultDescription"); } }; // Stats data consistent with other environment pages const statsData = [ { - title: "Type", - value: environment.environmentType || "Unknown", + title: trans("enterprise.environments.unlicensed.type"), + value: environment.environmentType || trans("enterprise.environments.detail.unknown"), icon: , color: "#1890ff" }, { - title: "Status", - value: "Unlicensed", + title: trans("enterprise.environments.unlicensed.status"), + value: trans("enterprise.environments.detail.unlicensed"), icon: , color: "#ff4d4f" }, { - title: "Master Env", - value: environment.isMaster ? "Yes" : "No", + title: trans("enterprise.environments.unlicensed.masterEnv"), + value: environment.isMaster ? trans("enterprise.environments.yes") : trans("enterprise.environments.no"), icon: , color: environment.isMaster ? "#722ed1" : "#8c8c8c" }, { - title: "License Issue", - value: environment.licenseStatus === 'error' ? "Error" : "Missing", + title: trans("enterprise.environments.unlicensed.licenseIssue"), + value: environment.licenseStatus === 'error' ? trans("enterprise.environments.unlicensed.error") : trans("enterprise.environments.unlicensed.missing"), icon: environment.licenseStatus === 'error' ? : , color: environment.licenseStatus === 'error' ? "#faad14" : "#ff4d4f" } @@ -94,16 +95,16 @@ const UnlicensedEnvironmentView: React.FC = ({ {/* Breadcrumbs */} - history.push('/setting/environments') }, { key: 'current', - title: environment.environmentName || "Environment Detail" + title: environment.environmentName || trans("enterprise.environments.detail.environmentDetail") } ]} /> @@ -128,6 +129,7 @@ const UnlicensedEnvironmentView: React.FC = ({ ))}
+ {/* License Issue Card */} = ({ fontWeight: 500 }} > - Contact Lowcoder Team + {trans("enterprise.environments.unlicensed.contactLowcoderTeam")} @@ -234,7 +236,7 @@ const UnlicensedEnvironmentView: React.FC = ({ display: 'block', lineHeight: '1.5' }}> - Need assistance? Contact our team for licensing support or edit the environment configuration to resolve this issue. + {trans("enterprise.environments.unlicensed.helpText")} diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/UserGroupsTab.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/UserGroupsTab.tsx index e9f781b3c..c97d2f461 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/components/UserGroupsTab.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/components/UserGroupsTab.tsx @@ -6,6 +6,7 @@ import { Environment } from '../types/environment.types'; import { UserGroup, UserGroupsTabStats } from '../types/userGroup.types'; import { getEnvironmentUserGroups } from '../services/environments.service'; import { Spin, Empty } from 'antd'; +import { trans } from 'i18n'; const { Search } = Input; @@ -36,7 +37,7 @@ const UserGroupsTab: React.FC = ({ environment }) => { try { // Check for required environment properties if (!environment.environmentApikey || !environment.environmentApiServiceUrl) { - setError('Missing required configuration: API key or API service URL'); + setError(trans("enterprise.environments.userGroups.missingConfiguration")); setLoading(false); return; } @@ -65,7 +66,7 @@ const UserGroupsTab: React.FC = ({ environment }) => { custom }); } catch (err) { - setError(err instanceof Error ? err.message : "Failed to fetch user groups"); + setError(err instanceof Error ? err.message : trans("enterprise.environments.userGroups.errorLoadingUserGroups")); } finally { setLoading(false); setRefreshing(false); @@ -134,7 +135,7 @@ const UserGroupsTab: React.FC = ({ environment }) => { // Table columns const columns = [ { - title: 'User Group', + title: trans("enterprise.environments.userGroups.userGroup"), key: 'group', render: (group: UserGroup) => (
@@ -158,31 +159,31 @@ const UserGroupsTab: React.FC = ({ environment }) => { ), }, { - title: 'Type', + title: trans("enterprise.environments.userGroups.type"), key: 'type', render: (_: any, group: UserGroup) => { if (group.allUsersGroup) return ( - All Users + {trans("enterprise.environments.userGroups.allUsers")} ); if (group.devGroup) return ( - Developers + {trans("enterprise.environments.userGroups.developers")} ); return ( - Custom + {trans("enterprise.environments.userGroups.custom")} ); }, }, { - title: 'Members', + title: trans("enterprise.environments.userGroups.members"), key: 'members', render: (_: any, group: UserGroup) => ( - + {group.stats?.userCount || 0} @@ -190,10 +191,10 @@ const UserGroupsTab: React.FC = ({ environment }) => { ), }, { - title: 'Admin Members', + title: trans("enterprise.environments.userGroups.adminMembers"), key: 'adminMembers', render: (_: any, group: UserGroup) => ( - + {group.stats?.adminUserCount || 0} @@ -201,7 +202,7 @@ const UserGroupsTab: React.FC = ({ environment }) => { ), }, { - title: 'Created', + title: trans("enterprise.environments.userGroups.created"), dataIndex: 'createTime', key: 'createTime', render: (createTime: number) => ( @@ -223,10 +224,10 @@ const UserGroupsTab: React.FC = ({ environment }) => { }}>
- <UsergroupAddOutlined style={{ marginRight: 8 }} /> User Groups + <UsergroupAddOutlined style={{ marginRight: 8 }} /> {trans("enterprise.environments.userGroups.title")}

- Manage user groups in this environment + {trans("enterprise.environments.userGroups.subtitle")}

{/* Error display */} {error && ( = ({ environment }) => { {/* Configuration warnings */} {(!environment.environmentApikey || !environment.environmentApiServiceUrl) && !error && ( = ({ environment }) => { } /> } /> } /> } /> @@ -305,7 +306,7 @@ const UserGroupsTab: React.FC = ({ environment }) => { ) : userGroups.length === 0 ? ( ) : ( @@ -313,7 +314,7 @@ const UserGroupsTab: React.FC = ({ environment }) => { {/* Search Bar */}
setSearchText(value)} onChange={e => setSearchText(e.target.value)} @@ -321,7 +322,7 @@ const UserGroupsTab: React.FC = ({ environment }) => { /> {searchText && filteredUserGroups.length !== userGroups.length && (
- Showing {filteredUserGroups.length} of {userGroups.length} user groups + {trans("enterprise.environments.userGroups.showingResults", { count: filteredUserGroups.length, total: userGroups.length })}
)}
@@ -332,7 +333,7 @@ const UserGroupsTab: React.FC = ({ environment }) => { rowKey="groupId" pagination={{ pageSize: 10, - showTotal: (total, range) => `${range[0]}-${range[1]} of ${total} user groups`, + showTotal: (total, range) => trans("enterprise.environments.userGroups.paginationTotal", { start: range[0], end: range[1], total }), size: 'small' }} size="middle" diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/WorkspacesTab.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/WorkspacesTab.tsx index 26732c76a..8e265350c 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/components/WorkspacesTab.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/components/WorkspacesTab.tsx @@ -6,6 +6,7 @@ import { Environment } from '../types/environment.types'; import { Workspace } from '../types/workspace.types'; import { getMergedEnvironmentWorkspaces } from '../services/workspace.service'; import { Spin, Empty } from 'antd'; +import { trans } from 'i18n'; import history from '@lowcoder-ee/util/history'; @@ -38,7 +39,7 @@ const WorkspacesTab: React.FC = ({ environment }) => { try { // Check for required environment properties if (!environment.environmentApikey || !environment.environmentApiServiceUrl) { - setError('Missing required configuration: API key or API service URL'); + setError(trans("enterprise.environments.workspaces.missingConfiguration")); setLoading(false); return; } @@ -52,7 +53,7 @@ const WorkspacesTab: React.FC = ({ environment }) => { setWorkspaces(result.workspaces); setStats(result.stats); } catch (err) { - setError(err instanceof Error ? err.message : "Failed to fetch workspaces"); + setError(err instanceof Error ? err.message : trans("enterprise.environments.workspaces.errorLoadingWorkspaces")); } finally { setLoading(false); setRefreshing(false); @@ -130,7 +131,7 @@ const WorkspacesTab: React.FC = ({ environment }) => { // Table columns const columns = [ { - title: 'Workspace', + title: trans("enterprise.environments.workspaces.workspace"), key: 'workspace', render: (workspace: Workspace) => (
@@ -154,12 +155,12 @@ const WorkspacesTab: React.FC = ({ environment }) => { ), }, { - title: 'Role', + title: trans("enterprise.environments.workspaces.role"), dataIndex: 'role', key: 'role', }, { - title: 'Status', + title: trans("enterprise.environments.workspaces.status"), dataIndex: 'status', key: 'status', render: (status: string) => ( @@ -170,7 +171,7 @@ const WorkspacesTab: React.FC = ({ environment }) => { ), }, { - title: 'Managed', + title: trans("enterprise.environments.workspaces.managed"), key: 'managed', render: (_: any, workspace: Workspace) => ( = ({ environment }) => { ? : } - {workspace.managed ? 'Managed' : 'Unmanaged'} + {workspace.managed ? trans("enterprise.environments.workspaces.managed") : trans("enterprise.environments.workspaces.unmanaged")} ), }, { - title: 'Actions', + title: trans("enterprise.environments.workspaces.actions"), key: 'actions', render: (_: any, workspace: Workspace) => ( e.stopPropagation()}> - + @@ -219,10 +220,10 @@ const WorkspacesTab: React.FC = ({ environment }) => { }}>
- <TeamOutlined style={{ marginRight: 8 }} /> Workspaces + <TeamOutlined style={{ marginRight: 8 }} /> {trans("enterprise.environments.workspaces.title")}

- Manage workspaces in this environment + {trans("enterprise.environments.workspaces.subtitle")}

{/* Error display */} {error && ( = ({ environment }) => { {/* Configuration warnings */} {(!environment.environmentApikey || !environment.environmentApiServiceUrl) && !error && ( = ({ environment }) => { } /> } /> } /> @@ -294,7 +295,7 @@ const WorkspacesTab: React.FC = ({ environment }) => { ) : workspaces.length === 0 ? ( ) : ( @@ -302,7 +303,7 @@ const WorkspacesTab: React.FC = ({ environment }) => { {/* Search and Filter Bar */}
setSearchText(value)} onChange={e => setSearchText(e.target.value)} @@ -314,13 +315,13 @@ const WorkspacesTab: React.FC = ({ environment }) => { icon={} style={{ marginLeft: '8px' }} > - {showManagedOnly ? 'Show All' : 'Managed Only'} + {showManagedOnly ? trans("enterprise.environments.workspaces.showAll") : trans("enterprise.environments.workspaces.managedOnly")}
{searchText && displayedWorkspaces.length !== workspaces.length && (
- Showing {displayedWorkspaces.length} of {workspaces.length} workspaces + {trans("enterprise.environments.workspaces.showingResults", { count: displayedWorkspaces.length, total: workspaces.length })}
)} @@ -330,7 +331,7 @@ const WorkspacesTab: React.FC = ({ environment }) => { rowKey="id" pagination={{ pageSize: 10, - showTotal: (total, range) => `${range[0]}-${range[1]} of ${total} workspaces`, + showTotal: (total, range) => trans("enterprise.environments.workspaces.paginationTotal", { start: range[0], end: range[1], total }), size: 'small' }} size="middle" diff --git a/client/packages/lowcoder/src/pages/setting/environments/components/credentialConfirmations.tsx b/client/packages/lowcoder/src/pages/setting/environments/components/credentialConfirmations.tsx index dfaee1cc5..694eec008 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/components/credentialConfirmations.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/components/credentialConfirmations.tsx @@ -1,6 +1,6 @@ - import { Modal, Alert } from 'antd'; import { ExclamationCircleOutlined, WarningOutlined } from '@ant-design/icons'; +import { trans } from "i18n"; interface ConfirmHandlers { onOk: () => void; @@ -15,21 +15,23 @@ export function showFirstCredentialOverwriteConfirm({ onOk, onCancel }: ConfirmH title: (
- Overwrite Credentials Warning + + {trans("enterprise.environments.credentialConfirmations.firstConfirmation.title")} +
), icon: null, content: (

- This is a serious operation that may affect other applications and users. + {trans("enterprise.environments.credentialConfirmations.firstConfirmation.description")}

- Are you sure you want to proceed? + {trans("enterprise.environments.credentialConfirmations.firstConfirmation.question")}

} @@ -39,8 +41,8 @@ export function showFirstCredentialOverwriteConfirm({ onOk, onCancel }: ConfirmH /> ), - okText: 'Continue', - cancelText: 'Cancel', + okText: trans("enterprise.environments.credentialConfirmations.firstConfirmation.continueButton"), + cancelText: trans("enterprise.environments.credentialConfirmations.firstConfirmation.cancelButton"), okButtonProps: { style: { backgroundColor: '#ff7a00', borderColor: '#ff7a00', fontWeight: 500 } }, @@ -62,21 +64,23 @@ export function showSecondCredentialOverwriteConfirm({ onOk, onCancel }: Confirm title: (
- Final Confirmation Required + + {trans("enterprise.environments.credentialConfirmations.secondConfirmation.title")} +
), icon: null, content: (

- You are about to overwrite credentials in the target environment. This action cannot be undone and may break existing integrations. + {trans("enterprise.environments.credentialConfirmations.secondConfirmation.description")}

- Please confirm one more time. + {trans("enterprise.environments.credentialConfirmations.secondConfirmation.confirmOnceMore")}

} @@ -93,14 +97,14 @@ export function showSecondCredentialOverwriteConfirm({ onOk, onCancel }: Confirm }} >

- Are you absolutely certain you want to overwrite the credentials? + {trans("enterprise.environments.credentialConfirmations.secondConfirmation.finalQuestion")}

), - okText: 'Yes, Overwrite Credentials', + okText: trans("enterprise.environments.credentialConfirmations.secondConfirmation.confirmButton"), okType: 'danger', - cancelText: 'Cancel', + cancelText: trans("enterprise.environments.credentialConfirmations.secondConfirmation.cancelButton"), okButtonProps: { style: { fontWeight: 500 } }, cancelButtonProps: { style: { fontWeight: 500 } }, width: 520, diff --git a/client/packages/lowcoder/src/pages/setting/environments/config/apps.config.tsx b/client/packages/lowcoder/src/pages/setting/environments/config/apps.config.tsx index 197b2a826..6409cd5e4 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/config/apps.config.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/config/apps.config.tsx @@ -2,11 +2,9 @@ import { DeployableItemConfig } from '../types/deployable-item.types'; import { Environment } from '../types/environment.types'; import { deployApp } from '../services/apps.service'; - +import { trans } from "i18n"; import { App } from '../types/app.types'; - - // Define AppStats interface if not already defined @@ -14,35 +12,35 @@ export const appsConfig: DeployableItemConfig = { deploy: { - singularLabel: 'App', + singularLabel: trans("enterprise.environments.config.singularLabels.app"), fields: [ { name: 'updateDependenciesIfNeeded', - label: 'Update Dependencies If Needed', + label: trans("enterprise.environments.config.fields.updateDependenciesIfNeeded"), type: 'checkbox', defaultValue: false }, { name: 'publishOnTarget', - label: 'Publish On Target', + label: trans("enterprise.environments.config.fields.publishOnTarget"), type: 'checkbox', defaultValue: false }, { name: 'publicToAll', - label: 'Public To All', + label: trans("enterprise.environments.config.fields.publicToAll"), type: 'checkbox', defaultValue: false }, { name: 'publicToMarketplace', - label: 'Public To Marketplace', + label: trans("enterprise.environments.config.fields.publicToMarketplace"), type: 'checkbox', defaultValue: false }, { name: 'deployCredential', - label: 'Overwrite Credentials', + label: trans("enterprise.environments.config.fields.overwriteCredentials"), type: 'checkbox', defaultValue: false } diff --git a/client/packages/lowcoder/src/pages/setting/environments/config/data-sources.config.tsx b/client/packages/lowcoder/src/pages/setting/environments/config/data-sources.config.tsx index ce802e8de..c739a972d 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/config/data-sources.config.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/config/data-sources.config.tsx @@ -4,14 +4,15 @@ import { DeployableItemConfig } from '../types/deployable-item.types'; import { DataSource} from '../types/datasource.types'; import { Environment } from '../types/environment.types'; import { deployDataSource, DataSourceStats } from '../services/datasources.service'; +import { trans } from "i18n"; export const dataSourcesConfig: DeployableItemConfig = { deploy: { - singularLabel: 'Data Source', + singularLabel: trans("enterprise.environments.config.singularLabels.dataSource"), fields: [ { name: 'deployCredential', - label: 'Overwrite Credentials', + label: trans("enterprise.environments.config.fields.overwriteCredentials"), type: 'checkbox', defaultValue: false } diff --git a/client/packages/lowcoder/src/pages/setting/environments/config/query.config.tsx b/client/packages/lowcoder/src/pages/setting/environments/config/query.config.tsx index 7495e5371..0a10f2bff 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/config/query.config.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/config/query.config.tsx @@ -3,15 +3,16 @@ import { DeployableItemConfig } from '../types/deployable-item.types'; import { Query } from '../types/query.types'; import { deployQuery } from '../services/query.service'; import { Environment } from '../types/environment.types'; +import { trans } from "i18n"; export const queryConfig: DeployableItemConfig = { deploy: { - singularLabel: 'Query', + singularLabel: trans("enterprise.environments.config.singularLabels.query"), fields: [ { name: 'deployCredential', - label: 'Overwrite Credentials', + label: trans("enterprise.environments.config.fields.overwriteCredentials"), type: 'checkbox', defaultValue: false } diff --git a/client/packages/lowcoder/src/pages/setting/environments/config/workspace.config.tsx b/client/packages/lowcoder/src/pages/setting/environments/config/workspace.config.tsx index e35423f2f..78865a91a 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/config/workspace.config.tsx +++ b/client/packages/lowcoder/src/pages/setting/environments/config/workspace.config.tsx @@ -4,12 +4,13 @@ import { DeployableItemConfig } from '../types/deployable-item.types'; import { Environment } from '../types/environment.types'; import { deployWorkspace } from '../services/workspace.service'; import { Workspace } from '../types/workspace.types'; +import { trans } from "i18n"; export const workspaceConfig: DeployableItemConfig = { // Deploy configuration deploy: { - singularLabel: 'Workspace', + singularLabel: trans("enterprise.environments.config.singularLabels.workspace"), fields: [ // Removed deployCredential field as workspaces don't need credential overwrite ], diff --git a/client/packages/lowcoder/src/pages/setting/environments/services/apps.service.ts b/client/packages/lowcoder/src/pages/setting/environments/services/apps.service.ts index db7f21dff..3078bb604 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/services/apps.service.ts +++ b/client/packages/lowcoder/src/pages/setting/environments/services/apps.service.ts @@ -1,5 +1,6 @@ // services/appService.ts import { messageInstance } from "lowcoder-design/src/components/GlobalInstances"; +import { trans } from "i18n"; import { getWorkspaceApps } from "./environments.service"; import { getManagedApps } from "./enterprise.service"; import { App, AppStats } from "../types/app.types"; @@ -99,7 +100,7 @@ export async function getMergedWorkspaceApps( }; } catch (error) { const errorMessage = - error instanceof Error ? error.message : "Failed to fetch apps"; + error instanceof Error ? error.message : trans("enterprise.environments.services.apps.failedToFetchApps"); messageInstance.error(errorMessage); throw error; } @@ -137,7 +138,7 @@ export const deployApp = async (params: DeployAppParams): Promise => { return response.status === 200; } catch (error) { - const errorMessage = error instanceof Error ? error.message : 'Failed to deploy app'; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.apps.failedToDeployApp"); // Don't show message directly, let the calling component handle it throw new Error(errorMessage); } diff --git a/client/packages/lowcoder/src/pages/setting/environments/services/datasources.service.ts b/client/packages/lowcoder/src/pages/setting/environments/services/datasources.service.ts index 2fc492028..a14fe941b 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/services/datasources.service.ts +++ b/client/packages/lowcoder/src/pages/setting/environments/services/datasources.service.ts @@ -1,6 +1,7 @@ // services/dataSources.service.ts import axios from 'axios'; import { messageInstance } from "lowcoder-design/src/components/GlobalInstances"; +import { trans } from "i18n"; import { DataSource, DataSourceWithMeta } from "../types/datasource.types"; import { getManagedObjects, ManagedObject, ManagedObjectType , transferManagedObject } from "./managed-objects.service"; @@ -32,15 +33,15 @@ export async function getWorkspaceDataSources( try { // Check if required parameters are provided if (!workspaceId) { - throw new Error('Workspace ID is required'); + throw new Error(trans("enterprise.environments.services.datasources.workspaceIdRequired")); } if (!apiKey) { - throw new Error('API key is required to fetch data sources'); + throw new Error(trans("enterprise.environments.services.datasources.apiKeyRequiredToFetchDataSources")); } if (!apiServiceUrl) { - throw new Error('API service URL is required to fetch data sources'); + throw new Error(trans("enterprise.environments.services.datasources.apiServiceUrlRequiredToFetchDataSources")); } // Set up headers with the Bearer token format @@ -64,7 +65,7 @@ export async function getWorkspaceDataSources( return response.data.data; } catch (error) { // Handle and transform error - const errorMessage = error instanceof Error ? error.message : 'Failed to fetch data sources'; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.datasources.failedToFetchDataSources"); messageInstance.error(errorMessage); throw error; } @@ -143,7 +144,7 @@ export async function getMergedWorkspaceDataSources( }; } catch (error) { const errorMessage = - error instanceof Error ? error.message : "Failed to fetch data sources"; + error instanceof Error ? error.message : trans("enterprise.environments.services.datasources.failedToFetchDataSources"); messageInstance.error(errorMessage); throw error; } @@ -170,7 +171,7 @@ export async function deployDataSource(params: DeployDataSourceParams): Promise< } return response.status === 200; } catch (error) { - const errorMessage = error instanceof Error ? error.message : 'Failed to deploy data source'; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.datasources.failedToDeployDataSource"); messageInstance.error(errorMessage); throw error; } diff --git a/client/packages/lowcoder/src/pages/setting/environments/services/enterprise.service.ts b/client/packages/lowcoder/src/pages/setting/environments/services/enterprise.service.ts index f676f1734..208085c69 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/services/enterprise.service.ts +++ b/client/packages/lowcoder/src/pages/setting/environments/services/enterprise.service.ts @@ -1,5 +1,6 @@ import axios from "axios"; import { messageInstance } from "lowcoder-design/src/components/GlobalInstances"; +import { trans } from "i18n"; import { ManagedOrg } from "../types/enterprise.types"; import { Query } from "../types/query.types"; @@ -17,7 +18,7 @@ export async function getManagedWorkspaces( ): Promise { if (!environmentId) { - throw new Error("Missing environmentId"); + throw new Error(trans("enterprise.environments.services.enterprise.missingEnvironmentId")); } try { @@ -25,7 +26,7 @@ export async function getManagedWorkspaces( const all: ManagedOrg[] = res.data.data; return all.filter(org => org.environmentId === environmentId); } catch (err) { - const errorMsg = err instanceof Error ? err.message : "Failed to fetch managed workspaces"; + const errorMsg = err instanceof Error ? err.message : trans("enterprise.environments.services.enterprise.failedToFetchManagedWorkspaces"); messageInstance.error(errorMsg); throw err; } @@ -48,7 +49,7 @@ export async function connectManagedWorkspace( orgTags: string[] = [], ) { if (!environmentId || !orgName || !org_gid) { - throw new Error("Missing required params to connect org"); + throw new Error(trans("enterprise.environments.services.enterprise.missingRequiredParamsToConnectOrg")); } try { @@ -62,7 +63,7 @@ export async function connectManagedWorkspace( const res = await axios.post(`/api/plugins/enterprise/org`, payload); return res.data; } catch (err) { - const errorMsg = err instanceof Error ? err.message : "Failed to connect org"; + const errorMsg = err instanceof Error ? err.message : trans("enterprise.environments.services.enterprise.failedToConnectOrg"); messageInstance.error(errorMsg); throw err; } @@ -78,7 +79,7 @@ export async function connectManagedWorkspace( */ export async function unconnectManagedWorkspace(orgGid: string) { if (!orgGid) { - throw new Error("Missing orgGid to unconnect workspace"); + throw new Error(trans("enterprise.environments.services.enterprise.missingOrgGidToUnconnectWorkspace")); } try { @@ -87,7 +88,7 @@ export async function unconnectManagedWorkspace(orgGid: string) { }); } catch (err) { const errorMsg = - err instanceof Error ? err.message : "Failed to unconnect org"; + err instanceof Error ? err.message : trans("enterprise.environments.services.enterprise.failedToUnconnectOrg"); messageInstance.error(errorMsg); throw err; } @@ -123,7 +124,7 @@ export async function connectManagedApp( return res.data; } catch (err) { const errorMsg = - err instanceof Error ? err.message : "Failed to connect app"; + err instanceof Error ? err.message : trans("enterprise.environments.services.enterprise.failedToConnectApp"); messageInstance.error(errorMsg); throw err; } @@ -136,7 +137,7 @@ export async function unconnectManagedApp(appGid: string) { params: { appGid }, }); } catch (err) { - const errorMsg = err instanceof Error ? err.message : "Failed to unconnect app"; + const errorMsg = err instanceof Error ? err.message : trans("enterprise.environments.services.enterprise.failedToUnconnectApp"); messageInstance.error(errorMsg); throw err; } @@ -151,7 +152,7 @@ export const getManagedDataSources = async (environmentId: string): Promise { try { if (!environmentId) { - throw new Error('Environment ID is required'); + throw new Error(trans("enterprise.environments.services.enterprise.environmentIdRequired")); } // Get managed queries from the enterprise endpoint @@ -226,7 +227,7 @@ export async function getManagedQueries(environmentId: string): Promise })); } catch (error) { - const errorMsg = error instanceof Error ? error.message : 'Failed to fetch queries'; + const errorMsg = error instanceof Error ? error.message : trans("enterprise.environments.services.enterprise.failedToFetchQueries"); messageInstance.error(errorMsg); throw error; } @@ -240,7 +241,7 @@ export async function connectManagedQuery( ): Promise { try { if (!environmentId || !queryGid) { - throw new Error('Environment ID and Query GID are required'); + throw new Error(trans("enterprise.environments.services.enterprise.environmentIdAndQueryGidRequired")); } const response = await axios.post('/api/plugins/enterprise/qlQuery', { @@ -253,7 +254,7 @@ export async function connectManagedQuery( return response.status === 200; } catch (error) { - const errorMsg = error instanceof Error ? error.message : 'Failed to deploy query'; + const errorMsg = error instanceof Error ? error.message : trans("enterprise.environments.services.enterprise.failedToDeployQuery"); messageInstance.error(errorMsg); throw error; } @@ -263,7 +264,7 @@ export async function connectManagedQuery( export async function unconnectManagedQuery(queryGid: string): Promise { try { if (!queryGid) { - throw new Error('Query GID is required'); + throw new Error(trans("enterprise.environments.services.enterprise.queryGidRequired")); } const response = await axios.delete(`/api/plugins/enterprise/qlQuery`, { @@ -275,7 +276,7 @@ export async function unconnectManagedQuery(queryGid: string): Promise return response.status === 200; } catch (error) { - const errorMsg = error instanceof Error ? error.message : 'Failed to disconnect query'; + const errorMsg = error instanceof Error ? error.message : trans("enterprise.environments.services.enterprise.failedToDisconnectQuery"); messageInstance.error(errorMsg); throw error; } diff --git a/client/packages/lowcoder/src/pages/setting/environments/services/environments.service.ts b/client/packages/lowcoder/src/pages/setting/environments/services/environments.service.ts index f818f3599..a781184f4 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/services/environments.service.ts +++ b/client/packages/lowcoder/src/pages/setting/environments/services/environments.service.ts @@ -1,5 +1,6 @@ import axios from "axios"; import { messageInstance } from "lowcoder-design/src/components/GlobalInstances"; +import { trans } from "i18n"; import { Environment } from "../types/environment.types"; import { Workspace } from "../types/workspace.types"; import { UserGroup } from "../types/userGroup.types"; @@ -7,14 +8,13 @@ import {App} from "../types/app.types"; import { DataSourceWithMeta } from '../types/datasource.types'; import { Query, QueryResponse } from "../types/query.types"; import { checkEnvironmentLicense } from './license.service'; -import { trans } from "i18n"; export async function updateEnvironment( environmentId: string, environmentData: Partial ): Promise { if (!environmentId) { - throw new Error("Missing environmentId"); + throw new Error(trans("enterprise.environments.services.environments.missingEnvironmentId")); } try { @@ -37,7 +37,7 @@ export async function updateEnvironment( return res.data; } catch (err) { - const errorMsg = err instanceof Error ? err.message : "Failed to update environment"; + const errorMsg = err instanceof Error ? err.message : trans("enterprise.environments.services.environments.failedToUpdateEnvironment"); messageInstance.error(errorMsg); throw err; } @@ -68,13 +68,13 @@ export async function createEnvironment( const res = await axios.post(`/api/plugins/enterprise/environments`, payload); if (res.data) { - messageInstance.success("Environment created successfully"); + messageInstance.success(trans("enterprise.environments.services.environments.environmentCreatedSuccessfully")); return res.data; } else { - throw new Error("Failed to create environment"); + throw new Error(trans("enterprise.environments.services.environments.failedToCreateEnvironment")); } } catch (err) { - const errorMsg = err instanceof Error ? err.message : "Failed to create environment"; + const errorMsg = err instanceof Error ? err.message : trans("enterprise.environments.services.environments.failedToCreateEnvironment"); messageInstance.error(errorMsg); throw err; } @@ -95,7 +95,7 @@ export async function getEnvironments(): Promise { return response.data.data || []; } catch (error) { const errorMessage = - error instanceof Error ? error.message : "Failed to fetch environments"; + error instanceof Error ? error.message : trans("enterprise.environments.services.environments.failedToFetchEnvironments"); messageInstance.error(errorMessage); throw error; } @@ -113,7 +113,7 @@ export async function getEnvironmentById(id: string): Promise { ); if (!response.data) { - throw new Error("Failed to fetch environment"); + throw new Error(trans("enterprise.environments.services.environments.failedToFetchEnvironment")); } const environment = response.data.data; @@ -138,18 +138,18 @@ export async function getEnvironmentById(id: string): Promise { } else { envWithLicense.isLicensed = false; envWithLicense.licenseStatus = 'error'; - envWithLicense.licenseError = 'API service URL not configured'; + envWithLicense.licenseError = trans("enterprise.environments.services.environments.apiServiceUrlNotConfigured"); } } catch (error) { envWithLicense.isLicensed = false; envWithLicense.licenseStatus = 'error'; - envWithLicense.licenseError = error instanceof Error ? error.message : 'License check failed'; + envWithLicense.licenseError = error instanceof Error ? error.message : trans("enterprise.environments.services.environments.licenseCheckFailed"); } return envWithLicense; } catch (error) { const errorMessage = - error instanceof Error ? error.message : "Failed to fetch environment"; + error instanceof Error ? error.message : trans("enterprise.environments.services.environments.failedToFetchEnvironment"); messageInstance.error(errorMessage); throw error; } @@ -175,14 +175,14 @@ export async function getEnvironmentWorkspaces( try { // Check if required parameters are provided if (!environmentId) { - throw new Error("Environment ID is required"); + throw new Error(trans("enterprise.environments.services.environments.environmentIdRequired")); } if (!apiKey) { - throw new Error("API key is required to fetch workspaces"); + throw new Error(trans("enterprise.environments.services.environments.apiKeyRequiredForWorkspaces")); } if (!apiServiceUrl) { - throw new Error('API service URL is required to fetch workspaces'); + throw new Error(trans("enterprise.environments.services.environments.apiServiceUrlRequiredForWorkspaces")); } // Set up headers with the API key @@ -195,7 +195,7 @@ export async function getEnvironmentWorkspaces( // Check if response is valid if (!response.data || !response.data.success) { - throw new Error(response.data?.message || "Failed to fetch workspaces"); + throw new Error(response.data?.message || trans("enterprise.environments.services.environments.failedToFetchWorkspaces")); } // Extract workspaces from the response @@ -222,7 +222,7 @@ export async function getEnvironmentWorkspaces( } catch (error) { // Handle and transform error const errorMessage = - error instanceof Error ? error.message : "Failed to fetch workspaces"; + error instanceof Error ? error.message : trans("enterprise.environments.services.environments.failedToFetchWorkspaces"); messageInstance.error(errorMessage); throw error; } @@ -242,15 +242,15 @@ export async function getEnvironmentUserGroups( try { // Check if required parameters are provided if (!environmentId) { - throw new Error('Environment ID is required'); + throw new Error(trans("enterprise.environments.services.environments.environmentIdRequired")); } if (!apiKey) { - throw new Error('API key is required to fetch user groups'); + throw new Error(trans("enterprise.environments.services.environments.apiKeyRequiredForUserGroups")); } if (!apiServiceUrl) { - throw new Error('API service URL is required to fetch user groups'); + throw new Error(trans("enterprise.environments.services.environments.apiServiceUrlRequiredForUserGroups")); } // Set up headers with the Bearer token format @@ -263,7 +263,7 @@ export async function getEnvironmentUserGroups( // Check if response is valid if (!response.data) { - throw new Error('Failed to fetch user groups'); + throw new Error(trans("enterprise.environments.services.environments.failedToFetchUserGroups")); } // The response data is already an array of user groups @@ -272,7 +272,7 @@ export async function getEnvironmentUserGroups( return userGroups; } catch (error) { // Handle and transform error - const errorMessage = error instanceof Error ? error.message : 'Failed to fetch user groups'; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.environments.failedToFetchUserGroups"); messageInstance.error(errorMessage); throw error; } @@ -339,15 +339,15 @@ export async function getWorkspaceApps( try { // Check if required parameters are provided if (!workspaceId) { - throw new Error('Workspace ID is required'); + throw new Error(trans("enterprise.environments.services.environments.workspaceIdRequired")); } if (!apiKey) { - throw new Error('API key is required to fetch apps'); + throw new Error(trans("enterprise.environments.services.environments.apiKeyRequiredForApps")); } if (!apiServiceUrl) { - throw new Error('API service URL is required to fetch apps'); + throw new Error(trans("enterprise.environments.services.environments.apiServiceUrlRequiredForApps")); } // Set up headers with the Bearer token format @@ -382,7 +382,7 @@ export async function getWorkspaceApps( } catch (error) { // Handle and transform error - const errorMessage = error instanceof Error ? error.message : 'Failed to fetch workspace apps'; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.environments.failedToFetchWorkspaceApps"); messageInstance.error(errorMessage); throw error; } @@ -408,15 +408,15 @@ export async function getWorkspaceDataSources( try { // Check if required parameters are provided if (!workspaceId) { - throw new Error('Workspace ID is required'); + throw new Error(trans("enterprise.environments.services.environments.workspaceIdRequired")); } if (!apiKey) { - throw new Error('API key is required to fetch data sources'); + throw new Error(trans("enterprise.environments.services.environments.apiKeyRequiredForDataSources")); } if (!apiServiceUrl) { - throw new Error('API service URL is required to fetch data sources'); + throw new Error(trans("enterprise.environments.services.environments.apiServiceUrlRequiredForDataSources")); } // Set up headers with the Bearer token format @@ -440,7 +440,7 @@ export async function getWorkspaceDataSources( return response.data.data ; } catch (error) { // Handle and transform error - const errorMessage = error instanceof Error ? error.message : 'Failed to fetch workspace data sources'; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.environments.failedToFetchWorkspaceDataSources"); messageInstance.error(errorMessage); throw error; } @@ -469,15 +469,15 @@ export async function getWorkspaceQueries( try { // Check if required parameters are provided if (!workspaceId) { - throw new Error('Workspace ID is required'); + throw new Error(trans("enterprise.environments.services.environments.workspaceIdRequired")); } if (!apiKey) { - throw new Error('API key is required to fetch queries'); + throw new Error(trans("enterprise.environments.services.environments.apiKeyRequiredForQueries")); } if (!apiServiceUrl) { - throw new Error('API service URL is required to fetch queries'); + throw new Error(trans("enterprise.environments.services.environments.apiServiceUrlRequiredForQueries")); } // Set up headers with the Bearer token format @@ -522,7 +522,7 @@ export async function getWorkspaceQueries( } catch (error) { // Handle and transform error - const errorMessage = error instanceof Error ? error.message : 'Failed to fetch workspace queries'; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.environments.failedToFetchWorkspaceQueries"); messageInstance.error(errorMessage); throw error; } @@ -559,12 +559,12 @@ export async function getEnvironmentsWithLicenseStatus(): Promise } else { envWithLicense.isLicensed = false; envWithLicense.licenseStatus = 'error'; - envWithLicense.licenseError = 'API service URL not configured'; + envWithLicense.licenseError = trans("enterprise.environments.services.environments.apiServiceUrlNotConfigured"); } } catch (error) { envWithLicense.isLicensed = false; envWithLicense.licenseStatus = 'error'; - envWithLicense.licenseError = error instanceof Error ? error.message : 'License check failed'; + envWithLicense.licenseError = error instanceof Error ? error.message : trans("enterprise.environments.services.environments.licenseCheckFailed"); } return envWithLicense; @@ -574,7 +574,7 @@ export async function getEnvironmentsWithLicenseStatus(): Promise return environmentsWithLicense; } catch (error) { const errorMessage = - error instanceof Error ? error.message : "Failed to fetch environments"; + error instanceof Error ? error.message : trans("enterprise.environments.services.environments.failedToFetchEnvironments"); messageInstance.error(errorMessage); throw error; } @@ -593,11 +593,11 @@ export async function getEnvironmentDeploymentId( try { // Check if required parameters are provided if (!apiServiceUrl) { - throw new Error('API service URL is required'); + throw new Error(trans("enterprise.environments.services.environments.apiServiceUrlRequiredForWorkspaces")); } if (!apiKey) { - throw new Error('API key is required to fetch deployment ID'); + throw new Error(trans("enterprise.environments.services.environments.apiKeyRequiredForDeploymentId")); } // Set up headers with the Bearer token format @@ -610,14 +610,14 @@ export async function getEnvironmentDeploymentId( // Check if response is valid if (!response.data) { - throw new Error('Failed to fetch deployment ID'); + throw new Error(trans("enterprise.environments.services.environments.failedToFetchDeploymentId")); } // The response should return a string directly return response.data; } catch (error) { // Handle and transform error - const errorMessage = error instanceof Error ? error.message : 'Failed to fetch deployment ID'; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.environments.failedToFetchDeploymentId"); messageInstance.error(errorMessage); throw error; } diff --git a/client/packages/lowcoder/src/pages/setting/environments/services/license.service.ts b/client/packages/lowcoder/src/pages/setting/environments/services/license.service.ts index ebc0ae46a..e2fac5ef6 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/services/license.service.ts +++ b/client/packages/lowcoder/src/pages/setting/environments/services/license.service.ts @@ -1,4 +1,5 @@ import axios from 'axios'; +import { trans } from 'i18n'; import { EnvironmentLicense, DetailedLicenseInfo } from '../types/environment.types'; /** @@ -15,7 +16,7 @@ export async function checkEnvironmentLicense( if (!apiServiceUrl) { return { isValid: false, - error: 'API service URL is required' + error: trans('enterprise.environments.services.license.apiServiceUrlRequired') }; } @@ -30,7 +31,7 @@ export async function checkEnvironmentLicense( `${apiServiceUrl}/api/plugins/enterprise/license`, { headers, - timeout: 500 // Very short timeout for immediate failure when endpoint doesn't exist + timeout: 1500 // Very short timeout for immediate failure when endpoint doesn't exist } ); @@ -65,17 +66,17 @@ export async function checkEnvironmentLicense( } catch (error) { // Determine the specific error type - let errorMessage = 'License information unavailable'; + let errorMessage = trans('enterprise.environments.services.license.licenseInformationUnavailable'); if (axios.isAxiosError(error)) { if (error.code === 'ECONNABORTED') { - errorMessage = 'License check took too long'; + errorMessage = trans('enterprise.environments.services.license.licenseCheckTookTooLong'); } else if (error.response?.status === 404) { - errorMessage = 'License service not available'; + errorMessage = trans('enterprise.environments.services.license.licenseServiceNotAvailable'); } else if (error.response?.status === 401) { - errorMessage = 'Authentication required - please check API key'; + errorMessage = trans('enterprise.environments.services.license.authenticationRequired'); } else if (error.response && error.response.status >= 500) { - errorMessage = 'License service temporarily unavailable'; + errorMessage = trans('enterprise.environments.services.license.licenseServiceTemporarilyUnavailable'); } } @@ -96,7 +97,12 @@ export function formatAPICalls(remaining: number, total: number): string { const used = total - remaining; const percentage = total > 0 ? Math.round((used / total) * 100) : 0; - return `${remaining.toLocaleString()} remaining (${used.toLocaleString()}/${total.toLocaleString()} used, ${percentage}%)`; + return trans('enterprise.environments.services.license.remainingAPICalls', { + remaining: remaining.toLocaleString(), + used: used.toLocaleString(), + total: total.toLocaleString(), + percentage + }); } /** diff --git a/client/packages/lowcoder/src/pages/setting/environments/services/managed-objects.service.ts b/client/packages/lowcoder/src/pages/setting/environments/services/managed-objects.service.ts index 0a4e0b14a..e70322221 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/services/managed-objects.service.ts +++ b/client/packages/lowcoder/src/pages/setting/environments/services/managed-objects.service.ts @@ -1,5 +1,6 @@ import axios from "axios"; import { messageInstance } from "lowcoder-design/src/components/GlobalInstances"; +import { trans } from "i18n"; // Object types that can be managed export enum ManagedObjectType { @@ -32,7 +33,7 @@ export async function isManagedObject( ): Promise { try { if (!objGid || !environmentId || !objType) { - throw new Error("Missing required parameters"); + throw new Error(trans("enterprise.environments.services.managedObjects.missingRequiredParameters")); } const response = await axios.get(`/api/plugins/enterprise/managed-obj`, { @@ -50,7 +51,7 @@ export async function isManagedObject( return false; } - const errorMessage = error instanceof Error ? error.message : "Failed to check managed status"; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.managedObjects.failedToCheckManagedStatus"); messageInstance.error(errorMessage); throw error; } @@ -73,7 +74,7 @@ export async function setManagedObject( ): Promise { try { if (!objGid || !environmentId || !objType) { - throw new Error("Missing required parameters"); + throw new Error(trans("enterprise.environments.services.managedObjects.missingRequiredParameters")); } const requestBody = { @@ -87,7 +88,7 @@ export async function setManagedObject( return response.status === 200; } catch (error) { - const errorMessage = error instanceof Error ? error.message : `Failed to set ${objType} as managed`; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.managedObjects.failedToSetAsManaged", { objType }); messageInstance.error(errorMessage); throw error; } @@ -108,7 +109,7 @@ export async function unsetManagedObject( ): Promise { try { if (!objGid || !environmentId || !objType) { - throw new Error("Missing required parameters"); + throw new Error(trans("enterprise.environments.services.managedObjects.missingRequiredParameters")); } const response = await axios.delete(`/api/plugins/enterprise/managed-obj`, { @@ -121,7 +122,7 @@ export async function unsetManagedObject( return response.status === 200; } catch (error) { - const errorMessage = error instanceof Error ? error.message : `Failed to remove ${objType} from managed`; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.managedObjects.failedToRemoveFromManaged", { objType }); messageInstance.error(errorMessage); throw error; } @@ -134,7 +135,7 @@ export async function getManagedObjects( ): Promise { try { if (!environmentId) { - throw new Error("Missing environment ID"); + throw new Error(trans("enterprise.environments.services.managedObjects.missingEnvironmentId")); } const response = await axios.get(`/api/plugins/enterprise/managed-obj/list`, { @@ -146,7 +147,7 @@ export async function getManagedObjects( return response.data.data; } catch (error) { - const errorMessage = error instanceof Error ? error.message : "Failed to fetch managed objects"; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.managedObjects.failedToFetchManagedObjects"); messageInstance.error(errorMessage); throw error; } @@ -166,7 +167,7 @@ export async function getSingleManagedObject( ): Promise { try { if (!objGid || !environmentId || !objType) { - throw new Error("Missing required parameters"); + throw new Error(trans("enterprise.environments.services.managedObjects.missingRequiredParameters")); } const response = await axios.get(`/api/plugins/enterprise/managed-obj`, { @@ -184,7 +185,7 @@ export async function getSingleManagedObject( return null; } - const errorMessage = error instanceof Error ? error.message : "Failed to fetch managed object"; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.managedObjects.failedToFetchManagedObject"); messageInstance.error(errorMessage); throw error; } @@ -197,7 +198,7 @@ export async function transferManagedObject(objGid: string, sourceEnvId: string, if (managedObject) { await setManagedObject(managedObject.objGid, targetEnvId, objType, managedObject.managedId); } else { - throw new Error(`Managed object not found for objGid: ${objGid}`); + throw new Error(trans("enterprise.environments.services.managedObjects.managedObjectNotFound", { objGid })); } } catch (error) { console.error('Error transferring managed object:', error); diff --git a/client/packages/lowcoder/src/pages/setting/environments/services/query.service.ts b/client/packages/lowcoder/src/pages/setting/environments/services/query.service.ts index 20b79f4ee..a79f10f87 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/services/query.service.ts +++ b/client/packages/lowcoder/src/pages/setting/environments/services/query.service.ts @@ -2,6 +2,7 @@ * Get merged queries (both regular and managed) for a workspace */ import axios from 'axios'; +import { trans } from 'i18n'; import { getManagedObjects, ManagedObjectType, transferManagedObject } from './managed-objects.service'; import { getWorkspaceQueries } from './environments.service'; import { Query, QueryStats } from '../types/query.types'; diff --git a/client/packages/lowcoder/src/pages/setting/environments/services/workspace.service.ts b/client/packages/lowcoder/src/pages/setting/environments/services/workspace.service.ts index b7cf4a37c..6cbe947ab 100644 --- a/client/packages/lowcoder/src/pages/setting/environments/services/workspace.service.ts +++ b/client/packages/lowcoder/src/pages/setting/environments/services/workspace.service.ts @@ -1,5 +1,6 @@ // services/workspacesService.ts (or wherever makes sense in your structure) import { messageInstance } from "lowcoder-design/src/components/GlobalInstances"; +import { trans } from "i18n"; import { getEnvironmentWorkspaces } from "./environments.service"; import { getManagedObjects, ManagedObject, ManagedObjectType, transferManagedObject } from "./managed-objects.service"; import { Workspace } from "../types/workspace.types"; @@ -69,7 +70,7 @@ export async function getMergedEnvironmentWorkspaces( } }; } catch (error) { - const errorMessage = error instanceof Error ? error.message : "Failed to fetch workspaces"; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.workspace.failedToFetchWorkspaces"); messageInstance.error(errorMessage); throw error; } @@ -107,7 +108,7 @@ export async function deployWorkspace(params: { return response.status === 200; } catch (error) { - const errorMessage = error instanceof Error ? error.message : 'Failed to deploy workspace'; + const errorMessage = error instanceof Error ? error.message : trans("enterprise.environments.services.workspace.failedToDeployWorkspace"); // Don't show message directly, let the calling component handle it throw new Error(errorMessage); }