Commit 3258468e751df893d79d65f5d6c519f3fe258f0d

Authored by ly525
1 parent 90d0b6a4

feat(i18n) i18n for homepage

front-end/h5/src/components/common/header/links.js
@@ -15,16 +15,17 @@ export default { @@ -15,16 +15,17 @@ export default {
15 <a-menu-item key="dingtalk" > 15 <a-menu-item key="dingtalk" >
16 <a-popover title="👨🏻‍💻👩🏻‍💻欢迎加入鲁班-H5交流群"> 16 <a-popover title="👨🏻‍💻👩🏻‍💻欢迎加入鲁班-H5交流群">
17 <template slot="content"> 17 <template slot="content">
18 - <p>For users in other languages, <br />please keep using Github issue tracker. 🤟 </p> 18 + <p>For users in other languages(not zh-CN), <br />please keep using Github issue tracker. 🤟 </p>
19 <p>扫描二维码加入 钉钉 讨论组</p> 19 <p>扫描二维码加入 钉钉 讨论组</p>
20 <img src="https://user-images.githubusercontent.com/12668546/61447488-a379f700-a983-11e9-9956-139352a2585d.png" width="200" /> 20 <img src="https://user-images.githubusercontent.com/12668546/61447488-a379f700-a983-11e9-9956-139352a2585d.png" width="200" />
21 <p>因为微信群二维码会过期,<br />请前往<a href="https://github.com/ly525/luban-h5/issues/57" target="_blank" rel="noopener">微信群和QQ群</a> 查看</p> 21 <p>因为微信群二维码会过期,<br />请前往<a href="https://github.com/ly525/luban-h5/issues/57" target="_blank" rel="noopener">微信群和QQ群</a> 查看</p>
22 </template> 22 </template>
23 - <span style={{ color: 'white', lineHeight: '64px', height: '64px', display: 'inline-block' }}><a-icon type="qrcode" />交流群</span> 23 + <span style={{ color: 'white', lineHeight: '64px', height: '64px', display: 'inline-block' }}><a-icon type="qrcode" />{this.$t('header.chat')}</span>
24 </a-popover> 24 </a-popover>
25 </a-menu-item> 25 </a-menu-item>
26 <a-menu-item key="document"> 26 <a-menu-item key="document">
27 - <a href="https://ly525.github.io/luban-h5" target="_blank" rel="noopener" style={{ color: 'white' }}><a-icon type="read" />文档</a> 27 + {/* <a href="https://ly525.github.io/luban-h5" target="_blank" rel="noopener" style={{ color: 'white' }}><a-icon type="read" />文档</a> */}
  28 + <a href="https://ly525.github.io/luban-h5" target="_blank" rel="noopener" style={{ color: 'white' }}><a-icon type="read" />{this.$t('header.chineseDocument')}</a>
28 </a-menu-item> 29 </a-menu-item>
29 <a-menu-item key="document-en"> 30 <a-menu-item key="document-en">
30 <a href="https://www.yuque.com/liuyan-ew1qk/oh5d0n?language=en-us" target="_blank" rel="noopener" style={{ color: 'white' }}><a-icon type="read" />Document(En)</a> 31 <a href="https://www.yuque.com/liuyan-ew1qk/oh5d0n?language=en-us" target="_blank" rel="noopener" style={{ color: 'white' }}><a-icon type="read" />Document(En)</a>
front-end/h5/src/components/common/header/logo.js
1 export default { 1 export default {
2 render () { 2 render () {
3 - return <div class="logo"><router-link to={{ path: '/' }}>鲁班 H5</router-link></div> 3 + return <div class="logo"><router-link to={{ path: '/' }}>
  4 + {/* 鲁班 H5 Luban H5 */}
  5 + {this.$t('app.title')}
  6 + </router-link></div>
4 } 7 }
5 } 8 }
front-end/h5/src/views/work-manager/form-stat/column.js
1 export const columns = [ 1 export const columns = [
2 { 2 {
3 - title: '标题', 3 + title: 'Title',
4 dataIndex: 'title', 4 dataIndex: 'title',
5 key: 'title' 5 key: 'title'
6 }, 6 },
@@ -15,7 +15,7 @@ export const columns = [ @@ -15,7 +15,7 @@ export const columns = [
15 key: 'uv' 15 key: 'uv'
16 }, 16 },
17 { 17 {
18 - title: '表单数', 18 + title: 'Form Count',
19 key: 'formCount', 19 key: 'formCount',
20 dataIndex: 'formCount' 20 dataIndex: 'formCount'
21 }, 21 },
front-end/h5/src/views/work-manager/form-stat/detail.vue
@@ -81,7 +81,8 @@ export default { @@ -81,7 +81,8 @@ export default {
81 <div class="works-wrapper"> 81 <div class="works-wrapper">
82 <a-table columns={this.columns} dataSource={this.rows} row-key="id" scopedSlots={{ 82 <a-table columns={this.columns} dataSource={this.rows} row-key="id" scopedSlots={{
83 action: function (props) { 83 action: function (props) {
84 - return [<router-link to={{ name: 'stat-detail', params: { id: props.id } }} >查看数据</router-link>] 84 + // 查看数据
  85 + return [<router-link to={{ name: 'stat-detail', params: { id: props.id } }} >{this.$t('basicData.viewData')}</router-link>]
85 } 86 }
86 }}> 87 }}>
87 </a-table> 88 </a-table>
front-end/h5/src/views/work-manager/form-stat/index.vue
@@ -37,11 +37,13 @@ export default { @@ -37,11 +37,13 @@ export default {
37 } 37 }
38 }, 38 },
39 render (h) { 39 render (h) {
  40 + const that = this
40 return ( 41 return (
41 <div class="works-wrapper" style="background-color:white;padding: 12px;margin-top: 24px;"> 42 <div class="works-wrapper" style="background-color:white;padding: 12px;margin-top: 24px;">
42 <a-table size="middle" columns={columns} dataSource={this.computedWorks} row-key="id" scopedSlots={{ 43 <a-table size="middle" columns={columns} dataSource={this.computedWorks} row-key="id" scopedSlots={{
43 action: function (props) { 44 action: function (props) {
44 - return [<router-link to={{ name: 'stat-detail', params: { id: props.id } }} >查看数据</router-link>] 45 + // 查看数据
  46 + return [<router-link to={{ name: 'stat-detail', params: { id: props.id } }} >{that.$t('basicData.viewData')}</router-link>]
45 } 47 }
46 }}> 48 }}>
47 </a-table> 49 </a-table>
front-end/h5/src/views/work-manager/index.vue
@@ -4,10 +4,12 @@ @@ -4,10 +4,12 @@
4 import '@/components/core/styles/index.scss' 4 import '@/components/core/styles/index.scss'
5 import LogoOfHeader from '@/components/common/header/logo.js' 5 import LogoOfHeader from '@/components/common/header/logo.js'
6 import ExternalLinksOfHeader from '@/components/common/header/links.js' 6 import ExternalLinksOfHeader from '@/components/common/header/links.js'
  7 +import LangSelect from '@/components/common/header/LangSelect.vue'
7 8
8 const sidebarMenus = [ 9 const sidebarMenus = [
9 { 10 {
10 label: '我的作品', 11 label: '我的作品',
  12 + i18nLabel: 'sidebar.myWorks',
11 value: 'workManager', 13 value: 'workManager',
12 antIcon: 'bars', 14 antIcon: 'bars',
13 key: '1', 15 key: '1',
@@ -15,12 +17,14 @@ const sidebarMenus = [ @@ -15,12 +17,14 @@ const sidebarMenus = [
15 }, 17 },
16 { 18 {
17 label: '数据中心', 19 label: '数据中心',
  20 + i18nLabel: 'sidebar.dataCenter',
18 value: 'dataCenter', 21 value: 'dataCenter',
19 antIcon: 'snippets', 22 antIcon: 'snippets',
20 key: '2', 23 key: '2',
21 children: [ 24 children: [
22 { 25 {
23 label: '基础数据', 26 label: '基础数据',
  27 + i18nLabel: 'sidebar.basicData',
24 value: 'basicData', 28 value: 'basicData',
25 antIcon: 'snippets', 29 antIcon: 'snippets',
26 key: '2-1', 30 key: '2-1',
@@ -30,12 +34,14 @@ const sidebarMenus = [ @@ -30,12 +34,14 @@ const sidebarMenus = [
30 }, 34 },
31 { 35 {
32 label: '模板中心', 36 label: '模板中心',
  37 + i18nLabel: 'sidebar.templateCenter',
33 value: 'templateCenter', 38 value: 'templateCenter',
34 antIcon: 'snippets', 39 antIcon: 'snippets',
35 key: '3', 40 key: '3',
36 children: [ 41 children: [
37 { 42 {
38 - label: '免费模板', 43 + label: '模板列表',
  44 + i18nLabel: 'sidebar.freeTemplates',
39 value: 'freeTemplates', 45 value: 'freeTemplates',
40 antIcon: 'snippets', 46 antIcon: 'snippets',
41 key: '3-1', 47 key: '3-1',
@@ -45,6 +51,7 @@ const sidebarMenus = [ @@ -45,6 +51,7 @@ const sidebarMenus = [
45 }, 51 },
46 { 52 {
47 label: '账号中心', 53 label: '账号中心',
  54 + i18nLabel: 'sidebar.accountCenter',
48 value: 'freeTemplate', 55 value: 'freeTemplate',
49 antIcon: 'appstore', 56 antIcon: 'appstore',
50 key: '4' 57 key: '4'
@@ -56,17 +63,20 @@ export default { @@ -56,17 +63,20 @@ export default {
56 // PreView, 63 // PreView,
57 // Sidebar 64 // Sidebar
58 LogoOfHeader, 65 LogoOfHeader,
59 - ExternalLinksOfHeader 66 + ExternalLinksOfHeader,
  67 + LangSelect
60 }, 68 },
61 methods: { 69 methods: {
62 renderSidebar (menus) { 70 renderSidebar (menus) {
63 - const renderLabel = menu => menu.routerName ? <router-link class="default-router-link" to={{ name: menu.routerName }}>{menu.label}</router-link> : menu.label 71 + // const renderLabel = menu => menu.routerName ? <router-link class="default-router-link" to={{ name: menu.routerName }}>{menu.label}</router-link> : menu.label
  72 + const renderLabel = menu => menu.routerName ? <router-link class="default-router-link" to={{ name: menu.routerName }}>{this.$t(menu.i18nLabel)}</router-link> : this.$t(menu.i18nLabel)
64 73
65 return menus.map(menu => ( 74 return menus.map(menu => (
66 menu.children 75 menu.children
67 ? ( 76 ? (
68 <a-sub-menu key={menu.key}> 77 <a-sub-menu key={menu.key}>
69 - <span slot="title"><a-icon type={menu.antIcon} />{menu.label}</span> 78 + {/** <span slot="title"><a-icon type={menu.antIcon} />{menu.label}</span> */}
  79 + <span slot="title"><a-icon type={menu.antIcon} />{this.$t(menu.i18nLabel)}</span>
70 { 80 {
71 (menu.children).map(submenu => ( 81 (menu.children).map(submenu => (
72 <a-menu-item key={submenu.key}>{renderLabel(submenu)}</a-menu-item> 82 <a-menu-item key={submenu.key}>{renderLabel(submenu)}</a-menu-item>
@@ -89,6 +99,7 @@ export default { @@ -89,6 +99,7 @@ export default {
89 <a-layout id="luban-work-manager-layout" style={{ height: '100vh' }}> 99 <a-layout id="luban-work-manager-layout" style={{ height: '100vh' }}>
90 <a-layout-header class="header"> 100 <a-layout-header class="header">
91 <LogoOfHeader /> 101 <LogoOfHeader />
  102 + <LangSelect />
92 {/* TODO we can show the plugins shortcuts here */} 103 {/* TODO we can show the plugins shortcuts here */}
93 <a-dropdown> 104 <a-dropdown>
94 <a-menu slot="overlay" onClick={() => {}}> 105 <a-menu slot="overlay" onClick={() => {}}>
@@ -116,7 +127,7 @@ export default { @@ -116,7 +127,7 @@ export default {
116 {this.renderSidebar(sidebarMenus)} 127 {this.renderSidebar(sidebarMenus)}
117 </a-menu> 128 </a-menu>
118 </a-layout-sider> 129 </a-layout-sider>
119 - <a-layout style="padding: 0 24px 24px"> 130 + <a-layout style="padding: 0 0 24px">
120 <a-layout-content style={{ padding: '24px', minHeight: '280px' }}> 131 <a-layout-content style={{ padding: '24px', minHeight: '280px' }}>
121 <router-view /> 132 <router-view />
122 </a-layout-content> 133 </a-layout-content>
front-end/h5/src/views/work-manager/list.vue
@@ -45,13 +45,15 @@ const ListItemCard = { @@ -45,13 +45,15 @@ const ListItemCard = {
45 <CardCover qrcodeUrl={this.qrcodeUrl} coverImageUrl={this.work.cover_image_url} /> 45 <CardCover qrcodeUrl={this.qrcodeUrl} coverImageUrl={this.work.cover_image_url} />
46 </div> 46 </div>
47 <template class="ant-card-actions" slot="actions"> 47 <template class="ant-card-actions" slot="actions">
48 - <a-tooltip effect="dark" placement="bottom" title="编辑"> 48 + {/** 编辑 */}
  49 + <a-tooltip effect="dark" placement="bottom" title={this.$t('workCard.edit')}>
49 <router-link to={{ name: 'editor', params: { workId: this.work.id } }} target="_blank"> 50 <router-link to={{ name: 'editor', params: { workId: this.work.id } }} target="_blank">
50 - <a-icon type="edit" title="编辑"/> 51 + <a-icon type="edit" title={this.$t('workCard.edit')}/>
51 </router-link> 52 </router-link>
52 </a-tooltip> 53 </a-tooltip>
53 - <a-tooltip effect="dark" placement="bottom" title="预览">  
54 - <a-icon type="eye" title="预览" onClick={this.handleClickPreview} /> 54 + {/** 预览 */}
  55 + <a-tooltip effect="dark" placement="bottom" title={this.$t('workCard.preview')}>
  56 + <a-icon type="eye" title={this.$t('workCard.preview')} onClick={this.handleClickPreview} />
55 </a-tooltip> 57 </a-tooltip>
56 { 58 {
57 this.qrcodeUrl 59 this.qrcodeUrl
@@ -69,8 +71,9 @@ const ListItemCard = { @@ -69,8 +71,9 @@ const ListItemCard = {
69 {this.work.title}({this.work.id}) 71 {this.work.title}({this.work.id})
70 </div> 72 </div>
71 <div slot="description" style="font-size: 12px;"> 73 <div slot="description" style="font-size: 12px;">
72 - <div>描述:{this.work.description}</div>  
73 - <div>时间:{this.timeFmt(this.work.created_at)}</div> 74 + {/** 描述 时间 */}
  75 + <div>{this.$t('workCard.description')}: {this.work.description}</div>
  76 + <div>{this.$t('workCard.createTime')}: {this.timeFmt(this.work.created_at)}</div>
74 </div> 77 </div>
75 </a-card-meta> 78 </a-card-meta>
76 </a-card> 79 </a-card>
@@ -80,14 +83,16 @@ const ListItemCard = { @@ -80,14 +83,16 @@ const ListItemCard = {
80 83
81 const AddNewCard = { 84 const AddNewCard = {
82 functional: true, 85 functional: true,
83 - render (h, { props }) { 86 + render (h, { props, parent }) {
84 return ( 87 return (
85 <a-card hoverable> 88 <a-card hoverable>
86 <div slot="cover" class="flex-center" style="height: 305px;background: #f7f5f557;" onClick={props.handleCreate}> 89 <div slot="cover" class="flex-center" style="height: 305px;background: #f7f5f557;" onClick={props.handleCreate}>
87 <a-icon type="plus" /> 90 <a-icon type="plus" />
88 </div> 91 </div>
89 <template class="ant-card-actions" slot="actions"> 92 <template class="ant-card-actions" slot="actions">
90 - <span onClick={props.handleCreate}>创建新作品</span> 93 + {/** 创建新作品 */}
  94 + {/** https://kazupon.github.io/vue-i18n/guide/component.html#translation-in-functional-component */}
  95 + <span onClick={props.handleCreate}>{parent.$t('workCard.createNewWork')}</span>
91 </template> 96 </template>
92 </a-card> 97 </a-card>
93 ) 98 )
@@ -121,7 +126,7 @@ export default { @@ -121,7 +126,7 @@ export default {
121 render (h) { 126 render (h) {
122 return ( 127 return (
123 <div class="works-wrapper"> 128 <div class="works-wrapper">
124 - <a-row gutter={48}> 129 + <a-row gutter={12}>
125 <a-col span={6} style="margin-bottom: 10px;"> 130 <a-col span={6} style="margin-bottom: 10px;">
126 <AddNewCard handleCreate={this.createWork} /> 131 <AddNewCard handleCreate={this.createWork} />
127 </a-col> 132 </a-col>
front-end/h5/src/views/work-manager/templates.vue
@@ -49,20 +49,14 @@ const ListItemCard = { @@ -49,20 +49,14 @@ const ListItemCard = {
49 <CardCover qrcodeUrl={this.qrcodeUrl} coverImageUrl={this.work.cover_image_url} /> 49 <CardCover qrcodeUrl={this.qrcodeUrl} coverImageUrl={this.work.cover_image_url} />
50 </div> 50 </div>
51 <template class="ant-card-actions" slot="actions"> 51 <template class="ant-card-actions" slot="actions">
52 - {/**  
53 - <router-link to={{ name: 'editor', params: { workId: this.work.id } }} target="_blank">  
54 - <a-tooltip effect="dark" placement="bottom" title="立即使用">  
55 - <a-icon type="plus-square" title="立即使用"/>  
56 - </a-tooltip>  
57 - </router-link>  
58 - */}  
59 - <a-tooltip effect="dark" placement="bottom" title="立即使用">  
60 - <a-icon type="plus-square" title="立即使用" onClick={() => { 52 + <a-tooltip effect="dark" placement="bottom" title={this.$t('workCard.useNow')}>
  53 + <a-icon type="plus-square" title={this.$t('workCard.useNow')} onClick={() => {
61 this.handleUseTemplate(this.work) 54 this.handleUseTemplate(this.work)
62 }} /> 55 }} />
63 </a-tooltip> 56 </a-tooltip>
64 - <a-tooltip effect="dark" placement="bottom" title="预览">  
65 - <a-icon type="eye" title="预览" onClick={this.handleClickPreview} /> 57 + {/** 预览 */}
  58 + <a-tooltip effect="dark" placement="bottom" title={this.$t('workCard.preview')}>
  59 + <a-icon type="eye" title={this.$t('workCard.preview')} onClick={this.handleClickPreview} />
66 </a-tooltip> 60 </a-tooltip>
67 { 61 {
68 this.qrcodeUrl 62 this.qrcodeUrl
@@ -80,8 +74,9 @@ const ListItemCard = { @@ -80,8 +74,9 @@ const ListItemCard = {
80 {this.work.title}({this.work.id}) 74 {this.work.title}({this.work.id})
81 </div> 75 </div>
82 <div slot="description" style="font-size: 12px;"> 76 <div slot="description" style="font-size: 12px;">
83 - <div>描述:{this.work.description}</div>  
84 - <div>时间:{this.timeFmt(this.work.created_at)}</div> 77 + {/** 描述 时间 */}
  78 + <div>{this.$t('workCard.description')}: {this.work.description}</div>
  79 + <div>{this.$t('workCard.createTime')}: {this.timeFmt(this.work.created_at)}</div>
85 </div> 80 </div>
86 </a-card-meta> 81 </a-card-meta>
87 </a-card> 82 </a-card>
@@ -120,7 +115,7 @@ export default { @@ -120,7 +115,7 @@ export default {
120 render (h) { 115 render (h) {
121 return ( 116 return (
122 <div class="works-wrapper"> 117 <div class="works-wrapper">
123 - <a-row gutter={24}> 118 + <a-row gutter={12}>
124 { 119 {
125 this.fetchWorkTemplates_loading 120 this.fetchWorkTemplates_loading
126 ? <a-col span={24} style="margin-bottom: 10px;text-align: center;height: 355px;line-height: 355px;border-bottom: 1px solid #ebedf0;background: rgba(255, 255, 255, 0.5);"> 121 ? <a-col span={24} style="margin-bottom: 10px;text-align: center;height: 355px;line-height: 355px;border-bottom: 1px solid #ebedf0;background: rgba(255, 255, 255, 0.5);">