Add language files, language change setup

This commit is contained in:
cristij 2018-09-24 22:17:11 +03:00
parent cf960ca9bd
commit 1e10e82d78
8 changed files with 355 additions and 67 deletions

2
.env Normal file
View File

@ -0,0 +1,2 @@
VUE_APP_I18N_LOCALE=en
VUE_APP_I18N_FALLBACK_LOCALE=en

View File

@ -1,5 +1,5 @@
{ {
"name": "vue-paper-dashboard", "name": "vue-black-dashboard",
"version": "1.0.0", "version": "1.0.0",
"private": true, "private": true,
"scripts": { "scripts": {

View File

@ -5,7 +5,7 @@
<link rel="icon" type="image/png" sizes="96x96" href="<%= webpackConfig.output.publicPath %>favicon.png"> <link rel="icon" type="image/png" sizes="96x96" href="<%= webpackConfig.output.publicPath %>favicon.png">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>Vue Paper Dashboard</title> <title>Vue Black Dashboard Free</title>
<!-- Bootstrap core CSS --> <!-- Bootstrap core CSS -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">

23
src/i18n.js Normal file
View File

@ -0,0 +1,23 @@
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
function loadLocaleMessages () {
const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
const messages = {}
locales.keys().forEach(key => {
const matched = key.match(/([a-z0-9]+)\./i)
if (matched && matched.length > 1) {
const locale = matched[1]
messages[locale] = locales(key)
}
})
return messages
}
export default new VueI18n({
locale: process.env.VUE_APP_I18N_LOCALE || 'en',
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
messages: loadLocaleMessages()
})

View File

@ -1,9 +1,11 @@
<template> <template>
<nav class="navbar navbar-expand-lg navbar-absolute navbar-transparent"> <nav class="navbar navbar-expand-lg navbar-absolute"
:class="{'bg-white': showMenu}">
<div class="container-fluid"> <div class="container-fluid">
<div class="navbar-wrapper"> <div class="navbar-wrapper">
<div class="navbar-toggle d-inline"> <div class="navbar-toggle d-inline" :class="{toggled: $sidebar.showSidebar}">
<button type="button" class="navbar-toggler"> <button type="button" class="navbar-toggler"
@click="toggleSidebar">
<span class="navbar-toggler-bar bar1"></span> <span class="navbar-toggler-bar bar1"></span>
<span class="navbar-toggler-bar bar2"></span> <span class="navbar-toggler-bar bar2"></span>
<span class="navbar-toggler-bar bar3"></span> <span class="navbar-toggler-bar bar3"></span>
@ -12,9 +14,8 @@
<a class="navbar-brand" href="#pablo">{{routeName}}</a> <a class="navbar-brand" href="#pablo">{{routeName}}</a>
</div> </div>
<button class="navbar-toggler" type="button" <button class="navbar-toggler" type="button"
@click="toggleMenu"
data-toggle="collapse" data-toggle="collapse"
@click="toggleSidebar"
:aria-expanded="$sidebar.showSidebar"
data-target="#navigation" data-target="#navigation"
aria-controls="navigation-index" aria-controls="navigation-index"
aria-label="Toggle navigation"> aria-label="Toggle navigation">
@ -23,68 +24,74 @@
<span class="navbar-toggler-bar navbar-kebab"></span> <span class="navbar-toggler-bar navbar-kebab"></span>
</button> </button>
<div class="collapse navbar-collapse"> <collapse-transition>
<ul class="navbar-nav" :class="$rtl.isRTL ? 'mr-auto' : 'ml-auto'"> <div class="collapse navbar-collapse show" v-show="showMenu">
<div class="search-bar input-group"> <ul class="navbar-nav" :class="$rtl.isRTL ? 'mr-auto' : 'ml-auto'">
<!-- <input type="text" class="form-control" placeholder="Search..."> <div class="search-bar input-group">
<div class="input-group-addon"><i class="tim-icons icon-zoom-split"></i></div> --> <!-- <input type="text" class="form-control" placeholder="Search...">
<button class="btn btn-link" id="search-button" data-toggle="modal" data-target="#searchModal"> <div class="input-group-addon"><i class="tim-icons icon-zoom-split"></i></div> -->
<i class="tim-icons icon-zoom-split"></i> <button class="btn btn-link" id="search-button" data-toggle="modal" data-target="#searchModal">
</button> <i class="tim-icons icon-zoom-split"></i>
<!-- You can choose types of search input --> </button>
</div> <!-- You can choose types of search input -->
<base-dropdown class="nav-item" menu-on-right> </div>
<a slot="title" href="#" class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="true"> <base-dropdown class="nav-item" menu-on-right>
<div class="notification d-none d-lg-block d-xl-block"></div> <a slot="title" href="#" class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="true">
<i class="tim-icons icon-sound-wave"></i> <div class="notification d-none d-lg-block d-xl-block"></div>
<p class="d-lg-none"> <i class="tim-icons icon-sound-wave"></i>
New Notifications <p class="d-lg-none">
</p> New Notifications
</a> </p>
<li class="nav-link"> </a>
<a href="#" class="nav-item dropdown-item">Mike John responded to your email</a> <li class="nav-link">
</li> <a href="#" class="nav-item dropdown-item">Mike John responded to your email</a>
<li class="nav-link"> </li>
<a href="#" class="nav-item dropdown-item">You have 5 more tasks</a> <li class="nav-link">
</li> <a href="#" class="nav-item dropdown-item">You have 5 more tasks</a>
<li class="nav-link"> </li>
<a href="#" class="nav-item dropdown-item">Your friend Michael is in town</a> <li class="nav-link">
</li> <a href="#" class="nav-item dropdown-item">Your friend Michael is in town</a>
<li class="nav-link"> </li>
<a href="#" class="nav-item dropdown-item">Another notification</a> <li class="nav-link">
</li> <a href="#" class="nav-item dropdown-item">Another notification</a>
<li class="nav-link"> </li>
<a href="#" class="nav-item dropdown-item">Another one</a> <li class="nav-link">
</li> <a href="#" class="nav-item dropdown-item">Another one</a>
</base-dropdown> </li>
<base-dropdown class="nav-item" menu-classes="dropdown-navbar"> </base-dropdown>
<a slot="title" href="#" class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="true"> <base-dropdown class="nav-item" menu-classes="dropdown-navbar">
<div class="photo"> <a slot="title" href="#" class="dropdown-toggle nav-link" data-toggle="dropdown" aria-expanded="true">
<img src="/img/anime3.png"> <div class="photo">
</div> <img src="/img/anime3.png">
<b class="caret d-none d-lg-block d-xl-block"></b> </div>
<p class="d-lg-none"> <b class="caret d-none d-lg-block d-xl-block"></b>
Log out <p class="d-lg-none">
</p> Log out
</a> </p>
<li class="nav-link"> </a>
<a href="#" class="nav-item dropdown-item">Profile</a> <li class="nav-link">
</li> <a href="#" class="nav-item dropdown-item">Profile</a>
<li class="nav-link"> </li>
<a href="#" class="nav-item dropdown-item">Settings</a> <li class="nav-link">
</li> <a href="#" class="nav-item dropdown-item">Settings</a>
<div class="dropdown-divider"></div> </li>
<li class="nav-link"> <div class="dropdown-divider"></div>
<a href="#" class="nav-item dropdown-item">Log out</a> <li class="nav-link">
</li> <a href="#" class="nav-item dropdown-item">Log out</a>
</base-dropdown> </li>
</ul> </base-dropdown>
</ul>
</div> </div>
</collapse-transition>
</div> </div>
</nav> </nav>
</template> </template>
<script> <script>
import { CollapseTransition } from 'vue2-transitions';
export default { export default {
components: {
CollapseTransition
},
computed: { computed: {
routeName() { routeName() {
const { name } = this.$route; const { name } = this.$route;
@ -96,7 +103,8 @@
}, },
data() { data() {
return { return {
activeNotifications: false activeNotifications: false,
showMenu: false
}; };
}, },
methods: { methods: {
@ -114,6 +122,9 @@
}, },
hideSidebar() { hideSidebar() {
this.$sidebar.displaySidebar(false); this.$sidebar.displaySidebar(false);
},
toggleMenu() {
this.showMenu = !this.showMenu;
} }
} }
}; };

125
src/locales/ar.json Normal file
View File

@ -0,0 +1,125 @@
{
"dashboard": {
"completedTasks": "المهام المكتملة",
"dailySales": "المبيعات اليومية",
"performance": "أداء",
"simpleTable": "جدول بسيط",
"totalShipments": "مجموع الشحنات",
"chartCategories": [
"حسابات",
"المشتريات",
"جلسات"
],
"tasks": "تتبع",
"today": "اليوم",
"dropdown": {
"action": "عمل",
"anotherAction": "عمل آخر",
"somethingElse": "شيء آخر هنا"
},
"usersTable": {
"title": "جدول بسيط",
"columns": [
"اسم",
"بلد",
"مدينة",
"راتب"
],
"data": [
{
"id": 1,
"اسم": "رايس داكوتا",
"راتب": "$36.738",
"بلد": "النيجر",
"مدينة": "العود-تورنهاوت"
},
{
"id": 2,
"اسم": "مينيرفا هوبر",
"راتب": "$23,789",
"بلد": "كوراساو",
"مدينة": "Sinaai-واس"
},
{
"id": 3,
"اسم": "سيج رودريجيز",
"راتب": "$56,142",
"بلد": "هولندا",
"مدينة": "بايلي"
},
{
"id": 4,
"اسم": "فيليب شانيه",
"راتب": "$38,735",
"بلد": "كوريا، جنوب",
"مدينة": "اوفرلاند بارك"
},
{
"id": 5,
"اسم": "دوريس غرين",
"راتب": "$63,542",
"بلد": "مالاوي",
"مدينة": "المنع"
},
{
"id": 6,
"اسم": "ميسون بورتر",
"راتب": "$98,615",
"بلد": "تشيلي",
"مدينة": "غلوستر"
},
{
"id": 7,
"اسم": "جون بورتر",
"راتب": "$78,615",
"بلد": "البرتغال",
"مدينة": "غلوستر"
}
]
},
"taskList": [
{
"title": "مركز معالجة موقع محور",
"description": "نص آخر هناالوثائق",
"done": false
},
{
"title": "لامتثال GDPR",
"description": "الناتج المحلي الإجمالي هو نظام يتطلب من الشركات حماية البيانات الشخصية والخصوصية لمواطني أوروبا بالنسبة للمعاملات التي تتم داخل الدول الأعضاء في الاتحاد الأوروبي.",
"done": true
},
{
"title": "القضاياالقضايا",
"description": "سيكونونقال 50٪ من جميع المستجيبين أنهم سيكونون أكثر عرضة للتسوق في شركة",
"done": false
},
{
"title": "تصدير الملفات التي تمت معالجتها",
"description": "كما يبين التقرير أن المستهلكين لن يغفروا شركة بسهولة بمجرد حدوث خرق يعرض بياناتهم الشخصية.",
"done": false
},
{
"title": "الوصول إلى عملية التصدير",
"description": "سياسة السيء إنطلاق في قبل, مساعدة والمانيا أخذ قد. بل أما أمام ماشاء الشتاء،, تكاليف الإقتصادي بـ حين. ٣٠ يتعلّق للإتحاد ولم, وتم هناك مدينة بتحدّي إذ, كان بل عمل",
"done": false
},
{
"title": "الافراج عن v2.0.0",
"description": "عن رئيس طوكيو البولندي لمّ, مايو مرجع وباءت قبل هو, تسمّى الطريق الإقتصادي ذات أن. لغات الإطلاق الفرنسية دار ان, بين بتخصيص الساحة اقتصادية أم. و الآخ",
"done": false
}
]
},
"sidebar": {
"title": "توقيت الإبداعية",
"shortTitle": "ط م",
"dashboard": "لوحة القيادة",
"icons": "الرموز",
"maps": "خرائط",
"notifications": "إخطارات",
"userProfile": "ملف تعريفي للمستخدم",
"tableList": "قائمة الجدول",
"typography": "طباعة",
"rtlSupport": "دعم RTL"
}
}

125
src/locales/en.json Normal file
View File

@ -0,0 +1,125 @@
{
"dashboard": {
"completedTasks": "Completed Tasks",
"dailySales": "Daily Sales",
"performance": "Performance",
"simpleTable": "Simple Table",
"totalShipments": "Total Shipments",
"chartCategories": [
"Accounts",
"Purchases",
"Sessions"
],
"tasks": "Tasks({count})",
"today": "Today",
"dropdown": {
"action": "Action",
"anotherAction": "Another Action",
"somethingElse": "Something else"
},
"usersTable": {
"title": "Simple Table",
"columns": [
"Name",
"Country",
"City",
"Salary"
],
"data": [
{
"id": 1,
"name": "Dakota Rice",
"salary": "$36.738",
"country": "Niger",
"city": "Oud-Turnhout"
},
{
"id": 2,
"name": "Minerva Hooper",
"salary": "$23,789",
"country": "Curaçao",
"city": "Sinaai-Waas"
},
{
"id": 3,
"name": "Sage Rodriguez",
"salary": "$56,142",
"country": "Netherlands",
"city": "Baileux"
},
{
"id": 4,
"name": "Philip Chaney",
"salary": "$38,735",
"country": "Korea, South",
"city": "Overland Park"
},
{
"id": 5,
"name": "Doris Greene",
"salary": "$63,542",
"country": "Malawi",
"city": "Feldkirchen in Kärnten"
},
{
"id": 6,
"name": "Mason Porter",
"salary": "$98,615",
"country": "Chile",
"city": "Gloucester"
},
{
"id": 7,
"name": "Jon Porter",
"salary": "$78,615",
"country": "Portugal",
"city": "Gloucester"
}
]
},
"taskList": [
{
"title": "Update the Documentation",
"description": "Dwuamish Head, Seattle, WA 8:47 AM",
"done": false
},
{
"title": "GDPR Compliance",
"description": "The GDPR is a regulation that requires businesses to protect the personal data and privacy of Europe citizens for transactions that occur within EU member states.",
"done": true
},
{
"title": "Solve the issues",
"description": "Fifty percent of all respondents said they would be more likely to shop at a company",
"done": false
},
{
"title": "Release v2.0.0",
"description": "Ra Ave SW, Seattle, WA 98116, SUA 11:19 AM",
"done": false
},
{
"title": "Export the processed files",
"description": "The report also shows that consumers will not easily forgive a company once a breach exposing their personal data occurs.",
"done": false
},
{
"title": "Arival at export process",
"description": "Capitol Hill, Seattle, WA 12:34 AM",
"done": false
}
]
},
"sidebar": {
"title": "Creative Tim",
"shortTitle": "CT",
"dashboard": "dashboard",
"icons": "Icons",
"maps": "Maps",
"notifications": "Notifications",
"userProfile": "User Profile",
"tableList": "Table List",
"typography": "Typography",
"rtlSupport": "RTL Support"
}
}

View File

@ -95,8 +95,8 @@
<div class="col-lg-6 col-md-12"> <div class="col-lg-6 col-md-12">
<card type="tasks" :header-classes="{'text-right': isRTL}"> <card type="tasks" :header-classes="{'text-right': isRTL}">
<template slot="header"> <template slot="header">
<h6 class="title d-inline">Tasks(5)</h6> <h6 class="title d-inline">{{$t('dashboard.tasks', {count: 5})}}</h6>
<p class="card-category d-inline">today</p> <p class="card-category d-inline">{{$t('dashboard.today')}}</p>
<base-dropdown menu-on-right="" tag="div" :class="{'float-left': isRTL}"> <base-dropdown menu-on-right="" tag="div" :class="{'float-left': isRTL}">
<base-button slot="title" type="link" icon class="dropdown-toggle"> <base-button slot="title" type="link" icon class="dropdown-toggle">
<i class="tim-icons icon-settings-gear-63"></i> <i class="tim-icons icon-settings-gear-63"></i>
@ -226,7 +226,6 @@
return this.$rtl.isRTL; return this.$rtl.isRTL;
}, },
bigLineChartCategories() { bigLineChartCategories() {
console.log(this.$t('dashboard'))
return this.$t('dashboard.chartCategories'); return this.$t('dashboard.chartCategories');
} }
}, },
@ -256,13 +255,16 @@
} }
}, },
mounted() { mounted() {
this.i18n = this.$i18n;
if (this.enableRTL) { if (this.enableRTL) {
this.i18n.locale = 'ar';
this.$rtl.enableRTL(); this.$rtl.enableRTL();
} }
this.initBigChart(0); this.initBigChart(0);
}, },
beforeDestroy() { beforeDestroy() {
if (this.$rtl.isRTL) { if (this.$rtl.isRTL) {
this.i18n.locale = 'en';
this.$rtl.disableRTL(); this.$rtl.disableRTL();
} }
} }