From 6b0f361c7cd718376340402acd17566f858ffc70 Mon Sep 17 00:00:00 2001 From: brookshi Date: Wed, 28 Feb 2018 18:44:59 +0800 Subject: [PATCH 01/12] multiple language support --- client/package.json | 5 +++-- client/src/App.tsx | 3 ++- client/src/index.tsx | 17 ++++++++++++++--- client/src/locales/en.json | 3 +++ client/src/locales/index.tsx | 8 ++++++++ client/src/locales/lang.ts | 24 ++++++++++++++++++++++++ client/src/locales/zh.json | 3 +++ client/src/utils/global_var.ts | 2 ++ 8 files changed, 59 insertions(+), 6 deletions(-) create mode 100644 client/src/locales/en.json create mode 100644 client/src/locales/index.tsx create mode 100644 client/src/locales/lang.ts create mode 100644 client/src/locales/zh.json diff --git a/client/package.json b/client/package.json index 9316cb4..eb10393 100644 --- a/client/package.json +++ b/client/package.json @@ -16,7 +16,8 @@ "react-ace": "5.8.0", "react-copy-to-clipboard": "5.0.0", "react-dom": "15.5.4", - "react-json-tree": "^0.11.0", + "react-intl": "2.4.0", + "react-json-tree": "0.11.0", "react-perfect-scrollbar": "0.2.1", "react-redux": "5.0.5", "react-sortable-hoc": "0.6.3", @@ -120,4 +121,4 @@ "theme": { "@icon-url": "'/static/fonts/iconfont'" } -} +} \ No newline at end of file diff --git a/client/src/App.tsx b/client/src/App.tsx index fe6e51f..d7f61a5 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -19,6 +19,7 @@ import Perf from 'react-addons-perf'; import './style/App.less'; import * as _ from 'lodash'; import { toolBarWidth } from './common/constants'; +import Msg from './locales'; const { Header, Sider } = Layout; @@ -102,7 +103,7 @@ class App extends React.Component { onClick={this.onClick} > - + diff --git a/client/src/index.tsx b/client/src/index.tsx index 6dcbc7f..79729f0 100644 --- a/client/src/index.tsx +++ b/client/src/index.tsx @@ -2,14 +2,25 @@ import * as React from 'react'; import * as ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { store } from './store'; +import * as l from './locales/lang'; import App from './App'; import LocalStore from './utils/local_store'; +import { LocaleProvider } from 'antd'; +import { addLocaleData, IntlProvider } from 'react-intl'; + +const appLocale = l.language['zh']; + +addLocaleData(appLocale.data); LocalStore.init(); ReactDOM.render( - - - , + + + + + + + , document.getElementById('root') as HTMLElement ); \ No newline at end of file diff --git a/client/src/locales/en.json b/client/src/locales/en.json new file mode 100644 index 0000000..6eec0e3 --- /dev/null +++ b/client/src/locales/en.json @@ -0,0 +1,3 @@ +{ + "App.Collections": "Collections" +} \ No newline at end of file diff --git a/client/src/locales/index.tsx b/client/src/locales/index.tsx new file mode 100644 index 0000000..784f767 --- /dev/null +++ b/client/src/locales/index.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { FormattedMessage } from 'react-intl'; + +export default function (msgID: string) { + return ( + + ); +} \ No newline at end of file diff --git a/client/src/locales/lang.ts b/client/src/locales/lang.ts new file mode 100644 index 0000000..f217012 --- /dev/null +++ b/client/src/locales/lang.ts @@ -0,0 +1,24 @@ +import antdEn from 'antd/lib/locale-provider/en_US'; +import appLocaleDataEn from 'react-intl/locale-data/en'; +import appLocaleDataZh from 'react-intl/locale-data/zh'; +const enMessages = require('./en'); +const zhMessages = require('./zh'); + +export const language = { + en: { + messages: { + ...enMessages, + }, + antd: antdEn, + locale: 'en-US', + data: appLocaleDataEn + }, + zh: { + messages: { + ...zhMessages, + }, + antd: {}, + locale: 'zh-Hans-CN', + data: appLocaleDataZh + } +}; \ No newline at end of file diff --git a/client/src/locales/zh.json b/client/src/locales/zh.json new file mode 100644 index 0000000..86353eb --- /dev/null +++ b/client/src/locales/zh.json @@ -0,0 +1,3 @@ +{ + "App.Collections": "集合" +} \ No newline at end of file diff --git a/client/src/utils/global_var.ts b/client/src/utils/global_var.ts index 16dc26a..8fd5392 100644 --- a/client/src/utils/global_var.ts +++ b/client/src/utils/global_var.ts @@ -11,4 +11,6 @@ export class GlobalVar { enableUploadProjectData: boolean = true; schedulePageSize: number = 50; + + lang = 'cn'; } \ No newline at end of file From 1faab702b14034e8a54a2f9fdb06cd0170a341a8 Mon Sep 17 00:00:00 2001 From: brookshi Date: Thu, 1 Mar 2018 18:37:28 +0800 Subject: [PATCH 02/12] multiple lang for collection, project --- client/src/App.tsx | 10 +- client/src/components/confirm_dialog/index.ts | 10 +- .../item_with_menu/style/index.less | 2 +- client/src/components/name_with_tag/index.tsx | 2 +- client/src/components/script_dialog/index.tsx | 2 +- client/src/index.tsx | 2 +- client/src/locales/en.json | 164 +++++++++++++++++- client/src/locales/index.tsx | 4 +- client/src/locales/input.tsx | 24 +++ client/src/locales/zh.json | 26 +++ .../collection_tree/collection_item.tsx | 28 +-- .../collection/collection_tree/index.tsx | 45 ++--- .../collection_tree/record_folder.tsx | 9 +- .../collection_tree/record_item.tsx | 9 +- .../collection_tree/style/index.less | 2 +- .../req_res_panel/environment_select.tsx | 11 +- .../collection/req_res_panel/index.tsx | 15 +- .../req_res_panel/request_name_panel.tsx | 17 +- .../req_res_panel/request_option_panel.tsx | 77 ++++---- .../req_res_panel/request_tab_extra.tsx | 5 +- .../req_res_panel/request_url_panel.tsx | 26 +-- .../req_res_panel/response_loading_panel.tsx | 3 +- .../req_res_panel/response_panel.tsx | 39 ++--- .../modules/header/change_password_dialog.tsx | 38 ++-- client/src/modules/header/index.tsx | 24 +-- client/src/modules/login/find_password.tsx | 18 +- client/src/modules/login/index.tsx | 9 +- client/src/modules/login/login.tsx | 26 +-- client/src/modules/login/register.tsx | 36 ++-- client/src/modules/project/environments.tsx | 27 ++- client/src/modules/project/members.tsx | 32 ++-- .../modules/project/project_data_dialog.tsx | 23 +-- client/src/modules/project/project_item.tsx | 18 +- client/src/modules/project/project_list.tsx | 9 +- .../modules/schedule/schedule_edit_dialog.tsx | 45 +++-- client/src/modules/schedule/schedule_item.tsx | 6 +- .../src/modules/stress_test/stress_item.tsx | 6 +- 37 files changed, 563 insertions(+), 286 deletions(-) create mode 100644 client/src/locales/input.tsx diff --git a/client/src/App.tsx b/client/src/App.tsx index d7f61a5..1680ef4 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -108,27 +108,27 @@ class App extends React.Component { - + - + - + - + - + diff --git a/client/src/components/confirm_dialog/index.ts b/client/src/components/confirm_dialog/index.ts index d682340..b579c2d 100644 --- a/client/src/components/confirm_dialog/index.ts +++ b/client/src/components/confirm_dialog/index.ts @@ -1,12 +1,12 @@ import { Modal } from 'antd'; -import { StringUtil } from '../../utils/string_util'; +import Msg from '../../locales'; -export function confirmDlg(type: string, onOk: (func: Function) => any, action: string = 'delete', target: string = '') { +export function confirmDlg(title: string | React.ReactNode, onOk: (func: Function) => any, action: string | React.ReactNode = 'delete') { Modal.confirm({ - title: `${StringUtil.upperFirstAlphabet(action)} ${type}`, - content: `You want to ${action} this ${type}${target ? ': ' : ''}${target}, right?`, + title, + content: Msg('Common.ConfirmContent', { action }), okText: 'Yes', cancelText: 'No', - onOk: onOk, + onOk, }); } \ No newline at end of file diff --git a/client/src/components/item_with_menu/style/index.less b/client/src/components/item_with_menu/style/index.less index 0f88994..678e378 100644 --- a/client/src/components/item_with_menu/style/index.less +++ b/client/src/components/item_with_menu/style/index.less @@ -24,7 +24,7 @@ &::before { display: none; } -} +} .item-with-menu-icon { display: none; diff --git a/client/src/components/name_with_tag/index.tsx b/client/src/components/name_with_tag/index.tsx index 35bb752..4f0207c 100644 --- a/client/src/components/name_with_tag/index.tsx +++ b/client/src/components/name_with_tag/index.tsx @@ -1,7 +1,7 @@ import './style/index.less'; import React from 'react'; -export const nameWithTag = (name: string, tag: string, type: 'normal' | 'warning' = 'normal') => ( +export const nameWithTag = (name: string | React.ReactNode, tag: string, type: 'normal' | 'warning' = 'normal') => (
{name} { diff --git a/client/src/components/script_dialog/index.tsx b/client/src/components/script_dialog/index.tsx index 05bc4fc..3126426 100644 --- a/client/src/components/script_dialog/index.tsx +++ b/client/src/components/script_dialog/index.tsx @@ -4,7 +4,7 @@ import Editor from '../editor'; interface ScriptDialogProps { - title: string; + title: string | React.ReactNode; isOpen: boolean; diff --git a/client/src/index.tsx b/client/src/index.tsx index 79729f0..339c79a 100644 --- a/client/src/index.tsx +++ b/client/src/index.tsx @@ -8,7 +8,7 @@ import LocalStore from './utils/local_store'; import { LocaleProvider } from 'antd'; import { addLocaleData, IntlProvider } from 'react-intl'; -const appLocale = l.language['zh']; +const appLocale = l.language['en']; addLocaleData(appLocale.data); diff --git a/client/src/locales/en.json b/client/src/locales/en.json index 6eec0e3..63ce437 100644 --- a/client/src/locales/en.json +++ b/client/src/locales/en.json @@ -1,3 +1,165 @@ { - "App.Collections": "Collections" + "Common.Submit": "Submit", + "Common.Cancel": "Cancel", + "Common.OK": "OK", + "Common.Edit": "Edit", + "Common.WarningMsg": "Warning Message", + "Common.Rename": "Rename", + "Common.Delete": "Delete", + "Common.Copy": "Copy", + "Common.Duplicate": "Duplicate", + "Common.DontSave": "Don't Save", + "Common.Save": "Save", + "Common.SaveAs": "Save As", + "Common.Send": "Send", + "Common.MicroSecond": "ms", + "Common.delete": "delete", + "Common.ConfirmContent": "You want to {action}, right?", + "Common.SureDelete": "Sure to delete?", + + "Login.Desc.Title": "Api integrated testing tool for team", + "Login.Desc.Content": "Hitchhiker is an {opensource} Restful Api integrated testing tool. You can deploy it in your local server. It make easier to manage Api with your team. {break} {break}More useful features (Document, Api Mock etc.) will come in future.", + "Login.Desc.OpenSource": "Open Source", + "Login.InvalidEmail": "The input is not valid email!", + "Login.EmailPlaceholder": "Your email address", + "Login.EnterEmail": "Please enter your email!", + "Login.EnterPassword": "Please enter your Password!", + "Login.BackToLogin": "<- Back to login", + "Login.Email": "Email", + "Login.Password": "Password", + "Login.ForgotPassword": "Forgot password?", + "Login.SignIn": "Sign in", + "Login.New": "New to Hitchhiker? {create}", + "Login.CreateAccount": "Create an account.", + "Login.OrTry": "Or {try}", + "Login.Try": "try without login.", + "FindPassword.Desc": "Enter your email address and we will send you a new password", + "FindPassword.Send": "Send password email", + "Reg.ConfirmPassword": "Confirm Password", + "Reg.ConfirmYourPassword": "Confirm your password", + "Reg.PleaseConfirmYourPassword": "Please confirm your password!", + "Reg.CreatePassword": "Create a password", + "Reg.SignUp": "Sign up", + "Reg.Have": "Have an account already? {sign}", + "Reg.Inconsistent": "Two passwords are inconsistent!", + "Reg.PasswordRule": "6 - 16 characters, letter or numeral.", + + "Header.ChangePassword": "Change password", + "Header.EnterOldPassword": "Please enter your old password!", + "Header.YourOldPassword": "Your old password", + "Header.OldPassword": "Old password", + "Header.NewPassword": "New Password", + "Header.YourNewPassword": "Create a password", + "Header.EnterNewPassword": "Please enter your new password!", + "Header.ConfirmNewPassword": "Confirm New Password", + "Header.ConfirmYourPassword": "Confirm your password", + "Header.ConfirmYourNewPassword": "Please confirm your new password!", + "Header.SelectProjectFirst": "Please select a project first.", + "Header.Logout": "Logout", + "Header.Logout&Clear": "Logout & Clear cache", + "Header.Syncing": "SYNCING", + "Header.Insync": "IN SYNC", + "Header.Import": "Import", + "Header.ImportJson": "Import Postman V1 or Swagger V2 JSON", + "Header.SelectProject": "Select project for import data:", + "Header.DragFile": "Click or drag json file to this area", + + "Collection.CreateFolder": "Create folder", + "Collection.CreateRequest": "Create request", + "Collection.CommonPreRequestScript": "Common Pre Request Script", + "Collection.RequestStrictSSL": "Request Strict SSL", + "Collection.RequestFollowRedirect": "Request Follow Redirect", + "Collection.Request": "{count} {count, plural, one {request} other {requests}}", + "Collection.EnterNewCollectionName": "Enter new collection name:", + "Collection.Create": "Create collection", + "Collection.History": "History", + "Collection.NewRequestFromcURL": "New Request from cUrl", + "Collection.ParsecURLFailed": "Parse cURL failed.", + "Collection.CloseTab": "Close Tab", + "Collection.LoseChanges": "Your changed will be lost if you close this tab without saving.", + "Collection.HasModified": "This request had been modified by someone else.", + "Collection.ViewChanges": "View changes", + "Collection.HasDelete": "This request had been delete in remote.", + "Collection.EnterNameForRequest": "Please enter name for this request", + "Collection.AllParameter": "allParameter", + "Collection.Parameters": "Parameters", + "Collection.ParameterRequest": "{length} requests: ", + "Collection.Body": "Body", + "Collection.PreRequestScript": "Pre Request Script", + "Collection.Test": "Test", + "Collection.AssertBaseOnUI": "Assert base on UI", + "Collection.NoValidResponseForAssert": "There is no valid response, please ensure response exist with json format.", + "Collection.Beautify": "Beautify", + "Collection.Snippets": "Snippets", + "Collection.MissName": "Miss name", + "Collection.GenerateCodeSnippet": "Generate Code Snippet", + "Collection.EnterUrlForRequest": "please enter url of this request", + "Collection.Select": "Select collection/folder:", + "Collection.CancelRequest": "Cancel Request", + "Collection.Response": "Response", + "Collection.HitToGetResponse": "Hit {send} to get a response.", + "Collection.Error": "error", + "Collection.Tests": "Tests: ", + "Collection.Status": "Status: ", + "Collection.Time": "Time: ", + "Collection.Content": "Content", + "Collection.Headers": "Headers", + "Collection.Cookies": "Cookies", + "Collection.DeleteCollection": "Delete collection", + "Collection.DeleteThisCollection": "delete this collection", + "Collection.DeleteFolder": "Delete folder", + "Collection.DeleteThisFolder": "delete this folder", + "Collection.DeleteRequest": "Delete request", + "Collection.DeleteThisRequest": "delete this request", + + "Project.DeleteEnvironment": "Delete environment", + "Project.DeleteThisEnvironment": "delete environment: {name}", + "Project.RemoveUser": "Remove user", + "Project.RemoveThisUser": "remove user: {name}", + "Project.DeleteProject": "{action} project", + "Project.DeleteThisProject": "{action} project: {name}", + "Project.Disband": "Disband", + "Project.disband": "disband", + "Project.Quit": "Quit", + "Project.quit": "quit", + "Project.Environments": "Environments", + "Project.NewEnvironment": "New Environment", + "Project.EditEnvironment": "Edit Environment", + "Project.EnvironmentTip": "Variables can be used in Url, Headers with format {{key}}, when send request, {{key}} will be replaced with its corresponding value. For example, you can use different host for environment(QA, Staging, Product) by using variables.", + "Project.EnvironmentName": "Environment Name:", + "Project.Variables": "Variables:", + "Project.Members": "Members", + "Project.InviteMembers": "Invite Members", + "Project.Name": "Name", + "Project.Email": "Email", + "Project.Localhost": "Localhost", + "Project.IsOwner": "Is Owner", + "Project.Action": "Action", + "Project.Path": "Path", + "Project.Origin": "Origin", + "Project.CreatedDate": "CreatedDate", + "Project.InviterDesc": "Please input members' emails split with ';':", + "Project.UploadFileSuccess": "file: {name} uploaded successfully", + "Project.UploadFileFail": "file: {name} upload failed", + "Project.Upload": "Upload new {name}", + "Project.GlobalFunction": "Global function", + "Project.ProjectLibs": "Project libs", + "Project.ProjectDatas": "Project datas", + "Project.MemberDesc": "{count} {count, plural, one {member} other {members}}", + "Project.GlobalFuncOfTest": "{name}Global Function of Tests", + "Project.Projects": "Projects", + "Project.CreateProject": "Create project", + + "Schedule.DeleteSchedule": "Delete schedule", + "Schedule.DeleteThisSchedule": "delete schedule: {name}", + + "Stress.DeleteStress": "Delete Stress", + "Stress.DeleteThisStress": "delete stress: {name}", + + "App.Collections": "Collections", + "App.Project": "Project", + "App.Scheduler": "Scheduler", + "App.StressTest": "Stress test", + "App.ApiDocument": "Api document", + "App.Mock": "Api mock" } \ No newline at end of file diff --git a/client/src/locales/index.tsx b/client/src/locales/index.tsx index 784f767..d355ad0 100644 --- a/client/src/locales/index.tsx +++ b/client/src/locales/index.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; -export default function (msgID: string) { +export default function (msgID: string, values?: any) { return ( - + ); } \ No newline at end of file diff --git a/client/src/locales/input.tsx b/client/src/locales/input.tsx new file mode 100644 index 0000000..6555162 --- /dev/null +++ b/client/src/locales/input.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { injectIntl } from 'react-intl'; +import { Input } from 'antd'; +import { InputProps } from 'antd/lib/input/Input'; + +interface LoInputProps extends InputProps { + + intl: any; + + placeholderId: string; +} + +interface LoInputState { } + +class LoInput extends React.Component { + public render() { + const { intl, placeholderId } = this.props; + return ( + + ); + } +} + +export default injectIntl(LoInput); \ No newline at end of file diff --git a/client/src/locales/zh.json b/client/src/locales/zh.json index 86353eb..68a2e0b 100644 --- a/client/src/locales/zh.json +++ b/client/src/locales/zh.json @@ -1,3 +1,29 @@ { + "Login.Desc.Title": "专为团队打造的API测试工具", + "Login.Desc.Content": "Hitchhiker是一款{opensource}的Restful API测试工具。你可以把它部署在局域网,它会帮助你和你的团队轻松管理、测试API。{break} {break}更多功能 (文档, Api Mock等)正在开发中,敬请期待。", + "Login.Desc.OpenSource": "开源", + "Login.InvalidEmail": "无效的Email!", + "Login.EmailPlaceholder": "Email地址", + "Login.EnterEmail": "请输入您的Email!", + "Login.EnterPassword": "请输入您的密码!", + "Login.BackToLogin": "<- 返回登录", + "Login.Email": "Email", + "Login.Password": "密码", + "Login.ForgotPassword": "忘记密码?", + "Login.SignIn": "登录", + "Login.New": "第一次使用? {create}", + "Login.CreateAccount": "创建一个新账号", + "Login.OrTry": "或者{try}", + "Login.Try": "免登录试用", + "FindPassword.Desc": "输入你的Email,我们会把新的密码发送给您", + "FindPassword.Send": "发送密码邮件", + "Reg.ConfirmPassword": "确认密码", + "Reg.ConfirmYourPassword": "再次输入密码", + "Reg.PleaseConfirmYourPassword": "请再次输入密码!", + "Reg.CreatePassword": "输入密码", + "Reg.SignUp": "注册", + "Reg.Have": "已有账号? {sign}", + "Reg.Inconsistent": "两次密码输入不一致!", + "Reg.PasswordRule": "密码必须是6 - 16个字母或数字", "App.Collections": "集合" } \ No newline at end of file diff --git a/client/src/modules/collection/collection_tree/collection_item.tsx b/client/src/modules/collection/collection_tree/collection_item.tsx index 8f539da..33cab83 100644 --- a/client/src/modules/collection/collection_tree/collection_item.tsx +++ b/client/src/modules/collection/collection_tree/collection_item.tsx @@ -10,6 +10,7 @@ import { DtoCollection } from '../../../../../api/interfaces/dto_collection'; import { newFolderName } from '../../../common/constants'; import { getDefaultRecord } from '../../../state/collection'; import { ParameterType } from '../../../common/parameter_type'; +import Msg from '../../../locales'; interface CollectionItemProps { @@ -75,34 +76,34 @@ class CollectionItem extends React.Component - Rename + {Msg('Common.Rename')} - Create folder + {Msg('Collection.CreateFolder')} - Create request + {Msg('Collection.CreateRequest')} {/* Share */} - Common Pre Request Script + {Msg('Collection.CommonPreRequestScript')} - Request Strict SSL + {Msg('Collection.RequestStrictSSL')} {reqStrictSSL ? : ''} - Request Follow Redirect + {Msg('Collection.RequestFollowRedirect')} {reqFollowRedirect ? : ''} - Delete + {Msg('Common.Delete')} ); @@ -112,7 +113,7 @@ class CollectionItem extends React.Component confirmDlg('collection', () => this.props.deleteCollection()); + delete = () => confirmDlg(Msg('Collection.DeleteCollection'), () => this.props.deleteCollection(), Msg('Collection.DeleteThisCollection')); share = () => this.props.shareCollection(this.props.collection.id); @@ -159,19 +160,20 @@ class CollectionItem extends React.Component this.itemWithMenu = ele} - onNameChanged={this.props.onNameChanged} + onNameChanged={onNameChanged} icon={} - name={this.props.collection.name} - subName={
{`${this.props.recordCount} request${this.props.recordCount > 1 ? 's' : ''}`}
} + name={collection.name} + subName={
{Msg('Collection.Request', { count: recordCount })}
} menu={this.getMenu()} />
diff --git a/client/src/modules/collection/collection_tree/index.tsx b/client/src/modules/collection/collection_tree/index.tsx index be1bdcd..4584022 100644 --- a/client/src/modules/collection/collection_tree/index.tsx +++ b/client/src/modules/collection/collection_tree/index.tsx @@ -20,6 +20,7 @@ import { newCollectionName, allProject } from '../../../common/constants'; import RecordTimeline from '../../../components/record_timeline'; import { ShowTimelineType, CloseTimelineType } from '../../../action/ui'; import ScriptDialog from '../../../components/script_dialog'; +import Msg from '../../../locales'; import './style/index.less'; const SubMenu = Menu.SubMenu; @@ -232,18 +233,22 @@ class CollectionList extends React.Component -1; const children = _.remove(data, (d) => d.pid === r.id); return ( - this.folderRefs[r.id] = ele} - folder={{ ...r }} - isOpen={isOpen} - deleteRecord={() => deleteRecord(r.id, records[cid])} - createRecord={this.createRecord} - onNameChanged={(name) => this.changeFolderName(r, name)} - moveRecordToFolder={this.moveRecordToFolder} - moveToCollection={this.moveToCollection} - /> - )}> + this.folderRefs[r.id] = ele} + folder={{ ...r }} + isOpen={isOpen} + deleteRecord={() => deleteRecord(r.id, records[cid])} + createRecord={this.createRecord} + onNameChanged={(name) => this.changeFolderName(r, name)} + moveRecordToFolder={this.moveRecordToFolder} + moveToCollection={this.moveToCollection} + /> + )} + > {this.loopRecords(children, cid, true)} ); @@ -282,7 +287,7 @@ class CollectionList extends React.Component this.setState({ ...this.state, isProjectSelectedDlgOpen: false })} > { ProjectSelectedDialogType.isCreateMode(projectSelectedDlgMode) ? (
-
Enter new collection name:
+
{Msg('Collection.EnterNewCollectionName')}
this.newCollectionNameRef = ele} style={{ width: '100%', marginBottom: '8px' }} value={this.state.newCollectionName} onChange={e => this.setState({ ...this.state, newCollectionName: e.currentTarget.value })} />
) : '' @@ -321,7 +324,8 @@ class CollectionList extends React.Component this.setState({ ...this.state, selectedProjectInDlg: e })} - treeData={this.props.projects.map(t => ({ key: t.id, value: t.id, label: t.name }))} /> + treeData={this.props.projects.map(t => ({ key: t.id, value: t.id, label: t.name }))} + /> ); } @@ -363,7 +367,8 @@ class CollectionList extends React.Component this.props.updateCollection({ ...c, reqStrictSSL: !c.reqStrictSSL })} editReqFollowRedirect={() => this.props.updateCollection({ ...c, reqFollowRedirect: !c.reqFollowRedirect })} /> - )}> + )} + > { sortRecords.length === 0 ?
: @@ -383,7 +388,7 @@ class CollectionList extends React.Component - Project: + {Msg('App.Project')}: @@ -391,7 +396,7 @@ class CollectionList extends React.Component - +
diff --git a/client/src/modules/collection/collection_tree/record_folder.tsx b/client/src/modules/collection/collection_tree/record_folder.tsx index 4d50ac2..63e08c1 100644 --- a/client/src/modules/collection/collection_tree/record_folder.tsx +++ b/client/src/modules/collection/collection_tree/record_folder.tsx @@ -6,6 +6,7 @@ import { DtoRecord } from '../../../../../api/interfaces/dto_record'; import { confirmDlg } from '../../../components/confirm_dialog/index'; import { getDefaultRecord } from '../../../state/collection'; import { StringUtil } from '../../../utils/string_util'; +import Msg from '../../../locales'; interface RecordFolderProps { @@ -52,13 +53,13 @@ class RecordFolder extends React.Component return ( - Rename + {Msg('Common.Rename')} - Create request + {Msg('Collection.CreateRequest')} - Delete + {Msg('Common.Delete')} ); @@ -68,7 +69,7 @@ class RecordFolder extends React.Component this[e.key](); } - delete = () => confirmDlg('folder', () => this.props.deleteRecord()); + delete = () => confirmDlg(Msg('Collection.DeleteFolder'), () => this.props.deleteRecord(), Msg('Collection.DeleteThisFolder')); createRecord = () => this.props.createRecord({ ...getDefaultRecord(false), collectionId: this.props.folder.collectionId, pid: this.props.folder.id, id: StringUtil.generateUID() }); diff --git a/client/src/modules/collection/collection_tree/record_item.tsx b/client/src/modules/collection/collection_tree/record_item.tsx index 3399d77..e5c49f7 100644 --- a/client/src/modules/collection/collection_tree/record_item.tsx +++ b/client/src/modules/collection/collection_tree/record_item.tsx @@ -6,6 +6,7 @@ import { Menu, Icon, Badge } from 'antd'; import { confirmDlg } from '../../../components/confirm_dialog/index'; import { DtoRecord } from '../../../../../api/interfaces/dto_record'; import { StringUtil } from '../../../utils/string_util'; +import Msg from '../../../locales'; interface RecordItemProps { @@ -47,13 +48,13 @@ class RecordItem extends React.Component { return ( - Duplicate + {Msg('Common.Duplicate')} - Delete + {Msg('Common.Delete')} - History + {Msg('Collection.History')} ); @@ -63,7 +64,7 @@ class RecordItem extends React.Component { this[e.key](); } - delete = () => confirmDlg('record', () => this.props.deleteRecord()); + delete = () => confirmDlg(Msg('Collection.DeleteRequest'), () => this.props.deleteRecord(), Msg('Collection.DeleteThisRequest')); duplicate = () => this.props.duplicateRecord(); diff --git a/client/src/modules/collection/collection_tree/style/index.less b/client/src/modules/collection/collection_tree/style/index.less index aba56d7..36bf2d2 100644 --- a/client/src/modules/collection/collection_tree/style/index.less +++ b/client/src/modules/collection/collection_tree/style/index.less @@ -28,7 +28,7 @@ margin-bottom: 4px; height: 60px; line-height: 60px; - span { + div.item-with-menu-title { font-size: 16px; } } diff --git a/client/src/modules/collection/req_res_panel/environment_select.tsx b/client/src/modules/collection/req_res_panel/environment_select.tsx index 555fd55..0086f30 100644 --- a/client/src/modules/collection/req_res_panel/environment_select.tsx +++ b/client/src/modules/collection/req_res_panel/environment_select.tsx @@ -11,6 +11,7 @@ import ScriptDialog from '../../../components/script_dialog'; import { RecordState } from '../../../state/collection'; import { CurlImport } from '../../../utils/curl_import'; import { ConflictType } from '../../../common/conflict_type'; +import Msg from '../../../locales'; const Option = Select.Option; @@ -54,7 +55,7 @@ class EnvironmentSelect extends React.Component - new Request from cUrl + {Msg('Collection.NewRequestFromcURL')} ); @@ -74,14 +75,14 @@ class EnvironmentSelect extends React.Component { try { const record = CurlImport.do(value); if (!record) { - message.warning(`parse cURL failed.`); + message.warning(Msg('Collection.ParsecURLFailed')); return; } const recordState: RecordState = { @@ -97,10 +98,10 @@ class EnvironmentSelect extends React.Component this.setState({ ...this.state, isImportDlgOpen: false })} - /> + /> ); } diff --git a/client/src/modules/collection/req_res_panel/index.tsx b/client/src/modules/collection/req_res_panel/index.tsx index b2c7cd9..9a66003 100644 --- a/client/src/modules/collection/req_res_panel/index.tsx +++ b/client/src/modules/collection/req_res_panel/index.tsx @@ -16,6 +16,7 @@ import { ResizeResHeightType } from '../../../action/ui'; import { getReqActiveTabKeySelector, getIsResPanelMaximumSelector, getActiveRecordStateSelector, getResHeightSelector } from './selector'; import { newRecordFlag } from '../../../common/constants'; import { ConflictType } from '../../../common/conflict_type'; +import Msg from '../../../locales'; interface ReqResPanelStateProps { @@ -131,24 +132,25 @@ class ReqResPanel extends React.Component { private get confirmCloseDialog() { return ( - this.setState({ ...this.state, isConfirmCloseDlgOpen: false })} footer={[( ), ( ), ( )]} > - Your changed will be lost if you close this tab without saving. + {Msg('Collection.LoseChanges')} ); } @@ -176,7 +178,8 @@ class ReqResPanel extends React.Component { {name}} - closable={true} /> + closable={true} + /> ); }) } diff --git a/client/src/modules/collection/req_res_panel/request_name_panel.tsx b/client/src/modules/collection/req_res_panel/request_name_panel.tsx index 8e84ba7..7009310 100644 --- a/client/src/modules/collection/req_res_panel/request_name_panel.tsx +++ b/client/src/modules/collection/req_res_panel/request_name_panel.tsx @@ -1,12 +1,14 @@ import React from 'react'; import { connect, Dispatch } from 'react-redux'; -import { Form, Input, Alert } from 'antd'; +import { Form, Alert } from 'antd'; import { ValidateStatus, ValidateType } from '../../../common/custom_type'; import { actionCreator } from '../../../action/index'; import { UpdateDisplayRecordPropertyType } from '../../../action/record'; import { getActiveRecordSelector, getActiveRecordStateSelector } from './selector'; import { ConflictType } from '../../../common/conflict_type'; import { ShowTimelineType } from '../../../action/ui'; +import Msg from '../../../locales'; +import LoInput from '../../../locales/input'; const FItem = Form.Item; @@ -62,8 +64,8 @@ class RequestNamePanel extends React.Component { return ( ); } @@ -78,7 +80,7 @@ class RequestNamePanel extends React.Component { currentConflictType === ConflictType.delete ? - : ( + : ( currentConflictType === ConflictType.modify ? : '' ) @@ -90,11 +92,12 @@ class RequestNamePanel extends React.Component - this.onNameChanged(e.currentTarget.value)} - value={name} /> + value={name} + /> diff --git a/client/src/modules/collection/req_res_panel/request_option_panel.tsx b/client/src/modules/collection/req_res_panel/request_option_panel.tsx index 9309074..62034e8 100644 --- a/client/src/modules/collection/req_res_panel/request_option_panel.tsx +++ b/client/src/modules/collection/req_res_panel/request_option_panel.tsx @@ -24,6 +24,7 @@ import { RequestStatus } from '../../../common/request_status'; import AssertJsonView from '../../../components/assert_json_view'; import { DtoAssert } from '../../../../../api/interfaces/dto_assert'; import { DtoEnvironment } from '../../../../../api/interfaces/dto_environment'; +import Msg from '../../../locales'; const TabPane = Tabs.TabPane; const RadioGroup = Radio.Group; @@ -113,7 +114,7 @@ class RequestOptionPanel extends React.Component - + { arr.map((e, i) => (