提交 6e213677 编写于 作者: N nepeplwu 提交者: Nicky Chan

fix #506 (#508)

* front-end add vue-i18n dependency

* back-end support language selection with option --language or -L

* front-end add language support with vue-i18n
上级 da716c85
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
"qs": "^6.5.1", "qs": "^6.5.1",
"vue": "^2.5.2", "vue": "^2.5.2",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
"vue-i18n": ">=7.0.0",
"vuetify": "^0.17.7", "vuetify": "^0.17.7",
"xlsx": "^0.11.3" "xlsx": "^0.11.3"
}, },
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
<script> <script>
import AppMenu from './common/component/AppMenu'; import AppMenu from './common/component/AppMenu';
import {getLanguage} from './service';
export default { export default {
name: 'App', name: 'App',
...@@ -21,6 +22,10 @@ export default { ...@@ -21,6 +22,10 @@ export default {
}; };
}, },
created() { created() {
getLanguage().then(({errno, data}) => {
this.$i18n.locale = data;
});
if (location.hash && location.hash != '#/') { if (location.hash && location.hash != '#/') {
this.initialRoute = /(\#\/)(\w*)([?|&]{0,1})/.exec(location.hash)[2]; this.initialRoute = /(\#\/)(\w*)([?|&]{0,1})/.exec(location.hash)[2];
} else { } else {
......
{
"lang": {
"runs": "Runs",
"notRunsSelect": "None selected",
"metrics": "metrics",
"samples": "samples",
"graphs": "graphs",
"HighDimensional": "HighDimensional",
"text": "Text",
"image": "Image",
"audio": "Audio",
"showActualImageSize": "Show actual image size",
"startRunning": "Running",
"stopRunning": "Stopped",
"searchTagInReg": "Search tags in RegExp",
"scalars": "Scalars",
"smoothing": "Smoothing",
"xAxis": "X-axis",
"toolTipSorting": "Tooltip sorting",
"ignoreOutliers": "Ignore outliers in chart scaling",
"histogram": "Histogram",
"mode": "Mode",
"step": "Step",
"relative": "Relative",
"wall": "Wall Time",
"default": "default",
"descending": "descending",
"ascending": "ascending",
"nearest": "nearest",
"overlay": "Overlay",
"offset": "Offset",
"downloadImage": "Download image",
"restoreImage": "Restore image",
"scale": "Scale",
"nodeInfo": "Node Info",
"nodeName": "Name",
"nodeType": "Node Type",
"dataShape": "Shape",
"dataType": "Data Type",
"input": "Input",
"output": "Output",
"opType": "Operator Type",
"search": "Search",
"searchByLabel": "Search by label",
"dimension": "Dimension",
"2D": "2D",
"3D": "3D",
"displayAllLabel": "Display All Labels",
"reductionMethod": "Reduction Method",
"downloadDataInJson": "Download data in JSON",
"all": "All"
}
}
{
"lang": {
"runs": "数据流",
"notRunsSelect": "未选中任何数据",
"metrics": "度量数据",
"samples": "样本数据",
"graphs": "网络结构",
"HighDimensional": "高维数据映射",
"text": "文本",
"image": "图片",
"audio": "音频",
"showActualImageSize": "按真实大小显示",
"startRunning": "运行",
"stopRunning": "停止",
"searchTagInReg": "搜索标签(支持正则)",
"scalars": "标量",
"smoothing": "平滑度",
"xAxis": "x轴",
"toolTipSorting": "标签排序方法",
"ignoreOutliers": "图表缩放时忽略极端值",
"histogram": "直方图",
"mode": "模式",
"step": "步",
"relative": "相对值",
"wall": "时间",
"default": "默认",
"descending": "降序",
"ascending": "升序",
"nearest": "最近",
"overlay": "概览",
"offset": "偏移",
"downloadImage": "下载图片",
"restoreImage": "还原图片",
"scale": "比例",
"nodeInfo": "节点信息",
"nodeName": "节点名称",
"nodeType": "节点类型",
"dataShape": "数据形状",
"dataType": "数据类型",
"input": "输入",
"output": "输出",
"opType": "算子类型",
"search": "搜索",
"searchByLabel": "通过标签搜索",
"dimension": "维度",
"2D": "二维",
"3D": "三维",
"displayAllLabel": "展示所有标签",
"reductionMethod": "降维方法",
"downloadDataInJson": "下载数据(json格式)",
"all": "全部"
}
}
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
:ripple="false" :ripple="false"
:color="runsSelectorOpen ? 'dark_primary' : 'primary'" :color="runsSelectorOpen ? 'dark_primary' : 'primary'"
:class="runsSelectorOpen ? 'runs-selected-menu-open' : 'runs-selected-menu'" :class="runsSelectorOpen ? 'runs-selected-menu-open' : 'runs-selected-menu'"
> <span class="runs-selected-text">Runs: {{ runs.length == 0 ? 'None selected' : runs.join(', ') }} </span> > <span class="runs-selected-text">{{ $t("lang.runs") }}: {{ runs.length == 0 ? $t("lang.notRunsSelect") : runs.join(', ') }} </span>
<v-icon>arrow_drop_down</v-icon> <v-icon>arrow_drop_down</v-icon>
</v-btn> </v-btn>
<v-list dense> <v-list dense>
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
dark dark
:class="selected.toLowerCase() === item.name.toLowerCase() ? 'menu-item-selected': 'menu-item'" :class="selected.toLowerCase() === item.name.toLowerCase() ? 'menu-item-selected': 'menu-item'"
@click="handleItemClick(item)" @click="handleItemClick(item)"
>{{ item.title }}</v-btn> >{{ $t('lang.' + item.name) }}</v-btn>
</v-toolbar-items> </v-toolbar-items>
</v-toolbar> </v-toolbar>
</div> </div>
...@@ -95,29 +95,29 @@ export default { ...@@ -95,29 +95,29 @@ export default {
}; };
}, },
created() { created() {
this.runs = this.$route.query.runs; //maintain runs state after refresh this.runs = this.$route.query.runs; // maintain runs state after refresh
getRuns().then(({errno, data}) => { getRuns().then(({errno, data}) => {
this.availableRuns = data; this.availableRuns = data;
if (!this.runs) this.runs = data; if (!this.runs) this.runs = data;
//use replace here instead of push so that user cannot go back to empty run state // use replace here instead of push so that user cannot go back to empty run state
this.$router.replace( { path: this.initialRoute, query: { runs: this.runs }}); this.$router.replace( {path: this.initialRoute, query: {runs: this.runs}});
}); });
}, },
watch: { watch: {
runs: function(val) { runs: function(val) {
if (this.runs) { if (this.runs) {
this.$router.push( {query: { runs: this.runs }}); this.$router.push( {query: {runs: this.runs}});
} }
}, },
'$route' (to, from) { //this will get called when back button is hit that changes path or query '$route'(to, from) { // this will get called when back button is hit that changes path or query
this.runs = this.$route.query.runs; this.runs = this.$route.query.runs;
this.selected = this.$route.name; this.selected = this.$route.name;
} },
}, },
methods: { methods: {
handleItemClick: function(item) { handleItemClick: function(item) {
this.selected = item.name; this.selected = item.name;
this.$router.push( { path: item.url, query: { runs: this.runs }}); this.$router.push( {path: item.url, query: {runs: this.runs}});
}, },
}, },
}; };
...@@ -174,5 +174,4 @@ export default { ...@@ -174,5 +174,4 @@ export default {
overflow visible overflow visible
</style> </style>
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
@click="handleDownload" @click="handleDownload"
dark> dark>
<v-icon style="margin-right: 6px">file_download</v-icon> <v-icon style="margin-right: 6px">file_download</v-icon>
Download image {{ $t("lang.downloadImage") }}
</v-btn> </v-btn>
<v-btn <v-btn
...@@ -16,11 +16,11 @@ ...@@ -16,11 +16,11 @@
@click="resetImage" @click="resetImage"
dark> dark>
<v-icon style="margin-right: 6px">restore</v-icon> <v-icon style="margin-right: 6px">restore</v-icon>
Restore image {{ $t("lang.restoreImage") }}
</v-btn> </v-btn>
<v-slider <v-slider
label="Scale" :label="$t('lang.scale')"
max="1" max="1"
min="0.1" min="0.1"
step="0.1" step="0.1"
...@@ -30,22 +30,22 @@ ...@@ -30,22 +30,22 @@
<div class="node-info"> <div class="node-info">
<h3>Node Info: </h3> <h3>{{ $t("lang.nodeInfo") }}: </h3>
<div v-if="curNode.nodeType === 'input'"> <div v-if="curNode.nodeType === 'input'">
<div>Node Type: {{ curNode.nodeType }}</div> <div>{{ $t("lang.nodeType") }}: {{ curNode.nodeType }}</div>
<div>Name: {{ curNode.nodeInfo.name }}</div> <div>{{ $t("lang.nodeName") }}: {{ curNode.nodeInfo.name }}</div>
<div>Shape: {{ curNode.nodeInfo.shape }}</div> <div>{{ $t("lang.dataShape") }}: {{ curNode.nodeInfo.shape }}</div>
<div>Data Type: {{ curNode.nodeInfo.data_type }}</div> <div>{{ $t("lang.dataType") }}: {{ curNode.nodeInfo.data_type }}</div>
</div> </div>
<div v-else-if="curNode.nodeType === 'output'"> <div v-else-if="curNode.nodeType === 'output'">
<div>Node Type: {{ curNode.nodeType }}</div> <div>{{ $t("lang.nodeType") }}: {{ curNode.nodeType }}</div>
</div> </div>
<div v-else-if="curNode.nodeType === 'operator'"> <div v-else-if="curNode.nodeType === 'operator'">
<div>Node Type: {{ curNode.nodeType }}</div> <div>{{ $t("lang.nodeType") }}: {{ curNode.nodeType }}</div>
<div>Input: {{ curNode.nodeInfo.input }}</div> <div>{{ $t("lang.input") }}: {{ curNode.nodeInfo.input }}</div>
<div>Operator Type: {{ curNode.nodeInfo.opType }}</div> <div>{{ $t("lang.opType") }}: {{ curNode.nodeInfo.opType }}</div>
<div>Output: {{ curNode.nodeInfo.output }}</div> <div>{{ $t("lang.output") }}: {{ curNode.nodeInfo.output }}</div>
</div> </div>
<div v-else/> <div v-else/>
</div> </div>
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
<div class="visual-dl-page-config-com"> <div class="visual-dl-page-config-com">
<v-text-field <v-text-field
label="Search" :label="$t('lang.search')"
hint="Search by label" :hint="$t('lang.searchByLabel')"
v-model="config.searchText" v-model="config.searchText"
dark dark
/> />
...@@ -11,24 +11,24 @@ ...@@ -11,24 +11,24 @@
<v-checkbox <v-checkbox
class="visual-dl-page-config-checkbox" class="visual-dl-page-config-checkbox"
label="Display All Labels" :label="$t('lang.displayAllLabel')"
v-model="config.displayWordLabel" v-model="config.displayWordLabel"
dark/> dark/>
<v-radio-group <v-radio-group
label="Dimension" :label="$t('lang.dimension')"
v-model="config.dimension" v-model="config.dimension"
dark> dark>
<v-radio <v-radio
label="2D" :label="$t('lang.2D')"
value="2"/> value="2"/>
<v-radio <v-radio
label="3D" :label="$t('lang.3D')"
value="3"/> value="3"/>
</v-radio-group> </v-radio-group>
<v-radio-group <v-radio-group
label="Reduction Method" :label="$t('lang.reductionMethod')"
v-model="config.reduction" v-model="config.reduction"
dark> dark>
<v-radio <v-radio
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
dark dark
block block
> >
{{ config.running ? 'Running' : 'Stopped' }} {{ config.running ? $t('lang.startRunning') : $t('lang.stopRunning') }}
</v-btn> </v-btn>
</div> </div>
</template> </template>
......
// The Vue build version to load with the `import` command // The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias. // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'; import Vue from 'vue';
import VueI18n from 'vue-i18n';
import App from './App'; import App from './App';
import Vuetify from 'vuetify'; import Vuetify from 'vuetify';
import router from '@/router'; import router from '@/router';
Vue.config.productionTip = false; Vue.config.productionTip = false;
Vue.use(VueI18n);
const DEFAULT_LANG = 'zh';
const locales = {
zh: require('./assets/language/zh.json'),
en: require('./assets/language/en.json'),
};
const i18n = new VueI18n({
locale: DEFAULT_LANG,
messages: locales,
});
Vue.use(Vuetify, { Vue.use(Vuetify, {
theme: { theme: {
primary: '#008c99', primary: '#008c99',
...@@ -20,6 +33,7 @@ Vue.use(Vuetify, { ...@@ -20,6 +33,7 @@ Vue.use(Vuetify, {
new Vue({ new Vue({
el: '#root', el: '#root',
router, router,
i18n: i18n,
components: {App}, components: {App},
template: '<App/>', template: '<App/>',
}); });
...@@ -8,15 +8,17 @@ ...@@ -8,15 +8,17 @@
color="tag_background" color="tag_background"
class="visual-dl-tags-tab"> class="visual-dl-tags-tab">
<v-icon>search</v-icon> <v-icon>search</v-icon>
<input type="search" v-model="config.groupNameReg" <input
type="search"
v-model="config.groupNameReg"
autocomplete="false" autocomplete="false"
placeholder="Search tags in RegExp" :placeholder="$t('lang.searchTagInReg')"
class="visual-dl-tags-search-input"> class="visual-dl-tags-search-input">
</v-card> </v-card>
<ui-tags-tab <ui-tags-tab
:total="tagsListCount(allTagsMatchingList)" :total="tagsListCount(allTagsMatchingList)"
:title="config.groupNameReg.trim().length == 0 ? 'All' : config.groupNameReg" :title="config.groupNameReg.trim().length == 0 ? $t('lang.all') : config.groupNameReg"
:active="selectedGroup === '' " :active="selectedGroup === '' "
@click="selectedGroup = '' " @click="selectedGroup = '' "
/> />
...@@ -24,6 +26,7 @@ ...@@ -24,6 +26,7 @@
v-for="item in groupedTags" v-for="item in groupedTags"
:total="tagsListCount(item.tags)" :total="tagsListCount(item.tags)"
:title="item.group" :title="item.group"
:key="item.group"
:active="item.group === selectedGroup" :active="item.group === selectedGroup"
@click="selectedGroup = item.group" @click="selectedGroup = item.group"
/> />
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div class="visual-dl-page-config-com"> <div class="visual-dl-page-config-com">
<v-checkbox <v-checkbox
class="visual-dl-page-config-checkbox" class="visual-dl-page-config-checkbox"
label="Scalars" :label="$t('lang.scalars')"
v-model="config.scalar.display" v-model="config.scalar.display"
:disabled="!config.scalar.enabled" :disabled="!config.scalar.enabled"
dark/> dark/>
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<div class="visual-dl-page-component-block"> <div class="visual-dl-page-component-block">
<div class="visual-dl-page-control-block"> <div class="visual-dl-page-control-block">
<span :class="'visual-dl-page-control-span' + (config.scalar.display ? '' : ' visual-dl-page-disabled-text')">Smoothing</span> <span :class="'visual-dl-page-control-span' + (config.scalar.display ? '' : ' visual-dl-page-disabled-text')">{{ $t("lang.smoothing") }}</span>
<v-slider <v-slider
:max="0.99" :max="0.99"
:min="0" :min="0"
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
</div> </div>
<div class="visual-dl-page-control-block"> <div class="visual-dl-page-control-block">
<span :class="'visual-dl-page-control-span' + (config.scalar.display ? '' : ' visual-dl-page-disabled-text')">X-axis</span> <span :class="'visual-dl-page-control-span' + (config.scalar.display ? '' : ' visual-dl-page-disabled-text')">{{ $t("lang.xAxis") }}</span>
<v-select <v-select
:items="horizontalItems" :items="horizontalItems"
v-model="config.horizontal" v-model="config.horizontal"
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
</div> </div>
<div class="visual-dl-page-control-block"> <div class="visual-dl-page-control-block">
<span :class="'visual-dl-page-control-span' + (config.scalar.display ? '' : ' visual-dl-page-disabled-text')">Tooltip sorting</span> <span :class="'visual-dl-page-control-span' + (config.scalar.display ? '' : ' visual-dl-page-disabled-text')">{{ $t("lang.toolTipSorting") }}</span>
<v-select <v-select
:items="sortingMethodItems" :items="sortingMethodItems"
v-model="config.sortingMethod" v-model="config.sortingMethod"
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
<v-checkbox <v-checkbox
class="visual-dl-page-outliers-checkbox" class="visual-dl-page-outliers-checkbox"
label="Ignore outliers in chart scaling" :label="$t('lang.ignoreOutliers')"
v-model="config.outlier" v-model="config.outlier"
dark dark
:disabled="!config.scalar.display"/> :disabled="!config.scalar.display"/>
...@@ -57,14 +57,14 @@ ...@@ -57,14 +57,14 @@
<v-checkbox <v-checkbox
class="visual-dl-page-config-checkbox" class="visual-dl-page-config-checkbox"
label="Histogram" :label="$t('lang.histogram')"
v-model="config.histogram.display" v-model="config.histogram.display"
:disabled="!config.histogram.enabled" :disabled="!config.histogram.enabled"
dark/> dark/>
<div class="visual-dl-page-component-block"> <div class="visual-dl-page-component-block">
<div class="visual-dl-page-control-block"> <div class="visual-dl-page-control-block">
<span :class="'visual-dl-page-control-span' + (config.histogram.display ? '' : ' visual-dl-page-disabled-text')">Mode</span> <span :class="'visual-dl-page-control-span' + (config.histogram.display ? '' : ' visual-dl-page-disabled-text')">{{ $t("lang.mode") }}</span>
<v-select <v-select
:items="chartTypeItems" :items="chartTypeItems"
v-model="config.chartType" v-model="config.chartType"
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
dark dark
block block
> >
{{ config.running ? 'Running' : 'Stopped' }} {{ config.running ? $t("lang.startRunning") : $t("lang.stopRunning") }}
</v-btn> </v-btn>
</div> </div>
</template> </template>
...@@ -100,36 +100,59 @@ export default { ...@@ -100,36 +100,59 @@ export default {
}, },
data() { data() {
return { return {
horizontalItems: [ smoothingValue: this.config.smoothing,
isDemo: process.env.NODE_ENV === 'demo',
};
},
computed: {
sortingMethodItems() {
return [
{ {
text: 'Step', text: this.$i18n.t('lang.default'),
value: 'step', value: 'default',
}, },
{ {
text: 'Relative', text: this.$i18n.t('lang.descending'),
value: 'relative', value: 'descending',
}, },
{ {
text: 'Wall Time', text: this.$i18n.t('lang.ascending'),
value: 'wall', value: 'ascending',
},
{
text: this.$i18n.t('lang.nearest'),
value: 'nearest',
}, },
], ];
sortingMethodItems: [ },
'default', 'descending', 'ascending', 'nearest', chartTypeItems() {
], return [
chartTypeItems: [
{ {
text: 'Overlay', text: this.$i18n.t('lang.overlay'),
value: 'overlay', value: 'overlay',
}, },
{ {
text: 'Offset', text: this.$i18n.t('lang.offset'),
value: 'offset', value: 'offset',
}, },
], ];
smoothingValue: this.config.smoothing, },
isDemo: process.env.NODE_ENV === 'demo', horizontalItems() {
}; return [
{
text: this.$i18n.t('lang.step'),
value: 'step',
},
{
text: this.$i18n.t('lang.relative'),
value: 'relative',
},
{
text: this.$i18n.t('lang.wall'),
value: 'wall',
},
];
},
}, },
watch: { watch: {
smoothingValue: _.debounce( smoothingValue: _.debounce(
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
<v-list dense> <v-list dense>
<v-list-tile> <v-list-tile>
<v-list-tile-content> <v-list-tile-content>
<v-list-tile-title>Download data in JSON</v-list-tile-title> <v-list-tile-title>{{ $t("lang.downloadDataInJson") }}</v-list-tile-title>
</v-list-tile-content> </v-list-tile-content>
<v-list-tile-action> <v-list-tile-action>
<v-icon>expand_more</v-icon> <v-icon>expand_more</v-icon>
......
...@@ -8,15 +8,17 @@ ...@@ -8,15 +8,17 @@
color="tag_background" color="tag_background"
class="visual-dl-tags-tab"> class="visual-dl-tags-tab">
<v-icon>search</v-icon> <v-icon>search</v-icon>
<input type="search" v-model="config.groupNameReg" <input
type="search"
v-model="config.groupNameReg"
autocomplete="false" autocomplete="false"
placeholder="Search tags in RegExp" :placeholder="$t('lang.searchTagInReg')"
class="visual-dl-tags-search-input"> class="visual-dl-tags-search-input">
</v-card> </v-card>
<ui-tags-tab <ui-tags-tab
:total="tagsListCount(allTagsMatchingList)" :total="tagsListCount(allTagsMatchingList)"
:title="config.groupNameReg.trim().length == 0 ? 'All' : config.groupNameReg" :title="config.groupNameReg.trim().length == 0 ? $t('lang.all') : config.groupNameReg"
:active="selectedGroup === '' " :active="selectedGroup === '' "
@click="selectedGroup = '' " @click="selectedGroup = '' "
/> />
...@@ -24,6 +26,7 @@ ...@@ -24,6 +26,7 @@
v-for="item in groupedTags" v-for="item in groupedTags"
:total="tagsListCount(item.tags)" :total="tagsListCount(item.tags)"
:title="item.group" :title="item.group"
:key="item.group"
:active="item.group === selectedGroup" :active="item.group === selectedGroup"
@click="selectedGroup = item.group" @click="selectedGroup = item.group"
/> />
...@@ -70,17 +73,17 @@ export default { ...@@ -70,17 +73,17 @@ export default {
}, },
data() { data() {
return { return {
tagInfo: { image: {}, audio: {}, text: {} }, tagInfo: {image: {}, audio: {}, text: {}},
config: { config: {
groupNameReg: '', groupNameReg: '',
image: { enabled: false, display: false }, image: {enabled: false, display: false},
audio: { enabled: false, display: false }, audio: {enabled: false, display: false},
text: { enabled: false, display: false }, text: {enabled: false, display: false},
isActualImageSize: false, isActualImageSize: false,
runs: [], runs: [],
running: true, running: true,
}, },
filteredTagsList: { image: {}, audio: {}, text: {} }, filteredTagsList: {image: {}, audio: {}, text: {}},
selectedGroup: '', selectedGroup: '',
}; };
}, },
...@@ -107,7 +110,6 @@ export default { ...@@ -107,7 +110,6 @@ export default {
let list = {}; let list = {};
Object.keys(this.tagInfo).forEach((type) => { Object.keys(this.tagInfo).forEach((type) => {
let tags = this.tagInfo[type]; let tags = this.tagInfo[type];
let runs = Object.keys(tags); let runs = Object.keys(tags);
...@@ -133,7 +135,6 @@ export default { ...@@ -133,7 +135,6 @@ export default {
return list; return list;
}, },
groupedTags() { groupedTags() {
let tagsList = this.tagsList || []; let tagsList = this.tagsList || [];
// put data in group // put data in group
...@@ -143,11 +144,10 @@ export default { ...@@ -143,11 +144,10 @@ export default {
let tagsForEachType = tagsList[type]; let tagsForEachType = tagsList[type];
tagsForEachType.forEach((item) => { tagsForEachType.forEach((item) => {
let group = item.group; let group = item.group;
if (groupData[group] === undefined) { if (groupData[group] === undefined) {
groupData[group] = {} groupData[group] = {};
} }
if (groupData[group][type] === undefined) { if (groupData[group][type] === undefined) {
groupData[group][type] = []; groupData[group][type] = [];
...@@ -207,9 +207,9 @@ export default { ...@@ -207,9 +207,9 @@ export default {
'config.groupNameReg': function(val) { 'config.groupNameReg': function(val) {
this.throttledFilterTagsList(); this.throttledFilterTagsList();
}, },
runs: function(val) { 'runs': function(val) {
this.config.runs = val; this.config.runs = val;
} },
}, },
methods: { methods: {
filterTagsList(groupNameReg) { filterTagsList(groupNameReg) {
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div class="visual-dl-page-config-com"> <div class="visual-dl-page-config-com">
<v-checkbox <v-checkbox
class="visual-dl-page-config-checkbox" class="visual-dl-page-config-checkbox"
label="Image" :label="$t('lang.image')"
v-model="config.image.display" v-model="config.image.display"
:disabled="!config.image.enabled" :disabled="!config.image.enabled"
dark/> dark/>
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<div class="visual-dl-page-component-block"> <div class="visual-dl-page-component-block">
<v-checkbox <v-checkbox
class="visual-dl-page-subconfig-checkbox" class="visual-dl-page-subconfig-checkbox"
label="Show actual image size" :label="$t('lang.showActualImageSize')"
v-model="config.isActualImageSize" v-model="config.isActualImageSize"
dark dark
:disabled="!config.image.display"/> :disabled="!config.image.display"/>
...@@ -18,14 +18,14 @@ ...@@ -18,14 +18,14 @@
<v-checkbox <v-checkbox
class="visual-dl-page-config-checkbox" class="visual-dl-page-config-checkbox"
label="Audio" :label="$t('lang.audio')"
v-model="config.audio.display" v-model="config.audio.display"
:disabled="!config.audio.enabled" :disabled="!config.audio.enabled"
dark/> dark/>
<v-checkbox <v-checkbox
class="visual-dl-page-config-checkbox" class="visual-dl-page-config-checkbox"
label="Text" :label="$t('lang.text')"
v-model="config.text.display" v-model="config.text.display"
:disabled="!config.text.enabled" :disabled="!config.text.enabled"
dark/> dark/>
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
dark dark
block block
> >
{{ config.running ? 'Running' : 'Stopped' }} {{ config.running ? $t('lang.startRunning') : $t('lang.stopRunning') }}
</v-btn> </v-btn>
</div> </div>
</template> </template>
......
...@@ -4,6 +4,8 @@ export const getPluginScalarsTags = makeService('/data/plugin/scalars/tags'); ...@@ -4,6 +4,8 @@ export const getPluginScalarsTags = makeService('/data/plugin/scalars/tags');
export const getRuns = makeService('/data/runs'); export const getRuns = makeService('/data/runs');
export const getLanguage = makeService('/data/language');
export const getPluginScalarsScalars = makeService('/data/plugin/scalars/scalars'); export const getPluginScalarsScalars = makeService('/data/plugin/scalars/scalars');
export const getPluginImagesTags = makeService('/data/plugin/images/tags'); export const getPluginImagesTags = makeService('/data/plugin/images/tags');
......
...@@ -48,6 +48,9 @@ error_sleep_time = 2 # seconds ...@@ -48,6 +48,9 @@ error_sleep_time = 2 # seconds
SERVER_DIR = os.path.join(visualdl.ROOT, 'server') SERVER_DIR = os.path.join(visualdl.ROOT, 'server')
support_language = ["en", "zh"]
default_language = support_language[0]
def try_call(function, *args, **kwargs): def try_call(function, *args, **kwargs):
res = lib.retry(error_retry_times, function, error_sleep_time, *args, res = lib.retry(error_retry_times, function, error_sleep_time, *args,
...@@ -98,6 +101,14 @@ def parse_args(): ...@@ -98,6 +101,14 @@ def parse_args():
default=20, default=20,
help="memory cache timeout duration in seconds, default 20", help="memory cache timeout duration in seconds, default 20",
) )
parser.add_argument(
"-L",
"--language",
type=str,
default=default_language,
action="store",
help="set the default language")
args = parser.parse_args() args = parser.parse_args()
if not args.logdir: if not args.logdir:
parser.print_help() parser.print_help()
...@@ -162,6 +173,15 @@ def runs(): ...@@ -162,6 +173,15 @@ def runs():
return Response(json.dumps(result), mimetype='application/json') return Response(json.dumps(result), mimetype='application/json')
@app.route('/data/language')
def language():
data = args.language
if not data in support_language:
data = default_language
result = gen_result(0, "", data)
return Response(json.dumps(result), mimetype='application/json')
@app.route("/data/plugin/scalars/tags") @app.route("/data/plugin/scalars/tags")
def scalar_tags(): def scalar_tags():
data = cache_get("/data/plugin/scalars/tags", try_call, data = cache_get("/data/plugin/scalars/tags", try_call,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册