diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..d5408027
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,4 @@
+# These are supported funding model platforms
+
+patreon: panjiachen
+custom: https://panjiachen.github.io/vue-element-admin-site/donate
diff --git a/.postcssrc.js b/.postcssrc.js
deleted file mode 100644
index 09948d63..00000000
--- a/.postcssrc.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// https://github.com/michael-ciniawsky/postcss-load-config
-
-module.exports = {
- "plugins": {
- // to edit target browsers: use "browserslist" field in package.json
- "autoprefixer": {}
- }
-}
diff --git a/README.es.md b/README.es.md
index 32231508..f3fb1190 100644
--- a/README.es.md
+++ b/README.es.md
@@ -10,16 +10,16 @@
-
+
-
+
-
+
-
+
@@ -27,33 +27,35 @@ Español | [Inglés](./README.md)
## Introducción
-[adempiere-vue](https://github.com/adempiere/adempiere-vue) es una nueva UI para [ADempiere ERP, CRM & SCM](https://github.com/adempiere/adempiere)]. Se basa en [vue](https://github.com/vuejs/vue) y usa el conjunto de herraminentas de UI [element-ui](https://github.com/ElemeFE/element).
+[adempiere-vue](https://github.com/adempiere/adempiere-vue) es una nueva UI para [ADempiere ERP, CRM & SCM](https://github.com/adempiere/adempiere)]. Está basada en [vue](https://github.com/vuejs/vue) y usa [element-ui](https://github.com/ElemeFE/element) como conjunto de herramientas de interfáz de usuario.
Este es una gran UI para [ADempiere ERP, CRM & SCM](https://github.com/adempiere/adempiere)] basada en lo último desarrollado por vue, construido con i18n para manejo multi-idioma, plantillas para aplicaciones de negocio y muchas características asombrosas. Este proyecto es derivado de [Vue-Element-Admin](https://github.com/PanJiaChen/vue-element-admin) originalmente escrito por [PanJiaChen / 花裤衩](https://github.com/PanJiaChen) sobre [licencia MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE) y cambiado a [licencia GNU/GPL v3](https://github.com/adempiere/adempiere-vue/blob/master/LICENSE) por [Yamel Senih](https://github.com/yamelsenih) después de derivar el proyecto y con permisos del autor original [PanJiaChen / 花裤衩](https://github.com/PanJiaChen) en el reporte ["Extend as GNU/Gpl v3 License #1434"](https://github.com/PanJiaChen/vue-element-admin/issues/1434).
[adempiere-vue](https://github.com/adempiere/adempiere-vue) usa como RPC (Llamado a Procedimientos Remostos)[gRPC](https://grpc.io/) como [server](https://github.com/erpcya/adempiere-gRPC-Server).
-- [Vista Prévia](http://adempiere-ui.erpya.com:9526/)
+- [Vista Prévia de la Aplicación](http://adempiere-ui.erpya.com:9526/)
- [Documentación](https://panjiachen.github.io/vue-element-admin-site/)
-- [Gitter](https://gitter.im/adempiere/adempiere-vue)
+- [Canal de Gitter](https://gitter.im/adempiere/adempiere-vue)
-- [Donar](https://www.paypal.me/?)
+- [Para Donaciones](https://www.paypal.me/?)
-- [Wikipedia](http://wiki.adempiere.net/ADempiere_ERP)
+- [Enlace de Wiki](http://wiki.adempiere.net/ADempiere_ERP)
- [Derivado De](https://github.com/PanJiaChen/vue-element-admin)
-**La versión actual `v1.0+` está construida en `vue-cli`. Si encuentra algún problema, por favor escriba un [reporte de error](https://github.com/adempiere/adempiere-vue/issues/new).**
+**La versión actual `v1.0+` está construida con `vue-cli`. Si encuentra algún problema, por favor escriba un [reporte de error](https://github.com/adempiere/adempiere-vue/issues/new).**
-**Este proyecto no soporta versiones bajas de los navegadores (e.g. IE).**
+**Este proyecto no está soportado para versiones muy viejas de navegadores (e.g. IE).**
## Preparación
Necesita instalar [node](https://nodejs.org/) y [git](https://git-scm.com/) localmente. El proyecto está basado en [ES2015+](https://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [vue-cli](https://github.com/vuejs/vue-cli) , [gRPC](https://grpc.io/) y [element-ui](https://github.com/ElemeFE/element).
Entendiendo y aprendiendo acerca de lo anterior le ayudará a conocer el proyecto.
+[](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox)
+
@@ -65,7 +67,7 @@ Entendiendo y aprendiendo acerca de lo anterior le ayudará a conocer el proyect
-Sea un patrocinante y coloque su logo en nuestro LEEME en GitHub con un link a su sitio web. [Sea un Patrocinante](https://www.paypal.me/?)
+Sea un patrocinante y coloque su logo en nuestro LEEME en GitHub con un enlace directo a su sitio web. [Sea un Patrocinante](https://www.paypal.me/?)
## Características
@@ -125,10 +127,11 @@ Sea un patrocinante y coloque su logo en nuestro LEEME en GitHub con un link a s
- Adhesión de objetos
- Contador hasta
- Soporte a ADempiere
- - Ventan
- - Proceso
- - Reporte
- - Visor Inteligente
+ - Ventana
+ - Proceso
+ - Reporte
+ - Consulta Inteligente
+ - Formulario
- Ejemplo Avanzado
- Registro de Errores
@@ -145,7 +148,7 @@ Use [gRPC ADempiere Server](https://github.com/erpcya/adempiere-gRPC-Server) com
```bash
# clone el proyecto
-git clone -b develop git@github.com:adempiere/vue-element-admin.git
+git clone -b develop git@github.com:adempiere/adempiere-vue.git
# vaya al directorio clonado
cd adempiere-vue
@@ -185,7 +188,7 @@ npm run lint
npm run lint -- --fix
```
-Vaya a [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) para mayor información.
+Vaya a [Documentación](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) para mayor información.
## Registro de Cambios
@@ -193,13 +196,13 @@ Los cambios detallados por cada liberación se encuentran en [notas de liberaci
## Demostración en línea
-[Preview](http://adempiere-ui.erpya.com:9526/)
+[Vista Prévia de la Aplicación](http://adempiere-ui.erpya.com:9526/)
## Donación
Si este proyecto es de mucha ayuda para ti, puedes ayudar a hacer una mejor UI
-[Dona por Paypal](https://www.paypal.me/?)
+[dona por Paypal](https://www.paypal.me/?)
## Navegadores Soportados
@@ -207,7 +210,7 @@ Navegadores modernos e Internet Explorer 10+.
| [
](https://godban.github.io/browsers-support-badges/)IE / Edge | [
](https://godban.github.io/browsers-support-badges/)Firefox | [
](https://godban.github.io/browsers-support-badges/)Chrome | [
](https://godban.github.io/browsers-support-badges/)Safari |
| --------- | --------- | --------- | --------- |
-| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
+| IE10, IE11, Edge| últimas 2 versiones| últimas 2 versiones| últimas 2 versiones
## Licencia
diff --git a/README.md b/README.md
index 0589b859..b57ea512 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,9 @@ It is a great UI for [ADempiere ERP, CRM & SCM](https://github.com/adempiere/ade
You need to install [node](https://nodejs.org/) and [git](https://git-scm.com/) locally. The project is based on [ES2015+](https://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [vue-cli](https://github.com/vuejs/vue-cli) , [gRPC](https://grpc.io/) and [element-ui](https://github.com/ElemeFE/element).
Understanding and learning this knowledge in advance will greatly help the use of this project.
-
+[](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox)
+
+
diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 00000000..958df046
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,9 @@
+{
+ "compilerOptions": {
+ "baseUrl": "./",
+ "paths": {
+ "@/*": ["src/*"]
+ }
+ },
+ "exclude": ["node_modules", "dist"]
+}
\ No newline at end of file
diff --git a/mock/article.js b/mock/article.js
index bc236eb9..50218ae4 100644
--- a/mock/article.js
+++ b/mock/article.js
@@ -18,7 +18,7 @@ for (let i = 0; i < count; i++) {
forecast: '@float(0, 100, 2, 2)',
importance: '@integer(1, 3)',
'type|1': ['CN', 'US', 'JP', 'EU'],
- 'status|1': ['published', 'draft', 'deleted'],
+ 'status|1': ['published', 'draft'],
display_time: '@datetime',
comment_disabled: true,
pageviews: '@integer(300, 5000)',
@@ -29,7 +29,7 @@ for (let i = 0; i < count; i++) {
export default [
{
- url: '/article/list',
+ url: '/vue-element-admin/article/list',
type: 'get',
response: config => {
const { importance, type, title, page = 1, limit = 20, sort } = config.query
@@ -58,7 +58,7 @@ export default [
},
{
- url: '/article/detail',
+ url: '/vue-element-admin/article/detail',
type: 'get',
response: config => {
const { id } = config.query
@@ -74,7 +74,7 @@ export default [
},
{
- url: '/article/pv',
+ url: '/vue-element-admin/article/pv',
type: 'get',
response: _ => {
return {
@@ -92,7 +92,7 @@ export default [
},
{
- url: '/article/create',
+ url: '/vue-element-admin/article/create',
type: 'post',
response: _ => {
return {
@@ -103,7 +103,7 @@ export default [
},
{
- url: '/article/update',
+ url: '/vue-element-admin/article/update',
type: 'post',
response: _ => {
return {
diff --git a/mock/index.js b/mock/index.js
index 6907e861..196e2927 100644
--- a/mock/index.js
+++ b/mock/index.js
@@ -54,17 +54,4 @@ export function mockXHR() {
}
}
-// for mock server
-const responseFake = (url, type, respond) => {
- return {
- url: new RegExp(`/mock${url}`),
- type: type || 'get',
- response(req, res) {
- res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
- }
- }
-}
-
-export default mocks.map(route => {
- return responseFake(route.url, route.type, route.response)
-})
+export default mocks
diff --git a/mock/mock-server.js b/mock/mock-server.js
index 4c4cb2af..806fdacc 100644
--- a/mock/mock-server.js
+++ b/mock/mock-server.js
@@ -2,17 +2,21 @@ const chokidar = require('chokidar')
const bodyParser = require('body-parser')
const chalk = require('chalk')
const path = require('path')
+const Mock = require('mockjs')
const mockDir = path.join(process.cwd(), 'mock')
function registerRoutes(app) {
let mockLastIndex
const { default: mocks } = require('./index.js')
- for (const mock of mocks) {
+ const mocksForServer = mocks.map(route => {
+ return responseFake(route.url, route.type, route.response)
+ })
+ for (const mock of mocksForServer) {
app[mock.type](mock.url, mock.response)
mockLastIndex = app._router.stack.length
}
- const mockRoutesLength = Object.keys(mocks).length
+ const mockRoutesLength = Object.keys(mocksForServer).length
return {
mockRoutesLength: mockRoutesLength,
mockStartIndex: mockLastIndex - mockRoutesLength
@@ -27,6 +31,18 @@ function unregisterRoutes() {
})
}
+// for mock server
+const responseFake = (url, type, respond) => {
+ return {
+ url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
+ type: type || 'get',
+ response(req, res) {
+ console.log('request invoke:' + req.path)
+ res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
+ }
+ }
+}
+
module.exports = app => {
// es6 polyfill
require('@babel/register')
diff --git a/mock/remote-search.js b/mock/remote-search.js
index bb33c2f4..60809cb8 100644
--- a/mock/remote-search.js
+++ b/mock/remote-search.js
@@ -13,7 +13,7 @@ NameList.push({ name: 'mock-Pan' })
export default [
// username search
{
- url: '/search/user',
+ url: '/vue-element-admin/search/user',
type: 'get',
response: config => {
const { name } = config.query
@@ -30,7 +30,7 @@ export default [
// transaction list
{
- url: '/transaction/list',
+ url: '/vue-element-admin/transaction/list',
type: 'get',
response: _ => {
return {
diff --git a/mock/role/index.js b/mock/role/index.js
index 39148076..d957493b 100644
--- a/mock/role/index.js
+++ b/mock/role/index.js
@@ -38,7 +38,7 @@ const roles = [
export default [
// mock get all routes form server
{
- url: '/routes',
+ url: '/vue-element-admin/routes',
type: 'get',
response: _ => {
return {
@@ -50,7 +50,7 @@ export default [
// mock get all roles form server
{
- url: '/roles',
+ url: '/vue-element-admin/roles',
type: 'get',
response: _ => {
return {
@@ -62,7 +62,7 @@ export default [
// add role
{
- url: '/role',
+ url: '/vue-element-admin/role',
type: 'post',
response: {
code: 20000,
@@ -74,7 +74,7 @@ export default [
// update role
{
- url: '/role/[A-Za-z0-9]',
+ url: '/vue-element-admin/role/[A-Za-z0-9]',
type: 'put',
response: {
code: 20000,
@@ -86,7 +86,7 @@ export default [
// delete role
{
- url: '/role/[A-Za-z0-9]',
+ url: '/vue-element-admin/role/[A-Za-z0-9]',
type: 'delete',
response: {
code: 20000,
diff --git a/mock/user.js b/mock/user.js
index 43f93a04..859bd6f3 100644
--- a/mock/user.js
+++ b/mock/user.js
@@ -26,7 +26,7 @@ const users = {
export default [
// user login
{
- url: '/user/login',
+ url: '/vue-element-admin/user/login',
type: 'post',
response: config => {
const { username } = config.body
@@ -49,7 +49,7 @@ export default [
// get user info
{
- url: '/user/info\.*',
+ url: '/vue-element-admin/user/info\.*',
type: 'get',
response: config => {
const { token } = config.query
@@ -72,7 +72,7 @@ export default [
// user logout
{
- url: '/user/logout',
+ url: '/vue-element-admin/user/logout',
type: 'post',
response: _ => {
return {
diff --git a/package.json b/package.json
index 5b84730a..a1cf73ec 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,14 @@
{
"name": "adempiere-vue",
- "version": "4.1.0",
+ "version": "4.2.1",
"description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features",
"author": "Pan ",
+ "contributors": [
+ {
+ "name": "Edwin Betancourt",
+ "url": "https://github.com/EdwinBetanc0urt/"
+ }
+ ],
"license": "GPL-3.0-or-later",
"scripts": {
"start": "vue-cli-service serve",
@@ -68,6 +74,7 @@
"normalize.css": "8.0.1",
"nprogress": "0.2.0",
"path-to-regexp": "2.4.0",
+ "pinyin": "2.9.0",
"screenfull": "5.0.2",
"script-loader": "0.7.2",
"showdown": "1.9.1",
@@ -124,7 +131,6 @@
},
"browserslist": [
"> 1%",
- "last 2 versions",
- "not ie <= 8"
+ "last 2 versions"
]
}
diff --git a/plop-templates/store/index.hbs b/plop-templates/store/index.hbs
new file mode 100644
index 00000000..4f8e2dc0
--- /dev/null
+++ b/plop-templates/store/index.hbs
@@ -0,0 +1,16 @@
+{{#if state}}
+const state = {}
+{{/if}}
+
+{{#if mutations}}
+const mutations = {}
+{{/if}}
+
+{{#if actions}}
+const actions = {}
+{{/if}}
+
+export default {
+ namespaced: true,
+ {{options}}
+}
diff --git a/plop-templates/store/prompt.js b/plop-templates/store/prompt.js
new file mode 100644
index 00000000..bcbc11d1
--- /dev/null
+++ b/plop-templates/store/prompt.js
@@ -0,0 +1,62 @@
+const { notEmpty } = require('../utils.js')
+
+module.exports = {
+ description: 'generate store',
+ prompts: [{
+ type: 'input',
+ name: 'name',
+ message: 'store name please',
+ validate: notEmpty('name')
+ },
+ {
+ type: 'checkbox',
+ name: 'blocks',
+ message: 'Blocks:',
+ choices: [{
+ name: 'state',
+ value: 'state',
+ checked: true
+ },
+ {
+ name: 'mutations',
+ value: 'mutations',
+ checked: true
+ },
+ {
+ name: 'actions',
+ value: 'actions',
+ checked: true
+ }
+ ],
+ validate(value) {
+ if (!value.includes('state') || !value.includes('mutations')) {
+ return 'store require at least state and mutations'
+ }
+ return true
+ }
+ }
+ ],
+ actions(data) {
+ const name = '{{name}}'
+ const { blocks } = data
+ const options = ['state', 'mutations']
+ const joinFlag = `,
+ `
+ if (blocks.length === 3) {
+ options.push('actions')
+ }
+
+ const actions = [{
+ type: 'add',
+ path: `src/store/modules/${name}.js`,
+ templateFile: 'plop-templates/store/index.hbs',
+ data: {
+ options: options.join(joinFlag),
+ state: blocks.includes('state'),
+ mutations: blocks.includes('mutations'),
+ actions: blocks.includes('actions')
+ }
+ }]
+ return actions
+ }
+}
diff --git a/plopfile.js b/plopfile.js
index a4a0546a..2ec8a279 100644
--- a/plopfile.js
+++ b/plopfile.js
@@ -1,5 +1,6 @@
const viewGenerator = require('./plop-templates/view/prompt')
const componentGenerator = require('./plop-templates/component/prompt')
+const storeGenerator = require('./plop-templates/store/prompt.js')
const ADempiereView = require('./plop-templates/ADempiere/view/prompt')
const ADempiereComponent = require('./plop-templates/ADempiere/component/prompt')
const ADempiereStore = require('./plop-templates/ADempiere/store/prompt')
@@ -7,6 +8,7 @@ const ADempiereStore = require('./plop-templates/ADempiere/store/prompt')
module.exports = function(plop) {
plop.setGenerator('view', viewGenerator)
plop.setGenerator('component', componentGenerator)
+ plop.setGenerator('store', storeGenerator)
plop.setGenerator('ADempiere View', ADempiereView)
plop.setGenerator('ADempiere Component', ADempiereComponent)
plop.setGenerator('ADempiere Store Module', ADempiereStore)
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 00000000..961986e2
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ plugins: {
+ autoprefixer: {}
+ }
+}
diff --git a/public/index.html b/public/index.html
index 9bb2d7fc..e9185009 100644
--- a/public/index.html
+++ b/public/index.html
@@ -9,10 +9,6 @@
<%= webpackConfig.name %>
-
- <% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
-
- <% } %>
diff --git a/src/api/article.js b/src/api/article.js
index f54b8af6..407bda16 100644
--- a/src/api/article.js
+++ b/src/api/article.js
@@ -2,7 +2,7 @@ import request from '@/utils/request'
export function fetchList(query) {
return request({
- url: '/article/list',
+ url: '/vue-element-admin/article/list',
method: 'get',
params: query
})
@@ -10,7 +10,7 @@ export function fetchList(query) {
export function fetchArticle(id) {
return request({
- url: '/article/detail',
+ url: '/vue-element-admin/article/detail',
method: 'get',
params: { id }
})
@@ -18,7 +18,7 @@ export function fetchArticle(id) {
export function fetchPv(pv) {
return request({
- url: '/article/pv',
+ url: '/vue-element-admin/article/pv',
method: 'get',
params: { pv }
})
@@ -26,7 +26,7 @@ export function fetchPv(pv) {
export function createArticle(data) {
return request({
- url: '/article/create',
+ url: '/vue-element-admin/article/create',
method: 'post',
data
})
@@ -34,7 +34,7 @@ export function createArticle(data) {
export function updateArticle(data) {
return request({
- url: '/article/update',
+ url: '/vue-element-admin/article/update',
method: 'post',
data
})
diff --git a/src/api/remote-search.js b/src/api/remote-search.js
index c7e19117..02e42b46 100644
--- a/src/api/remote-search.js
+++ b/src/api/remote-search.js
@@ -2,7 +2,7 @@ import request from '@/utils/request'
export function searchUser(name) {
return request({
- url: '/search/user',
+ url: '/vue-element-admin/search/user',
method: 'get',
params: { name }
})
@@ -10,7 +10,7 @@ export function searchUser(name) {
export function transactionList(query) {
return request({
- url: '/transaction/list',
+ url: '/vue-element-admin/transaction/list',
method: 'get',
params: query
})
diff --git a/src/api/role.js b/src/api/role.js
index f6a983f1..959bbd21 100644
--- a/src/api/role.js
+++ b/src/api/role.js
@@ -2,21 +2,21 @@ import request from '@/utils/request'
export function getRoutes() {
return request({
- url: '/routes',
+ url: '/vue-element-admin/routes',
method: 'get'
})
}
export function getRoles() {
return request({
- url: '/roles',
+ url: '/vue-element-admin/roles',
method: 'get'
})
}
export function addRole(data) {
return request({
- url: '/role',
+ url: '/vue-element-admin/role',
method: 'post',
data
})
@@ -24,7 +24,7 @@ export function addRole(data) {
export function updateRole(id, data) {
return request({
- url: `/role/${id}`,
+ url: `/vue-element-admin/role/${id}`,
method: 'put',
data
})
@@ -32,7 +32,7 @@ export function updateRole(id, data) {
export function deleteRole(id) {
return request({
- url: `/role/${id}`,
+ url: `/vue-element-admin/role/${id}`,
method: 'delete'
})
}
diff --git a/src/components/Breadcrumb/index.vue b/src/components/Breadcrumb/index.vue
index 433a5b4f..369e336f 100644
--- a/src/components/Breadcrumb/index.vue
+++ b/src/components/Breadcrumb/index.vue
@@ -12,7 +12,9 @@
- {{ generateTitle(item.meta.title) }}
+
+ {{ generateTitle(item.meta.title) }}
+
@@ -26,8 +28,9 @@
- {{
- generateTitle(item.meta.title) }}
+
+ {{ generateTitle(item.meta.title) }}
+
{{ generateTitle(item.meta.title) }}
@@ -48,7 +51,11 @@ export default {
}
},
watch: {
- $route() {
+ $route(route) {
+ // if you go to the redirect page, do not update the breadcrumbs
+ if (route.path.startsWith('/redirect/')) {
+ return
+ }
this.getBreadcrumb()
}
},
diff --git a/src/components/Charts/mixins/resize.js b/src/components/Charts/mixins/resize.js
index dccaf1a8..b1e76e94 100644
--- a/src/components/Charts/mixins/resize.js
+++ b/src/components/Charts/mixins/resize.js
@@ -3,32 +3,54 @@ import { debounce } from '@/utils'
export default {
data() {
return {
- $_sidebarElm: null
+ $_sidebarElm: null,
+ $_resizeHandler: null
}
},
mounted() {
- this.__resizeHandler = debounce(() => {
- if (this.chart) {
- this.chart.resize()
- }
- }, 100)
- window.addEventListener('resize', this.__resizeHandler)
+ this.initListener()
+ },
+ activated() {
+ if (!this.$_resizeHandler) {
+ // avoid duplication init
+ this.initListener()
+ }
- this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
- this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
+ // when keep-alive chart activated, auto resize
+ this.resize()
},
beforeDestroy() {
- window.removeEventListener('resize', this.__resizeHandler)
-
- this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
+ this.destroyListener()
+ },
+ deactivated() {
+ this.destroyListener()
},
methods: {
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_sidebarResizeHandler(e) {
if (e.propertyName === 'width') {
- this.__resizeHandler()
+ this.$_resizeHandler()
}
+ },
+ initListener() {
+ this.$_resizeHandler = debounce(() => {
+ this.resize()
+ }, 100)
+ window.addEventListener('resize', this.$_resizeHandler)
+
+ this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
+ this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
+ },
+ destroyListener() {
+ window.removeEventListener('resize', this.$_resizeHandler)
+ this.$_resizeHandler = null
+
+ this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
+ },
+ resize() {
+ const { chart } = this
+ chart && chart.resize()
}
}
}
diff --git a/src/components/ErrorLog/index.vue b/src/components/ErrorLog/index.vue
index 7ffa573b..6119c037 100644
--- a/src/components/ErrorLog/index.vue
+++ b/src/components/ErrorLog/index.vue
@@ -6,7 +6,11 @@
-
+
+
+ Error Log
+ Clear All
+
@@ -54,6 +58,12 @@ export default {
errorLogs() {
return this.$store.getters.errorLogs
}
+ },
+ methods: {
+ clearAll() {
+ this.dialogTableVisible = false
+ this.$store.dispatch('errorLog/clearErrorLog')
+ }
}
}
diff --git a/src/components/HeaderSearch/index.vue b/src/components/HeaderSearch/index.vue
index e836b55a..cdff74ff 100644
--- a/src/components/HeaderSearch/index.vue
+++ b/src/components/HeaderSearch/index.vue
@@ -45,6 +45,9 @@ export default {
},
lang() {
return this.$store.getters.language
+ },
+ supportPinyinSearch() {
+ return this.$store.state.settings.supportPinyinSearch
}
},
watch: {
@@ -55,6 +58,10 @@ export default {
this.searchPool = this.generateRoutes(this.routes)
},
searchPool(list) {
+ // Support pinyin search
+ if (this.lang === 'zh' && this.supportPinyinSearch) {
+ this.addPinyinField(list)
+ }
this.initFuse(list)
},
show(value) {
@@ -70,6 +77,23 @@ export default {
},
methods: {
generateTitle,
+ async addPinyinField(list) {
+ const { default: pinyin } = await import('pinyin')
+ if (Array.isArray(list)) {
+ list.forEach(element => {
+ const title = element.title
+ if (Array.isArray(title)) {
+ title.forEach(v => {
+ v = pinyin(v, {
+ style: pinyin.STYLE_NORMAL
+ }).join('')
+ element.pinyinTitle = v
+ })
+ }
+ })
+ return list
+ }
+ },
click() {
this.show = !this.show
if (this.show) {
@@ -108,6 +132,9 @@ export default {
keys: [{
name: 'title',
weight: 0.7
+ }, {
+ name: 'pinyinTitle',
+ weight: 0.3
}, {
name: 'path',
weight: 0.3
@@ -118,7 +145,6 @@ export default {
// And generate the internationalized title
generateRoutes(routes, basePath = '/', prefixTitle = []) {
let res = []
-
for (const router of routes) {
// skip hidden router
// if (router.meta && router.meta.isIndex) { continue }
@@ -128,7 +154,6 @@ export default {
meta: router.meta,
name: router.name
}
-
if (router.meta && router.meta.title) {
// generate internationalized title
const i18ntitle = this.generateTitle(router.meta.title)
@@ -139,7 +164,6 @@ export default {
res.push(data)
}
}
-
// recursive child routes
if (router.children) {
const tempRoutes = this.generateRoutes(router.children, data.path, data.title)
@@ -164,13 +188,11 @@ export default {
-->
-
-
diff --git a/src/components/MDinput/index.vue b/src/components/MDinput/index.vue
index 013462fa..c59ea34a 100644
--- a/src/components/MDinput/index.vue
+++ b/src/components/MDinput/index.vue
@@ -9,7 +9,7 @@
:placeholder="fillPlaceHolder"
:readonly="readonly"
:disabled="disabled"
- :autoComplete="autoComplete"
+ :autocomplete="autoComplete"
:required="required"
type="email"
class="material-input"
@@ -24,7 +24,7 @@
:placeholder="fillPlaceHolder"
:readonly="readonly"
:disabled="disabled"
- :autoComplete="autoComplete"
+ :autocomplete="autoComplete"
:required="required"
type="url"
class="material-input"
@@ -40,7 +40,7 @@
:step="step"
:readonly="readonly"
:disabled="disabled"
- :autoComplete="autoComplete"
+ :autocomplete="autoComplete"
:max="max"
:min="min"
:minlength="minlength"
@@ -59,7 +59,7 @@
:placeholder="fillPlaceHolder"
:readonly="readonly"
:disabled="disabled"
- :autoComplete="autoComplete"
+ :autocomplete="autoComplete"
:max="max"
:min="min"
:required="required"
@@ -76,7 +76,7 @@
:placeholder="fillPlaceHolder"
:readonly="readonly"
:disabled="disabled"
- :autoComplete="autoComplete"
+ :autocomplete="autoComplete"
:required="required"
type="tel"
class="material-input"
@@ -91,7 +91,7 @@
:placeholder="fillPlaceHolder"
:readonly="readonly"
:disabled="disabled"
- :autoComplete="autoComplete"
+ :autocomplete="autoComplete"
:minlength="minlength"
:maxlength="maxlength"
:required="required"
diff --git a/src/components/MarkdownEditor/index.vue b/src/components/MarkdownEditor/index.vue
index 3d6794b5..1a8a01ee 100644
--- a/src/components/MarkdownEditor/index.vue
+++ b/src/components/MarkdownEditor/index.vue
@@ -12,7 +12,7 @@ import Editor from 'tui-editor'
import defaultOptions from './default-options'
export default {
- name: 'MarddownEditor',
+ name: 'MarkdownEditor',
props: {
value: {
type: String,
diff --git a/src/components/PanThumb/index.vue b/src/components/PanThumb/index.vue
index de6940ad..1bcf4170 100644
--- a/src/components/PanThumb/index.vue
+++ b/src/components/PanThumb/index.vue
@@ -5,7 +5,8 @@
-
+
+
@@ -52,7 +53,8 @@ export default {
.pan-thumb {
width: 100%;
height: 100%;
- background-size: 100%;
+ background-position: center center;
+ background-size: cover;
border-radius: 50%;
overflow: hidden;
position: absolute;
@@ -60,7 +62,7 @@ export default {
transition: all 0.3s ease-in-out;
}
-.pan-thumb:after {
+/* .pan-thumb:after {
content: '';
width: 8px;
height: 8px;
@@ -71,7 +73,7 @@ export default {
margin: -4px 0 0 -4px;
background: radial-gradient(ellipse at center, rgba(14, 14, 14, 1) 0%, rgba(125, 126, 125, 1) 100%);
box-shadow: 0 0 1px rgba(255, 255, 255, 0.9);
-}
+} */
.pan-info {
position: absolute;
diff --git a/src/components/RightPanel/index.vue b/src/components/RightPanel/index.vue
index ede48961..19b46591 100644
--- a/src/components/RightPanel/index.vue
+++ b/src/components/RightPanel/index.vue
@@ -105,32 +105,27 @@ export default {
diff --git a/src/components/Tinymce/dynamicLoadScript.js b/src/components/Tinymce/dynamicLoadScript.js
new file mode 100644
index 00000000..185f58dc
--- /dev/null
+++ b/src/components/Tinymce/dynamicLoadScript.js
@@ -0,0 +1,59 @@
+let callbacks = []
+
+function loadedTinymce() {
+ // to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2144
+ // check is successfully downloaded script
+ return window.tinymce
+}
+
+const dynamicLoadScript = (src, callback) => {
+ const existingScript = document.getElementById(src)
+ const cb = callback || function() {}
+
+ if (!existingScript) {
+ const script = document.createElement('script')
+ script.src = src // src url for the third-party library being loaded.
+ script.id = src
+ document.body.appendChild(script)
+ callbacks.push(cb)
+ const onEnd = 'onload' in script ? stdOnEnd : ieOnEnd
+ onEnd(script)
+ }
+
+ if (existingScript && cb) {
+ if (loadedTinymce()) {
+ cb(null, existingScript)
+ } else {
+ callbacks.push(cb)
+ }
+ }
+
+ function stdOnEnd(script) {
+ script.onload = function() {
+ // this.onload = null here is necessary
+ // because even IE9 works not like others
+ this.onerror = this.onload = null
+ for (const cb of callbacks) {
+ cb(null, script)
+ }
+ callbacks = null
+ }
+ script.onerror = function() {
+ this.onerror = this.onload = null
+ cb(new Error('Failed to load ' + src), script)
+ }
+ }
+
+ function ieOnEnd(script) {
+ script.onreadystatechange = function() {
+ if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
+ this.onreadystatechange = null
+ for (const cb of callbacks) {
+ cb(null, script) // there is no way to catch loading errors in IE8
+ }
+ callbacks = null
+ }
+ }
+}
+
+export default dynamicLoadScript
diff --git a/src/components/Tinymce/index.vue b/src/components/Tinymce/index.vue
index 08ef768d..8fb5cc8d 100644
--- a/src/components/Tinymce/index.vue
+++ b/src/components/Tinymce/index.vue
@@ -15,6 +15,10 @@
import editorImage from './components/EditorImage'
import plugins from './plugins'
import toolbar from './toolbar'
+import load from './dynamicLoadScript'
+
+// why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
+const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'
export default {
name: 'Tinymce',
@@ -91,10 +95,12 @@ export default {
}
},
mounted() {
- this.initTinymce()
+ this.init()
},
activated() {
- this.initTinymce()
+ if (window.tinymce) {
+ this.initTinymce()
+ }
},
deactivated() {
this.destroyTinymce()
@@ -103,6 +109,16 @@ export default {
this.destroyTinymce()
},
methods: {
+ init() {
+ // dynamic load tinymce from cdn
+ load(tinymceCDN, (err) => {
+ if (err) {
+ this.$message.error(err.message)
+ return
+ }
+ this.initTinymce()
+ })
+ },
initTinymce() {
const _this = this
window.tinymce.init({
@@ -138,7 +154,11 @@ export default {
editor.on('FullscreenStateChanged', (e) => {
_this.fullscreen = e.state
})
- }
+ },
+ // it will try to keep these URLs intact
+ // https://www.tiny.cloud/docs-3x/reference/configuration/Configuration3x@convert_urls/
+ // https://stackoverflow.com/questions/5196205/disable-tinymce-absolute-to-relative-url-conversions
+ convert_urls: false
// 整合七牛上传
// images_dataimg_filter(img) {
// setTimeout(() => {
diff --git a/src/filters/index.js b/src/filters/index.js
index f6a28488..98222339 100644
--- a/src/filters/index.js
+++ b/src/filters/index.js
@@ -45,7 +45,7 @@ export function numberFormatter(num, digits) {
]
for (let i = 0; i < si.length; i++) {
if (num >= si[i].value) {
- return (num / si[i].value + 0.1).toFixed(digits).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].symbol
+ return (num / si[i].value).toFixed(digits).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].symbol
}
}
return num.toString()
diff --git a/src/layout/components/AppMain.vue b/src/layout/components/AppMain.vue
index 7ff967c7..9b47d5b6 100644
--- a/src/layout/components/AppMain.vue
+++ b/src/layout/components/AppMain.vue
@@ -58,8 +58,6 @@ export default {
.fixed-header+.app-main {
padding-top: 50px;
- height: 100vh;
- overflow: auto;
}
.hasTagsView {
diff --git a/src/layout/components/Navbar.vue b/src/layout/components/Navbar.vue
index c2f771a2..f40d870c 100644
--- a/src/layout/components/Navbar.vue
+++ b/src/layout/components/Navbar.vue
@@ -30,8 +30,8 @@
Docs
-
- {{ $t('navbar.logOut') }}
+
+ {{ $t('navbar.logOut') }}
-->
diff --git a/src/layout/components/Settings/index.vue b/src/layout/components/Settings/index.vue
index 09ebad54..131b190e 100644
--- a/src/layout/components/Settings/index.vue
+++ b/src/layout/components/Settings/index.vue
@@ -27,6 +27,18 @@
{{ $t('settings.sidebarLogo') }}
+
+
+
+
+
+ 菜单支持拼音搜索
+
+
@@ -41,6 +53,9 @@ export default {
return {}
},
computed: {
+ isShowJob() {
+ return this.$store.getters.language === 'zh'
+ },
fixedHeader: {
get() {
return this.$store.state.settings.fixedHeader
@@ -84,6 +99,20 @@ export default {
value: val
})
}
+ },
+ supportPinyinSearch: {
+ get() {
+ return this.$store.state.settings.supportPinyinSearch
+ },
+ set(val) {
+ this.$store.dispatch('settings/changeSetting', {
+ key: 'supportPinyinSearch',
+ value: val
+ })
+ }
+ },
+ lang() {
+ return this.$store.getters.language
}
},
methods: {
@@ -120,5 +149,13 @@ export default {
.drawer-switch {
float: right
}
+
+ .job-link{
+ display: block;
+ position: absolute;
+ width: 100%;
+ left: 0;
+ bottom: 0;
+ }
}
diff --git a/src/layout/components/Sidebar/Link.vue b/src/layout/components/Sidebar/Link.vue
index bef9ac14..9d1a2e6d 100644
--- a/src/layout/components/Sidebar/Link.vue
+++ b/src/layout/components/Sidebar/Link.vue
@@ -1,7 +1,5 @@
-
-
-
+
@@ -16,19 +14,28 @@ export default {
required: true
}
},
+ computed: {
+ isExternal() {
+ return isExternal(this.to)
+ },
+ type() {
+ if (this.isExternal) {
+ return 'a'
+ }
+ return 'router-link'
+ }
+ },
methods: {
- linkProps(route) {
- if (isExternal(route.path)) {
+ linkProps(to) {
+ if (this.isExternal) {
return {
- is: 'a',
- href: route.path,
+ href: to,
target: '_blank',
rel: 'noopener'
}
}
return {
- is: 'router-link',
- to: { name: route.name }
+ to: to
}
}
}
diff --git a/src/layout/components/Sidebar/SidebarItem.vue b/src/layout/components/Sidebar/SidebarItem.vue
index 0efe4464..bd4d6679 100644
--- a/src/layout/components/Sidebar/SidebarItem.vue
+++ b/src/layout/components/Sidebar/SidebarItem.vue
@@ -1,5 +1,5 @@
-