@ -0,0 +1,12 @@ |
|||||
|
using Microsoft.AspNetCore.Http; |
||||
|
|
||||
|
namespace Microsoft.AspNetCore.Builder |
||||
|
{ |
||||
|
public static class SignalRJwtTokenApplicationBuilderExtensions |
||||
|
{ |
||||
|
public static IApplicationBuilder UseSignalRJwtToken(this IApplicationBuilder app) |
||||
|
{ |
||||
|
return app.UseMiddleware<SignalRJwtTokenMiddleware>(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,8 +1,7 @@ |
|||||
using Microsoft.AspNetCore.Http; |
using System.Threading.Tasks; |
||||
using System.Threading.Tasks; |
|
||||
using Volo.Abp.DependencyInjection; |
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
namespace Microsoft.AspNetCore.Builder |
namespace Microsoft.AspNetCore.Http |
||||
{ |
{ |
||||
public class SignalRJwtTokenMiddleware : IMiddleware, ITransientDependency |
public class SignalRJwtTokenMiddleware : IMiddleware, ITransientDependency |
||||
{ |
{ |
||||
@ -0,0 +1,2 @@ |
|||||
|
> 1% |
||||
|
last 2 versions |
||||
@ -0,0 +1,35 @@ |
|||||
|
# http://editorconfig.org |
||||
|
|
||||
|
# top-most EditorConfig file |
||||
|
root = true |
||||
|
|
||||
|
# Unix-style newlines with a newline ending every file |
||||
|
[*] |
||||
|
charset = utf-8 |
||||
|
end_of_line = lf |
||||
|
insert_final_newline = true |
||||
|
trim_trailing_whitespace = true |
||||
|
|
||||
|
# Indentation override for js(x), ts(x) and vue files |
||||
|
[*.{js,jsx,ts,tsx,vue}] |
||||
|
indent_size = 2 |
||||
|
indent_style = space |
||||
|
|
||||
|
# Indentation override for css related files |
||||
|
[*.{css,styl,scss,less,sass}] |
||||
|
indent_size = 2 |
||||
|
indent_style = space |
||||
|
|
||||
|
# Indentation override for html files |
||||
|
[*.html] |
||||
|
indent_size = 2 |
||||
|
indent_style = space |
||||
|
|
||||
|
# Trailing space override for markdown file |
||||
|
[*.md] |
||||
|
trim_trailing_whitespace = false |
||||
|
|
||||
|
# Indentation override for config files |
||||
|
[*.{json,yml}] |
||||
|
indent_size = 2 |
||||
|
indent_style = space |
||||
@ -0,0 +1,20 @@ |
|||||
|
# Base api |
||||
|
VUE_APP_BASE_API = '/api' |
||||
|
|
||||
|
#Signalr |
||||
|
VUE_APP_SIGNALR_SERVER = '/signalr-hubs' |
||||
|
|
||||
|
#IdentityServer |
||||
|
VUE_APP_BASE_IDENTITY_SERVER = '/connect' |
||||
|
|
||||
|
VUE_APP_CLIENT_ID = 'vue-admin-element' |
||||
|
VUE_APP_CLIENT_SECRET = '1q2w3e*' |
||||
|
|
||||
|
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable, |
||||
|
# to control whether the babel-plugin-dynamic-import-node plugin is enabled. |
||||
|
# It only does one thing by converting all import() to require(). |
||||
|
# This configuration can significantly increase the speed of hot updates, |
||||
|
# when you have a large number of pages. |
||||
|
# Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js |
||||
|
|
||||
|
VUE_CLI_BABEL_TRANSPILE_MODULES = true |
||||
@ -0,0 +1,6 @@ |
|||||
|
# Set to production for building optimization |
||||
|
NODE_ENV = production |
||||
|
|
||||
|
# Base api |
||||
|
VUE_APP_BASE_API = '/stage-api' |
||||
|
|
||||
@ -0,0 +1,4 @@ |
|||||
|
dist/*.js |
||||
|
src/assets |
||||
|
tests/unit/coverage |
||||
|
public/**/*.js |
||||
@ -0,0 +1,53 @@ |
|||||
|
module.exports = { |
||||
|
root: true, |
||||
|
env: { |
||||
|
node: true |
||||
|
}, |
||||
|
extends: [ |
||||
|
'plugin:vue/recommended', |
||||
|
'@vue/standard', |
||||
|
'@vue/typescript/recommended' |
||||
|
], |
||||
|
parserOptions: { |
||||
|
ecmaVersion: 2020 |
||||
|
}, |
||||
|
rules: { |
||||
|
'@typescript-eslint/ban-types': 'off', |
||||
|
'@typescript-eslint/explicit-module-boundary-types': 'off', |
||||
|
'@typescript-eslint/member-delimiter-style': ['error', |
||||
|
{ |
||||
|
multiline: { |
||||
|
delimiter: 'none' |
||||
|
}, |
||||
|
singleline: { |
||||
|
delimiter: 'comma' |
||||
|
} |
||||
|
}], |
||||
|
'@typescript-eslint/no-explicit-any': 'off', |
||||
|
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', |
||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', |
||||
|
'space-before-function-paren': ['error', 'never'], |
||||
|
'vue/array-bracket-spacing': 'error', |
||||
|
'vue/arrow-spacing': 'error', |
||||
|
'vue/block-spacing': 'error', |
||||
|
'vue/brace-style': 'error', |
||||
|
'vue/camelcase': 'error', |
||||
|
'vue/comma-dangle': 'error', |
||||
|
'vue/component-name-in-template-casing': 'error', |
||||
|
'vue/eqeqeq': 'error', |
||||
|
'vue/key-spacing': 'error', |
||||
|
'vue/match-component-file-name': 'error', |
||||
|
'vue/object-curly-spacing': 'error' |
||||
|
}, |
||||
|
overrides: [ |
||||
|
{ |
||||
|
files: [ |
||||
|
'**/__tests__/*.{j,t}s?(x)', |
||||
|
'**/tests/unit/**/*.spec.{j,t}s?(x)' |
||||
|
], |
||||
|
env: { |
||||
|
jest: true |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
.DS_Store |
||||
|
node_modules |
||||
|
/dist |
||||
|
|
||||
|
/tests/e2e/videos/ |
||||
|
/tests/e2e/screenshots/ |
||||
|
/tests/**/coverage/ |
||||
|
|
||||
|
# local env files |
||||
|
.env.local |
||||
|
.env.*.local |
||||
|
|
||||
|
# Log files |
||||
|
npm-debug.log* |
||||
|
yarn-debug.log* |
||||
|
yarn-error.log* |
||||
|
|
||||
|
# Editor directories and files |
||||
|
.idea |
||||
|
.vscode |
||||
|
.history |
||||
|
.ionide |
||||
|
*.suo |
||||
|
*.ntvs* |
||||
|
*.njsproj |
||||
|
*.sln |
||||
|
*.sw* |
||||
@ -0,0 +1,21 @@ |
|||||
|
MIT License |
||||
|
|
||||
|
Copyright (c) 2018 Chong Guo |
||||
|
|
||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy |
||||
|
of this software and associated documentation files (the "Software"), to deal |
||||
|
in the Software without restriction, including without limitation the rights |
||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||
|
copies of the Software, and to permit persons to whom the Software is |
||||
|
furnished to do so, subject to the following conditions: |
||||
|
|
||||
|
The above copyright notice and this permission notice shall be included in all |
||||
|
copies or substantial portions of the Software. |
||||
|
|
||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||
|
SOFTWARE. |
||||
@ -0,0 +1,243 @@ |
|||||
|
<p align="center"> |
||||
|
<img width="120" src="public/img/icons/android-chrome-512x512.png"> |
||||
|
</p> |
||||
|
|
||||
|
<p align="center"> |
||||
|
<a href="https://github.com/vuejs/vue"> |
||||
|
<img src="https://img.shields.io/badge/vue-2.6.10-brightgreen.svg" alt="vue"> |
||||
|
</a> |
||||
|
<a href="https://github.com/ElemeFE/element"> |
||||
|
<img src="https://img.shields.io/badge/element--ui-2.12.0-brightgreen.svg" alt="element-ui"> |
||||
|
</a> |
||||
|
<a href="https://circleci.com/gh/Armour/vue-typescript-admin-template/tree/master"> |
||||
|
<img src="https://circleci.com/gh/Armour/vue-typescript-admin-template/tree/master.svg?style=shield" alt="CircleCI"> |
||||
|
</a> |
||||
|
<a href="http://makeapullrequest.com"> |
||||
|
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" alt="PRs Welcome"> |
||||
|
</a> |
||||
|
<a href="https://opensource.org/licenses/MIT"> |
||||
|
<img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"> |
||||
|
</a> |
||||
|
<a href="https://github.com/Armour/Jarvis"> |
||||
|
<img src="https://img.shields.io/badge/Hi-Jarvis-ff69b4.svg" alt="Template from jarvis"> |
||||
|
</a> |
||||
|
</p> |
||||
|
|
||||
|
[English](./README.md) | 简体中文 |
||||
|
|
||||
|
## 总览 |
||||
|
|
||||
|
[vue-typescript-admin-template](http://armour.github.io/vue-typescript-admin-template) 是一个后台前端解决方案,它基于 [vue](https://github.com/vuejs/vue), [typescript](https://www.typescriptlang.org/) 和 [element-ui](https://github.com/ElemeFE/element)实现。原始的 Javascript 版本的代码是由 [PanJiaChen](https://github.com/PanJiaChen) 开发维护的 [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin/), 十分感谢大佬对开源社区做出的贡献 :) |
||||
|
|
||||
|
如果你想从一个十分简单的基础模版开始,而不是直接使用这个功能丰富的集成方案的话,你可以看一看本项目的 [minimal](https://github.com/Armour/vue-typescript-admin-template/tree/minimal) 分支. |
||||
|
|
||||
|
## 线上文档 |
||||
|
|
||||
|
[文档](https://armour.github.io/vue-typescript-admin-docs/zh) |
||||
|
|
||||
|
## 线上地址 |
||||
|
|
||||
|
[示例](https://armour.github.io/vue-typescript-admin-template) |
||||
|
|
||||
|
## 截图 |
||||
|
|
||||
|
) |
||||
|
|
||||
|
## 相关项目 |
||||
|
|
||||
|
[Armour/vue-typescript-admin-mock-server](https://github.com/armour/vue-typescript-admin-mock-server) (mock server for this project) |
||||
|
|
||||
|
[Armour/vue-typescript-admin-docs](https://github.com/armour/vue-typescript-admin-docs) (documentation source for this project) |
||||
|
|
||||
|
Javascript 版本: |
||||
|
|
||||
|
[PanJiaChen/vue-admin-template](https://github.com/PanJiaChen/vue-admin-template) (a vue2.0 minimal admin template) |
||||
|
|
||||
|
[PanJiaChen/vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) (full features supported vue admin) |
||||
|
|
||||
|
[PanJiaChen/electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin) (a vue electron admin project) |
||||
|
|
||||
|
## 功能 |
||||
|
|
||||
|
```txt |
||||
|
- 登录 / 注销 |
||||
|
|
||||
|
- 权限验证 |
||||
|
- 页面权限 |
||||
|
- 指令权限 |
||||
|
- 权限配置 |
||||
|
- 二步登录 |
||||
|
|
||||
|
- 多环境发布 |
||||
|
- Dev / Stage / Prod |
||||
|
|
||||
|
- 全局功能 |
||||
|
- 国际化多语言 |
||||
|
- 动态换肤 |
||||
|
- 动态侧边栏(支持多级路由嵌套) |
||||
|
- 动态面包屑 |
||||
|
- 快捷导航(支持右键操作) |
||||
|
- 粘贴板 |
||||
|
- Svg 图标 |
||||
|
- 搜索 |
||||
|
- 全屏 |
||||
|
- 设置 |
||||
|
- Mock 数据 / Mock 服务器 |
||||
|
- 支持 PWA |
||||
|
|
||||
|
- 组件 |
||||
|
- 编辑器 |
||||
|
- 富文本编辑器 |
||||
|
- Markdown 编辑器 |
||||
|
- JSON 编辑器 |
||||
|
- 头像上传 |
||||
|
- 返回顶部 |
||||
|
- CountTo |
||||
|
- 拖放区 |
||||
|
- 拖拽弹窗 |
||||
|
- 拖拽看板 |
||||
|
- 拖拽列表 |
||||
|
- 拖拽选择 |
||||
|
- ECharts 图表 |
||||
|
- Mixin |
||||
|
- 拆分窗格 |
||||
|
- 黏性组件 |
||||
|
|
||||
|
- 表格 |
||||
|
- 动态表格 |
||||
|
- 拖拽表格 |
||||
|
- 内联编辑表格 |
||||
|
- 复杂表格 |
||||
|
|
||||
|
- Excel |
||||
|
- 导出excel |
||||
|
- 导入excel |
||||
|
- 前端可视化excel |
||||
|
|
||||
|
- Zip |
||||
|
- 导出zip |
||||
|
|
||||
|
- PDF |
||||
|
- 下载 pdf |
||||
|
|
||||
|
- 控制台 |
||||
|
- 引导页 |
||||
|
- 综合实例 |
||||
|
- 错误日志 |
||||
|
- 错误页面 |
||||
|
- 401 |
||||
|
- 404 |
||||
|
``` |
||||
|
|
||||
|
## 前序准备 |
||||
|
|
||||
|
你需要在本地安装 [node](http://nodejs.org/) 和 [git](https://git-scm.com/)。本项目技术栈基于 [typescript](https://www.typescriptlang.org/)、[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) 、[axios](https://github.com/axios/axios) 和 [element-ui](https://github.com/ElemeFE/element),所有的请求数据都使用[faker.js](https://github.com/Marak/Faker.js)进行模拟,提前了解和学习这些知识会对使用本项目有很大的帮助。 |
||||
|
|
||||
|
## 目录结构 |
||||
|
|
||||
|
本项目已经为你生成了一个完整的开发框架,提供了涵盖后台开发的各类功能和坑位,下面是整个项目的目录结构。 |
||||
|
|
||||
|
```bash |
||||
|
├── mock # mock 服务器 与 模拟数据 |
||||
|
├── public # 静态资源 (会被直接复制) |
||||
|
│ │── favicon.ico # favicon图标 |
||||
|
│ │── manifest.json # PWA 配置文件 |
||||
|
│ └── index.html # html模板 |
||||
|
├── src # 源代码 |
||||
|
│ ├── api # 所有请求 |
||||
|
│ ├── assets # 主题 字体等静态资源 (由 webpack 处理加载) |
||||
|
│ ├── components # 全局组件 |
||||
|
│ ├── directive # 全局指令 |
||||
|
│ ├── filters # 全局过滤函数 |
||||
|
│ ├── icons # svg 图标 |
||||
|
│ ├── lang # 国际化 |
||||
|
│ ├── layout # 全局布局 |
||||
|
│ ├── pwa # PWA service worker 相关的文件 |
||||
|
│ ├── router # 路由 |
||||
|
│ ├── store # 全局 vuex store |
||||
|
│ ├── styles # 全局样式 |
||||
|
│ ├── utils # 全局方法 |
||||
|
│ ├── views # 所有页面 |
||||
|
│ ├── App.vue # 入口页面 |
||||
|
│ ├── main.js # 入口文件 加载组件 初始化等 |
||||
|
│ ├── permission.ts # 权限管理 |
||||
|
│ ├── settings.ts # 设置文件 |
||||
|
│ └── shims.d.ts # 模块注入 |
||||
|
├── tests # 测试 |
||||
|
├── .circleci/ # 自动化 CI 配置 |
||||
|
├── .browserslistrc # browserslistrc 配置文件 (用于支持 Autoprefixer) |
||||
|
├── .editorconfig # 编辑相关配置 |
||||
|
├── .env.xxx # 环境变量配置 |
||||
|
├── .eslintrc.js # eslint 配置 |
||||
|
├── babel.config.js # babel-loader 配置 |
||||
|
├── cypress.json # e2e 测试配置 |
||||
|
├── jest.config.js # jest 单元测试配置 |
||||
|
├── package.json # package.json 依赖 |
||||
|
├── postcss.config.js # postcss 配置 |
||||
|
├── tsconfig.json # typescript 配置 |
||||
|
└── vue.config.js # vue-cli 配置 |
||||
|
``` |
||||
|
|
||||
|
## 如何设置以及启动项目 |
||||
|
|
||||
|
### 安装依赖 |
||||
|
|
||||
|
```bash |
||||
|
yarn install |
||||
|
``` |
||||
|
|
||||
|
### 启动本地开发环境(自带热启动) |
||||
|
|
||||
|
```bash |
||||
|
yarn serve |
||||
|
``` |
||||
|
|
||||
|
### 构建生产环境 (自带压缩) |
||||
|
|
||||
|
```bash |
||||
|
yarn build:prod |
||||
|
``` |
||||
|
|
||||
|
### 代码格式检查以及自动修复 |
||||
|
|
||||
|
```bash |
||||
|
yarn lint |
||||
|
``` |
||||
|
|
||||
|
### 运行单元测试 |
||||
|
|
||||
|
```bash |
||||
|
yarn test:unit |
||||
|
``` |
||||
|
|
||||
|
### 运行端对端测试 |
||||
|
|
||||
|
```bash |
||||
|
yarn test:e2e |
||||
|
``` |
||||
|
|
||||
|
### 自动生成 svg 组件 |
||||
|
|
||||
|
```bash |
||||
|
yarn run svg |
||||
|
``` |
||||
|
|
||||
|
### 自定义 Vue 配置 |
||||
|
|
||||
|
请看 [Configuration Reference](https://cli.vuejs.org/config/). |
||||
|
|
||||
|
## 浏览器支持 |
||||
|
|
||||
|
Modern browsers and Internet Explorer 10+. |
||||
|
|
||||
|
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | |
||||
|
| --------- | --------- | --------- | --------- | |
||||
|
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions |
||||
|
|
||||
|
## 参与贡献 |
||||
|
|
||||
|
请看 [CONTRIBUTING.md](https://github.com/Armour/vue-typescript-admin-template/blob/master/.github/CONTRIBUTING.md) |
||||
|
|
||||
|
## License |
||||
|
|
||||
|
[MIT License](https://github.com/Armour/vue-typescript-admin-template/blob/master/LICENSE) |
||||
@ -0,0 +1,244 @@ |
|||||
|
<p align="center"> |
||||
|
<img width="120" src="public/img/icons/android-chrome-512x512.png"> |
||||
|
</p> |
||||
|
|
||||
|
<p align="center"> |
||||
|
<a href="https://github.com/vuejs/vue"> |
||||
|
<img src="https://img.shields.io/badge/vue-2.6.10-brightgreen.svg" alt="vue"> |
||||
|
</a> |
||||
|
<a href="https://github.com/ElemeFE/element"> |
||||
|
<img src="https://img.shields.io/badge/element--ui-2.12.0-brightgreen.svg" alt="element-ui"> |
||||
|
</a> |
||||
|
<a href="https://circleci.com/gh/Armour/vue-typescript-admin-template/tree/master"> |
||||
|
<img src="https://circleci.com/gh/Armour/vue-typescript-admin-template/tree/master.svg?style=shield" alt="CircleCI"> |
||||
|
</a> |
||||
|
<a href="http://makeapullrequest.com"> |
||||
|
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" alt="PRs Welcome"> |
||||
|
</a> |
||||
|
<a href="https://opensource.org/licenses/MIT"> |
||||
|
<img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"> |
||||
|
</a> |
||||
|
<a href="https://github.com/Armour/Jarvis"> |
||||
|
<img src="https://img.shields.io/badge/Hi-Jarvis-ff69b4.svg" alt="Template from jarvis"> |
||||
|
</a> |
||||
|
</p> |
||||
|
|
||||
|
English | [简体中文](./README-zh.md) |
||||
|
|
||||
|
## Overview |
||||
|
|
||||
|
[vue-typescript-admin-template](http://armour.github.io/vue-typescript-admin-template) is a production-ready front-end solution for admin interfaces based on [vue](https://github.com/vuejs/vue), [typescript](https://www.typescriptlang.org/) and UI Toolkit [element-ui](https://github.com/ElemeFE/element). The original Javascript version code [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin/) was written by [PanJiaChen](https://github.com/PanJiaChen), many thanks to him for the awesome open source project! :) |
||||
|
|
||||
|
If you want to get started with a minimal template code instead of integration solution, you can take a look at the [minimal](https://github.com/Armour/vue-typescript-admin-template/tree/minimal) branch. |
||||
|
|
||||
|
## Documentation |
||||
|
|
||||
|
[Docs](https://armour.github.io/vue-typescript-admin-docs) |
||||
|
|
||||
|
## Live demo |
||||
|
|
||||
|
[Demo](https://armour.github.io/vue-typescript-admin-template) |
||||
|
|
||||
|
## Screenshots |
||||
|
|
||||
|
 |
||||
|
|
||||
|
## Related Projects |
||||
|
|
||||
|
[Armour/vue-typescript-admin-mock-server](https://github.com/armour/vue-typescript-admin-mock-server) (mock server for this project) |
||||
|
|
||||
|
[Armour/vue-typescript-admin-docs](https://github.com/armour/vue-typescript-admin-docs) (documentation source for this project) |
||||
|
|
||||
|
Javascript version: |
||||
|
|
||||
|
[PanJiaChen/vue-admin-template](https://github.com/PanJiaChen/vue-admin-template) (a vue2.0 minimal admin template) |
||||
|
|
||||
|
[PanJiaChen/vue-element-admin](https://github.com/PanJiaChen/vue-element-admin) (full features supported vue admin) |
||||
|
|
||||
|
[PanJiaChen/electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin) (a vue electron admin project) |
||||
|
|
||||
|
## Features |
||||
|
|
||||
|
```txt |
||||
|
- Login / Logout |
||||
|
|
||||
|
- Permission Authentication |
||||
|
- Page permission |
||||
|
- Directive permission |
||||
|
- Permission configuration page |
||||
|
- Two-step login |
||||
|
|
||||
|
- Multi-environment build |
||||
|
- Dev / Stage / Prod |
||||
|
|
||||
|
- Global Features |
||||
|
- I18n |
||||
|
- Dynamic themes |
||||
|
- Dynamic sidebar (supports multi-level routing) |
||||
|
- Dynamic breadcrumb |
||||
|
- Tags-view (supports right-click operation) |
||||
|
- Clipboard |
||||
|
- Svg icons |
||||
|
- Search |
||||
|
- Screenfull |
||||
|
- Settings |
||||
|
- Mock data / Mock server |
||||
|
- PWA support |
||||
|
|
||||
|
- Components |
||||
|
- Editors |
||||
|
- Rich Text Editor |
||||
|
- Markdown Editor |
||||
|
- JSON Editor |
||||
|
- Avatar Upload |
||||
|
- Back To Top |
||||
|
- CountTo |
||||
|
- Dropzone |
||||
|
- Draggable Dialog |
||||
|
- Draggable Kanban |
||||
|
- Draggable List |
||||
|
- Draggable Select |
||||
|
- ECharts |
||||
|
- Mixin |
||||
|
- SplitPane |
||||
|
- Sticky |
||||
|
|
||||
|
- Table |
||||
|
- Dynamic Table |
||||
|
- Draggable Table |
||||
|
- Inline Edit Table |
||||
|
- Complex Table |
||||
|
|
||||
|
- Excel |
||||
|
- Export Excel |
||||
|
- Upload Excel |
||||
|
- Excel Visualization |
||||
|
|
||||
|
- Zip |
||||
|
- Export zip |
||||
|
|
||||
|
- PDF |
||||
|
- Download pdf |
||||
|
|
||||
|
- Dashboard |
||||
|
- Guide Page |
||||
|
- Advanced Example Page |
||||
|
- Error Log |
||||
|
- Error Page |
||||
|
- 401 |
||||
|
- 404 |
||||
|
``` |
||||
|
|
||||
|
## Preparation |
||||
|
|
||||
|
You need to install [node](http://nodejs.org/) and [git](https://git-scm.com/) locally. The project is based on [typescript](https://www.typescriptlang.org/), [vue](https://vuejs.org/index.html), [vuex](https://vuex.vuejs.org/), [vue-router](https://router.vuejs.org/), [vue-cli](https://github.com/vuejs/vue-cli) , [axios](https://github.com/axios/axios) and [element-ui](https://github.com/ElemeFE/element), all request data is simulated using [faker.js](https://github.com/Marak/Faker.js). |
||||
|
Understanding and learning these knowledge in advance will greatly help you on using this project. |
||||
|
|
||||
|
## Project Structure |
||||
|
|
||||
|
```bash |
||||
|
├── mock/ # mock server & mock data |
||||
|
├── public # public static assets (directly copied) |
||||
|
│ │── favicon.ico # favicon |
||||
|
│ │── manifest.json # PWA config file |
||||
|
│ └── index.html # index.html template |
||||
|
├── src # main source code |
||||
|
│ ├── api # api service |
||||
|
│ ├── assets # module assets like fonts, images (processed by webpack) |
||||
|
│ ├── components # global components |
||||
|
│ ├── directives # global directives |
||||
|
│ ├── filters # global filter |
||||
|
│ ├── icons # svg icons |
||||
|
│ ├── lang # i18n language |
||||
|
│ ├── layout # global layout |
||||
|
│ ├── pwa # PWA service worker related files |
||||
|
│ ├── router # router |
||||
|
│ ├── store # store |
||||
|
│ ├── styles # global css |
||||
|
│ ├── utils # global utils |
||||
|
│ ├── views # views |
||||
|
│ ├── App.vue # main app component |
||||
|
│ ├── main.ts # app entry file |
||||
|
│ ├── permission.ts # permission authentication |
||||
|
│ ├── settings.ts # setting file |
||||
|
│ └── shims.d.ts # type definition shims |
||||
|
├── tests/ # tests |
||||
|
├── .circleci/ # automated CI configuration |
||||
|
├── .browserslistrc # browserslist config file (to support Autoprefixer) |
||||
|
├── .editorconfig # editor code format consistency config |
||||
|
├── .env.xxx # env variable configuration |
||||
|
├── .eslintrc.js # eslint config |
||||
|
├── babel.config.js # babel config |
||||
|
├── cypress.json # e2e test config |
||||
|
├── jest.config.js # jest unit test config |
||||
|
├── package.json # package.json |
||||
|
├── postcss.config.js # postcss config |
||||
|
├── tsconfig.json # typescript config |
||||
|
└── vue.config.js # vue-cli config |
||||
|
``` |
||||
|
|
||||
|
## Project setup |
||||
|
|
||||
|
With [yarn](https://yarnpkg.com/lang/en/) or [npm](https://www.npmjs.com/get-npm) |
||||
|
|
||||
|
#### Install dependencies |
||||
|
|
||||
|
```bash |
||||
|
yarn install |
||||
|
``` |
||||
|
|
||||
|
#### Compiles and hot-reloads for development |
||||
|
|
||||
|
```bash |
||||
|
yarn run serve |
||||
|
``` |
||||
|
|
||||
|
#### Compiles and minifies for production |
||||
|
|
||||
|
```bash |
||||
|
yarn run build:prod |
||||
|
``` |
||||
|
|
||||
|
#### Lints and fixes files |
||||
|
|
||||
|
```bash |
||||
|
yarn run lint |
||||
|
``` |
||||
|
|
||||
|
#### Run your unit tests |
||||
|
|
||||
|
```bash |
||||
|
yarn run test:unit |
||||
|
``` |
||||
|
|
||||
|
#### Run your end-to-end tests |
||||
|
|
||||
|
```bash |
||||
|
yarn run test:e2e |
||||
|
``` |
||||
|
|
||||
|
#### Generate all svg components |
||||
|
|
||||
|
```bash |
||||
|
yarn run svg |
||||
|
``` |
||||
|
|
||||
|
#### Customize Vue configuration |
||||
|
|
||||
|
See [Configuration Reference](https://cli.vuejs.org/config/). |
||||
|
|
||||
|
## Browsers support |
||||
|
|
||||
|
Modern browsers and Internet Explorer 10+. |
||||
|
|
||||
|
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | |
||||
|
| --------- | --------- | --------- | --------- | |
||||
|
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions |
||||
|
|
||||
|
## Contributing |
||||
|
|
||||
|
See [CONTRIBUTING.md](https://github.com/Armour/vue-typescript-admin-template/blob/master/.github/CONTRIBUTING.md) |
||||
|
|
||||
|
## License |
||||
|
|
||||
|
[MIT License](https://github.com/Armour/vue-typescript-admin-template/blob/master/LICENSE) |
||||
@ -0,0 +1,5 @@ |
|||||
|
module.exports = { |
||||
|
presets: [ |
||||
|
'@vue/cli-plugin-babel/preset' |
||||
|
] |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
{ |
||||
|
"pluginsFile": "tests/e2e/plugins/index.js" |
||||
|
} |
||||
@ -0,0 +1,3 @@ |
|||||
|
module.exports = { |
||||
|
preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel' |
||||
|
} |
||||
@ -0,0 +1,139 @@ |
|||||
|
{ |
||||
|
"name": "vue-typescript-admin-template", |
||||
|
"version": "1.0.0", |
||||
|
"private": true, |
||||
|
"author": "Chong Guo <armourcy@gmail.com>", |
||||
|
"scripts": { |
||||
|
"serve": "concurrently \"npm:mock\" \"vue-cli-service serve\"", |
||||
|
"build:prod": "vue-cli-service build", |
||||
|
"build:stage": "vue-cli-service build --mode staging", |
||||
|
"lint": "vue-cli-service lint", |
||||
|
"mock": "cd mock && ts-node-dev mock-server.ts", |
||||
|
"svg": "vsvg -s ./src/icons/svg -t ./src/icons/components --ext ts --es6", |
||||
|
"test:e2e": "vue-cli-service test:e2e", |
||||
|
"test:unit": "jest --clearCache && vue-cli-service test:unit" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"@tinymce/tinymce-vue": "^3.2.2", |
||||
|
"axios": "^0.19.2", |
||||
|
"clipboard": "^2.0.6", |
||||
|
"codemirror": "^5.54.0", |
||||
|
"core-js": "^3.6.5", |
||||
|
"cors": "^2.8.5", |
||||
|
"driver.js": "^0.9.8", |
||||
|
"echarts": "^4.8.0", |
||||
|
"element-ui": "^2.13.2", |
||||
|
"faker": "^4.1.0", |
||||
|
"file-saver": "^2.0.2", |
||||
|
"fuse.js": "^6.0.4", |
||||
|
"js-cookie": "^2.2.1", |
||||
|
"jsonlint": "^1.6.3", |
||||
|
"jszip": "^3.4.0", |
||||
|
"lodash": "^4.17.15", |
||||
|
"morgan": "^1.10.0", |
||||
|
"normalize.css": "^8.0.1", |
||||
|
"nprogress": "^0.2.0", |
||||
|
"path-to-regexp": "^6.1.0", |
||||
|
"register-service-worker": "^1.7.1", |
||||
|
"screenfull": "^5.0.2", |
||||
|
"script-loader": "^0.7.2", |
||||
|
"sortablejs": "^1.10.2", |
||||
|
"tinymce": "^5.3.2", |
||||
|
"tui-editor": "^1.4.10", |
||||
|
"vue": "^2.6.11", |
||||
|
"vue-class-component": "^7.2.3", |
||||
|
"vue-count-to": "^1.0.13", |
||||
|
"vue-i18n": "^8.18.2", |
||||
|
"vue-image-crop-upload": "^2.5.0", |
||||
|
"vue-property-decorator": "^8.5.0", |
||||
|
"vue-router": "^3.3.4", |
||||
|
"vue-splitpane": "^1.0.6", |
||||
|
"vue-svgicon": "^3.2.6", |
||||
|
"vue2-dropzone": "^3.6.0", |
||||
|
"vuedraggable": "^2.23.2", |
||||
|
"vuex": "^3.4.0", |
||||
|
"vuex-module-decorators": "^0.17.0", |
||||
|
"xlsx": "^0.16.2", |
||||
|
"yamljs": "^0.3.0" |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"@types/clipboard": "^2.0.1", |
||||
|
"@types/codemirror": "^0.0.96", |
||||
|
"@types/compression": "^1.7.0", |
||||
|
"@types/cors": "^2.8.6", |
||||
|
"@types/echarts": "^4.6.1", |
||||
|
"@types/express": "^4.17.6", |
||||
|
"@types/faker": "^4.1.12", |
||||
|
"@types/file-saver": "^2.0.1", |
||||
|
"@types/jest": "^26.0.0", |
||||
|
"@types/js-cookie": "^2.2.6", |
||||
|
"@types/lodash": "^4.14.155", |
||||
|
"@types/morgan": "^1.9.1", |
||||
|
"@types/node": "^14.0.13", |
||||
|
"@types/nprogress": "^0.2.0", |
||||
|
"@types/sortablejs": "^1.10.4", |
||||
|
"@types/tinymce": "^4.5.24", |
||||
|
"@types/vue-splitpane": "^1.0.0", |
||||
|
"@types/webpack-env": "^1.15.2", |
||||
|
"@types/yamljs": "^0.2.31", |
||||
|
"@typescript-eslint/eslint-plugin": "^3.2.0", |
||||
|
"@typescript-eslint/parser": "^3.2.0", |
||||
|
"@vue/cli-plugin-babel": "^4.4.4", |
||||
|
"@vue/cli-plugin-e2e-cypress": "^4.4.4", |
||||
|
"@vue/cli-plugin-eslint": "^4.4.4", |
||||
|
"@vue/cli-plugin-pwa": "^4.4.4", |
||||
|
"@vue/cli-plugin-router": "^4.4.4", |
||||
|
"@vue/cli-plugin-typescript": "^4.4.4", |
||||
|
"@vue/cli-plugin-unit-jest": "^4.4.4", |
||||
|
"@vue/cli-plugin-vuex": "^4.4.4", |
||||
|
"@vue/cli-service": "^4.4.4", |
||||
|
"@vue/eslint-config-standard": "^5.1.2", |
||||
|
"@vue/eslint-config-typescript": "^5.0.2", |
||||
|
"@vue/test-utils": "^1.0.3", |
||||
|
"babel-core": "^7.0.0-bridge.0", |
||||
|
"babel-eslint": "^10.1.0", |
||||
|
"concurrently": "^5.2.0", |
||||
|
"eslint": "^7.2.0", |
||||
|
"eslint-plugin-import": "^2.21.2", |
||||
|
"eslint-plugin-node": "^11.1.0", |
||||
|
"eslint-plugin-promise": "^4.2.1", |
||||
|
"eslint-plugin-standard": "^4.0.1", |
||||
|
"eslint-plugin-vue": "^6.2.2", |
||||
|
"fibers": "^5.0.0", |
||||
|
"jest": "^26.0.1", |
||||
|
"lint-staged": "^10.2.10", |
||||
|
"sass": "^1.26.8", |
||||
|
"sass-loader": "^8.0.2", |
||||
|
"style-resources-loader": "^1.3.3", |
||||
|
"swagger-routes-express": "^3.1.3", |
||||
|
"ts-jest": "^26.1.0", |
||||
|
"ts-node-dev": "^1.0.0-pre.47", |
||||
|
"typescript": "3.8.3", |
||||
|
"vue-cli-plugin-element": "^1.0.1", |
||||
|
"vue-cli-plugin-style-resources-loader": "^0.1.4", |
||||
|
"vue-template-compiler": "^2.6.11", |
||||
|
"webpack": "^4.43.0" |
||||
|
}, |
||||
|
"bugs": { |
||||
|
"url": "https://github.com/armour/vue-typescript-admin-template/issues" |
||||
|
}, |
||||
|
"gitHooks": { |
||||
|
"pre-commit": "lint-staged" |
||||
|
}, |
||||
|
"keywords": [ |
||||
|
"vue", |
||||
|
"typescript", |
||||
|
"admin", |
||||
|
"template", |
||||
|
"element-ui" |
||||
|
], |
||||
|
"lint-staged": { |
||||
|
"*.{js,vue}": [ |
||||
|
"vue-cli-service lint" |
||||
|
] |
||||
|
}, |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "git+https://github.com/armour/vue-typescript-admin-template.git" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,5 @@ |
|||||
|
module.exports = { |
||||
|
plugins: { |
||||
|
autoprefixer: {} |
||||
|
} |
||||
|
} |
||||
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 803 B |
|
After Width: | Height: | Size: 964 B |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 480 B |
|
After Width: | Height: | Size: 645 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
@ -0,0 +1,17 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
<head> |
||||
|
<meta charset="utf-8"> |
||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge"> |
||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0"> |
||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> |
||||
|
<title><%= webpackConfig.name %></title> |
||||
|
</head> |
||||
|
<body> |
||||
|
<noscript> |
||||
|
<strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> |
||||
|
</noscript> |
||||
|
<div id="app"></div> |
||||
|
<!-- built files will be auto injected --> |
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,20 @@ |
|||||
|
{ |
||||
|
"name": "Vue Typescript Admin", |
||||
|
"short_name": "Vue Ts Admin", |
||||
|
"icons": [ |
||||
|
{ |
||||
|
"src": "./img/icons/android-chrome-192x192.png", |
||||
|
"sizes": "192x192", |
||||
|
"type": "image/png" |
||||
|
}, |
||||
|
{ |
||||
|
"src": "./img/icons/android-chrome-512x512.png", |
||||
|
"sizes": "512x512", |
||||
|
"type": "image/png" |
||||
|
} |
||||
|
], |
||||
|
"start_url": "./index.html", |
||||
|
"display": "standalone", |
||||
|
"background_color": "#fff", |
||||
|
"theme_color": "#4DBA87" |
||||
|
} |
||||
@ -0,0 +1,2 @@ |
|||||
|
User-agent: * |
||||
|
Disallow: |
||||
@ -0,0 +1,17 @@ |
|||||
|
# Tinymce |
||||
|
|
||||
|
## Docs |
||||
|
|
||||
|
Check [Vue integration doc for Tinymce](https://www.tiny.cloud/docs/integrations/vue/#installingthetinymcevuejsintegrationusingnpm). |
||||
|
|
||||
|
## Language |
||||
|
|
||||
|
Resources under `langs` folder are copied from [tinymce language package](https://www.tiny.cloud/get-tiny/language-packages). |
||||
|
|
||||
|
## Skin |
||||
|
|
||||
|
First download latest tinymce release from [offical website](https://www.tiny.cloud/get-tiny/self-hosted/) , resources under `skins` folder are copied from `skins/ui/oxide`. |
||||
|
|
||||
|
## Emojis |
||||
|
|
||||
|
First download latest tinymce release from [offical website](https://www.tiny.cloud/get-tiny/self-hosted/), `emojis.min.js` file is copied from `plugins/emoticons/js`. |
||||
@ -0,0 +1,419 @@ |
|||||
|
tinymce.addI18n('es', { |
||||
|
"Redo": "Rehacer", |
||||
|
"Undo": "Deshacer", |
||||
|
"Cut": "Cortar", |
||||
|
"Copy": "Copiar", |
||||
|
"Paste": "Pegar", |
||||
|
"Select all": "Seleccionar todo", |
||||
|
"New document": "Nuevo documento", |
||||
|
"Ok": "Ok", |
||||
|
"Cancel": "Cancelar", |
||||
|
"Visual aids": "Ayudas visuales", |
||||
|
"Bold": "Negrita", |
||||
|
"Italic": "Cursiva", |
||||
|
"Underline": "Subrayado", |
||||
|
"Strikethrough": "Tachado", |
||||
|
"Superscript": "Super\u00edndice", |
||||
|
"Subscript": "Sub\u00edndice", |
||||
|
"Clear formatting": "Limpiar formato", |
||||
|
"Align left": "Alinear a la izquierda", |
||||
|
"Align center": "Alinear al centro", |
||||
|
"Align right": "Alinear a la derecha", |
||||
|
"Justify": "Justificar", |
||||
|
"Bullet list": "Lista de vi\u00f1etas", |
||||
|
"Numbered list": "Lista numerada", |
||||
|
"Decrease indent": "Disminuir sangr\u00eda", |
||||
|
"Increase indent": "Incrementar sangr\u00eda", |
||||
|
"Close": "Cerrar", |
||||
|
"Formats": "Formatos", |
||||
|
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "Su navegador no es compatible con el acceso directo al portapapeles. Use las teclas Crtl+X\/C\/V de su teclado.", |
||||
|
"Headers": "Encabezados", |
||||
|
"Header 1": "Encabezado 1", |
||||
|
"Header 2": "Encabezado 2", |
||||
|
"Header 3": "Encabezado 3", |
||||
|
"Header 4": "Encabezado 4", |
||||
|
"Header 5": "Encabezado 5", |
||||
|
"Header 6": "Encabezado 6", |
||||
|
"Headings": "Encabezados", |
||||
|
"Heading 1": "Encabezado 1", |
||||
|
"Heading 2": "Encabezado 2", |
||||
|
"Heading 3": "Encabezado 3", |
||||
|
"Heading 4": "Encabezado 4", |
||||
|
"Heading 5": "Encabezado 5", |
||||
|
"Heading 6": "Encabezado 6", |
||||
|
"Preformatted": "Con formato previo", |
||||
|
"Div": "Div", |
||||
|
"Pre": "Pre", |
||||
|
"Code": "C\u00f3digo", |
||||
|
"Paragraph": "P\u00e1rrafo", |
||||
|
"Blockquote": "Blockquote", |
||||
|
"Inline": "Alineado", |
||||
|
"Blocks": "Bloques", |
||||
|
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "Pegar est\u00e1 ahora en modo de texto plano. El contenido se pegar\u00e1 como texto plano hasta que desactive esta opci\u00f3n.", |
||||
|
"Fonts": "Fuentes", |
||||
|
"Font Sizes": "Tama\u00f1os de fuente", |
||||
|
"Class": "Clase", |
||||
|
"Browse for an image": "Buscar una imagen", |
||||
|
"OR": "OR", |
||||
|
"Drop an image here": "Arrastre una imagen aqu\u00ed", |
||||
|
"Upload": "Cargar", |
||||
|
"Block": "Bloque", |
||||
|
"Align": "Alinear", |
||||
|
"Default": "Por defecto", |
||||
|
"Circle": "C\u00edrculo", |
||||
|
"Disc": "Disco", |
||||
|
"Square": "Cuadrado", |
||||
|
"Lower Alpha": "Inferior Alfa", |
||||
|
"Lower Greek": "Inferior Griega", |
||||
|
"Lower Roman": "Inferior Romana", |
||||
|
"Upper Alpha": "Superior Alfa", |
||||
|
"Upper Roman": "Superior Romana", |
||||
|
"Anchor...": "Anclaje...", |
||||
|
"Name": "Nombre", |
||||
|
"Id": "Id", |
||||
|
"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "Deber\u00eda comenzar por una letra, seguida solo de letras, n\u00fameros, guiones, puntos, dos puntos o guiones bajos.", |
||||
|
"You have unsaved changes are you sure you want to navigate away?": "Tiene cambios sin guardar. \u00bfEst\u00e1 seguro de que quiere salir?", |
||||
|
"Restore last draft": "Restaurar el \u00faltimo borrador", |
||||
|
"Special character...": "Car\u00e1cter especial...", |
||||
|
"Source code": "C\u00f3digo fuente", |
||||
|
"Insert\/Edit code sample": "Insertar\/editar c\u00f3digo de prueba", |
||||
|
"Language": "Idioma", |
||||
|
"Code sample...": "Ejemplo de c\u00f3digo...", |
||||
|
"Color Picker": "Selector de colores", |
||||
|
"R": "R", |
||||
|
"G": "V", |
||||
|
"B": "A", |
||||
|
"Left to right": "De izquierda a derecha", |
||||
|
"Right to left": "De derecha a izquierda", |
||||
|
"Emoticons...": "Emoticones...", |
||||
|
"Metadata and Document Properties": "Metadatos y propiedades del documento", |
||||
|
"Title": "T\u00edtulo", |
||||
|
"Keywords": "Palabras clave", |
||||
|
"Description": "Descripci\u00f3n", |
||||
|
"Robots": "Robots", |
||||
|
"Author": "Autor", |
||||
|
"Encoding": "Codificaci\u00f3n", |
||||
|
"Fullscreen": "Pantalla completa", |
||||
|
"Action": "Acci\u00f3n", |
||||
|
"Shortcut": "Atajo", |
||||
|
"Help": "Ayuda", |
||||
|
"Address": "Direcci\u00f3n", |
||||
|
"Focus to menubar": "Enfocar la barra del men\u00fa", |
||||
|
"Focus to toolbar": "Enfocar la barra de herramientas", |
||||
|
"Focus to element path": "Enfocar la ruta del elemento", |
||||
|
"Focus to contextual toolbar": "Enfocar la barra de herramientas contextual", |
||||
|
"Insert link (if link plugin activated)": "Insertar enlace (si el complemento de enlace est\u00e1 activado)", |
||||
|
"Save (if save plugin activated)": "Guardar (si el componente de salvar est\u00e1 activado)", |
||||
|
"Find (if searchreplace plugin activated)": "Buscar (si el complemento buscar-remplazar est\u00e1 activado)", |
||||
|
"Plugins installed ({0}):": "Plugins instalados ({0}):", |
||||
|
"Premium plugins:": "Complementos premium:", |
||||
|
"Learn more...": "Aprende m\u00e1s...", |
||||
|
"You are using {0}": "Estas usando {0}", |
||||
|
"Plugins": "Complementos", |
||||
|
"Handy Shortcuts": "Accesos directos", |
||||
|
"Horizontal line": "L\u00ednea horizontal", |
||||
|
"Insert\/edit image": "Insertar\/editar imagen", |
||||
|
"Image description": "Descripci\u00f3n de la imagen", |
||||
|
"Source": "Enlace", |
||||
|
"Dimensions": "Dimensiones", |
||||
|
"Constrain proportions": "Restringir proporciones", |
||||
|
"General": "General", |
||||
|
"Advanced": "Avanzado", |
||||
|
"Style": "Estilo", |
||||
|
"Vertical space": "Espacio vertical", |
||||
|
"Horizontal space": "Espacio horizontal", |
||||
|
"Border": "Borde", |
||||
|
"Insert image": "Insertar imagen", |
||||
|
"Image...": "Imagen...", |
||||
|
"Image list": "Lista de im\u00e1genes", |
||||
|
"Rotate counterclockwise": "Girar a la izquierda", |
||||
|
"Rotate clockwise": "Girar a la derecha", |
||||
|
"Flip vertically": "Invertir verticalmente", |
||||
|
"Flip horizontally": "Invertir horizontalmente", |
||||
|
"Edit image": "Editar imagen", |
||||
|
"Image options": "Opciones de imagen", |
||||
|
"Zoom in": "Acercar", |
||||
|
"Zoom out": "Alejar", |
||||
|
"Crop": "Recortar", |
||||
|
"Resize": "Redimensionar", |
||||
|
"Orientation": "Orientaci\u00f3n", |
||||
|
"Brightness": "Brillo", |
||||
|
"Sharpen": "Forma", |
||||
|
"Contrast": "Contraste", |
||||
|
"Color levels": "Niveles de color", |
||||
|
"Gamma": "Gamma", |
||||
|
"Invert": "Invertir", |
||||
|
"Apply": "Aplicar", |
||||
|
"Back": "Atr\u00e1s", |
||||
|
"Insert date\/time": "Insertar fecha\/hora", |
||||
|
"Date\/time": "Fecha\/hora", |
||||
|
"Insert\/Edit Link": "Insertar\/editar enlace", |
||||
|
"Insert\/edit link": "Insertar\/editar enlace", |
||||
|
"Text to display": "Texto para mostrar", |
||||
|
"Url": "URL", |
||||
|
"Open link in...": "Abrir enlace en...", |
||||
|
"Current window": "Ventana actual", |
||||
|
"None": "Ninguno", |
||||
|
"New window": "Nueva ventana", |
||||
|
"Remove link": "Quitar enlace", |
||||
|
"Anchors": "Anclas", |
||||
|
"Link...": "Enlace...", |
||||
|
"Paste or type a link": "Pega o introduce un enlace", |
||||
|
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "El enlace que has introducido no parece ser una direcci\u00f3n de correo electr\u00f3nico. Quieres a\u00f1adir el prefijo necesario mailto: ?", |
||||
|
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "El enlace que has introducido no parece ser una enlace externo. Quieres a\u00f1adir el prefijo necesario http:\/\/ ?", |
||||
|
"Link list": "Lista de enlaces", |
||||
|
"Insert video": "Insertar video", |
||||
|
"Insert\/edit video": "Insertar\/editar video", |
||||
|
"Insert\/edit media": "Insertar\/editar medio", |
||||
|
"Alternative source": "Enlace alternativo", |
||||
|
"Alternative source URL": "Origen de URL alternativo", |
||||
|
"Media poster (Image URL)": "P\u00f3ster de medio (URL de imagen)", |
||||
|
"Paste your embed code below:": "Pega tu c\u00f3digo embebido debajo", |
||||
|
"Embed": "Incrustado", |
||||
|
"Media...": "Medios...", |
||||
|
"Nonbreaking space": "Espacio fijo", |
||||
|
"Page break": "Salto de p\u00e1gina", |
||||
|
"Paste as text": "Pegar como texto", |
||||
|
"Preview": "Previsualizar", |
||||
|
"Print...": "Imprimir...", |
||||
|
"Save": "Guardar", |
||||
|
"Find": "Buscar", |
||||
|
"Replace with": "Reemplazar con", |
||||
|
"Replace": "Reemplazar", |
||||
|
"Replace all": "Reemplazar todo", |
||||
|
"Previous": "Anterior", |
||||
|
"Next": "Siguiente", |
||||
|
"Find and replace...": "Buscar y reemplazar...", |
||||
|
"Could not find the specified string.": "No se encuentra la cadena de texto especificada", |
||||
|
"Match case": "Coincidencia exacta", |
||||
|
"Find whole words only": "Solo palabras completas", |
||||
|
"Spell check": "Revisar ortograf\u00eda", |
||||
|
"Ignore": "Ignorar", |
||||
|
"Ignore all": "Ignorar todos", |
||||
|
"Finish": "Finalizar", |
||||
|
"Add to Dictionary": "A\u00f1adir al Diccionario", |
||||
|
"Insert table": "Insertar tabla", |
||||
|
"Table properties": "Propiedades de la tabla", |
||||
|
"Delete table": "Eliminar tabla", |
||||
|
"Cell": "Celda", |
||||
|
"Row": "Fila", |
||||
|
"Column": "Columna", |
||||
|
"Cell properties": "Propiedades de la celda", |
||||
|
"Merge cells": "Combinar celdas", |
||||
|
"Split cell": "Dividir celdas", |
||||
|
"Insert row before": "Insertar fila antes", |
||||
|
"Insert row after": "Insertar fila despu\u00e9s ", |
||||
|
"Delete row": "Eliminar fila", |
||||
|
"Row properties": "Propiedades de la fila", |
||||
|
"Cut row": "Cortar fila", |
||||
|
"Copy row": "Copiar fila", |
||||
|
"Paste row before": "Pegar la fila antes", |
||||
|
"Paste row after": "Pegar la fila despu\u00e9s", |
||||
|
"Insert column before": "Insertar columna antes", |
||||
|
"Insert column after": "Insertar columna despu\u00e9s", |
||||
|
"Delete column": "Eliminar columna", |
||||
|
"Cols": "Columnas", |
||||
|
"Rows": "Filas", |
||||
|
"Width": "Ancho", |
||||
|
"Height": "Alto", |
||||
|
"Cell spacing": "Espacio entre celdas", |
||||
|
"Cell padding": "Relleno de celda", |
||||
|
"Show caption": "Mostrar t\u00edtulo", |
||||
|
"Left": "Izquierda", |
||||
|
"Center": "Centrado", |
||||
|
"Right": "Derecha", |
||||
|
"Cell type": "Tipo de celda", |
||||
|
"Scope": "\u00c1mbito", |
||||
|
"Alignment": "Alineaci\u00f3n", |
||||
|
"H Align": "Alineamiento Horizontal", |
||||
|
"V Align": "Alineamiento Vertical", |
||||
|
"Top": "Arriba", |
||||
|
"Middle": "Centro", |
||||
|
"Bottom": "Abajo", |
||||
|
"Header cell": "Celda de la cebecera", |
||||
|
"Row group": "Grupo de filas", |
||||
|
"Column group": "Grupo de columnas", |
||||
|
"Row type": "Tipo de fila", |
||||
|
"Header": "Cabecera", |
||||
|
"Body": "Cuerpo", |
||||
|
"Footer": "Pie de p\u00e1gina", |
||||
|
"Border color": "Color del borde", |
||||
|
"Insert template...": "Insertar plantilla...", |
||||
|
"Templates": "Plantillas", |
||||
|
"Template": "Plantilla", |
||||
|
"Text color": "Color del texto", |
||||
|
"Background color": "Color de fondo", |
||||
|
"Custom...": "Personalizar...", |
||||
|
"Custom color": "Color personalizado", |
||||
|
"No color": "Sin color", |
||||
|
"Remove color": "Quitar color", |
||||
|
"Table of Contents": "Tabla de contenidos", |
||||
|
"Show blocks": "Mostrar bloques", |
||||
|
"Show invisible characters": "Mostrar caracteres invisibles", |
||||
|
"Word count": "Contar palabras", |
||||
|
"Count": "Recuento", |
||||
|
"Document": "Documento", |
||||
|
"Selection": "Selecci\u00f3n", |
||||
|
"Words": "Palabras", |
||||
|
"Words: {0}": "Palabras: {0}", |
||||
|
"{0} words": "{0} palabras", |
||||
|
"File": "Archivo", |
||||
|
"Edit": "Editar", |
||||
|
"Insert": "Insertar", |
||||
|
"View": "Ver", |
||||
|
"Format": "Formato", |
||||
|
"Table": "Tabla", |
||||
|
"Tools": "Herramientas", |
||||
|
"Powered by {0}": "Desarrollado por {0}", |
||||
|
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u00c1rea de texto enriquecido. Pulse ALT-F9 para el menu. Pulse ALT-F10 para la barra de herramientas. Pulse ALT-0 para ayuda", |
||||
|
"Image title": "Titulo de imagen", |
||||
|
"Border width": "Ancho de borde", |
||||
|
"Border style": "Estilo de borde", |
||||
|
"Error": "Error", |
||||
|
"Warn": "Advertencia", |
||||
|
"Valid": "V\u00e1lido", |
||||
|
"To open the popup, press Shift+Enter": "Para abrir el elemento emergente, pulse May\u00fas+Intro", |
||||
|
"Rich Text Area. Press ALT-0 for help.": "\u00c1rea de texto enriquecido. Pulse ALT-0 para abrir la ayuda.", |
||||
|
"System Font": "Fuente de sistema", |
||||
|
"Failed to upload image: {0}": "Fallo al cargar imagen: {0}", |
||||
|
"Failed to load plugin: {0} from url {1}": "Fallo al cargar complemento: {0} desde URL {1}", |
||||
|
"Failed to load plugin url: {0}": "Fallo al cargar URL del complemento: {0}", |
||||
|
"Failed to initialize plugin: {0}": "Fallo al iniciar el complemento: {0}", |
||||
|
"example": "ejemplo", |
||||
|
"Search": "Buscar", |
||||
|
"All": "Todo", |
||||
|
"Currency": "Divisa", |
||||
|
"Text": "Texto", |
||||
|
"Quotations": "Comillas", |
||||
|
"Mathematical": "S\u00edmbolo matem\u00e1tico", |
||||
|
"Extended Latin": "Latino extendido A", |
||||
|
"Symbols": "S\u00edmbolos", |
||||
|
"Arrows": "Flechas", |
||||
|
"User Defined": "Definido por el usuario", |
||||
|
"dollar sign": "signo de d\u00f3lar", |
||||
|
"currency sign": "signo de divisa", |
||||
|
"euro-currency sign": "signo de euro", |
||||
|
"colon sign": "signo de dos puntos", |
||||
|
"cruzeiro sign": "signo de cruceiro", |
||||
|
"french franc sign": "signo de franco franc\u00e9s", |
||||
|
"lira sign": "signo de lira", |
||||
|
"mill sign": "signo de mill", |
||||
|
"naira sign": "signo de naira", |
||||
|
"peseta sign": "signo de peseta", |
||||
|
"rupee sign": "signo de rupia", |
||||
|
"won sign": "signo de won", |
||||
|
"new sheqel sign": "signo de nuevo s\u00e9quel", |
||||
|
"dong sign": "signo de dong", |
||||
|
"kip sign": "signo de kip", |
||||
|
"tugrik sign": "signo de tugrik", |
||||
|
"drachma sign": "signo de dracma", |
||||
|
"german penny symbol": "signo de penique alem\u00e1n", |
||||
|
"peso sign": "signo de peso", |
||||
|
"guarani sign": "signo de guaran\u00ed", |
||||
|
"austral sign": "signo de austral", |
||||
|
"hryvnia sign": "signo de grivna", |
||||
|
"cedi sign": "signo de cedi", |
||||
|
"livre tournois sign": "signo de libra tornesa", |
||||
|
"spesmilo sign": "signo de spesmilo", |
||||
|
"tenge sign": "signo de tenge", |
||||
|
"indian rupee sign": "signo de rupia india", |
||||
|
"turkish lira sign": "signo de lira turca", |
||||
|
"nordic mark sign": "signo de marco n\u00f3rdico", |
||||
|
"manat sign": "signo de manat", |
||||
|
"ruble sign": "signo de rublo", |
||||
|
"yen character": "car\u00e1cter de yen", |
||||
|
"yuan character": "car\u00e1cter de yuan", |
||||
|
"yuan character, in hong kong and taiwan": "car\u00e1cter de yuan en Hong Kong y Taiw\u00e1n", |
||||
|
"yen\/yuan character variant one": "Variante uno de car\u00e1cter de yen\/yuan", |
||||
|
"Loading emoticons...": "Cargando emoticonos...", |
||||
|
"Could not load emoticons": "No se han podido cargar los emoticonos", |
||||
|
"People": "Personas", |
||||
|
"Animals and Nature": "Animales y naturaleza", |
||||
|
"Food and Drink": "Comida y bebida", |
||||
|
"Activity": "Actividad", |
||||
|
"Travel and Places": "Viajes y lugares", |
||||
|
"Objects": "Objetos", |
||||
|
"Flags": "Banderas", |
||||
|
"Characters": "Caracteres", |
||||
|
"Characters (no spaces)": "Caracteres (sin espacios)", |
||||
|
"{0} characters": "{0} caracteres", |
||||
|
"Error: Form submit field collision.": "Error: Colisi\u00f3n de campo al enviar formulario.", |
||||
|
"Error: No form element found.": "Error: No se encuentra ning\u00fan elemento de formulario.", |
||||
|
"Update": "Actualizar", |
||||
|
"Color swatch": "Muestrario de colores", |
||||
|
"Turquoise": "Turquesa", |
||||
|
"Green": "Verde", |
||||
|
"Blue": "Azul", |
||||
|
"Purple": "P\u00farpura", |
||||
|
"Navy Blue": "Azul marino", |
||||
|
"Dark Turquoise": "Turquesa oscuro", |
||||
|
"Dark Green": "Verde oscuro", |
||||
|
"Medium Blue": "Azul medio", |
||||
|
"Medium Purple": "P\u00farpura medio", |
||||
|
"Midnight Blue": "Azul medio", |
||||
|
"Yellow": "Amarillo", |
||||
|
"Orange": "Naranja", |
||||
|
"Red": "Rojo", |
||||
|
"Light Gray": "Gris claro", |
||||
|
"Gray": "Gris", |
||||
|
"Dark Yellow": "Amarillo oscuro", |
||||
|
"Dark Orange": "Naranja oscuro", |
||||
|
"Dark Red": "Rojo oscuro", |
||||
|
"Medium Gray": "Gris medio", |
||||
|
"Dark Gray": "Gris oscuro", |
||||
|
"Light Green": "Verde claro", |
||||
|
"Light Yellow": "Amarillo claro", |
||||
|
"Light Red": "Rojo claro", |
||||
|
"Light Purple": "Morado claro", |
||||
|
"Light Blue": "Azul claro", |
||||
|
"Dark Purple": "Morado oscuro", |
||||
|
"Dark Blue": "Azul oscuro", |
||||
|
"Black": "Negro", |
||||
|
"White": "Blanco", |
||||
|
"Switch to or from fullscreen mode": "Activar o desactivar modo pantalla completa", |
||||
|
"Open help dialog": "Abrir di\u00e1logo de ayuda", |
||||
|
"history": "historial", |
||||
|
"styles": "estilos", |
||||
|
"formatting": "formato", |
||||
|
"alignment": "alineaci\u00f3n", |
||||
|
"indentation": "sangr\u00eda", |
||||
|
"permanent pen": "bol\u00edgrafo permanente", |
||||
|
"comments": "comentarios", |
||||
|
"Format Painter": "Copiar formato", |
||||
|
"Insert\/edit iframe": "Insertar\/editar iframe", |
||||
|
"Capitalization": "Uso de may\u00fasculas", |
||||
|
"lowercase": "min\u00fasculas", |
||||
|
"UPPERCASE": "MAY\u00daSCULAS", |
||||
|
"Title Case": "Tipo T\u00edtulo", |
||||
|
"Permanent Pen Properties": "Propiedades del bol\u00edgrafo permanente", |
||||
|
"Permanent pen properties...": "Propiedades del bol\u00edgrafo permanente...", |
||||
|
"Font": "Fuente", |
||||
|
"Size": "Tama\u00f1o", |
||||
|
"More...": "M\u00e1s...", |
||||
|
"Spellcheck Language": "Corrector", |
||||
|
"Select...": "Seleccionar...", |
||||
|
"Preferences": "Preferencias", |
||||
|
"Yes": "S\u00ed", |
||||
|
"No": "No", |
||||
|
"Keyboard Navigation": "Navegaci\u00f3n con el teclado", |
||||
|
"Version": "Versi\u00f3n", |
||||
|
"Anchor": "Ancla", |
||||
|
"Special character": "Car\u00e1cter especial", |
||||
|
"Code sample": "Ejemplo de c\u00f3digo", |
||||
|
"Color": "Color", |
||||
|
"Emoticons": "Emoticonos", |
||||
|
"Document properties": "Propiedades del documento", |
||||
|
"Image": "Imagen", |
||||
|
"Insert link": "Insertar enlace", |
||||
|
"Target": "Destino", |
||||
|
"Link": "Enlace", |
||||
|
"Poster": "Miniatura", |
||||
|
"Media": "Media", |
||||
|
"Print": "Imprimir", |
||||
|
"Prev": "Anterior", |
||||
|
"Find and replace": "Buscar y reemplazar", |
||||
|
"Whole words": "Palabras completas", |
||||
|
"Spellcheck": "Corrector ortogr\u00e1fico", |
||||
|
"Caption": "Subt\u00edtulo", |
||||
|
"Insert template": "Insertar plantilla" |
||||
|
}); |
||||
@ -0,0 +1,419 @@ |
|||||
|
tinymce.addI18n('ja', { |
||||
|
"Redo": "\u3084\u308a\u76f4\u3057", |
||||
|
"Undo": "\u5143\u306b\u623b\u3059", |
||||
|
"Cut": "\u5207\u308a\u53d6\u308a", |
||||
|
"Copy": "\u30b3\u30d4\u30fc", |
||||
|
"Paste": "\u8cbc\u308a\u4ed8\u3051", |
||||
|
"Select all": "\u3059\u3079\u3066\u9078\u629e", |
||||
|
"New document": "\u65b0\u898f\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8", |
||||
|
"Ok": "OK", |
||||
|
"Cancel": "\u53d6\u6d88", |
||||
|
"Visual aids": "\u8868\u306e\u67a0\u7dda\u3092\u70b9\u7dda\u3067\u8868\u793a", |
||||
|
"Bold": "\u592a\u5b57", |
||||
|
"Italic": "\u659c\u4f53", |
||||
|
"Underline": "\u4e0b\u7dda", |
||||
|
"Strikethrough": "\u53d6\u6d88\u7dda", |
||||
|
"Superscript": "\u4e0a\u4ed8\u304d", |
||||
|
"Subscript": "\u4e0b\u4ed8\u304d", |
||||
|
"Clear formatting": "\u66f8\u5f0f\u3092\u30af\u30ea\u30a2", |
||||
|
"Align left": "\u5de6\u63c3\u3048", |
||||
|
"Align center": "\u4e2d\u592e\u63c3\u3048", |
||||
|
"Align right": "\u53f3\u63c3\u3048", |
||||
|
"Justify": "\u4e21\u7aef\u63c3\u3048", |
||||
|
"Bullet list": "\u7b87\u6761\u66f8\u304d", |
||||
|
"Numbered list": "\u756a\u53f7\u4ed8\u304d\u7b87\u6761\u66f8\u304d", |
||||
|
"Decrease indent": "\u30a4\u30f3\u30c7\u30f3\u30c8\u3092\u6e1b\u3089\u3059", |
||||
|
"Increase indent": "\u30a4\u30f3\u30c7\u30f3\u30c8\u3092\u5897\u3084\u3059", |
||||
|
"Close": "\u9589\u3058\u308b", |
||||
|
"Formats": "\u66f8\u5f0f", |
||||
|
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u304a\u4f7f\u3044\u306e\u30d6\u30e9\u30a6\u30b6\u3067\u306f\u30af\u30ea\u30c3\u30d7\u30dc\u30fc\u30c9\u6a5f\u80fd\u3092\u5229\u7528\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u305b\u3093\u3002\u30ad\u30fc\u30dc\u30fc\u30c9\u306e\u30b7\u30e7\u30fc\u30c8\u30ab\u30c3\u30c8\uff08Ctrl+X, Ctrl+C, Ctrl+V\uff09\u3092\u4f7f\u7528\u3057\u3066\u304f\u3060\u3055\u3044\u3002", |
||||
|
"Headers": "\u30d8\u30c3\u30c0\u30fc", |
||||
|
"Header 1": "\u30d8\u30c3\u30c0\u30fc 1", |
||||
|
"Header 2": "\u30d8\u30c3\u30c0\u30fc 2", |
||||
|
"Header 3": "\u30d8\u30c3\u30c0\u30fc 3", |
||||
|
"Header 4": "\u30d8\u30c3\u30c0\u30fc 4", |
||||
|
"Header 5": "\u30d8\u30c3\u30c0\u30fc 5", |
||||
|
"Header 6": "\u30d8\u30c3\u30c0\u30fc 6", |
||||
|
"Headings": "\u898b\u51fa\u3057", |
||||
|
"Heading 1": "\u898b\u51fa\u30571", |
||||
|
"Heading 2": "\u898b\u51fa\u30572", |
||||
|
"Heading 3": "\u898b\u51fa\u30573", |
||||
|
"Heading 4": "\u898b\u51fa\u30574", |
||||
|
"Heading 5": "\u898b\u51fa\u30575", |
||||
|
"Heading 6": "\u898b\u51fa\u30576", |
||||
|
"Preformatted": "\u66f8\u5f0f\u8a2d\u5b9a\u6e08\u307f", |
||||
|
"Div": "Div", |
||||
|
"Pre": "Pre", |
||||
|
"Code": "\u30b3\u30fc\u30c9", |
||||
|
"Paragraph": "\u6bb5\u843d", |
||||
|
"Blockquote": "Blockquote", |
||||
|
"Inline": "\u30a4\u30f3\u30e9\u30a4\u30f3", |
||||
|
"Blocks": "\u30d6\u30ed\u30c3\u30af", |
||||
|
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u8cbc\u308a\u4ed8\u3051\u306f\u73fe\u5728\u30d7\u30ec\u30fc\u30f3\u30c6\u30ad\u30b9\u30c8\u30e2\u30fc\u30c9\u3067\u3059\u3002\u3053\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3092\u30aa\u30d5\u306b\u3057\u306a\u3044\u9650\u308a\u5185\u5bb9\u306f\u30d7\u30ec\u30fc\u30f3\u30c6\u30ad\u30b9\u30c8\u3068\u3057\u3066\u8cbc\u308a\u4ed8\u3051\u3089\u308c\u307e\u3059\u3002", |
||||
|
"Fonts": "\u30d5\u30a9\u30f3\u30c8", |
||||
|
"Font Sizes": "\u30d5\u30a9\u30f3\u30c8\u30b5\u30a4\u30ba", |
||||
|
"Class": "\u30af\u30e9\u30b9", |
||||
|
"Browse for an image": "\u753b\u50cf\u3092\u53c2\u7167", |
||||
|
"OR": "OR", |
||||
|
"Drop an image here": "\u3053\u3053\u306b\u753b\u50cf\u3092\u30c9\u30ed\u30c3\u30d7", |
||||
|
"Upload": "\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9", |
||||
|
"Block": "\u30d6\u30ed\u30c3\u30af", |
||||
|
"Align": "\u914d\u7f6e", |
||||
|
"Default": "\u30c7\u30d5\u30a9\u30eb\u30c8", |
||||
|
"Circle": "\u5186", |
||||
|
"Disc": "\u70b9", |
||||
|
"Square": "\u56db\u89d2", |
||||
|
"Lower Alpha": "\u5c0f\u6587\u5b57\u306e\u30a2\u30eb\u30d5\u30a1\u30d9\u30c3\u30c8", |
||||
|
"Lower Greek": "\u5c0f\u6587\u5b57\u306e\u30ae\u30ea\u30b7\u30e3\u6587\u5b57", |
||||
|
"Lower Roman": "\u5c0f\u6587\u5b57\u306e\u30ed\u30fc\u30de\u6570\u5b57", |
||||
|
"Upper Alpha": "\u5927\u6587\u5b57\u306e\u30a2\u30eb\u30d5\u30a1\u30d9\u30c3\u30c8", |
||||
|
"Upper Roman": "\u5927\u6587\u5b57\u306e\u30ed\u30fc\u30de\u6570\u5b57", |
||||
|
"Anchor...": "\u30a2\u30f3\u30ab\u30fc...", |
||||
|
"Name": "\u30a2\u30f3\u30ab\u30fc\u540d", |
||||
|
"Id": "Id", |
||||
|
"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "ID\u306f\u6587\u5b57\u3067\u59cb\u307e\u308a\u3001\u6587\u5b57\u3001\u6570\u5b57\u3001\u30c0\u30c3\u30b7\u30e5\u3001\u30c9\u30c3\u30c8\u3001\u30b3\u30ed\u30f3\u307e\u305f\u306f\u30a2\u30f3\u30c0\u30fc\u30b9\u30b3\u30a2\u3067\u59cb\u307e\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002", |
||||
|
"You have unsaved changes are you sure you want to navigate away?": "\u307e\u3060\u4fdd\u5b58\u3057\u3066\u3044\u306a\u3044\u5909\u66f4\u304c\u3042\u308a\u307e\u3059\u304c\u3001\u672c\u5f53\u306b\u3053\u306e\u30da\u30fc\u30b8\u3092\u96e2\u308c\u307e\u3059\u304b\uff1f", |
||||
|
"Restore last draft": "\u524d\u56de\u306e\u4e0b\u66f8\u304d\u3092\u5fa9\u6d3b\u3055\u305b\u308b", |
||||
|
"Special character...": "\u7279\u6b8a\u6587\u5b57...", |
||||
|
"Source code": "\u30bd\u30fc\u30b9\u30b3\u30fc\u30c9", |
||||
|
"Insert\/Edit code sample": "\u30b3\u30fc\u30c9\u30b5\u30f3\u30d7\u30eb\u306e\u633f\u5165\u30fb\u7de8\u96c6", |
||||
|
"Language": "\u8a00\u8a9e", |
||||
|
"Code sample...": "\u30b3\u30fc\u30c9\u306e\u30b5\u30f3\u30d7\u30eb...", |
||||
|
"Color Picker": "\u30ab\u30e9\u30fc\u30d4\u30c3\u30ab\u30fc", |
||||
|
"R": "R", |
||||
|
"G": "G", |
||||
|
"B": "B", |
||||
|
"Left to right": "\u5de6\u304b\u3089\u53f3", |
||||
|
"Right to left": "\u53f3\u304b\u3089\u5de6", |
||||
|
"Emoticons...": "\u7d75\u6587\u5b57...", |
||||
|
"Metadata and Document Properties": "\u30e1\u30bf\u30c7\u30fc\u30bf\u3068\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u30d7\u30ed\u30d1\u30c6\u30a3", |
||||
|
"Title": "\u30bf\u30a4\u30c8\u30eb", |
||||
|
"Keywords": "\u30ad\u30fc\u30ef\u30fc\u30c9", |
||||
|
"Description": "\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u5185\u5bb9", |
||||
|
"Robots": "\u30ed\u30dc\u30c3\u30c4", |
||||
|
"Author": "\u8457\u8005", |
||||
|
"Encoding": "\u30a8\u30f3\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0", |
||||
|
"Fullscreen": "\u5168\u753b\u9762\u8868\u793a", |
||||
|
"Action": "\u30a2\u30af\u30b7\u30e7\u30f3", |
||||
|
"Shortcut": "\u30b7\u30e7\u30fc\u30c8\u30ab\u30c3\u30c8", |
||||
|
"Help": "\u30d8\u30eb\u30d7", |
||||
|
"Address": "\u30a2\u30c9\u30ec\u30b9", |
||||
|
"Focus to menubar": "\u30e1\u30cb\u30e5\u30fc\u30d0\u30fc\u306b\u30d5\u30a9\u30fc\u30ab\u30b9", |
||||
|
"Focus to toolbar": "\u30c4\u30fc\u30eb\u30d0\u30fc\u306b\u30d5\u30a9\u30fc\u30ab\u30b9", |
||||
|
"Focus to element path": "\u8981\u7d20\u30d1\u30b9\u306b\u30d5\u30a9\u30fc\u30ab\u30b9", |
||||
|
"Focus to contextual toolbar": "\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u30c4\u30fc\u30eb\u30d0\u30fc\u306b\u30d5\u30a9\u30fc\u30ab\u30b9", |
||||
|
"Insert link (if link plugin activated)": "\u30ea\u30f3\u30af\u3092\u633f\u5165 (\u30ea\u30f3\u30af\u30d7\u30e9\u30b0\u30a4\u30f3\u6709\u52b9\u6642)", |
||||
|
"Save (if save plugin activated)": "\u4fdd\u5b58 (\u4fdd\u5b58\u30d7\u30e9\u30b0\u30a4\u30f3\u6709\u52b9\u6642)", |
||||
|
"Find (if searchreplace plugin activated)": "\u691c\u7d22(\u7f6e\u63db\u30d7\u30e9\u30b0\u30a4\u30f3\u6709\u52b9\u6642)", |
||||
|
"Plugins installed ({0}):": "\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u6e08\u30d7\u30e9\u30b0\u30a4\u30f3 ({0}):", |
||||
|
"Premium plugins:": "\u30d7\u30ec\u30df\u30a2\u30e0\u30d7\u30e9\u30b0\u30a4\u30f3:", |
||||
|
"Learn more...": "\u8a73\u7d30...", |
||||
|
"You are using {0}": "\u3042\u306a\u305f\u306f {0} \u4f7f\u7528\u4e2d", |
||||
|
"Plugins": "\u30d7\u30e9\u30b0\u30a4\u30f3", |
||||
|
"Handy Shortcuts": "\u4fbf\u5229\u306a\u30b7\u30e7\u30fc\u30c8\u30ab\u30c3\u30c8", |
||||
|
"Horizontal line": "\u6c34\u5e73\u7f6b\u7dda", |
||||
|
"Insert\/edit image": "\u753b\u50cf\u306e\u633f\u5165\u30fb\u7de8\u96c6", |
||||
|
"Image description": "\u753b\u50cf\u306e\u8aac\u660e\u6587", |
||||
|
"Source": "\u753b\u50cf\u306e\u30bd\u30fc\u30b9", |
||||
|
"Dimensions": "\u753b\u50cf\u30b5\u30a4\u30ba\uff08\u6a2a\u30fb\u7e26\uff09", |
||||
|
"Constrain proportions": "\u7e26\u6a2a\u6bd4\u3092\u4fdd\u6301\u3059\u308b", |
||||
|
"General": "\u4e00\u822c", |
||||
|
"Advanced": "\u8a73\u7d30\u8a2d\u5b9a", |
||||
|
"Style": "\u30b9\u30bf\u30a4\u30eb", |
||||
|
"Vertical space": "\u7e26\u65b9\u5411\u306e\u4f59\u767d", |
||||
|
"Horizontal space": "\u6a2a\u65b9\u5411\u306e\u4f59\u767d", |
||||
|
"Border": "\u67a0\u7dda", |
||||
|
"Insert image": "\u753b\u50cf\u306e\u633f\u5165", |
||||
|
"Image...": "\u753b\u50cf..", |
||||
|
"Image list": "\u753b\u50cf\u4e00\u89a7", |
||||
|
"Rotate counterclockwise": "\u53cd\u6642\u8a08\u56de\u308a\u306b\u56de\u8ee2", |
||||
|
"Rotate clockwise": "\u6642\u8a08\u56de\u308a\u306b\u56de\u8ee2", |
||||
|
"Flip vertically": "\u4e0a\u4e0b\u306b\u53cd\u8ee2", |
||||
|
"Flip horizontally": "\u6c34\u5e73\u306b\u53cd\u8ee2", |
||||
|
"Edit image": "\u753b\u50cf\u306e\u7de8\u96c6", |
||||
|
"Image options": "\u753b\u50cf\u30aa\u30d7\u30b7\u30e7\u30f3", |
||||
|
"Zoom in": "\u30ba\u30fc\u30e0\u30a4\u30f3", |
||||
|
"Zoom out": "\u30ba\u30fc\u30e0\u30a2\u30a6\u30c8", |
||||
|
"Crop": "\u30af\u30ed\u30c3\u30d7", |
||||
|
"Resize": "\u30ea\u30b5\u30a4\u30ba", |
||||
|
"Orientation": "\u5411\u304d", |
||||
|
"Brightness": "\u660e\u308b\u3055", |
||||
|
"Sharpen": "\u30b7\u30e3\u30fc\u30d7\u5316", |
||||
|
"Contrast": "\u30b3\u30f3\u30c8\u30e9\u30b9\u30c8", |
||||
|
"Color levels": "\u30ab\u30e9\u30fc\u30ec\u30d9\u30eb", |
||||
|
"Gamma": "\u30ac\u30f3\u30de", |
||||
|
"Invert": "\u53cd\u8ee2", |
||||
|
"Apply": "\u9069\u7528", |
||||
|
"Back": "\u623b\u308b", |
||||
|
"Insert date\/time": "\u65e5\u4ed8\u30fb\u6642\u523b", |
||||
|
"Date\/time": "\u65e5\u4ed8\u30fb\u6642\u523b", |
||||
|
"Insert\/Edit Link": "\u30ea\u30f3\u30af\u306e\u633f\u5165\/\u7de8\u96c6", |
||||
|
"Insert\/edit link": "\u30ea\u30f3\u30af\u306e\u633f\u5165\u30fb\u7de8\u96c6", |
||||
|
"Text to display": "\u30ea\u30f3\u30af\u5143\u30c6\u30ad\u30b9\u30c8", |
||||
|
"Url": "\u30ea\u30f3\u30af\u5148URL", |
||||
|
"Open link in...": "\u30ea\u30f3\u30af\u306e\u958b\u304d\u65b9...", |
||||
|
"Current window": "\u540c\u3058\u30a6\u30a3\u30f3\u30c9\u30a6", |
||||
|
"None": "\u306a\u3057", |
||||
|
"New window": "\u65b0\u898f\u30a6\u30a3\u30f3\u30c9\u30a6", |
||||
|
"Remove link": "\u30ea\u30f3\u30af\u306e\u524a\u9664", |
||||
|
"Anchors": "\u30a2\u30f3\u30ab\u30fc\uff08\u30ea\u30f3\u30af\u306e\u5230\u9054\u70b9\uff09", |
||||
|
"Link...": "\u30ea\u30f3\u30af...", |
||||
|
"Paste or type a link": "\u30ea\u30f3\u30af\u3092\u30da\u30fc\u30b9\u30c8\u307e\u305f\u306f\u5165\u529b", |
||||
|
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u5165\u529b\u3055\u308c\u305fURL\u306f\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u306e\u3088\u3046\u3067\u3059\u3002\u300cmailto:\u300d\u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9\u3092\u8ffd\u52a0\u3057\u307e\u3059\u304b\uff1f", |
||||
|
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u5165\u529b\u3055\u308c\u305fURL\u306f\u5916\u90e8\u30ea\u30f3\u30af\u306e\u3088\u3046\u3067\u3059\u3002\u300chttp:\/\/\u300d\u30d7\u30ec\u30d5\u30a3\u30c3\u30af\u30b9\u3092\u8ffd\u52a0\u3057\u307e\u3059\u304b\uff1f", |
||||
|
"Link list": "\u30ea\u30f3\u30af\u4e00\u89a7", |
||||
|
"Insert video": "\u52d5\u753b", |
||||
|
"Insert\/edit video": "\u52d5\u753b\u306e\u633f\u5165\u30fb\u7de8\u96c6", |
||||
|
"Insert\/edit media": "\u30e1\u30c7\u30a3\u30a2\u306e\u633f\u5165\u30fb\u7de8\u96c6", |
||||
|
"Alternative source": "\u4ee3\u66ff\u52d5\u753b\u306e\u5834\u6240", |
||||
|
"Alternative source URL": "\u4ee3\u66ff\u30bd\u30fc\u30b9URL", |
||||
|
"Media poster (Image URL)": "\u30e1\u30c7\u30a3\u30a2\u30dd\u30b9\u30bf\u30fc (\u753b\u50cfURL)", |
||||
|
"Paste your embed code below:": "\u57cb\u3081\u8fbc\u307f\u7528\u30b3\u30fc\u30c9\u3092\u4e0b\u8a18\u306b\u8cbc\u308a\u4ed8\u3051\u3066\u304f\u3060\u3055\u3044\u3002", |
||||
|
"Embed": "\u57cb\u3081\u8fbc\u307f", |
||||
|
"Media...": "\u30e1\u30c7\u30a3\u30a2\u2026", |
||||
|
"Nonbreaking space": "\u56fa\u5b9a\u30b9\u30da\u30fc\u30b9\uff08 \uff09", |
||||
|
"Page break": "\u30da\u30fc\u30b8\u533a\u5207\u308a", |
||||
|
"Paste as text": "\u30c6\u30ad\u30b9\u30c8\u3068\u3057\u3066\u8cbc\u308a\u4ed8\u3051", |
||||
|
"Preview": "\u30d7\u30ec\u30d3\u30e5\u30fc", |
||||
|
"Print...": "\u5370\u5237...", |
||||
|
"Save": "\u4fdd\u5b58", |
||||
|
"Find": "\u691c\u7d22", |
||||
|
"Replace with": "\u7f6e\u304d\u63db\u3048\u308b\u6587\u5b57", |
||||
|
"Replace": "\u7f6e\u304d\u63db\u3048", |
||||
|
"Replace all": "\u5168\u3066\u3092\u7f6e\u304d\u63db\u3048\u308b", |
||||
|
"Previous": "\u524d\u3078", |
||||
|
"Next": "\u6b21", |
||||
|
"Find and replace...": "\u7f6e\u63db...", |
||||
|
"Could not find the specified string.": "\u304a\u63a2\u3057\u306e\u6587\u5b57\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002", |
||||
|
"Match case": "\u5927\u6587\u5b57\u30fb\u5c0f\u6587\u5b57\u3092\u533a\u5225\u3059\u308b", |
||||
|
"Find whole words only": "\u8a9e\u5168\u4f53\u3092\u542b\u3080\u3082\u306e\u306e\u307f\u691c\u7d22", |
||||
|
"Spell check": "\u30b9\u30da\u30eb\u30c1\u30a7\u30c3\u30af", |
||||
|
"Ignore": "\u7121\u8996", |
||||
|
"Ignore all": "\u5168\u3066\u3092\u7121\u8996", |
||||
|
"Finish": "\u7d42\u4e86", |
||||
|
"Add to Dictionary": "\u8f9e\u66f8\u306b\u8ffd\u52a0", |
||||
|
"Insert table": "\u8868\u306e\u633f\u5165", |
||||
|
"Table properties": "\u8868\u306e\u8a73\u7d30\u8a2d\u5b9a", |
||||
|
"Delete table": "\u8868\u306e\u524a\u9664", |
||||
|
"Cell": "\u30bb\u30eb", |
||||
|
"Row": "\u884c", |
||||
|
"Column": "\u5217", |
||||
|
"Cell properties": "\u30bb\u30eb\u306e\u8a73\u7d30\u8a2d\u5b9a", |
||||
|
"Merge cells": "\u30bb\u30eb\u306e\u7d50\u5408", |
||||
|
"Split cell": "\u30bb\u30eb\u306e\u5206\u5272", |
||||
|
"Insert row before": "\u4e0a\u5074\u306b\u884c\u3092\u633f\u5165", |
||||
|
"Insert row after": "\u4e0b\u5074\u306b\u884c\u3092\u633f\u5165", |
||||
|
"Delete row": "\u884c\u306e\u524a\u9664", |
||||
|
"Row properties": "\u884c\u306e\u8a73\u7d30\u8a2d\u5b9a", |
||||
|
"Cut row": "\u884c\u306e\u5207\u308a\u53d6\u308a", |
||||
|
"Copy row": "\u884c\u306e\u30b3\u30d4\u30fc", |
||||
|
"Paste row before": "\u4e0a\u5074\u306b\u884c\u3092\u8cbc\u308a\u4ed8\u3051", |
||||
|
"Paste row after": "\u4e0b\u5074\u306b\u884c\u3092\u8cbc\u308a\u4ed8\u3051", |
||||
|
"Insert column before": "\u5de6\u5074\u306b\u5217\u3092\u633f\u5165", |
||||
|
"Insert column after": "\u53f3\u5074\u306b\u5217\u3092\u633f\u5165", |
||||
|
"Delete column": "\u5217\u306e\u524a\u9664", |
||||
|
"Cols": "\u5217\u6570", |
||||
|
"Rows": "\u884c\u6570", |
||||
|
"Width": "\u5e45", |
||||
|
"Height": "\u9ad8\u3055", |
||||
|
"Cell spacing": "\u30bb\u30eb\u306e\u9593\u9694", |
||||
|
"Cell padding": "\u30bb\u30eb\u5185\u4f59\u767d\uff08\u30d1\u30c7\u30a3\u30f3\u30b0\uff09", |
||||
|
"Show caption": "\u30ad\u30e3\u30d7\u30b7\u30e7\u30f3\u306e\u8868\u793a", |
||||
|
"Left": "\u5de6\u5bc4\u305b", |
||||
|
"Center": "\u4e2d\u592e\u63c3\u3048", |
||||
|
"Right": "\u53f3\u5bc4\u305b", |
||||
|
"Cell type": "\u30bb\u30eb\u30bf\u30a4\u30d7", |
||||
|
"Scope": "\u30b9\u30b3\u30fc\u30d7", |
||||
|
"Alignment": "\u914d\u7f6e", |
||||
|
"H Align": "\u6c34\u5e73\u65b9\u5411\u306e\u914d\u7f6e", |
||||
|
"V Align": "\u5782\u76f4\u65b9\u5411\u306e\u914d\u7f6e", |
||||
|
"Top": "\u4e0a", |
||||
|
"Middle": "\u4e2d\u592e", |
||||
|
"Bottom": "\u4e0b", |
||||
|
"Header cell": "\u30d8\u30c3\u30c0\u30fc\u30bb\u30eb", |
||||
|
"Row group": "\u884c\u30b0\u30eb\u30fc\u30d7", |
||||
|
"Column group": "\u5217\u30b0\u30eb\u30fc\u30d7", |
||||
|
"Row type": "\u884c\u30bf\u30a4\u30d7", |
||||
|
"Header": "\u30d8\u30c3\u30c0\u30fc", |
||||
|
"Body": "\u30dc\u30c7\u30a3\u30fc", |
||||
|
"Footer": "\u30d5\u30c3\u30bf\u30fc", |
||||
|
"Border color": "\u67a0\u7dda\u306e\u8272", |
||||
|
"Insert template...": "\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u633f\u5165..", |
||||
|
"Templates": "\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u540d", |
||||
|
"Template": "\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8", |
||||
|
"Text color": "\u30c6\u30ad\u30b9\u30c8\u306e\u8272", |
||||
|
"Background color": "\u80cc\u666f\u8272", |
||||
|
"Custom...": "\u30ab\u30b9\u30bf\u30e0...", |
||||
|
"Custom color": "\u30ab\u30b9\u30bf\u30e0\u30ab\u30e9\u30fc", |
||||
|
"No color": "\u30ab\u30e9\u30fc\u306a\u3057", |
||||
|
"Remove color": "\u8272\u8a2d\u5b9a\u3092\u89e3\u9664", |
||||
|
"Table of Contents": "\u76ee\u6b21", |
||||
|
"Show blocks": "\u6587\u7ae0\u306e\u533a\u5207\u308a\u3092\u70b9\u7dda\u3067\u8868\u793a", |
||||
|
"Show invisible characters": "\u4e0d\u53ef\u8996\u6587\u5b57\u3092\u8868\u793a", |
||||
|
"Word count": "\u6587\u5b57\u6570\u30ab\u30a6\u30f3\u30c8", |
||||
|
"Count": "\u30ab\u30a6\u30f3\u30c8", |
||||
|
"Document": "\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8", |
||||
|
"Selection": "\u9078\u629e", |
||||
|
"Words": "\u5358\u8a9e\u6570", |
||||
|
"Words: {0}": "\u5358\u8a9e\u6570: {0}", |
||||
|
"{0} words": "{0} \u30ef\u30fc\u30c9", |
||||
|
"File": "\u30d5\u30a1\u30a4\u30eb", |
||||
|
"Edit": "\u7de8\u96c6", |
||||
|
"Insert": "\u633f\u5165", |
||||
|
"View": "\u8868\u793a", |
||||
|
"Format": "\u66f8\u5f0f", |
||||
|
"Table": "\u8868", |
||||
|
"Tools": "\u30c4\u30fc\u30eb", |
||||
|
"Powered by {0}": "Powered by {0}", |
||||
|
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u66f8\u5f0f\u4ed8\u304d\u30c6\u30ad\u30b9\u30c8\u306e\u7de8\u96c6\u753b\u9762\u3002ALT-F9\u3067\u30e1\u30cb\u30e5\u30fc\u3001ALT-F10\u3067\u30c4\u30fc\u30eb\u30d0\u30fc\u3001ALT-0\u3067\u30d8\u30eb\u30d7\u304c\u8868\u793a\u3055\u308c\u307e\u3059\u3002", |
||||
|
"Image title": "\u753b\u50cf\u30bf\u30a4\u30c8\u30eb", |
||||
|
"Border width": "\u67a0\u7dda\u5e45", |
||||
|
"Border style": "\u67a0\u7dda\u30b9\u30bf\u30a4\u30eb", |
||||
|
"Error": "\u30a8\u30e9\u30fc", |
||||
|
"Warn": "\u8b66\u544a", |
||||
|
"Valid": "\u6709\u52b9", |
||||
|
"To open the popup, press Shift+Enter": "\u30dd\u30c3\u30d7\u30a2\u30c3\u30d7\u3092\u958b\u304f\u306b\u306f\u3001Shift+Enter\u3092\u62bc\u3057\u3066\u304f\u3060\u3055\u3044", |
||||
|
"Rich Text Area. Press ALT-0 for help.": "\u30ea\u30c3\u30c1\u30c6\u30ad\u30b9\u30c8\u30a8\u30ea\u30a2\u3002Alt-0\u3067\u30d8\u30eb\u30d7\u304c\u8868\u793a\u3055\u308c\u307e\u3059\u3002", |
||||
|
"System Font": "\u30b7\u30b9\u30c6\u30e0\u30d5\u30a9\u30f3\u30c8", |
||||
|
"Failed to upload image: {0}": "\u753b\u50cf{0}\u3092\u30a2\u30c3\u30d7\u30ed\u30fc\u30c9\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f", |
||||
|
"Failed to load plugin: {0} from url {1}": "URL{1}\u304b\u3089\u306e\u30d7\u30e9\u30b0\u30a4\u30f3{0}\u306e\u8aad\u307f\u8fbc\u307f\u306b\u5931\u6557\u3057\u307e\u3057\u305f", |
||||
|
"Failed to load plugin url: {0}": "\u30d7\u30e9\u30b0\u30a4\u30f3\u306eURL{0}\u3092\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3067\u3057\u305f", |
||||
|
"Failed to initialize plugin: {0}": "\u30d7\u30e9\u30b0\u30a4\u30f3{0}\u306e\u521d\u671f\u5316\u306b\u5931\u6557\u3057\u307e\u3057\u305f", |
||||
|
"example": "\u4f8b", |
||||
|
"Search": "\u691c\u7d22", |
||||
|
"All": "\u3059\u3079\u3066", |
||||
|
"Currency": "\u901a\u8ca8", |
||||
|
"Text": "\u30c6\u30ad\u30b9\u30c8", |
||||
|
"Quotations": "\u5f15\u7528", |
||||
|
"Mathematical": "\u6570\u5b66\u8a18\u53f7", |
||||
|
"Extended Latin": "\u30e9\u30c6\u30f3\u6587\u5b57\u62e1\u5f35", |
||||
|
"Symbols": "\u8a18\u53f7", |
||||
|
"Arrows": "\u77e2\u5370", |
||||
|
"User Defined": "\u30e6\u30fc\u30b6\u30fc\u5b9a\u7fa9", |
||||
|
"dollar sign": "\u30c9\u30eb\u8a18\u53f7", |
||||
|
"currency sign": "\u901a\u8ca8\u8a18\u53f7", |
||||
|
"euro-currency sign": "\u30e6\u30fc\u30ed\u8a18\u53f7", |
||||
|
"colon sign": "\u30b3\u30ed\u30f3\u8a18\u53f7", |
||||
|
"cruzeiro sign": "\u30af\u30eb\u30bc\u30a4\u30ed\u8a18\u53f7", |
||||
|
"french franc sign": "\u30d5\u30e9\u30f3\u30b9\u30d5\u30e9\u30f3\u8a18\u53f7", |
||||
|
"lira sign": "\u30ea\u30e9\u8a18\u53f7", |
||||
|
"mill sign": "\u30df\u30eb\u8a18\u53f7", |
||||
|
"naira sign": "\u30ca\u30a4\u30e9\u8a18\u53f7", |
||||
|
"peseta sign": "\u30da\u30bb\u30bf\u8a18\u53f7", |
||||
|
"rupee sign": "\u30eb\u30d4\u30fc\u8a18\u53f7", |
||||
|
"won sign": "\u30a6\u30a9\u30f3\u8a18\u53f7", |
||||
|
"new sheqel sign": "\u65b0\u30b7\u30a7\u30b1\u30eb\u8a18\u53f7", |
||||
|
"dong sign": "\u30c9\u30f3\u8a18\u53f7", |
||||
|
"kip sign": "\u30ad\u30fc\u30d7\u8a18\u53f7", |
||||
|
"tugrik sign": "\u30c8\u30a5\u30b0\u30eb\u30b0\u8a18\u53f7", |
||||
|
"drachma sign": "\u30c9\u30e9\u30af\u30de\u8a18\u53f7", |
||||
|
"german penny symbol": "\u30c9\u30a4\u30c4\u30da\u30cb\u30fc\u8a18\u53f7", |
||||
|
"peso sign": "\u30da\u30bd\u8a18\u53f7", |
||||
|
"guarani sign": "\u30ac\u30e9\u30cb\u8a18\u53f7", |
||||
|
"austral sign": "\u30a2\u30a6\u30b9\u30c8\u30e9\u30eb\u8a18\u53f7", |
||||
|
"hryvnia sign": "\u30d5\u30ea\u30f4\u30cb\u30e3\u8a18\u53f7", |
||||
|
"cedi sign": "\u30bb\u30c7\u30a3\u8a18\u53f7", |
||||
|
"livre tournois sign": "\u30c8\u30a5\u30fc\u30eb\u30dd\u30f3\u30c9\u8a18\u53f7", |
||||
|
"spesmilo sign": "\u30b9\u30da\u30b9\u30df\u30fc\u30ed\u8a18\u53f7", |
||||
|
"tenge sign": "\u30c6\u30f3\u30b2\u8a18\u53f7", |
||||
|
"indian rupee sign": "\u30a4\u30f3\u30c9\u30eb\u30d4\u30fc\u8a18\u53f7", |
||||
|
"turkish lira sign": "\u30c8\u30eb\u30b3\u30ea\u30e9\u8a18\u53f7", |
||||
|
"nordic mark sign": "\u5317\u6b27\u30de\u30eb\u30af\u8a18\u53f7", |
||||
|
"manat sign": "\u30de\u30ca\u30c8\u8a18\u53f7", |
||||
|
"ruble sign": "\u30eb\u30fc\u30d6\u30eb\u8a18\u53f7", |
||||
|
"yen character": "\u5186\u8a18\u53f7", |
||||
|
"yuan character": "\u4eba\u6c11\u5143\u8a18\u53f7", |
||||
|
"yuan character, in hong kong and taiwan": "\u9999\u6e2f\u304a\u3088\u3073\u53f0\u6e7e\u306b\u304a\u3051\u308b\u5143\u8a18\u53f7", |
||||
|
"yen\/yuan character variant one": "\u5186\/\u5143\u8a18\u53f7\u306e\u30d0\u30ea\u30a8\u30fc\u30b7\u30e7\u30f3", |
||||
|
"Loading emoticons...": "\u7d75\u6587\u5b57\u3092\u8aad\u307f\u8fbc\u3093\u3067\u3044\u307e\u3059...", |
||||
|
"Could not load emoticons": "\u7d75\u6587\u5b57\u304c\u8aad\u307f\u8fbc\u3081\u307e\u305b\u3093\u3067\u3057\u305f\u3002", |
||||
|
"People": "\u4eba", |
||||
|
"Animals and Nature": "\u52d5\u7269\u3068\u81ea\u7136", |
||||
|
"Food and Drink": "\u98df\u3079\u7269\u3068\u98f2\u307f\u7269", |
||||
|
"Activity": "\u884c\u52d5", |
||||
|
"Travel and Places": "\u65c5\u884c\u3068\u5834\u6240", |
||||
|
"Objects": "\u7269", |
||||
|
"Flags": "\u65d7", |
||||
|
"Characters": "\u6587\u5b57\u6570", |
||||
|
"Characters (no spaces)": "\u6587\u5b57\u6570 (\u30b9\u30da\u30fc\u30b9\u306a\u3057)", |
||||
|
"{0} characters": "{0}\u6587\u5b57", |
||||
|
"Error: Form submit field collision.": "\u30a8\u30e9\u30fc\uff1a\u30d5\u30a9\u30fc\u30e0\u9001\u4fe1\u30d5\u30a3\u30fc\u30eb\u30c9\u304c\u7af6\u5408\u3057\u3066\u3044\u307e\u3059\u3002", |
||||
|
"Error: No form element found.": "\u30a8\u30e9\u30fc\uff1a\u30d5\u30a9\u30fc\u30e0\u8981\u7d20\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002", |
||||
|
"Update": "\u66f4\u65b0", |
||||
|
"Color swatch": "\u8272\u306e\u898b\u672c", |
||||
|
"Turquoise": "\u30bf\u30fc\u30b3\u30a4\u30ba", |
||||
|
"Green": "\u30b0\u30ea\u30fc\u30f3", |
||||
|
"Blue": "\u30d6\u30eb\u30fc", |
||||
|
"Purple": "\u30d1\u30fc\u30d7\u30eb", |
||||
|
"Navy Blue": "\u30cd\u30a4\u30d3\u30fc", |
||||
|
"Dark Turquoise": "\u30c0\u30fc\u30af\u30bf\u30fc\u30b3\u30a4\u30ba", |
||||
|
"Dark Green": "\u30c0\u30fc\u30af\u30b0\u30ea\u30fc\u30f3", |
||||
|
"Medium Blue": "\u30e1\u30c7\u30a3\u30a2\u30e0\u30d6\u30eb\u30fc", |
||||
|
"Medium Purple": "\u30df\u30c7\u30a3\u30a2\u30e0\u30d1\u30fc\u30d7\u30eb", |
||||
|
"Midnight Blue": "\u30df\u30c3\u30c9\u30ca\u30a4\u30c8\u30d6\u30eb\u30fc", |
||||
|
"Yellow": "\u30a4\u30a8\u30ed\u30fc", |
||||
|
"Orange": "\u30aa\u30ec\u30f3\u30b8", |
||||
|
"Red": "\u30ec\u30c3\u30c9", |
||||
|
"Light Gray": "\u30e9\u30a4\u30c8\u30b0\u30ec\u30fc", |
||||
|
"Gray": "\u30b0\u30ec\u30fc", |
||||
|
"Dark Yellow": "\u30c0\u30fc\u30af\u30a4\u30a8\u30ed\u30fc", |
||||
|
"Dark Orange": "\u30c0\u30fc\u30af\u30aa\u30ec\u30f3\u30b8", |
||||
|
"Dark Red": "\u30c0\u30fc\u30af\u30ec\u30c3\u30c9", |
||||
|
"Medium Gray": "\u30df\u30c7\u30a3\u30a2\u30e0\u30b0\u30ec\u30fc", |
||||
|
"Dark Gray": "\u30c0\u30fc\u30af\u30b0\u30ec\u30fc", |
||||
|
"Light Green": "\u30e9\u30a4\u30c8\u30b0\u30ea\u30fc\u30f3", |
||||
|
"Light Yellow": "\u30e9\u30a4\u30c8\u30a4\u30a8\u30ed\u30fc", |
||||
|
"Light Red": "\u30e9\u30a4\u30c8\u30ec\u30c3\u30c9", |
||||
|
"Light Purple": "\u30e9\u30a4\u30c8\u30d1\u30fc\u30d7\u30eb", |
||||
|
"Light Blue": "\u30e9\u30a4\u30c8\u30d6\u30eb\u30fc", |
||||
|
"Dark Purple": "\u30c0\u30fc\u30af\u30d1\u30fc\u30d7\u30eb", |
||||
|
"Dark Blue": "\u30c0\u30fc\u30af\u30d6\u30eb\u30fc", |
||||
|
"Black": "\u30d6\u30e9\u30c3\u30af", |
||||
|
"White": "\u30db\u30ef\u30a4\u30c8", |
||||
|
"Switch to or from fullscreen mode": "\u30d5\u30eb\u30b9\u30af\u30ea\u30fc\u30f3\u30e2\u30fc\u30c9\u5207\u66ff", |
||||
|
"Open help dialog": "\u30d8\u30eb\u30d7\u30c0\u30a4\u30a2\u30ed\u30b0\u3092\u958b\u304f", |
||||
|
"history": "\u5c65\u6b74", |
||||
|
"styles": "\u30b9\u30bf\u30a4\u30eb", |
||||
|
"formatting": "\u66f8\u5f0f", |
||||
|
"alignment": "\u914d\u7f6e", |
||||
|
"indentation": "\u30a4\u30f3\u30c7\u30f3\u30c8", |
||||
|
"permanent pen": "\u86cd\u5149\u30da\u30f3", |
||||
|
"comments": "\u30b3\u30e1\u30f3\u30c8", |
||||
|
"Format Painter": "\u66f8\u5f0f\u306e\u30b3\u30d4\u30fc\/\u8cbc\u308a\u4ed8\u3051", |
||||
|
"Insert\/edit iframe": "iframe\u306e\u633f\u5165\/\u7de8\u96c6", |
||||
|
"Capitalization": "\u5927\u6587\u5b57\u5316", |
||||
|
"lowercase": "\u5c0f\u6587\u5b57", |
||||
|
"UPPERCASE": "\u5927\u6587\u5b57", |
||||
|
"Title Case": "\u30bf\u30a4\u30c8\u30eb\u6587\u5b57", |
||||
|
"Permanent Pen Properties": "\u86cd\u5149\u30da\u30f3\u306e\u30d7\u30ed\u30d1\u30c6\u30a3", |
||||
|
"Permanent pen properties...": "\u86cd\u5149\u30da\u30f3\u306e\u30d7\u30ed\u30d1\u30c6\u30a3...", |
||||
|
"Font": "\u30d5\u30a9\u30f3\u30c8", |
||||
|
"Size": "\u30b5\u30a4\u30ba", |
||||
|
"More...": "\u8a73\u7d30...", |
||||
|
"Spellcheck Language": "\u8a00\u8a9e\u306e\u30b9\u30da\u30eb\u30c1\u30a7\u30c3\u30af", |
||||
|
"Select...": "\u9078\u629e...", |
||||
|
"Preferences": "\u30d7\u30ea\u30d5\u30a1\u30ec\u30f3\u30b9", |
||||
|
"Yes": "\u306f\u3044", |
||||
|
"No": "\u3044\u3044\u3048", |
||||
|
"Keyboard Navigation": "\u30ad\u30fc\u30dc\u30fc\u30c9\u30ca\u30d3\u30b2\u30fc\u30b7\u30e7\u30f3", |
||||
|
"Version": "\u30d0\u30fc\u30b8\u30e7\u30f3", |
||||
|
"Anchor": "\u30a2\u30f3\u30ab\u30fc\uff08\u30ea\u30f3\u30af\u306e\u5230\u9054\u70b9\uff09", |
||||
|
"Special character": "\u7279\u6b8a\u6587\u5b57", |
||||
|
"Code sample": "\u30b3\u30fc\u30c9\u30b5\u30f3\u30d7\u30eb", |
||||
|
"Color": "\u30ab\u30e9\u30fc", |
||||
|
"Emoticons": "\u7d75\u6587\u5b57", |
||||
|
"Document properties": "\u30c9\u30ad\u30e5\u30e1\u30f3\u30c8\u306e\u30d7\u30ed\u30d1\u30c6\u30a3", |
||||
|
"Image": "\u753b\u50cf", |
||||
|
"Insert link": "\u30ea\u30f3\u30af", |
||||
|
"Target": "\u30bf\u30fc\u30b2\u30c3\u30c8\u5c5e\u6027", |
||||
|
"Link": "\u30ea\u30f3\u30af", |
||||
|
"Poster": "\u4ee3\u66ff\u753b\u50cf\u306e\u5834\u6240", |
||||
|
"Media": "\u30e1\u30c7\u30a3\u30a2", |
||||
|
"Print": "\u5370\u5237", |
||||
|
"Prev": "\u524d", |
||||
|
"Find and replace": "\u691c\u7d22\u3068\u7f6e\u304d\u63db\u3048", |
||||
|
"Whole words": "\u5358\u8a9e\u5358\u4f4d\u3067\u691c\u7d22\u3059\u308b", |
||||
|
"Spellcheck": "\u30b9\u30da\u30eb\u30c1\u30a7\u30c3\u30af", |
||||
|
"Caption": "\u8868\u984c", |
||||
|
"Insert template": "\u30c6\u30f3\u30d7\u30ec\u30fc\u30c8\u306e\u633f\u5165" |
||||
|
}); |
||||
@ -0,0 +1,419 @@ |
|||||
|
tinymce.addI18n('ko_KR', { |
||||
|
"Redo": "\ub2e4\uc2dc \uc2e4\ud589", |
||||
|
"Undo": "\uc2e4\ud589 \ucde8\uc18c", |
||||
|
"Cut": "\uc798\ub77c\ub0b4\uae30", |
||||
|
"Copy": "\ubcf5\uc0ac", |
||||
|
"Paste": "\ubd99\uc5ec\ub123\uae30", |
||||
|
"Select all": "\uc804\uccb4\uc120\ud0dd", |
||||
|
"New document": "\uc0c8 \ubb38\uc11c", |
||||
|
"Ok": "\ud655\uc778", |
||||
|
"Cancel": "\ucde8\uc18c", |
||||
|
"Visual aids": "\uc2dc\uac01\uad50\uc7ac", |
||||
|
"Bold": "\uad75\uac8c", |
||||
|
"Italic": "\uae30\uc6b8\uc784\uaf34", |
||||
|
"Underline": "\ubc11\uc904", |
||||
|
"Strikethrough": "\ucde8\uc18c\uc120", |
||||
|
"Superscript": "\uc704 \ucca8\uc790", |
||||
|
"Subscript": "\uc544\ub798 \ucca8\uc790", |
||||
|
"Clear formatting": "\uc11c\uc2dd \uc9c0\uc6b0\uae30", |
||||
|
"Align left": "\uc67c\ucabd \ub9de\ucda4", |
||||
|
"Align center": "\uac00\uc6b4\ub370 \ub9de\ucda4", |
||||
|
"Align right": "\uc624\ub978\ucabd \ub9de\ucda4", |
||||
|
"Justify": "\uc591\ucabd \ub9de\ucda4", |
||||
|
"Bullet list": "\uae00\uba38\ub9ac \uae30\ud638 \ubaa9\ub85d", |
||||
|
"Numbered list": "\ubc88\ud638 \ub9e4\uae30\uae30 \ubaa9\ub85d", |
||||
|
"Decrease indent": "\ub0b4\uc5b4\uc4f0\uae30", |
||||
|
"Increase indent": "\ub4e4\uc5ec\uc4f0\uae30", |
||||
|
"Close": "\ub2eb\uae30", |
||||
|
"Formats": "\uc11c\uc2dd", |
||||
|
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\ube0c\ub77c\uc6b0\uc800\uac00 \ud074\ub9bd\ubcf4\ub4dc \uc811\uadfc\uc744 \uc9c0\uc6d0\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. Ctrl+X\/C\/V \ub2e8\ucd95\ud0a4\ub97c \uc774\uc6a9\ud558\uc2ed\uc2dc\uc624.", |
||||
|
"Headers": "\uba38\ub9ac\uae00", |
||||
|
"Header 1": "\uba38\ub9ac\uae00 1", |
||||
|
"Header 2": "\uba38\ub9ac\uae00 2", |
||||
|
"Header 3": "\uba38\ub9ac\uae00 3", |
||||
|
"Header 4": "\uba38\ub9ac\uae00 4", |
||||
|
"Header 5": "\uba38\ub9ac\uae00 5", |
||||
|
"Header 6": "\uba38\ub9ac\uae00 6", |
||||
|
"Headings": "\uc81c\ubaa9", |
||||
|
"Heading 1": "\uc81c\ubaa9 1", |
||||
|
"Heading 2": "\uc81c\ubaa9 2", |
||||
|
"Heading 3": "\uc81c\ubaa9 3", |
||||
|
"Heading 4": "\uc81c\ubaa9 4", |
||||
|
"Heading 5": "\uc81c\ubaa9 5", |
||||
|
"Heading 6": "\uc81c\ubaa9 6", |
||||
|
"Preformatted": "\uc11c\uc2dd \ubbf8\uc124\uc815", |
||||
|
"Div": "Div", |
||||
|
"Pre": "Pre", |
||||
|
"Code": "\ucf54\ub4dc", |
||||
|
"Paragraph": "\ub2e8\ub77d", |
||||
|
"Blockquote": "\uc778\uc6a9\ubb38", |
||||
|
"Inline": "\uc778\ub77c\uc778", |
||||
|
"Blocks": "\ube14\ub85d", |
||||
|
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\uc2a4\ud0c0\uc77c\ubcf5\uc0ac \ub044\uae30. \uc774 \uc635\uc158\uc744 \ub044\uae30 \uc804\uc5d0\ub294 \ubcf5\uc0ac \uc2dc, \uc2a4\ud0c0\uc77c\uc774 \ubcf5\uc0ac\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.", |
||||
|
"Fonts": "\uae00\uaf34", |
||||
|
"Font Sizes": "\uae00\uaf34 \ud06c\uae30", |
||||
|
"Class": "\ud074\ub798\uc2a4", |
||||
|
"Browse for an image": "\uc774\ubbf8\uc9c0 \ucc3e\uae30", |
||||
|
"OR": "\ub610\ub294", |
||||
|
"Drop an image here": "\uc5ec\uae30\ub85c \uc774\ubbf8\uc9c0 \ub04c\uc5b4\uc624\uae30", |
||||
|
"Upload": "\uc5c5\ub85c\ub4dc", |
||||
|
"Block": "\ube14\ub85d", |
||||
|
"Align": "\uc815\ub82c", |
||||
|
"Default": "\uae30\ubcf8", |
||||
|
"Circle": "\uc6d0", |
||||
|
"Disc": "\uc6d0\ubc18", |
||||
|
"Square": "\uc0ac\uac01", |
||||
|
"Lower Alpha": "\uc54c\ud30c\ubcb3 \uc18c\ubb38\uc790", |
||||
|
"Lower Greek": "\uadf8\ub9ac\uc2a4\uc5b4 \uc18c\ubb38\uc790", |
||||
|
"Lower Roman": "\ub85c\ub9c8\uc790 \uc18c\ubb38\uc790", |
||||
|
"Upper Alpha": "\uc54c\ud30c\ubcb3 \uc18c\ubb38\uc790", |
||||
|
"Upper Roman": "\ub85c\ub9c8\uc790 \ub300\ubb38\uc790", |
||||
|
"Anchor...": "\uc575\ucee4...", |
||||
|
"Name": "\uc774\ub984", |
||||
|
"Id": "\uc544\uc774\ub514", |
||||
|
"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\uc544\uc774\ub514\ub294 \ubb38\uc790, \uc22b\uc790, \ub300\uc2dc, \uc810, \ucf5c\ub860 \ub610\ub294 \ubc11\uc904\ub85c \uc2dc\uc791\ud574\uc57c\ud569\ub2c8\ub2e4.", |
||||
|
"You have unsaved changes are you sure you want to navigate away?": "\uc800\uc7a5\ud558\uc9c0 \uc54a\uc740 \uc815\ubcf4\uac00 \uc788\uc2b5\ub2c8\ub2e4. \uc774 \ud398\uc774\uc9c0\ub97c \ubc97\uc5b4\ub098\uc2dc\uaca0\uc2b5\ub2c8\uae4c?", |
||||
|
"Restore last draft": "\ub9c8\uc9c0\ub9c9 \ucd08\uc548 \ubcf5\uc6d0", |
||||
|
"Special character...": "\ud2b9\uc218 \ubb38\uc790...", |
||||
|
"Source code": "\uc18c\uc2a4\ucf54\ub4dc", |
||||
|
"Insert\/Edit code sample": "\ucf54\ub4dc\uc0d8\ud50c \uc0bd\uc785\/\ud3b8\uc9d1", |
||||
|
"Language": "\uc5b8\uc5b4", |
||||
|
"Code sample...": "\ucf54\ub4dc \uc0d8\ud50c...", |
||||
|
"Color Picker": "\uc0c9 \uc120\ud0dd\uae30", |
||||
|
"R": "R", |
||||
|
"G": "G", |
||||
|
"B": "B", |
||||
|
"Left to right": "\uc67c\ucabd\uc5d0\uc11c \uc624\ub978\ucabd", |
||||
|
"Right to left": "\uc624\ub978\ucabd\uc5d0\uc11c \uc67c\ucabd", |
||||
|
"Emoticons...": "\uc774\ubaa8\ud2f0\ucf58...", |
||||
|
"Metadata and Document Properties": "\uba54\ud0c0\ub370\uc774\ud130\uc640 \ubb38\uc11c \uc18d\uc131", |
||||
|
"Title": "\uc81c\ubaa9", |
||||
|
"Keywords": "\ud0a4\uc6cc\ub4dc", |
||||
|
"Description": "\uc124\uba85", |
||||
|
"Robots": "\ub85c\ubd07", |
||||
|
"Author": "\uc800\uc790", |
||||
|
"Encoding": "\uc778\ucf54\ub529", |
||||
|
"Fullscreen": "\uc804\uccb4\ud654\uba74", |
||||
|
"Action": "\ub3d9\uc791", |
||||
|
"Shortcut": "\ub2e8\ucd95\ud0a4", |
||||
|
"Help": "\ub3c4\uc6c0\ub9d0", |
||||
|
"Address": "\uc8fc\uc18c", |
||||
|
"Focus to menubar": "\uba54\ub274\uc5d0 \ud3ec\ucee4\uc2a4", |
||||
|
"Focus to toolbar": "\ud234\ubc14\uc5d0 \ud3ec\ucee4\uc2a4", |
||||
|
"Focus to element path": "element path\uc5d0 \ud3ec\ucee4\uc2a4", |
||||
|
"Focus to contextual toolbar": "\ucf04\ud14d\uc2a4\ud2b8 \ud234\ubc14\uc5d0 \ud3ec\ucee4\uc2a4", |
||||
|
"Insert link (if link plugin activated)": "\ub9c1\ud06c \uc0bd\uc785 (link \ud50c\ub7ec\uadf8\uc778\uc774 \ud65c\uc131\ud654\ub41c \uc0c1\ud0dc\uc5d0\uc11c)", |
||||
|
"Save (if save plugin activated)": "\uc800\uc7a5 (save \ud50c\ub7ec\uadf8\uc778\uc774 \ud65c\uc131\ud654\ub41c \uc0c1\ud0dc\uc5d0\uc11c)", |
||||
|
"Find (if searchreplace plugin activated)": "\ucc3e\uae30(searchreplace \ud50c\ub7ec\uadf8\uc778\uc774 \ud65c\uc131\ud654\ub41c \uc0c1\ud0dc\uc5d0\uc11c)", |
||||
|
"Plugins installed ({0}):": "\uc124\uce58\ub41c \ud50c\ub7ec\uadf8\uc778 ({0}):", |
||||
|
"Premium plugins:": "\uace0\uae09 \ud50c\ub7ec\uadf8\uc778", |
||||
|
"Learn more...": "\uc880 \ub354 \uc0b4\ud3b4\ubcf4\uae30", |
||||
|
"You are using {0}": "{0}\ub97c \uc0ac\uc6a9\uc911", |
||||
|
"Plugins": "\ud50c\ub7ec\uadf8\uc778", |
||||
|
"Handy Shortcuts": "\ub2e8\ucd95\ud0a4", |
||||
|
"Horizontal line": "\uac00\ub85c", |
||||
|
"Insert\/edit image": "\uc774\ubbf8\uc9c0 \uc0bd\uc785\/\uc218\uc815", |
||||
|
"Image description": "\uc774\ubbf8\uc9c0 \uc124\uba85", |
||||
|
"Source": "\uc18c\uc2a4", |
||||
|
"Dimensions": "\ud06c\uae30", |
||||
|
"Constrain proportions": "\uc791\uc5c5 \uc81c\ud55c", |
||||
|
"General": "\uc77c\ubc18", |
||||
|
"Advanced": "\uace0\uae09", |
||||
|
"Style": "\uc2a4\ud0c0\uc77c", |
||||
|
"Vertical space": "\uc218\uc9c1 \uacf5\ubc31", |
||||
|
"Horizontal space": "\uc218\ud3c9 \uacf5\ubc31", |
||||
|
"Border": "\ud14c\ub450\ub9ac", |
||||
|
"Insert image": "\uc774\ubbf8\uc9c0 \uc0bd\uc785", |
||||
|
"Image...": "\uc774\ubbf8\uc9c0...", |
||||
|
"Image list": "\uc774\ubbf8\uc9c0 \ubaa9\ub85d", |
||||
|
"Rotate counterclockwise": "\uc2dc\uacc4\ubc18\ub300\ubc29\ud5a5\uc73c\ub85c \ud68c\uc804", |
||||
|
"Rotate clockwise": "\uc2dc\uacc4\ubc29\ud5a5\uc73c\ub85c \ud68c\uc804", |
||||
|
"Flip vertically": "\uc218\uc9c1 \ub4a4\uc9d1\uae30", |
||||
|
"Flip horizontally": "\uc218\ud3c9 \ub4a4\uc9d1\uae30", |
||||
|
"Edit image": "\uc774\ubbf8\uc9c0 \ud3b8\uc9d1", |
||||
|
"Image options": "\uc774\ubbf8\uc9c0 \uc635\uc158", |
||||
|
"Zoom in": "\ud655\ub300", |
||||
|
"Zoom out": "\ucd95\uc18c", |
||||
|
"Crop": "\uc790\ub974\uae30", |
||||
|
"Resize": "\ud06c\uae30 \uc870\uc808", |
||||
|
"Orientation": "\ubc29\ud5a5", |
||||
|
"Brightness": "\ubc1d\uae30", |
||||
|
"Sharpen": "\uc120\uba85\ud558\uac8c", |
||||
|
"Contrast": "\ub300\ube44", |
||||
|
"Color levels": "\uc0c9\uc0c1\ub808\ubca8", |
||||
|
"Gamma": "\uac10\ub9c8", |
||||
|
"Invert": "\ubc18\uc804", |
||||
|
"Apply": "\uc801\uc6a9", |
||||
|
"Back": "\ub4a4\ub85c", |
||||
|
"Insert date\/time": "\ub0a0\uc9dc\/\uc2dc\uac04\uc0bd\uc785", |
||||
|
"Date\/time": "\ub0a0\uc9dc\/\uc2dc\uac04", |
||||
|
"Insert\/Edit Link": "\ub9c1\ud06c \uc0bd\uc785\/\ud3b8\uc9d1", |
||||
|
"Insert\/edit link": "\ub9c1\ud06c \uc0bd\uc785\/\uc218\uc815", |
||||
|
"Text to display": "\ubcf8\ubb38", |
||||
|
"Url": "\uc8fc\uc18c", |
||||
|
"Open link in...": "...\uc5d0\uc11c \ub9c1\ud06c \uc5f4\uae30", |
||||
|
"Current window": "\ud604\uc7ac \ucc3d", |
||||
|
"None": "\uc5c6\uc74c", |
||||
|
"New window": "\uc0c8\ucc3d", |
||||
|
"Remove link": "\ub9c1\ud06c\uc0ad\uc81c", |
||||
|
"Anchors": "\ucc45\uac08\ud53c", |
||||
|
"Link...": "\ub9c1\ud06c...", |
||||
|
"Paste or type a link": "\ub9c1\ud06c\ub97c \ubd99\uc5ec\ub123\uac70\ub098 \uc785\ub825\ud558\uc138\uc694", |
||||
|
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\ud604\uc7ac E-mail\uc8fc\uc18c\ub97c \uc785\ub825\ud558\uc168\uc2b5\ub2c8\ub2e4. E-mail \uc8fc\uc18c\uc5d0 \ub9c1\ud06c\ub97c \uac78\uae4c\uc694?", |
||||
|
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\ud604\uc7ac \uc6f9\uc0ac\uc774\ud2b8 \uc8fc\uc18c\ub97c \uc785\ub825\ud558\uc168\uc2b5\ub2c8\ub2e4. \ud574\ub2f9 \uc8fc\uc18c\uc5d0 \ub9c1\ud06c\ub97c \uac78\uae4c\uc694?", |
||||
|
"Link list": "\ub9c1\ud06c \ub9ac\uc2a4\ud2b8", |
||||
|
"Insert video": "\ube44\ub514\uc624 \uc0bd\uc785", |
||||
|
"Insert\/edit video": "\ube44\ub514\uc624 \uc0bd\uc785\/\uc218\uc815", |
||||
|
"Insert\/edit media": "\ubbf8\ub514\uc5b4 \uc0bd\uc785\/\uc218\uc815", |
||||
|
"Alternative source": "\ub300\uccb4 \uc18c\uc2a4", |
||||
|
"Alternative source URL": "\ub300\uccb4 \uc6d0\ubcf8 URL", |
||||
|
"Media poster (Image URL)": "\ub300\ud45c \uc774\ubbf8\uc9c0(\uc774\ubbf8\uc9c0 URL)", |
||||
|
"Paste your embed code below:": "\uc544\ub798\uc5d0 \ucf54\ub4dc\ub97c \ubd99\uc5ec\ub123\uc73c\uc138\uc694:", |
||||
|
"Embed": "\uc0bd\uc785", |
||||
|
"Media...": "\ubbf8\ub514\uc5b4...", |
||||
|
"Nonbreaking space": "\ub744\uc5b4\uc4f0\uae30", |
||||
|
"Page break": "\ud398\uc774\uc9c0 \uad6c\ubd84\uc790", |
||||
|
"Paste as text": "\ud14d\uc2a4\ud2b8\ub85c \ubd99\uc5ec\ub123\uae30", |
||||
|
"Preview": "\ubbf8\ub9ac\ubcf4\uae30", |
||||
|
"Print...": "\uc778\uc1c4...", |
||||
|
"Save": "\uc800\uc7a5", |
||||
|
"Find": "\ucc3e\uae30", |
||||
|
"Replace with": "\uad50\uccb4", |
||||
|
"Replace": "\uad50\uccb4", |
||||
|
"Replace all": "\uc804\uccb4 \uad50\uccb4", |
||||
|
"Previous": "\uc774\uc804", |
||||
|
"Next": "\ub2e4\uc74c", |
||||
|
"Find and replace...": "\ucc3e\uae30 \ubc0f \ubc14\uafb8\uae30...", |
||||
|
"Could not find the specified string.": "\ubb38\uc790\ub97c \ucc3e\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.", |
||||
|
"Match case": "\ub300\uc18c\ubb38\uc790 \uc77c\uce58", |
||||
|
"Find whole words only": "\ubaa8\ub450 \uc77c\uce58\ud558\ub294 \ubb38\uc790 \ucc3e\uae30", |
||||
|
"Spell check": "\ub9de\ucda4\ubc95 \uac80\uc0ac", |
||||
|
"Ignore": "\ubb34\uc2dc", |
||||
|
"Ignore all": "\uc804\uccb4\ubb34\uc2dc", |
||||
|
"Finish": "\uc644\ub8cc", |
||||
|
"Add to Dictionary": "\uc0ac\uc804\uc5d0 \ucd94\uac00", |
||||
|
"Insert table": "\ud14c\uc774\ube14 \uc0bd\uc785", |
||||
|
"Table properties": "\ud14c\uc774\ube14 \uc18d\uc131", |
||||
|
"Delete table": "\ud14c\uc774\ube14 \uc0ad\uc81c", |
||||
|
"Cell": "\uc140", |
||||
|
"Row": "\uc5f4", |
||||
|
"Column": "\ud589", |
||||
|
"Cell properties": "\uc140 \uc18d", |
||||
|
"Merge cells": "\uc140 \ud569\uce58\uae30", |
||||
|
"Split cell": "\uc140 \ub098\ub204\uae30", |
||||
|
"Insert row before": "\uc774\uc804\uc5d0 \ud589 \uc0bd\uc785", |
||||
|
"Insert row after": "\ub2e4\uc74c\uc5d0 \ud589 \uc0bd\uc785", |
||||
|
"Delete row": "\ud589 \uc9c0\uc6b0\uae30", |
||||
|
"Row properties": "\ud589 \uc18d\uc131", |
||||
|
"Cut row": "\ud589 \uc798\ub77c\ub0b4\uae30", |
||||
|
"Copy row": "\ud589 \ubcf5\uc0ac", |
||||
|
"Paste row before": "\uc774\uc804\uc5d0 \ud589 \ubd99\uc5ec\ub123\uae30", |
||||
|
"Paste row after": "\ub2e4\uc74c\uc5d0 \ud589 \ubd99\uc5ec\ub123\uae30", |
||||
|
"Insert column before": "\uc774\uc804\uc5d0 \ud589 \uc0bd\uc785", |
||||
|
"Insert column after": "\ub2e4\uc74c\uc5d0 \uc5f4 \uc0bd\uc785", |
||||
|
"Delete column": "\uc5f4 \uc9c0\uc6b0\uae30", |
||||
|
"Cols": "\uc5f4", |
||||
|
"Rows": "\ud589", |
||||
|
"Width": "\ub113\uc774", |
||||
|
"Height": "\ub192\uc774", |
||||
|
"Cell spacing": "\uc140 \uac04\uaca9", |
||||
|
"Cell padding": "\uc140 \uc548\ucabd \uc5ec\ubc31", |
||||
|
"Show caption": "\ucea1\uc158 \ud45c\uc2dc", |
||||
|
"Left": "\uc67c\ucabd", |
||||
|
"Center": "\uac00\uc6b4\ub370", |
||||
|
"Right": "\uc624\ub978\ucabd", |
||||
|
"Cell type": "\uc140 \ud0c0\uc785", |
||||
|
"Scope": "\ubc94\uc704", |
||||
|
"Alignment": "\uc815\ub82c", |
||||
|
"H Align": "\uac00\ub85c \uc815\ub82c", |
||||
|
"V Align": "\uc138\ub85c \uc815\ub82c", |
||||
|
"Top": "\uc0c1\ub2e8", |
||||
|
"Middle": "\uc911\uac04", |
||||
|
"Bottom": "\ud558\ub2e8", |
||||
|
"Header cell": "\ud5e4\ub354 \uc140", |
||||
|
"Row group": "\ud589 \uadf8\ub8f9", |
||||
|
"Column group": "\uc5f4 \uadf8\ub8f9", |
||||
|
"Row type": "\ud589 \ud0c0\uc785", |
||||
|
"Header": "\ud5e4\ub354", |
||||
|
"Body": "\ubc14\ub514", |
||||
|
"Footer": "\ud478\ud130", |
||||
|
"Border color": "\ud14c\ub450\ub9ac \uc0c9", |
||||
|
"Insert template...": "\ud15c\ud50c\ub9bf \uc0bd\uc785...", |
||||
|
"Templates": "\ud15c\ud50c\ub9bf", |
||||
|
"Template": "\ud15c\ud50c\ub9bf", |
||||
|
"Text color": "\ubb38\uc790 \uc0c9\uae54", |
||||
|
"Background color": "\ubc30\uacbd\uc0c9", |
||||
|
"Custom...": "\uc9c1\uc811 \uc0c9\uae54 \uc9c0\uc815\ud558\uae30", |
||||
|
"Custom color": "\uc9c1\uc811 \uc9c0\uc815\ud55c \uc0c9\uae54", |
||||
|
"No color": "\uc0c9\uc0c1 \uc5c6\uc74c", |
||||
|
"Remove color": "\uc0c9 \uc81c\uac70", |
||||
|
"Table of Contents": "\ubaa9\ucc28", |
||||
|
"Show blocks": "\ube14\ub7ed \ubcf4\uc5ec\uc8fc\uae30", |
||||
|
"Show invisible characters": "\uc548\ubcf4\uc774\ub294 \ubb38\uc790 \ubcf4\uc774\uae30", |
||||
|
"Word count": "\ub2e8\uc5b4 \uc218", |
||||
|
"Count": "\uac1c\uc218", |
||||
|
"Document": "\ubb38\uc11c", |
||||
|
"Selection": "\uc120\ud0dd", |
||||
|
"Words": "\ub2e8\uc5b4", |
||||
|
"Words: {0}": "\ub2e8\uc5b4: {0}", |
||||
|
"{0} words": "{0} \ub2e8\uc5b4", |
||||
|
"File": "\ud30c\uc77c", |
||||
|
"Edit": "\uc218\uc815", |
||||
|
"Insert": "\uc0bd\uc785", |
||||
|
"View": "\ubcf4\uae30", |
||||
|
"Format": "\ud3ec\ub9f7", |
||||
|
"Table": "\ud14c\uc774\ube14", |
||||
|
"Tools": "\ub3c4\uad6c", |
||||
|
"Powered by {0}": "Powered by {0}", |
||||
|
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\uc11c\uc2dd \uc788\ub294 \ud14d\uc2a4\ud2b8 \ud3b8\uc9d1\uae30 \uc785\ub2c8\ub2e4. ALT-F9\ub97c \ub204\ub974\uba74 \uba54\ub274, ALT-F10\ub97c \ub204\ub974\uba74 \ud234\ubc14, ALT-0\uc744 \ub204\ub974\uba74 \ub3c4\uc6c0\ub9d0\uc744 \ubcfc \uc218 \uc788\uc2b5\ub2c8\ub2e4.", |
||||
|
"Image title": "\uc774\ubbf8\uc9c0 \uc81c\ubaa9", |
||||
|
"Border width": "\ud14c\ub450\ub9ac \ub450\uaed8", |
||||
|
"Border style": "\ud14c\ub450\ub9ac \uc2a4\ud0c0\uc77c", |
||||
|
"Error": "\uc624\ub958", |
||||
|
"Warn": "\uacbd\uace0", |
||||
|
"Valid": "\uc720\ud6a8\ud568", |
||||
|
"To open the popup, press Shift+Enter": "\ud31d\uc5c5\uc744 \uc5f4\ub824\uba74 Shift+Enter\ub97c \ub204\ub974\uc2ed\uc2dc\uc624.", |
||||
|
"Rich Text Area. Press ALT-0 for help.": "\uc11c\uc2dd \uc788\ub294 \ud14d\uc2a4\ud2b8 \uc601\uc5ed. ALT-0\uc744 \ub204\ub974\uba74 \ub3c4\uc6c0\ub9d0\uc744 \ubcfc \uc218 \uc788\uc2b5\ub2c8\ub2e4.", |
||||
|
"System Font": "\uc2dc\uc2a4\ud15c \uae00\uaf34", |
||||
|
"Failed to upload image: {0}": "\uc774\ubbf8\uc9c0 \uc5c5\ub85c\ub4dc \uc2e4\ud328: {0}", |
||||
|
"Failed to load plugin: {0} from url {1}": "\ud50c\ub7ec\uadf8\uc778 \ub85c\ub4dc \uc2e4\ud328: URL: {1}\uc5d0\uc11c\uc758 {0}", |
||||
|
"Failed to load plugin url: {0}": "\ud50c\ub7ec\uadf8\uc778 URL \ub85c\ub4dc \uc2e4\ud328: {0}", |
||||
|
"Failed to initialize plugin: {0}": "\ud50c\ub7ec\uadf8\uc778 \ucd08\uae30\ud654 \uc2e4\ud328: {0}", |
||||
|
"example": "\uc608\uc81c", |
||||
|
"Search": "\uac80\uc0c9", |
||||
|
"All": "\ubaa8\ub450", |
||||
|
"Currency": "\ud1b5\ud654", |
||||
|
"Text": "\ud14d\uc2a4\ud2b8", |
||||
|
"Quotations": "\uc778\uc6a9\ubb38", |
||||
|
"Mathematical": "\uc218\ud559", |
||||
|
"Extended Latin": "\ud655\uc7a5 \ub77c\ud2f4\uc5b4", |
||||
|
"Symbols": "\uae30\ud638", |
||||
|
"Arrows": "\ud654\uc0b4\ud45c", |
||||
|
"User Defined": "\uc0ac\uc6a9\uc790 \uc815\uc758", |
||||
|
"dollar sign": "\ub2ec\ub7ec \uae30\ud638", |
||||
|
"currency sign": "\ud1b5\ud654 \uae30\ud638", |
||||
|
"euro-currency sign": "\uc720\ub85c\ud654 \uae30\ud638", |
||||
|
"colon sign": "\ucf5c\ub860 \uae30\ud638", |
||||
|
"cruzeiro sign": "\ud06c\ub8e8\uc81c\uc774\ub8e8 \uae30\ud638", |
||||
|
"french franc sign": "\ud504\ub791\uc2a4 \ud504\ub791 \uae30\ud638", |
||||
|
"lira sign": "\ub9ac\ub77c \uae30\ud638", |
||||
|
"mill sign": "\ubc00 \uae30\ud638", |
||||
|
"naira sign": "\ub098\uc774\ub77c \uae30\ud638", |
||||
|
"peseta sign": "\ud398\uc138\ud0c0 \uae30\ud638", |
||||
|
"rupee sign": "\ub8e8\ud53c \uae30\ud638", |
||||
|
"won sign": "\uc6d0 \uae30\ud638", |
||||
|
"new sheqel sign": "\ub274 \uc138\ucf08 \uae30\ud638", |
||||
|
"dong sign": "\ub3d9 \uae30\ud638", |
||||
|
"kip sign": "\ud0b5 \uae30\ud638", |
||||
|
"tugrik sign": "\ud22c\uadf8\ub9ac\ud06c \uae30\ud638", |
||||
|
"drachma sign": "\ub4dc\ub77c\ud06c\ub9c8 \uae30\ud638", |
||||
|
"german penny symbol": "\ub3c5\uc77c \ud398\ub2c8 \uae30\ud638", |
||||
|
"peso sign": "\ud398\uc18c \uae30\ud638", |
||||
|
"guarani sign": "\uacfc\ub77c\ub2c8 \uae30\ud638", |
||||
|
"austral sign": "\uc544\uc6b0\uc2a4\ud2b8\ub784 \uae30\ud638", |
||||
|
"hryvnia sign": "\uadf8\ub9ac\ube0c\ub098 \uae30\ud638", |
||||
|
"cedi sign": "\uc138\ub514 \uae30\ud638", |
||||
|
"livre tournois sign": "\ub9ac\ube0c\ub974 \ud2b8\ub974\ub204\uc544 \uae30\ud638", |
||||
|
"spesmilo sign": "\uc2a4\ud398\uc2a4\ubc00\ub85c \uae30\ud638", |
||||
|
"tenge sign": "\ud161\uac8c \uae30\ud638", |
||||
|
"indian rupee sign": "\uc778\ub3c4 \ub8e8\ud53c \uae30\ud638", |
||||
|
"turkish lira sign": "\ud130\ud0a4 \ub9ac\ub77c \uae30\ud638", |
||||
|
"nordic mark sign": "\ub178\ub974\ub515 \ub9c8\ub974\ud06c \uae30\ud638", |
||||
|
"manat sign": "\ub9c8\ub098\ud2b8 \uae30\ud638", |
||||
|
"ruble sign": "\ub8e8\ube14 \uae30\ud638", |
||||
|
"yen character": "\uc5d4 \uae30\ud638", |
||||
|
"yuan character": "\uc704\uc548 \uae30\ud638", |
||||
|
"yuan character, in hong kong and taiwan": "\ub300\ub9cc \uc704\uc548 \uae30\ud638", |
||||
|
"yen\/yuan character variant one": "\uc5d4\/\uc704\uc548 \ubb38\uc790 \ubcc0\ud615", |
||||
|
"Loading emoticons...": "\uc774\ubaa8\ud2f0\ucf58 \ubd88\ub7ec\uc624\ub294 \uc911...", |
||||
|
"Could not load emoticons": "\uc774\ubaa8\ud2f0\ucf58\uc744 \ubd88\ub7ec\uc62c \uc218 \uc5c6\uc74c", |
||||
|
"People": "\uc0ac\ub78c", |
||||
|
"Animals and Nature": "\ub3d9\ubb3c\uacfc \uc790\uc5f0", |
||||
|
"Food and Drink": "\uc74c\uc2dd\uacfc \uc74c\ub8cc", |
||||
|
"Activity": "\ud65c\ub3d9", |
||||
|
"Travel and Places": "\uc5ec\ud589\uacfc \uc7a5\uc18c", |
||||
|
"Objects": "\ubb3c\uac74", |
||||
|
"Flags": "\uae43\ubc1c", |
||||
|
"Characters": "\ubb38\uc790", |
||||
|
"Characters (no spaces)": "\ubb38\uc790(\uacf5\ubc31 \uc5c6\uc74c)", |
||||
|
"{0} characters": "{0} \ubb38\uc790", |
||||
|
"Error: Form submit field collision.": "\uc624\ub958: \uc591\uc2dd \uc81c\ucd9c \ud544\ub4dc \ubd88\uc77c\uce58", |
||||
|
"Error: No form element found.": "\uc624\ub958: \uc591\uc2dd \ud56d\ubaa9 \uc5c6\uc74c", |
||||
|
"Update": "\uc5c5\ub370\uc774\ud2b8", |
||||
|
"Color swatch": "\uc0c9\uc0c1 \uacac\ubcf8", |
||||
|
"Turquoise": "\uccad\ub85d\uc0c9", |
||||
|
"Green": "\ucd08\ub85d\uc0c9", |
||||
|
"Blue": "\ud30c\ub780\uc0c9", |
||||
|
"Purple": "\ubcf4\ub77c\uc0c9", |
||||
|
"Navy Blue": "\ub0a8\uc0c9", |
||||
|
"Dark Turquoise": "\uc9c4\ud55c \uccad\ub85d\uc0c9", |
||||
|
"Dark Green": "\uc9c4\ud55c \ucd08\ub85d\uc0c9", |
||||
|
"Medium Blue": "\uc911\uac04 \ud30c\ub780\uc0c9", |
||||
|
"Medium Purple": "\uc911\uac04 \ubcf4\ub77c\uc0c9", |
||||
|
"Midnight Blue": "\uc9c4\ud55c \ud30c\ub780\uc0c9", |
||||
|
"Yellow": "\ub178\ub780\uc0c9", |
||||
|
"Orange": "\uc8fc\ud669\uc0c9", |
||||
|
"Red": "\ube68\uac04\uc0c9", |
||||
|
"Light Gray": "\ubc1d\uc740 \ud68c\uc0c9", |
||||
|
"Gray": "\ud68c\uc0c9", |
||||
|
"Dark Yellow": "\uc9c4\ud55c \ub178\ub780\uc0c9", |
||||
|
"Dark Orange": "\uc9c4\ud55c \uc8fc\ud669\uc0c9", |
||||
|
"Dark Red": "\uc9c4\ud55c \ube68\uac04\uc0c9", |
||||
|
"Medium Gray": "\uc911\uac04 \ud68c\uc0c9", |
||||
|
"Dark Gray": "\uc9c4\ud55c \ud68c\uc0c9", |
||||
|
"Light Green": "\ubc1d\uc740 \ub179\uc0c9", |
||||
|
"Light Yellow": "\ubc1d\uc740 \ub178\ub780\uc0c9", |
||||
|
"Light Red": "\ubc1d\uc740 \ube68\uac04\uc0c9", |
||||
|
"Light Purple": "\ubc1d\uc740 \ubcf4\ub77c\uc0c9", |
||||
|
"Light Blue": "\ubc1d\uc740 \ud30c\ub780\uc0c9", |
||||
|
"Dark Purple": "\uc9c4\ud55c \ubcf4\ub77c\uc0c9", |
||||
|
"Dark Blue": "\uc9c4\ud55c \ud30c\ub780\uc0c9", |
||||
|
"Black": "\uac80\uc740\uc0c9", |
||||
|
"White": "\ud770\uc0c9", |
||||
|
"Switch to or from fullscreen mode": "\uc804\uccb4 \ud654\uba74\uc73c\ub85c\/\uc5d0\uc11c \uc804\ud658", |
||||
|
"Open help dialog": "\ub3c4\uc6c0\ub9d0 \ub300\ud654\ucc3d \uc5f4\uae30", |
||||
|
"history": "\uae30\ub85d", |
||||
|
"styles": "\uc2a4\ud0c0\uc77c", |
||||
|
"formatting": "\ud3ec\ub9f7\ud305", |
||||
|
"alignment": "\uc815\ub82c", |
||||
|
"indentation": "\ub4e4\uc5ec\uc4f0\uae30", |
||||
|
"permanent pen": "\uc720\uc131\ud39c", |
||||
|
"comments": "\uc8fc\uc11d", |
||||
|
"Format Painter": "\uc11c\uc2dd \ubcf5\uc0ac", |
||||
|
"Insert\/edit iframe": "\uc544\uc774\ud504\ub808\uc784 \uc0bd\uc785\/\ud3b8\uc9d1", |
||||
|
"Capitalization": "\ub300\ubb38\uc790\ud654", |
||||
|
"lowercase": "\uc18c\ubb38\uc790", |
||||
|
"UPPERCASE": "\ub300\ubb38\uc790", |
||||
|
"Title Case": "\uc81c\ubaa9\uc744 \ub300\ubb38\uc790\ud654", |
||||
|
"Permanent Pen Properties": "\uc601\uad6c \ud39c \ud2b9\uc131", |
||||
|
"Permanent pen properties...": "\uc601\uad6c \ud39c \ud2b9\uc131...", |
||||
|
"Font": "\uae00\uaf34", |
||||
|
"Size": "\ud06c\uae30", |
||||
|
"More...": "\ub354 \ubcf4\uae30...", |
||||
|
"Spellcheck Language": "\ub9de\ucda4\ubc95 \uac80\uc0ac \uc5b8\uc5b4", |
||||
|
"Select...": "\uc120\ud0dd...", |
||||
|
"Preferences": "\ud658\uacbd\uc124\uc815", |
||||
|
"Yes": "\ub124", |
||||
|
"No": "\uc544\ub2c8\uc624", |
||||
|
"Keyboard Navigation": "\ud0a4 \uc120\ud0dd", |
||||
|
"Version": "\ubc84\uc804", |
||||
|
"Anchor": "\uc575\ucee4", |
||||
|
"Special character": "\ud2b9\uc218\ubb38\uc790", |
||||
|
"Code sample": "\ucf54\ub4dc\uc0d8\ud50c", |
||||
|
"Color": "\uc0c9\uc0c1", |
||||
|
"Emoticons": "\uc774\ubaa8\ud2f0\ucf58", |
||||
|
"Document properties": "\ubb38\uc11c \uc18d\uc131", |
||||
|
"Image": "\uc774\ubbf8\uc9c0", |
||||
|
"Insert link": "\ub9c1\ud06c \uc0bd\uc785 ", |
||||
|
"Target": "\ub300\uc0c1", |
||||
|
"Link": "\ub9c1\ud06c", |
||||
|
"Poster": "\ud3ec\uc2a4\ud130", |
||||
|
"Media": "\ubbf8\ub514\uc5b4", |
||||
|
"Print": "\ucd9c\ub825", |
||||
|
"Prev": "\uc774\uc804", |
||||
|
"Find and replace": "\ucc3e\uc544\uc11c \uad50\uccb4", |
||||
|
"Whole words": "\uc804\uccb4 \ub2e8\uc5b4", |
||||
|
"Spellcheck": "\ubb38\ubc95\uccb4\ud06c", |
||||
|
"Caption": "\ucea1\uc158", |
||||
|
"Insert template": "\ud15c\ud50c\ub9bf \uc0bd\uc785" |
||||
|
}); |
||||
@ -0,0 +1,419 @@ |
|||||
|
tinymce.addI18n('zh_CN', { |
||||
|
"Redo": "\u91cd\u505a", |
||||
|
"Undo": "\u64a4\u9500", |
||||
|
"Cut": "\u526a\u5207", |
||||
|
"Copy": "\u590d\u5236", |
||||
|
"Paste": "\u7c98\u8d34", |
||||
|
"Select all": "\u5168\u9009", |
||||
|
"New document": "\u65b0\u6587\u4ef6", |
||||
|
"Ok": "\u786e\u5b9a", |
||||
|
"Cancel": "\u53d6\u6d88", |
||||
|
"Visual aids": "\u7f51\u683c\u7ebf", |
||||
|
"Bold": "\u7c97\u4f53", |
||||
|
"Italic": "\u659c\u4f53", |
||||
|
"Underline": "\u4e0b\u5212\u7ebf", |
||||
|
"Strikethrough": "\u5220\u9664\u7ebf", |
||||
|
"Superscript": "\u4e0a\u6807", |
||||
|
"Subscript": "\u4e0b\u6807", |
||||
|
"Clear formatting": "\u6e05\u9664\u683c\u5f0f", |
||||
|
"Align left": "\u5de6\u8fb9\u5bf9\u9f50", |
||||
|
"Align center": "\u4e2d\u95f4\u5bf9\u9f50", |
||||
|
"Align right": "\u53f3\u8fb9\u5bf9\u9f50", |
||||
|
"Justify": "\u4e24\u7aef\u5bf9\u9f50", |
||||
|
"Bullet list": "\u9879\u76ee\u7b26\u53f7", |
||||
|
"Numbered list": "\u7f16\u53f7\u5217\u8868", |
||||
|
"Decrease indent": "\u51cf\u5c11\u7f29\u8fdb", |
||||
|
"Increase indent": "\u589e\u52a0\u7f29\u8fdb", |
||||
|
"Close": "\u5173\u95ed", |
||||
|
"Formats": "\u683c\u5f0f", |
||||
|
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "\u4f60\u7684\u6d4f\u89c8\u5668\u4e0d\u652f\u6301\u6253\u5f00\u526a\u8d34\u677f\uff0c\u8bf7\u4f7f\u7528Ctrl+X\/C\/V\u7b49\u5feb\u6377\u952e\u3002", |
||||
|
"Headers": "\u6807\u9898", |
||||
|
"Header 1": "\u6807\u98981", |
||||
|
"Header 2": "\u6807\u98982", |
||||
|
"Header 3": "\u6807\u98983", |
||||
|
"Header 4": "\u6807\u98984", |
||||
|
"Header 5": "\u6807\u98985", |
||||
|
"Header 6": "\u6807\u98986", |
||||
|
"Headings": "\u6807\u9898", |
||||
|
"Heading 1": "\u6807\u98981", |
||||
|
"Heading 2": "\u6807\u98982", |
||||
|
"Heading 3": "\u6807\u98983", |
||||
|
"Heading 4": "\u6807\u98984", |
||||
|
"Heading 5": "\u6807\u98985", |
||||
|
"Heading 6": "\u6807\u98986", |
||||
|
"Preformatted": "\u9884\u5148\u683c\u5f0f\u5316\u7684", |
||||
|
"Div": "Div", |
||||
|
"Pre": "Pre", |
||||
|
"Code": "\u4ee3\u7801", |
||||
|
"Paragraph": "\u6bb5\u843d", |
||||
|
"Blockquote": "\u5f15\u6587\u533a\u5757", |
||||
|
"Inline": "\u6587\u672c", |
||||
|
"Blocks": "\u57fa\u5757", |
||||
|
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "\u5f53\u524d\u4e3a\u7eaf\u6587\u672c\u7c98\u8d34\u6a21\u5f0f\uff0c\u518d\u6b21\u70b9\u51fb\u53ef\u4ee5\u56de\u5230\u666e\u901a\u7c98\u8d34\u6a21\u5f0f\u3002", |
||||
|
"Fonts": "\u5b57\u4f53", |
||||
|
"Font Sizes": "\u5b57\u53f7", |
||||
|
"Class": "\u7c7b\u578b", |
||||
|
"Browse for an image": "\u6d4f\u89c8\u56fe\u50cf", |
||||
|
"OR": "\u6216", |
||||
|
"Drop an image here": "\u62d6\u653e\u4e00\u5f20\u56fe\u50cf\u81f3\u6b64", |
||||
|
"Upload": "\u4e0a\u4f20", |
||||
|
"Block": "\u5757", |
||||
|
"Align": "\u5bf9\u9f50", |
||||
|
"Default": "\u9ed8\u8ba4", |
||||
|
"Circle": "\u7a7a\u5fc3\u5706", |
||||
|
"Disc": "\u5b9e\u5fc3\u5706", |
||||
|
"Square": "\u65b9\u5757", |
||||
|
"Lower Alpha": "\u5c0f\u5199\u82f1\u6587\u5b57\u6bcd", |
||||
|
"Lower Greek": "\u5c0f\u5199\u5e0c\u814a\u5b57\u6bcd", |
||||
|
"Lower Roman": "\u5c0f\u5199\u7f57\u9a6c\u5b57\u6bcd", |
||||
|
"Upper Alpha": "\u5927\u5199\u82f1\u6587\u5b57\u6bcd", |
||||
|
"Upper Roman": "\u5927\u5199\u7f57\u9a6c\u5b57\u6bcd", |
||||
|
"Anchor...": "\u951a\u70b9...", |
||||
|
"Name": "\u540d\u79f0", |
||||
|
"Id": "\u6807\u8bc6\u7b26", |
||||
|
"Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "\u6807\u8bc6\u7b26\u5e94\u8be5\u4ee5\u5b57\u6bcd\u5f00\u5934\uff0c\u540e\u8ddf\u5b57\u6bcd\u3001\u6570\u5b57\u3001\u7834\u6298\u53f7\u3001\u70b9\u3001\u5192\u53f7\u6216\u4e0b\u5212\u7ebf\u3002", |
||||
|
"You have unsaved changes are you sure you want to navigate away?": "\u4f60\u8fd8\u6709\u6587\u6863\u5c1a\u672a\u4fdd\u5b58\uff0c\u786e\u5b9a\u8981\u79bb\u5f00\uff1f", |
||||
|
"Restore last draft": "\u6062\u590d\u4e0a\u6b21\u7684\u8349\u7a3f", |
||||
|
"Special character...": "\u7279\u6b8a\u5b57\u7b26...", |
||||
|
"Source code": "\u6e90\u4ee3\u7801", |
||||
|
"Insert\/Edit code sample": "\u63d2\u5165\/\u7f16\u8f91\u4ee3\u7801\u793a\u4f8b", |
||||
|
"Language": "\u8bed\u8a00", |
||||
|
"Code sample...": "\u793a\u4f8b\u4ee3\u7801...", |
||||
|
"Color Picker": "\u9009\u8272\u5668", |
||||
|
"R": "R", |
||||
|
"G": "G", |
||||
|
"B": "B", |
||||
|
"Left to right": "\u4ece\u5de6\u5230\u53f3", |
||||
|
"Right to left": "\u4ece\u53f3\u5230\u5de6", |
||||
|
"Emoticons...": "\u8868\u60c5\u7b26\u53f7...", |
||||
|
"Metadata and Document Properties": "\u5143\u6570\u636e\u548c\u6587\u6863\u5c5e\u6027", |
||||
|
"Title": "\u6807\u9898", |
||||
|
"Keywords": "\u5173\u952e\u8bcd", |
||||
|
"Description": "\u63cf\u8ff0", |
||||
|
"Robots": "\u673a\u5668\u4eba", |
||||
|
"Author": "\u4f5c\u8005", |
||||
|
"Encoding": "\u7f16\u7801", |
||||
|
"Fullscreen": "\u5168\u5c4f", |
||||
|
"Action": "\u64cd\u4f5c", |
||||
|
"Shortcut": "\u5feb\u6377\u952e", |
||||
|
"Help": "\u5e2e\u52a9", |
||||
|
"Address": "\u5730\u5740", |
||||
|
"Focus to menubar": "\u79fb\u52a8\u7126\u70b9\u5230\u83dc\u5355\u680f", |
||||
|
"Focus to toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u5de5\u5177\u680f", |
||||
|
"Focus to element path": "\u79fb\u52a8\u7126\u70b9\u5230\u5143\u7d20\u8def\u5f84", |
||||
|
"Focus to contextual toolbar": "\u79fb\u52a8\u7126\u70b9\u5230\u4e0a\u4e0b\u6587\u83dc\u5355", |
||||
|
"Insert link (if link plugin activated)": "\u63d2\u5165\u94fe\u63a5 (\u5982\u679c\u94fe\u63a5\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", |
||||
|
"Save (if save plugin activated)": "\u4fdd\u5b58(\u5982\u679c\u4fdd\u5b58\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", |
||||
|
"Find (if searchreplace plugin activated)": "\u67e5\u627e(\u5982\u679c\u67e5\u627e\u66ff\u6362\u63d2\u4ef6\u5df2\u6fc0\u6d3b)", |
||||
|
"Plugins installed ({0}):": "\u5df2\u5b89\u88c5\u63d2\u4ef6 ({0}):", |
||||
|
"Premium plugins:": "\u4f18\u79c0\u63d2\u4ef6\uff1a", |
||||
|
"Learn more...": "\u4e86\u89e3\u66f4\u591a...", |
||||
|
"You are using {0}": "\u4f60\u6b63\u5728\u4f7f\u7528 {0}", |
||||
|
"Plugins": "\u63d2\u4ef6", |
||||
|
"Handy Shortcuts": "\u5feb\u6377\u952e", |
||||
|
"Horizontal line": "\u6c34\u5e73\u5206\u5272\u7ebf", |
||||
|
"Insert\/edit image": "\u63d2\u5165\/\u7f16\u8f91\u56fe\u7247", |
||||
|
"Image description": "\u56fe\u7247\u63cf\u8ff0", |
||||
|
"Source": "\u5730\u5740", |
||||
|
"Dimensions": "\u5927\u5c0f", |
||||
|
"Constrain proportions": "\u4fdd\u6301\u7eb5\u6a2a\u6bd4", |
||||
|
"General": "\u666e\u901a", |
||||
|
"Advanced": "\u9ad8\u7ea7", |
||||
|
"Style": "\u6837\u5f0f", |
||||
|
"Vertical space": "\u5782\u76f4\u8fb9\u8ddd", |
||||
|
"Horizontal space": "\u6c34\u5e73\u8fb9\u8ddd", |
||||
|
"Border": "\u8fb9\u6846", |
||||
|
"Insert image": "\u63d2\u5165\u56fe\u7247", |
||||
|
"Image...": "\u56fe\u7247...", |
||||
|
"Image list": "\u56fe\u7247\u5217\u8868", |
||||
|
"Rotate counterclockwise": "\u9006\u65f6\u9488\u65cb\u8f6c", |
||||
|
"Rotate clockwise": "\u987a\u65f6\u9488\u65cb\u8f6c", |
||||
|
"Flip vertically": "\u5782\u76f4\u7ffb\u8f6c", |
||||
|
"Flip horizontally": "\u6c34\u5e73\u7ffb\u8f6c", |
||||
|
"Edit image": "\u7f16\u8f91\u56fe\u7247", |
||||
|
"Image options": "\u56fe\u7247\u9009\u9879", |
||||
|
"Zoom in": "\u653e\u5927", |
||||
|
"Zoom out": "\u7f29\u5c0f", |
||||
|
"Crop": "\u88c1\u526a", |
||||
|
"Resize": "\u8c03\u6574\u5927\u5c0f", |
||||
|
"Orientation": "\u65b9\u5411", |
||||
|
"Brightness": "\u4eae\u5ea6", |
||||
|
"Sharpen": "\u9510\u5316", |
||||
|
"Contrast": "\u5bf9\u6bd4\u5ea6", |
||||
|
"Color levels": "\u989c\u8272\u5c42\u6b21", |
||||
|
"Gamma": "\u4f3d\u9a6c\u503c", |
||||
|
"Invert": "\u53cd\u8f6c", |
||||
|
"Apply": "\u5e94\u7528", |
||||
|
"Back": "\u540e\u9000", |
||||
|
"Insert date\/time": "\u63d2\u5165\u65e5\u671f\/\u65f6\u95f4", |
||||
|
"Date\/time": "\u65e5\u671f\/\u65f6\u95f4", |
||||
|
"Insert\/Edit Link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5", |
||||
|
"Insert\/edit link": "\u63d2\u5165\/\u7f16\u8f91\u94fe\u63a5", |
||||
|
"Text to display": "\u663e\u793a\u6587\u5b57", |
||||
|
"Url": "\u5730\u5740", |
||||
|
"Open link in...": "\u94fe\u63a5\u6253\u5f00\u4f4d\u7f6e...", |
||||
|
"Current window": "\u5f53\u524d\u7a97\u53e3", |
||||
|
"None": "\u65e0", |
||||
|
"New window": "\u5728\u65b0\u7a97\u53e3\u6253\u5f00", |
||||
|
"Remove link": "\u5220\u9664\u94fe\u63a5", |
||||
|
"Anchors": "\u951a\u70b9", |
||||
|
"Link...": "\u94fe\u63a5...", |
||||
|
"Paste or type a link": "\u7c98\u8d34\u6216\u8f93\u5165\u94fe\u63a5", |
||||
|
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u4e3a\u90ae\u4ef6\u5730\u5740\uff0c\u9700\u8981\u52a0\u4e0amailto:\u524d\u7f00\u5417\uff1f", |
||||
|
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "\u4f60\u6240\u586b\u5199\u7684URL\u5730\u5740\u5c5e\u4e8e\u5916\u90e8\u94fe\u63a5\uff0c\u9700\u8981\u52a0\u4e0ahttp:\/\/:\u524d\u7f00\u5417\uff1f", |
||||
|
"Link list": "\u94fe\u63a5\u5217\u8868", |
||||
|
"Insert video": "\u63d2\u5165\u89c6\u9891", |
||||
|
"Insert\/edit video": "\u63d2\u5165\/\u7f16\u8f91\u89c6\u9891", |
||||
|
"Insert\/edit media": "\u63d2\u5165\/\u7f16\u8f91\u5a92\u4f53", |
||||
|
"Alternative source": "\u955c\u50cf", |
||||
|
"Alternative source URL": "\u66ff\u4ee3\u6765\u6e90\u7f51\u5740", |
||||
|
"Media poster (Image URL)": "\u5c01\u9762(\u56fe\u7247\u5730\u5740)", |
||||
|
"Paste your embed code below:": "\u5c06\u5185\u5d4c\u4ee3\u7801\u7c98\u8d34\u5728\u4e0b\u9762:", |
||||
|
"Embed": "\u5185\u5d4c", |
||||
|
"Media...": "\u591a\u5a92\u4f53...", |
||||
|
"Nonbreaking space": "\u4e0d\u95f4\u65ad\u7a7a\u683c", |
||||
|
"Page break": "\u5206\u9875\u7b26", |
||||
|
"Paste as text": "\u7c98\u8d34\u4e3a\u6587\u672c", |
||||
|
"Preview": "\u9884\u89c8", |
||||
|
"Print...": "\u6253\u5370...", |
||||
|
"Save": "\u4fdd\u5b58", |
||||
|
"Find": "\u67e5\u627e", |
||||
|
"Replace with": "\u66ff\u6362\u4e3a", |
||||
|
"Replace": "\u66ff\u6362", |
||||
|
"Replace all": "\u5168\u90e8\u66ff\u6362", |
||||
|
"Previous": "\u4e0a\u4e00\u4e2a", |
||||
|
"Next": "\u4e0b\u4e00\u4e2a", |
||||
|
"Find and replace...": "\u67e5\u627e\u5e76\u66ff\u6362...", |
||||
|
"Could not find the specified string.": "\u672a\u627e\u5230\u641c\u7d22\u5185\u5bb9.", |
||||
|
"Match case": "\u533a\u5206\u5927\u5c0f\u5199", |
||||
|
"Find whole words only": "\u5168\u5b57\u5339\u914d", |
||||
|
"Spell check": "\u62fc\u5199\u68c0\u67e5", |
||||
|
"Ignore": "\u5ffd\u7565", |
||||
|
"Ignore all": "\u5168\u90e8\u5ffd\u7565", |
||||
|
"Finish": "\u5b8c\u6210", |
||||
|
"Add to Dictionary": "\u6dfb\u52a0\u5230\u5b57\u5178", |
||||
|
"Insert table": "\u63d2\u5165\u8868\u683c", |
||||
|
"Table properties": "\u8868\u683c\u5c5e\u6027", |
||||
|
"Delete table": "\u5220\u9664\u8868\u683c", |
||||
|
"Cell": "\u5355\u5143\u683c", |
||||
|
"Row": "\u884c", |
||||
|
"Column": "\u5217", |
||||
|
"Cell properties": "\u5355\u5143\u683c\u5c5e\u6027", |
||||
|
"Merge cells": "\u5408\u5e76\u5355\u5143\u683c", |
||||
|
"Split cell": "\u62c6\u5206\u5355\u5143\u683c", |
||||
|
"Insert row before": "\u5728\u4e0a\u65b9\u63d2\u5165", |
||||
|
"Insert row after": "\u5728\u4e0b\u65b9\u63d2\u5165", |
||||
|
"Delete row": "\u5220\u9664\u884c", |
||||
|
"Row properties": "\u884c\u5c5e\u6027", |
||||
|
"Cut row": "\u526a\u5207\u884c", |
||||
|
"Copy row": "\u590d\u5236\u884c", |
||||
|
"Paste row before": "\u7c98\u8d34\u5230\u4e0a\u65b9", |
||||
|
"Paste row after": "\u7c98\u8d34\u5230\u4e0b\u65b9", |
||||
|
"Insert column before": "\u5728\u5de6\u4fa7\u63d2\u5165", |
||||
|
"Insert column after": "\u5728\u53f3\u4fa7\u63d2\u5165", |
||||
|
"Delete column": "\u5220\u9664\u5217", |
||||
|
"Cols": "\u5217", |
||||
|
"Rows": "\u884c", |
||||
|
"Width": "\u5bbd", |
||||
|
"Height": "\u9ad8", |
||||
|
"Cell spacing": "\u5355\u5143\u683c\u5916\u95f4\u8ddd", |
||||
|
"Cell padding": "\u5355\u5143\u683c\u5185\u8fb9\u8ddd", |
||||
|
"Show caption": "\u663e\u793a\u6807\u9898", |
||||
|
"Left": "\u5de6\u5bf9\u9f50", |
||||
|
"Center": "\u5c45\u4e2d", |
||||
|
"Right": "\u53f3\u5bf9\u9f50", |
||||
|
"Cell type": "\u5355\u5143\u683c\u7c7b\u578b", |
||||
|
"Scope": "\u8303\u56f4", |
||||
|
"Alignment": "\u5bf9\u9f50\u65b9\u5f0f", |
||||
|
"H Align": "\u6c34\u5e73\u5bf9\u9f50", |
||||
|
"V Align": "\u5782\u76f4\u5bf9\u9f50", |
||||
|
"Top": "\u9876\u90e8\u5bf9\u9f50", |
||||
|
"Middle": "\u5782\u76f4\u5c45\u4e2d", |
||||
|
"Bottom": "\u5e95\u90e8\u5bf9\u9f50", |
||||
|
"Header cell": "\u8868\u5934\u5355\u5143\u683c", |
||||
|
"Row group": "\u884c\u7ec4", |
||||
|
"Column group": "\u5217\u7ec4", |
||||
|
"Row type": "\u884c\u7c7b\u578b", |
||||
|
"Header": "\u8868\u5934", |
||||
|
"Body": "\u8868\u4f53", |
||||
|
"Footer": "\u8868\u5c3e", |
||||
|
"Border color": "\u8fb9\u6846\u989c\u8272", |
||||
|
"Insert template...": "\u63d2\u5165\u6a21\u677f...", |
||||
|
"Templates": "\u6a21\u677f", |
||||
|
"Template": "\u6a21\u677f", |
||||
|
"Text color": "\u6587\u5b57\u989c\u8272", |
||||
|
"Background color": "\u80cc\u666f\u8272", |
||||
|
"Custom...": "\u81ea\u5b9a\u4e49...", |
||||
|
"Custom color": "\u81ea\u5b9a\u4e49\u989c\u8272", |
||||
|
"No color": "\u65e0", |
||||
|
"Remove color": "\u79fb\u9664\u989c\u8272", |
||||
|
"Table of Contents": "\u5185\u5bb9\u5217\u8868", |
||||
|
"Show blocks": "\u663e\u793a\u533a\u5757\u8fb9\u6846", |
||||
|
"Show invisible characters": "\u663e\u793a\u4e0d\u53ef\u89c1\u5b57\u7b26", |
||||
|
"Word count": "\u5b57\u6570", |
||||
|
"Count": "\u8ba1\u6570", |
||||
|
"Document": "\u6587\u6863", |
||||
|
"Selection": "\u9009\u62e9", |
||||
|
"Words": "\u5355\u8bcd", |
||||
|
"Words: {0}": "\u5b57\u6570\uff1a{0}", |
||||
|
"{0} words": "{0} \u5b57", |
||||
|
"File": "\u6587\u4ef6", |
||||
|
"Edit": "\u7f16\u8f91", |
||||
|
"Insert": "\u63d2\u5165", |
||||
|
"View": "\u89c6\u56fe", |
||||
|
"Format": "\u683c\u5f0f", |
||||
|
"Table": "\u8868\u683c", |
||||
|
"Tools": "\u5de5\u5177", |
||||
|
"Powered by {0}": "\u7531{0}\u9a71\u52a8", |
||||
|
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "\u5728\u7f16\u8f91\u533a\u6309ALT-F9\u6253\u5f00\u83dc\u5355\uff0c\u6309ALT-F10\u6253\u5f00\u5de5\u5177\u680f\uff0c\u6309ALT-0\u67e5\u770b\u5e2e\u52a9", |
||||
|
"Image title": "\u56fe\u7247\u6807\u9898", |
||||
|
"Border width": "\u8fb9\u6846\u5bbd\u5ea6", |
||||
|
"Border style": "\u8fb9\u6846\u6837\u5f0f", |
||||
|
"Error": "\u9519\u8bef", |
||||
|
"Warn": "\u8b66\u544a", |
||||
|
"Valid": "\u6709\u6548", |
||||
|
"To open the popup, press Shift+Enter": "\u6309Shitf+Enter\u952e\u6253\u5f00\u5bf9\u8bdd\u6846", |
||||
|
"Rich Text Area. Press ALT-0 for help.": "\u7f16\u8f91\u533a\u3002\u6309Alt+0\u952e\u6253\u5f00\u5e2e\u52a9\u3002", |
||||
|
"System Font": "\u7cfb\u7edf\u5b57\u4f53", |
||||
|
"Failed to upload image: {0}": "\u56fe\u7247\u4e0a\u4f20\u5931\u8d25: {0}", |
||||
|
"Failed to load plugin: {0} from url {1}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25: {0} \u6765\u81ea\u94fe\u63a5 {1}", |
||||
|
"Failed to load plugin url: {0}": "\u63d2\u4ef6\u52a0\u8f7d\u5931\u8d25 \u94fe\u63a5: {0}", |
||||
|
"Failed to initialize plugin: {0}": "\u63d2\u4ef6\u521d\u59cb\u5316\u5931\u8d25: {0}", |
||||
|
"example": "\u793a\u4f8b", |
||||
|
"Search": "\u641c\u7d22", |
||||
|
"All": "\u5168\u90e8", |
||||
|
"Currency": "\u8d27\u5e01", |
||||
|
"Text": "\u6587\u5b57", |
||||
|
"Quotations": "\u5f15\u7528", |
||||
|
"Mathematical": "\u6570\u5b66", |
||||
|
"Extended Latin": "\u62c9\u4e01\u8bed\u6269\u5145", |
||||
|
"Symbols": "\u7b26\u53f7", |
||||
|
"Arrows": "\u7bad\u5934", |
||||
|
"User Defined": "\u81ea\u5b9a\u4e49", |
||||
|
"dollar sign": "\u7f8e\u5143\u7b26\u53f7", |
||||
|
"currency sign": "\u8d27\u5e01\u7b26\u53f7", |
||||
|
"euro-currency sign": "\u6b27\u5143\u7b26\u53f7", |
||||
|
"colon sign": "\u5192\u53f7", |
||||
|
"cruzeiro sign": "\u514b\u9c81\u8d5b\u7f57\u5e01\u7b26\u53f7", |
||||
|
"french franc sign": "\u6cd5\u90ce\u7b26\u53f7", |
||||
|
"lira sign": "\u91cc\u62c9\u7b26\u53f7", |
||||
|
"mill sign": "\u5bc6\u5c14\u7b26\u53f7", |
||||
|
"naira sign": "\u5948\u62c9\u7b26\u53f7", |
||||
|
"peseta sign": "\u6bd4\u585e\u5854\u7b26\u53f7", |
||||
|
"rupee sign": "\u5362\u6bd4\u7b26\u53f7", |
||||
|
"won sign": "\u97e9\u5143\u7b26\u53f7", |
||||
|
"new sheqel sign": "\u65b0\u8c22\u514b\u5c14\u7b26\u53f7", |
||||
|
"dong sign": "\u8d8a\u5357\u76fe\u7b26\u53f7", |
||||
|
"kip sign": "\u8001\u631d\u57fa\u666e\u7b26\u53f7", |
||||
|
"tugrik sign": "\u56fe\u683c\u91cc\u514b\u7b26\u53f7", |
||||
|
"drachma sign": "\u5fb7\u62c9\u514b\u9a6c\u7b26\u53f7", |
||||
|
"german penny symbol": "\u5fb7\u56fd\u4fbf\u58eb\u7b26\u53f7", |
||||
|
"peso sign": "\u6bd4\u7d22\u7b26\u53f7", |
||||
|
"guarani sign": "\u74dc\u62c9\u5c3c\u7b26\u53f7", |
||||
|
"austral sign": "\u6fb3\u5143\u7b26\u53f7", |
||||
|
"hryvnia sign": "\u683c\u91cc\u592b\u5c3c\u4e9a\u7b26\u53f7", |
||||
|
"cedi sign": "\u585e\u5730\u7b26\u53f7", |
||||
|
"livre tournois sign": "\u91cc\u5f17\u5f17\u5c14\u7b26\u53f7", |
||||
|
"spesmilo sign": "spesmilo\u7b26\u53f7", |
||||
|
"tenge sign": "\u575a\u6208\u7b26\u53f7", |
||||
|
"indian rupee sign": "\u5370\u5ea6\u5362\u6bd4", |
||||
|
"turkish lira sign": "\u571f\u8033\u5176\u91cc\u62c9", |
||||
|
"nordic mark sign": "\u5317\u6b27\u9a6c\u514b", |
||||
|
"manat sign": "\u9a6c\u7eb3\u7279\u7b26\u53f7", |
||||
|
"ruble sign": "\u5362\u5e03\u7b26\u53f7", |
||||
|
"yen character": "\u65e5\u5143\u5b57\u6837", |
||||
|
"yuan character": "\u4eba\u6c11\u5e01\u5143\u5b57\u6837", |
||||
|
"yuan character, in hong kong and taiwan": "\u5143\u5b57\u6837\uff08\u6e2f\u53f0\u5730\u533a\uff09", |
||||
|
"yen\/yuan character variant one": "\u5143\u5b57\u6837\uff08\u5927\u5199\uff09", |
||||
|
"Loading emoticons...": "\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7...", |
||||
|
"Could not load emoticons": "\u4e0d\u80fd\u52a0\u8f7d\u8868\u60c5\u7b26\u53f7", |
||||
|
"People": "\u4eba\u7c7b", |
||||
|
"Animals and Nature": "\u52a8\u7269\u548c\u81ea\u7136", |
||||
|
"Food and Drink": "\u98df\u7269\u548c\u996e\u54c1", |
||||
|
"Activity": "\u6d3b\u52a8", |
||||
|
"Travel and Places": "\u65c5\u6e38\u548c\u5730\u70b9", |
||||
|
"Objects": "\u7269\u4ef6", |
||||
|
"Flags": "\u65d7\u5e1c", |
||||
|
"Characters": "\u5b57\u7b26", |
||||
|
"Characters (no spaces)": "\u5b57\u7b26(\u65e0\u7a7a\u683c)", |
||||
|
"{0} characters": "{0} \u4e2a\u5b57\u7b26", |
||||
|
"Error: Form submit field collision.": "\u9519\u8bef: \u8868\u5355\u63d0\u4ea4\u5b57\u6bb5\u51b2\u7a81\u3002", |
||||
|
"Error: No form element found.": "\u9519\u8bef: \u6ca1\u6709\u8868\u5355\u63a7\u4ef6\u3002", |
||||
|
"Update": "\u66f4\u65b0", |
||||
|
"Color swatch": "\u989c\u8272\u6837\u672c", |
||||
|
"Turquoise": "\u9752\u7eff\u8272", |
||||
|
"Green": "\u7eff\u8272", |
||||
|
"Blue": "\u84dd\u8272", |
||||
|
"Purple": "\u7d2b\u8272", |
||||
|
"Navy Blue": "\u6d77\u519b\u84dd", |
||||
|
"Dark Turquoise": "\u6df1\u84dd\u7eff\u8272", |
||||
|
"Dark Green": "\u6df1\u7eff\u8272", |
||||
|
"Medium Blue": "\u4e2d\u84dd\u8272", |
||||
|
"Medium Purple": "\u4e2d\u7d2b\u8272", |
||||
|
"Midnight Blue": "\u6df1\u84dd\u8272", |
||||
|
"Yellow": "\u9ec4\u8272", |
||||
|
"Orange": "\u6a59\u8272", |
||||
|
"Red": "\u7ea2\u8272", |
||||
|
"Light Gray": "\u6d45\u7070\u8272", |
||||
|
"Gray": "\u7070\u8272", |
||||
|
"Dark Yellow": "\u6697\u9ec4\u8272", |
||||
|
"Dark Orange": "\u6df1\u6a59\u8272", |
||||
|
"Dark Red": "\u6df1\u7ea2\u8272", |
||||
|
"Medium Gray": "\u4e2d\u7070\u8272", |
||||
|
"Dark Gray": "\u6df1\u7070\u8272", |
||||
|
"Light Green": "\u6d45\u7eff\u8272", |
||||
|
"Light Yellow": "\u6d45\u9ec4\u8272", |
||||
|
"Light Red": "\u6d45\u7ea2\u8272", |
||||
|
"Light Purple": "\u6d45\u7d2b\u8272", |
||||
|
"Light Blue": "\u6d45\u84dd\u8272", |
||||
|
"Dark Purple": "\u6df1\u7d2b\u8272", |
||||
|
"Dark Blue": "\u6df1\u84dd\u8272", |
||||
|
"Black": "\u9ed1\u8272", |
||||
|
"White": "\u767d\u8272", |
||||
|
"Switch to or from fullscreen mode": "\u5207\u6362\u5168\u5c4f\u6a21\u5f0f", |
||||
|
"Open help dialog": "\u6253\u5f00\u5e2e\u52a9\u5bf9\u8bdd\u6846", |
||||
|
"history": "\u5386\u53f2", |
||||
|
"styles": "\u6837\u5f0f", |
||||
|
"formatting": "\u683c\u5f0f\u5316", |
||||
|
"alignment": "\u5bf9\u9f50", |
||||
|
"indentation": "\u7f29\u8fdb", |
||||
|
"permanent pen": "\u8bb0\u53f7\u7b14", |
||||
|
"comments": "\u5907\u6ce8", |
||||
|
"Format Painter": "\u683c\u5f0f\u5237", |
||||
|
"Insert\/edit iframe": "\u63d2\u5165\/\u7f16\u8f91\u6846\u67b6", |
||||
|
"Capitalization": "\u5927\u5199", |
||||
|
"lowercase": "\u5c0f\u5199", |
||||
|
"UPPERCASE": "\u5927\u5199", |
||||
|
"Title Case": "\u9996\u5b57\u6bcd\u5927\u5199", |
||||
|
"Permanent Pen Properties": "\u6c38\u4e45\u7b14\u5c5e\u6027", |
||||
|
"Permanent pen properties...": "\u6c38\u4e45\u7b14\u5c5e\u6027...", |
||||
|
"Font": "\u5b57\u4f53", |
||||
|
"Size": "\u5b57\u53f7", |
||||
|
"More...": "\u66f4\u591a...", |
||||
|
"Spellcheck Language": "\u62fc\u5199\u68c0\u67e5\u8bed\u8a00", |
||||
|
"Select...": "\u9009\u62e9...", |
||||
|
"Preferences": "\u9996\u9009\u9879", |
||||
|
"Yes": "\u662f", |
||||
|
"No": "\u5426", |
||||
|
"Keyboard Navigation": "\u952e\u76d8\u6307\u5f15", |
||||
|
"Version": "\u7248\u672c", |
||||
|
"Anchor": "\u951a\u70b9", |
||||
|
"Special character": "\u7279\u6b8a\u7b26\u53f7", |
||||
|
"Code sample": "\u4ee3\u7801\u793a\u4f8b", |
||||
|
"Color": "\u989c\u8272", |
||||
|
"Emoticons": "\u8868\u60c5", |
||||
|
"Document properties": "\u6587\u6863\u5c5e\u6027", |
||||
|
"Image": "\u56fe\u7247", |
||||
|
"Insert link": "\u63d2\u5165\u94fe\u63a5", |
||||
|
"Target": "\u6253\u5f00\u65b9\u5f0f", |
||||
|
"Link": "\u94fe\u63a5", |
||||
|
"Poster": "\u5c01\u9762", |
||||
|
"Media": "\u5a92\u4f53", |
||||
|
"Print": "\u6253\u5370", |
||||
|
"Prev": "\u4e0a\u4e00\u4e2a", |
||||
|
"Find and replace": "\u67e5\u627e\u548c\u66ff\u6362", |
||||
|
"Whole words": "\u5168\u5b57\u5339\u914d", |
||||
|
"Spellcheck": "\u62fc\u5199\u68c0\u67e5", |
||||
|
"Caption": "\u6807\u9898", |
||||
|
"Insert template": "\u63d2\u5165\u6a21\u677f" |
||||
|
}); |
||||
@ -0,0 +1,7 @@ |
|||||
|
/** |
||||
|
* Copyright (c) Tiny Technologies, Inc. All rights reserved. |
||||
|
* Licensed under the LGPL or a commercial license. |
||||
|
* For LGPL see License.txt in the project root for license information. |
||||
|
* For commercial licenses see https://www.tiny.cloud/ |
||||
|
*/ |
||||
|
.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{background-color:green;display:inline-block;opacity:.5;position:absolute}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}body{font-family:sans-serif}table{border-collapse:collapse} |
||||
@ -0,0 +1,19 @@ |
|||||
|
<template> |
||||
|
<div id="app"> |
||||
|
<router-view /> |
||||
|
<service-worker-update-popup /> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Vue } from 'vue-property-decorator' |
||||
|
import ServiceWorkerUpdatePopup from '@/pwa/components/ServiceWorkerUpdatePopup.vue' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'App', |
||||
|
components: { |
||||
|
ServiceWorkerUpdatePopup |
||||
|
} |
||||
|
}) |
||||
|
export default class extends Vue {} |
||||
|
</script> |
||||
@ -0,0 +1,91 @@ |
|||||
|
import { IPermission } from './types' |
||||
|
import ApiService from './serviceBase' |
||||
|
|
||||
|
const serviceUrl = process.env.VUE_APP_BASE_API |
||||
|
|
||||
|
export default class PermissionService { |
||||
|
/** 获取指定权限提供者的权限数据 |
||||
|
* @param providerName 权限提供者 如User(用户)、Role(角色) |
||||
|
* @param providerKey 权限提供者标识 User:userId Role:roleId |
||||
|
* @description 老版本的abp vNext用的User、Role、Client等提供者名称 |
||||
|
* 新版本的简写为U、R、C等 |
||||
|
*/ |
||||
|
public static getPermissionsByKey(providerName: string, providerKey: string) { |
||||
|
let _url = '/api/abp/permissions?' |
||||
|
_url += 'providerName=' + providerName |
||||
|
_url += '&providerKey=' + providerKey |
||||
|
return ApiService.Get<PermissionDto>(_url, serviceUrl) |
||||
|
} |
||||
|
|
||||
|
/** 授权指定权限提供者的权限数据 |
||||
|
* @param providerName 权限提供者 如User(用户)、Role(角色) |
||||
|
* @param providerKey 权限提供者标识 User:userId Role:roleId |
||||
|
* @param payload 授权数据 |
||||
|
*/ |
||||
|
public static setPermissionsByKey(providerName: string, providerKey: string, payload: UpdatePermissionsDto) { |
||||
|
let _url = '/api/abp/permissions?' |
||||
|
_url += 'providerName=' + providerName |
||||
|
_url += '&providerKey=' + providerKey |
||||
|
return ApiService.Put<any>(_url, payload, serviceUrl) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export class UpdatePermissionsDto { |
||||
|
permissions!: UpdatePermissionDto[] |
||||
|
|
||||
|
constructor() { |
||||
|
this.permissions = new Array<UpdatePermissionDto>() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export class UpdatePermissionDto implements IPermission { |
||||
|
name!: string |
||||
|
isGranted!: boolean |
||||
|
} |
||||
|
|
||||
|
export class PermissionProvider { |
||||
|
providerName!: string |
||||
|
providerKey!: string |
||||
|
} |
||||
|
|
||||
|
export class Permission implements IPermissionGrant { |
||||
|
allowedProviders!: string[] |
||||
|
grantedProviders!: PermissionProvider[] |
||||
|
displayName!: string |
||||
|
isGranted!: boolean |
||||
|
name!: string |
||||
|
parentName?: string |
||||
|
|
||||
|
constructor() { |
||||
|
this.allowedProviders = new Array<string>() |
||||
|
this.grantedProviders = new Array<PermissionProvider>() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export class PermissionGroup { |
||||
|
displayName!: string |
||||
|
name!: string |
||||
|
permissions!: Permission[] |
||||
|
|
||||
|
constructor() { |
||||
|
this.permissions = new Array<Permission>() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export class PermissionDto { |
||||
|
entityDisplayName!: string |
||||
|
groups!: PermissionGroup[] |
||||
|
|
||||
|
constructor() { |
||||
|
this.groups = new Array<PermissionGroup>() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export interface IPermissionGrant { |
||||
|
allowedProviders: string[] |
||||
|
grantedProviders: PermissionProvider[] |
||||
|
displayName: string |
||||
|
isGranted: boolean |
||||
|
name: string |
||||
|
parentName?: string |
||||
|
} |
||||
@ -0,0 +1,61 @@ |
|||||
|
import request from '@/utils/request' |
||||
|
import { AxiosRequestConfig, AxiosPromise } from 'axios' |
||||
|
|
||||
|
export default class ApiService { |
||||
|
public static Get<T>(url: string, baseUrl = process.env.VUE_APP_BASE_API): Promise<T> { |
||||
|
return this.HttpRequest<T>({ |
||||
|
baseURL: baseUrl, |
||||
|
url: url, |
||||
|
method: 'GET' |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
public static Post<T>(url: string, payload: any, baseUrl = process.env.VUE_APP_BASE_API): Promise<T> { |
||||
|
return this.HttpRequest<T>({ |
||||
|
baseURL: baseUrl, |
||||
|
url: url, |
||||
|
method: 'POST', |
||||
|
data: payload |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
public static Patch<T>(url: string, payload: any, baseUrl = process.env.VUE_APP_BASE_API): Promise<T> { |
||||
|
return this.HttpRequest<T>({ |
||||
|
baseURL: baseUrl, |
||||
|
url: url, |
||||
|
method: 'PATCH', |
||||
|
data: payload |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
public static Put<T>(url: string, payload: any, baseUrl = process.env.VUE_APP_BASE_API): Promise<T> { |
||||
|
return this.HttpRequest<T>({ |
||||
|
baseURL: baseUrl, |
||||
|
url: url, |
||||
|
method: 'PUT', |
||||
|
data: payload |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
public static Delete(url: string, baseUrl = process.env.VUE_APP_BASE_API) { |
||||
|
return request({ |
||||
|
baseURL: baseUrl, |
||||
|
url: url, |
||||
|
method: 'DELETE' |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
public static HttpRequestWithOriginResponse(options: AxiosRequestConfig): AxiosPromise<any> { |
||||
|
return request(options) |
||||
|
} |
||||
|
|
||||
|
public static HttpRequest<T>(options: AxiosRequestConfig): Promise<T> { |
||||
|
return new Promise<T>((resolve, reject) => { |
||||
|
request(options).then(res => { |
||||
|
resolve(res.data) |
||||
|
}).catch(error => { |
||||
|
reject(error) |
||||
|
}) |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,170 @@ |
|||||
|
/** 授权接口 */ |
||||
|
export interface IPermission { |
||||
|
/** 权限名称 */ |
||||
|
name: string |
||||
|
/** 是否授权 */ |
||||
|
isGranted: boolean |
||||
|
} |
||||
|
|
||||
|
/** 分页排序查询对象 */ |
||||
|
export class PagedAndSortedResultRequestDto implements IPagedResultRequest, ISortedResultRequest { |
||||
|
/** 查询页码 */ |
||||
|
skipCount: number |
||||
|
/** 单页最大返回数量 */ |
||||
|
maxResultCount: number |
||||
|
/** 排序字段 */ |
||||
|
sorting: string | undefined |
||||
|
|
||||
|
constructor() { |
||||
|
this.sorting = '' |
||||
|
this.skipCount = 1 |
||||
|
this.maxResultCount = 30 |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** 创建实体审计对象 */ |
||||
|
export class CreationAuditedEntityDto implements IMayHaveCreator { |
||||
|
creatorId: string | undefined |
||||
|
creationTime!: Date |
||||
|
} |
||||
|
|
||||
|
/** 实体审计对象 */ |
||||
|
export class AuditedEntityDto implements CreationAuditedEntityDto, IModificationAuditedObject { |
||||
|
lastModifierId: string | undefined |
||||
|
lastModificationTime: Date | undefined |
||||
|
creatorId: string | undefined |
||||
|
creationTime!: Date |
||||
|
} |
||||
|
|
||||
|
/** 所有实体审计对象 */ |
||||
|
export class FullAuditedEntityDto implements AuditedEntityDto, IDeletionAuditedObject { |
||||
|
lastModifierId: string | undefined |
||||
|
lastModificationTime: Date | undefined |
||||
|
creatorId: string | undefined |
||||
|
creationTime!: Date |
||||
|
deleterId!: string |
||||
|
deletionTime: Date | undefined |
||||
|
isDeleted!: boolean |
||||
|
} |
||||
|
|
||||
|
/** 通用分页请求接口 */ |
||||
|
export class PagedResultRequestDto implements IPagedResultRequest { |
||||
|
skipCount: number |
||||
|
maxResultCount: number |
||||
|
|
||||
|
constructor() { |
||||
|
this.skipCount = 1 |
||||
|
this.maxResultCount = 25 |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export class PagedResultDto<T> implements ListResultDto<T>, IPagedResult<T> { |
||||
|
items!: T[] |
||||
|
totalCount!: number |
||||
|
} |
||||
|
|
||||
|
/** 列表接口Dto */ |
||||
|
export class ListResultDto<T> implements IListResult<T> { |
||||
|
items!: T[] |
||||
|
} |
||||
|
/** 分页请求接口 */ |
||||
|
export interface IPagedResultRequest extends ILimitedResultRequest { |
||||
|
/** 当前页 */ |
||||
|
skipCount: number |
||||
|
} |
||||
|
|
||||
|
/** 最大请求接口 */ |
||||
|
export interface ILimitedResultRequest { |
||||
|
/** 当前页 */ |
||||
|
maxResultCount: number |
||||
|
} |
||||
|
|
||||
|
/** 返回列表接口 */ |
||||
|
export interface IListResult<T> { |
||||
|
/** 列表项 */ |
||||
|
items: T[] |
||||
|
} |
||||
|
|
||||
|
/** 分页请求接口 */ |
||||
|
export interface IPagedResult<T> { |
||||
|
/** 最大数据大小 */ |
||||
|
totalCount: number |
||||
|
} |
||||
|
|
||||
|
/** 排序请求接口 */ |
||||
|
export interface ISortedResultRequest { |
||||
|
/** 排序字段 */ |
||||
|
sorting: string | undefined |
||||
|
} |
||||
|
|
||||
|
/** 分页排序请求接口 */ |
||||
|
export interface IPagedAndSortedResultRequest extends IPagedResultRequest, ISortedResultRequest { |
||||
|
} |
||||
|
|
||||
|
/** 创建人接口 */ |
||||
|
export interface IMayHaveCreator extends IHasCreationTime { |
||||
|
/** 创建人标识 */ |
||||
|
creatorId: string | undefined |
||||
|
} |
||||
|
|
||||
|
/** 创建时间接口 */ |
||||
|
export interface IHasCreationTime { |
||||
|
/** 创建时间 */ |
||||
|
creationTime: Date |
||||
|
} |
||||
|
|
||||
|
/** 修改人接口 */ |
||||
|
export interface IModificationAuditedObject extends IHasModificationTime { |
||||
|
/** 上次修改人标识 */ |
||||
|
lastModifierId: string | undefined |
||||
|
} |
||||
|
|
||||
|
/** 修改时间接口 */ |
||||
|
export interface IHasModificationTime { |
||||
|
/** 上次修改时间 */ |
||||
|
lastModificationTime: Date | undefined |
||||
|
} |
||||
|
|
||||
|
/** 删除人接口 */ |
||||
|
export interface IDeletionAuditedObject extends IHasDeletionTime { |
||||
|
/** 删除人标识 */ |
||||
|
deleterId: string |
||||
|
} |
||||
|
|
||||
|
/** 删除时间接口 */ |
||||
|
export interface IHasDeletionTime extends ISoftDelete { |
||||
|
/** 删除时间 */ |
||||
|
deletionTime: Date | undefined |
||||
|
} |
||||
|
|
||||
|
/** 软删除接口 */ |
||||
|
export interface ISoftDelete { |
||||
|
/** 是否已删除 */ |
||||
|
isDeleted: boolean |
||||
|
} |
||||
|
|
||||
|
/** 作用于接口 */ |
||||
|
export interface IScope { |
||||
|
/** 作用域 */ |
||||
|
scope: string |
||||
|
} |
||||
|
|
||||
|
/** 密钥 */ |
||||
|
export interface ISecret { |
||||
|
/** 密钥类型 */ |
||||
|
type: string |
||||
|
/** 密钥值 */ |
||||
|
value: string |
||||
|
/** 密钥说明 */ |
||||
|
description: string | undefined |
||||
|
/** 过期日期 */ |
||||
|
expiration: Date | undefined |
||||
|
} |
||||
|
|
||||
|
/** 令牌 */ |
||||
|
export interface IClaim { |
||||
|
/** 类型 */ |
||||
|
type: string |
||||
|
/** 数值 */ |
||||
|
value: string |
||||
|
} |
||||
|
After Width: | Height: | Size: 160 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 96 KiB |
@ -0,0 +1,78 @@ |
|||||
|
<template> |
||||
|
<image-crop-upload |
||||
|
v-model="show" |
||||
|
:field="field" |
||||
|
:url="url" |
||||
|
:width="width" |
||||
|
:height="height" |
||||
|
:params="params" |
||||
|
:headers="headers" |
||||
|
:lang-type="language" |
||||
|
:with-credentials="true" |
||||
|
img-format="png" |
||||
|
@src-file-set="srcFileSet" |
||||
|
@crop-success="cropSuccess" |
||||
|
@crop-upload-success="cropUploadSuccess" |
||||
|
@crop-upload-fail="cropUploadFail" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import ImageCropUpload from 'vue-image-crop-upload' |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
import { AppModule } from '@/store/modules/app' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'AvatarUpload', |
||||
|
components: { |
||||
|
ImageCropUpload |
||||
|
} |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
// You can add more Prop, see: https://github.com/dai-siki/vue-image-crop-upload#usage |
||||
|
@Prop({ required: true }) private value!: boolean |
||||
|
@Prop({ required: true }) private url!: string |
||||
|
@Prop({ required: true }) private field!: string |
||||
|
@Prop({ default: 300 }) private width!: number |
||||
|
@Prop({ default: 300 }) private height!: number |
||||
|
@Prop({ default: () => null }) private params!: object |
||||
|
@Prop({ default: () => null }) private headers!: object |
||||
|
|
||||
|
// https://github.com/dai-siki/vue-image-crop-upload#language-package |
||||
|
private languageTypeList: { [key: string]: string } = { |
||||
|
en: 'en', |
||||
|
zh: 'zh', |
||||
|
es: 'es-MX', |
||||
|
ja: 'ja', |
||||
|
ko: 'ko' |
||||
|
} |
||||
|
|
||||
|
get show() { |
||||
|
return this.value |
||||
|
} |
||||
|
|
||||
|
set show(value) { |
||||
|
this.$emit('input', value) |
||||
|
} |
||||
|
|
||||
|
get language() { |
||||
|
return this.languageTypeList[AppModule.language] |
||||
|
} |
||||
|
|
||||
|
private srcFileSet(fileName: string, fileType: string, fileSize: number) { |
||||
|
this.$emit('src-file-set', fileName, fileType, fileSize) |
||||
|
} |
||||
|
|
||||
|
private cropSuccess(imgDataUrl: string, field: string) { |
||||
|
this.$emit('crop-success', imgDataUrl, field) |
||||
|
} |
||||
|
|
||||
|
private cropUploadSuccess(jsonData: any, field: string) { |
||||
|
this.$emit('crop-upload-success', jsonData, field) |
||||
|
} |
||||
|
|
||||
|
private cropUploadFail(status: boolean, field: string) { |
||||
|
this.$emit('crop-upload-fail', status, field) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,111 @@ |
|||||
|
<template> |
||||
|
<transition :name="transitionName"> |
||||
|
<div |
||||
|
v-show="visible" |
||||
|
:style="customStyle" |
||||
|
class="back-to-ceiling" |
||||
|
@click="backToTop" |
||||
|
> |
||||
|
<svg-icon |
||||
|
name="back-top" |
||||
|
class="backTopIcon" |
||||
|
/> |
||||
|
</div> |
||||
|
</transition> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'BackToTop' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ default: 400 }) private visibilityHeight!: number |
||||
|
@Prop({ default: 'fade' }) private transitionName!: string |
||||
|
@Prop({ default: 0 }) private backPosition!: number |
||||
|
@Prop({ |
||||
|
default: () => { |
||||
|
return { |
||||
|
right: '50px', |
||||
|
bottom: '50px', |
||||
|
width: '40px', |
||||
|
height: '40px', |
||||
|
'border-radius': '4px', |
||||
|
'line-height': '45px', |
||||
|
background: '#e7eaf1' |
||||
|
} |
||||
|
} |
||||
|
}) private customStyle!: object |
||||
|
|
||||
|
private visible = false |
||||
|
private isMoving = false |
||||
|
private interval?: number |
||||
|
|
||||
|
mounted() { |
||||
|
window.addEventListener('scroll', this.handleScroll) |
||||
|
} |
||||
|
|
||||
|
beforeDestroy() { |
||||
|
window.removeEventListener('scroll', this.handleScroll) |
||||
|
if (this.interval) { |
||||
|
clearInterval(this.interval) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private handleScroll() { |
||||
|
this.visible = window.pageYOffset > this.visibilityHeight |
||||
|
} |
||||
|
|
||||
|
private backToTop() { |
||||
|
if (this.isMoving) return |
||||
|
const start = window.pageYOffset |
||||
|
let i = 0 |
||||
|
this.isMoving = true |
||||
|
const interval = setInterval(() => { |
||||
|
const next = Math.floor(this.easeInOutQuad(10 * i, start, -start, 500)) |
||||
|
if (next <= this.backPosition) { |
||||
|
window.scrollTo(0, this.backPosition) |
||||
|
clearInterval(interval) |
||||
|
this.isMoving = false |
||||
|
} else { |
||||
|
window.scrollTo(0, next) |
||||
|
} |
||||
|
i++ |
||||
|
}, 16.7) |
||||
|
} |
||||
|
|
||||
|
private easeInOutQuad(t: number, b: number, c: number, d: number) { |
||||
|
if ((t /= d / 2) < 1) return (c / 2) * t * t + b |
||||
|
return (-c / 2) * (--t * (t - 2) - 1) + b |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.back-to-ceiling { |
||||
|
position: fixed; |
||||
|
display: inline-block; |
||||
|
text-align: center; |
||||
|
cursor: pointer; |
||||
|
|
||||
|
:hover { |
||||
|
background: #d5dbe7; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.fade-enter-active, |
||||
|
.fade-leave-active { |
||||
|
transition: opacity 0.5s; |
||||
|
} |
||||
|
|
||||
|
.fade-enter, |
||||
|
.fade-leave-to { |
||||
|
opacity: 0; |
||||
|
} |
||||
|
|
||||
|
.back-to-ceiling .backTopIcon { |
||||
|
fill: #9aaabf; |
||||
|
background: none; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,110 @@ |
|||||
|
<template> |
||||
|
<el-breadcrumb |
||||
|
class="app-breadcrumb" |
||||
|
separator="/" |
||||
|
> |
||||
|
<transition-group name="breadcrumb"> |
||||
|
<el-breadcrumb-item |
||||
|
v-for="(item, index) in breadcrumbs" |
||||
|
:key="item.path" |
||||
|
> |
||||
|
<span |
||||
|
v-if="item.redirect === 'noredirect' || index === breadcrumbs.length-1" |
||||
|
class="no-redirect" |
||||
|
>{{ $t('route.' + item.meta.title) }}</span> |
||||
|
<a |
||||
|
v-else |
||||
|
@click.prevent="handleLink(item)" |
||||
|
>{{ $t('route.' + item.meta.title) }}</a> |
||||
|
</el-breadcrumb-item> |
||||
|
</transition-group> |
||||
|
</el-breadcrumb> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { compile } from 'path-to-regexp' |
||||
|
import { Component, Vue, Watch } from 'vue-property-decorator' |
||||
|
import { RouteRecord, Route } from 'vue-router' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'Breadcrumb' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
private breadcrumbs: RouteRecord[] = [] |
||||
|
|
||||
|
@Watch('$route') |
||||
|
private onRouteChange(route: Route) { |
||||
|
// if you go to the redirect page, do not update the breadcrumbs |
||||
|
if (route.path.startsWith('/redirect/')) { |
||||
|
return |
||||
|
} |
||||
|
this.getBreadcrumb() |
||||
|
} |
||||
|
|
||||
|
created() { |
||||
|
this.getBreadcrumb() |
||||
|
} |
||||
|
|
||||
|
private getBreadcrumb() { |
||||
|
let matched = this.$route.matched.filter((item) => item.meta && item.meta.title) |
||||
|
const first = matched[0] |
||||
|
if (!this.isDashboard(first)) { |
||||
|
matched = [{ path: '/dashboard', meta: { title: 'dashboard' } } as RouteRecord].concat(matched) |
||||
|
} |
||||
|
this.breadcrumbs = matched.filter((item) => { |
||||
|
return item.meta && item.meta.title && item.meta.breadcrumb !== false |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
private isDashboard(route: RouteRecord) { |
||||
|
const name = route && route.name |
||||
|
if (!name) { |
||||
|
return false |
||||
|
} |
||||
|
return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase() |
||||
|
} |
||||
|
|
||||
|
private pathCompile(path: string) { |
||||
|
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561 |
||||
|
const { params } = this.$route |
||||
|
const toPath = compile(path) |
||||
|
return toPath(params) |
||||
|
} |
||||
|
|
||||
|
private handleLink(item: any) { |
||||
|
const { redirect, path } = item |
||||
|
if (redirect) { |
||||
|
this.$router.push(redirect).catch(err => { |
||||
|
// Throw Error "NavigationDuplicated" |
||||
|
// https://github.com/vuejs/vue-router/issues/2872#issuecomment-522341874 |
||||
|
console.warn(err) |
||||
|
}) |
||||
|
return |
||||
|
} |
||||
|
this.$router.push(this.pathCompile(path)).catch(err => { |
||||
|
// Throw Error "NavigationDuplicated" |
||||
|
// https://github.com/vuejs/vue-router/issues/2872#issuecomment-522341874 |
||||
|
console.warn(err) |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.el-breadcrumb__inner, |
||||
|
.el-breadcrumb__inner a { |
||||
|
font-weight: 400 !important; |
||||
|
} |
||||
|
|
||||
|
.app-breadcrumb.el-breadcrumb { |
||||
|
display: inline-block; |
||||
|
font-size: 14px; |
||||
|
line-height: 50px; |
||||
|
margin-left: 8px; |
||||
|
|
||||
|
.no-redirect { |
||||
|
color: #97a8be; |
||||
|
cursor: text; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,136 @@ |
|||||
|
<template> |
||||
|
<div |
||||
|
:id="id" |
||||
|
:class="className" |
||||
|
:style="{height: height, width: width}" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import echarts, { EChartOption } from 'echarts' |
||||
|
import { Component, Prop } from 'vue-property-decorator' |
||||
|
import { mixins } from 'vue-class-component' |
||||
|
import ResizeMixin from './mixins/resize' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'BarChart' |
||||
|
}) |
||||
|
export default class extends mixins(ResizeMixin) { |
||||
|
@Prop({ default: 'chart' }) private className!: string |
||||
|
@Prop({ default: 'chart' }) private id!: string |
||||
|
@Prop({ default: '200px' }) private width!: string |
||||
|
@Prop({ default: '200px' }) private height!: string |
||||
|
|
||||
|
mounted() { |
||||
|
this.$nextTick(() => { |
||||
|
this.initChart() |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
beforeDestroy() { |
||||
|
if (!this.chart) { |
||||
|
return |
||||
|
} |
||||
|
this.chart.dispose() |
||||
|
this.chart = null |
||||
|
} |
||||
|
|
||||
|
private initChart() { |
||||
|
this.chart = echarts.init(document.getElementById(this.id) as HTMLDivElement) |
||||
|
const xAxisData: string[] = [] |
||||
|
const data: number[] = [] |
||||
|
const data2: number[] = [] |
||||
|
for (let i = 0; i < 50; i++) { |
||||
|
xAxisData.push(i.toString()) |
||||
|
data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5) |
||||
|
data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3) |
||||
|
} |
||||
|
this.chart.setOption({ |
||||
|
backgroundColor: '#08263a', |
||||
|
grid: { |
||||
|
left: '5%', |
||||
|
right: '5%' |
||||
|
}, |
||||
|
xAxis: [{ |
||||
|
show: false, |
||||
|
data: xAxisData |
||||
|
}, { |
||||
|
show: false, |
||||
|
data: xAxisData |
||||
|
}], |
||||
|
visualMap: [{ |
||||
|
show: false, |
||||
|
min: 0, |
||||
|
max: 50, |
||||
|
dimension: 0, |
||||
|
inRange: { |
||||
|
color: ['#4a657a', '#308e92', '#b1cfa5', '#f5d69f', '#f5898b', '#ef5055'] |
||||
|
} |
||||
|
}], |
||||
|
yAxis: [{ |
||||
|
axisLine: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
color: '#43657a' |
||||
|
}, |
||||
|
splitLine: { |
||||
|
show: true, |
||||
|
lineStyle: { |
||||
|
color: '#08263f' |
||||
|
} |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: false |
||||
|
} |
||||
|
}], |
||||
|
series: [{ |
||||
|
name: 'back', |
||||
|
type: 'bar', |
||||
|
data: data2, |
||||
|
z: 1, |
||||
|
itemStyle: { |
||||
|
opacity: 0.4, |
||||
|
barBorderRadius: 5, |
||||
|
shadowBlur: 3, |
||||
|
shadowColor: '#111' |
||||
|
} |
||||
|
}, { |
||||
|
name: 'Simulate Shadow', |
||||
|
type: 'line', |
||||
|
data, |
||||
|
z: 2, |
||||
|
showSymbol: false, |
||||
|
animationDelay: 0, |
||||
|
animationEasing: 'linear', |
||||
|
animationDuration: 1200, |
||||
|
lineStyle: { |
||||
|
color: 'transparent' |
||||
|
}, |
||||
|
areaStyle: { |
||||
|
color: '#08263a', |
||||
|
shadowBlur: 50, |
||||
|
shadowColor: '#000' |
||||
|
} |
||||
|
}, { |
||||
|
name: 'front', |
||||
|
type: 'bar', |
||||
|
data, |
||||
|
xAxisIndex: 1, |
||||
|
z: 3, |
||||
|
itemStyle: { |
||||
|
barBorderRadius: 5 |
||||
|
} |
||||
|
}], |
||||
|
animationEasing: 'elasticOut', |
||||
|
animationEasingUpdate: 'elasticOut', |
||||
|
animationDelay(idx: number) { |
||||
|
return idx * 20 |
||||
|
}, |
||||
|
animationDelayUpdate(idx: number) { |
||||
|
return idx * 20 |
||||
|
} |
||||
|
} as EChartOption<EChartOption.SeriesBar>) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,192 @@ |
|||||
|
<template> |
||||
|
<div |
||||
|
:id="id" |
||||
|
:class="className" |
||||
|
:style="{height: height, width: width}" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import echarts, { EChartOption } from 'echarts' |
||||
|
import { Component, Prop } from 'vue-property-decorator' |
||||
|
import { mixins } from 'vue-class-component' |
||||
|
import ResizeMixin from './mixins/resize' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'LineChart' |
||||
|
}) |
||||
|
export default class extends mixins(ResizeMixin) { |
||||
|
@Prop({ default: 'chart' }) private className!: string |
||||
|
@Prop({ default: 'chart' }) private id!: string |
||||
|
@Prop({ default: '200px' }) private width!: string |
||||
|
@Prop({ default: '200px' }) private height!: string |
||||
|
|
||||
|
mounted() { |
||||
|
this.$nextTick(() => { |
||||
|
this.initChart() |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
beforeDestroy() { |
||||
|
if (!this.chart) { |
||||
|
return |
||||
|
} |
||||
|
this.chart.dispose() |
||||
|
this.chart = null |
||||
|
} |
||||
|
|
||||
|
private initChart() { |
||||
|
this.chart = echarts.init(document.getElementById(this.id) as HTMLDivElement) |
||||
|
this.chart.setOption({ |
||||
|
backgroundColor: '#394056', |
||||
|
title: { |
||||
|
top: 20, |
||||
|
text: 'Requests', |
||||
|
textStyle: { |
||||
|
fontWeight: 'normal', |
||||
|
fontSize: 16, |
||||
|
color: '#F1F1F3' |
||||
|
}, |
||||
|
left: '1%' |
||||
|
}, |
||||
|
tooltip: { |
||||
|
trigger: 'axis' |
||||
|
}, |
||||
|
legend: { |
||||
|
top: 20, |
||||
|
icon: 'rect', |
||||
|
itemWidth: 14, |
||||
|
itemHeight: 5, |
||||
|
itemGap: 13, |
||||
|
data: ['CMCC', 'CTCC', 'CUCC'], |
||||
|
right: '4%', |
||||
|
textStyle: { |
||||
|
fontSize: 12, |
||||
|
color: '#F1F1F3' |
||||
|
} |
||||
|
}, |
||||
|
grid: { |
||||
|
top: 100, |
||||
|
left: '2%', |
||||
|
right: '2%', |
||||
|
bottom: '2%', |
||||
|
containLabel: true |
||||
|
}, |
||||
|
xAxis: [{ |
||||
|
type: 'category', |
||||
|
boundaryGap: false, |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: '#57617B' |
||||
|
} |
||||
|
}, |
||||
|
data: ['13:00', '13:05', '13:10', '13:15', '13:20', '13:25', '13:30', '13:35', '13:40', '13:45', '13:50', '13:55'] |
||||
|
}], |
||||
|
yAxis: [{ |
||||
|
type: 'value', |
||||
|
name: '(%)', |
||||
|
axisTick: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: '#57617B' |
||||
|
} |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
margin: 10, |
||||
|
fontSize: 14 |
||||
|
}, |
||||
|
splitLine: { |
||||
|
lineStyle: { |
||||
|
color: '#57617B' |
||||
|
} |
||||
|
} |
||||
|
}], |
||||
|
series: [{ |
||||
|
name: 'CMCC', |
||||
|
type: 'line', |
||||
|
smooth: true, |
||||
|
symbol: 'circle', |
||||
|
symbolSize: 5, |
||||
|
showSymbol: false, |
||||
|
lineStyle: { |
||||
|
width: 1 |
||||
|
}, |
||||
|
areaStyle: { |
||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ |
||||
|
offset: 0, |
||||
|
color: 'rgba(137, 189, 27, 0.3)' |
||||
|
}, { |
||||
|
offset: 0.8, |
||||
|
color: 'rgba(137, 189, 27, 0)' |
||||
|
}], false), |
||||
|
shadowColor: 'rgba(0, 0, 0, 0.1)', |
||||
|
shadowBlur: 10 |
||||
|
}, |
||||
|
itemStyle: { |
||||
|
color: 'rgb(137,189,27)', |
||||
|
borderColor: 'rgba(137,189,2,0.27)', |
||||
|
borderWidth: 12 |
||||
|
}, |
||||
|
data: [220, 182, 191, 134, 150, 120, 110, 125, 145, 122, 165, 122] |
||||
|
}, { |
||||
|
name: 'CTCC', |
||||
|
type: 'line', |
||||
|
smooth: true, |
||||
|
symbol: 'circle', |
||||
|
symbolSize: 5, |
||||
|
showSymbol: false, |
||||
|
lineStyle: { |
||||
|
width: 1 |
||||
|
}, |
||||
|
areaStyle: { |
||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ |
||||
|
offset: 0, |
||||
|
color: 'rgba(0, 136, 212, 0.3)' |
||||
|
}, { |
||||
|
offset: 0.8, |
||||
|
color: 'rgba(0, 136, 212, 0)' |
||||
|
}], false), |
||||
|
shadowColor: 'rgba(0, 0, 0, 0.1)', |
||||
|
shadowBlur: 10 |
||||
|
}, |
||||
|
itemStyle: { |
||||
|
color: 'rgb(0,136,212)', |
||||
|
borderColor: 'rgba(0,136,212,0.2)', |
||||
|
borderWidth: 12 |
||||
|
}, |
||||
|
data: [120, 110, 125, 145, 122, 165, 122, 220, 182, 191, 134, 150] |
||||
|
}, { |
||||
|
name: 'CUCC', |
||||
|
type: 'line', |
||||
|
smooth: true, |
||||
|
symbol: 'circle', |
||||
|
symbolSize: 5, |
||||
|
showSymbol: false, |
||||
|
lineStyle: { |
||||
|
width: 1 |
||||
|
}, |
||||
|
areaStyle: { |
||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{ |
||||
|
offset: 0, |
||||
|
color: 'rgba(219, 50, 51, 0.3)' |
||||
|
}, { |
||||
|
offset: 0.8, |
||||
|
color: 'rgba(219, 50, 51, 0)' |
||||
|
}], false) as any, |
||||
|
shadowColor: 'rgba(0, 0, 0, 0.1)', |
||||
|
shadowBlur: 10 |
||||
|
}, |
||||
|
itemStyle: { |
||||
|
color: 'rgb(219,50,51)', |
||||
|
borderColor: 'rgba(219,50,51,0.2)', |
||||
|
borderWidth: 12 |
||||
|
}, |
||||
|
data: [220, 182, 125, 145, 122, 191, 134, 150, 120, 110, 165, 122] |
||||
|
}] |
||||
|
} as EChartOption<EChartOption.SeriesLine>) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
</script> |
||||
@ -0,0 +1,248 @@ |
|||||
|
<template> |
||||
|
<div |
||||
|
:id="id" |
||||
|
:class="className" |
||||
|
:style="{height: height, width: width}" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import echarts, { EChartOption } from 'echarts' |
||||
|
import { Component, Prop } from 'vue-property-decorator' |
||||
|
import { mixins } from 'vue-class-component' |
||||
|
import ResizeMixin from './mixins/resize' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'MixedChart' |
||||
|
}) |
||||
|
export default class extends mixins(ResizeMixin) { |
||||
|
@Prop({ default: 'chart' }) private className!: string |
||||
|
@Prop({ default: 'chart' }) private id!: string |
||||
|
@Prop({ default: '200px' }) private width!: string |
||||
|
@Prop({ default: '200px' }) private height!: string |
||||
|
|
||||
|
mounted() { |
||||
|
this.$nextTick(() => { |
||||
|
this.initChart() |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
beforeDestroy() { |
||||
|
if (!this.chart) { |
||||
|
return |
||||
|
} |
||||
|
this.chart.dispose() |
||||
|
this.chart = null |
||||
|
} |
||||
|
|
||||
|
private initChart() { |
||||
|
this.chart = echarts.init(document.getElementById(this.id) as HTMLDivElement) |
||||
|
const xData = (function() { |
||||
|
const data = [] |
||||
|
for (let i = 1; i < 13; i++) { |
||||
|
data.push(i + 'month') |
||||
|
} |
||||
|
return data |
||||
|
}()) |
||||
|
this.chart.setOption({ |
||||
|
backgroundColor: '#344b58', |
||||
|
title: { |
||||
|
text: 'statistics', |
||||
|
top: '20', |
||||
|
textStyle: { |
||||
|
color: '#fff', |
||||
|
fontSize: 22 |
||||
|
}, |
||||
|
subtextStyle: { |
||||
|
color: '#90979c', |
||||
|
fontSize: 16 |
||||
|
} |
||||
|
}, |
||||
|
tooltip: { |
||||
|
trigger: 'axis' |
||||
|
}, |
||||
|
grid: { |
||||
|
left: '5%', |
||||
|
right: '5%', |
||||
|
borderWidth: 0, |
||||
|
top: 150, |
||||
|
bottom: 95, |
||||
|
textStyle: { |
||||
|
color: '#fff' |
||||
|
} |
||||
|
}, |
||||
|
legend: { |
||||
|
x: '5%', |
||||
|
top: '10%', |
||||
|
textStyle: { |
||||
|
color: '#90979c' |
||||
|
}, |
||||
|
data: ['female', 'male', 'average'] |
||||
|
}, |
||||
|
xAxis: [{ |
||||
|
type: 'category', |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: '#90979c' |
||||
|
} |
||||
|
}, |
||||
|
splitLine: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: false |
||||
|
}, |
||||
|
splitArea: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
interval: 0 |
||||
|
|
||||
|
}, |
||||
|
data: xData |
||||
|
}], |
||||
|
yAxis: [{ |
||||
|
type: 'value', |
||||
|
splitLine: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: '#90979c' |
||||
|
} |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: false |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
interval: 0 |
||||
|
}, |
||||
|
splitArea: { |
||||
|
show: false |
||||
|
} |
||||
|
}], |
||||
|
dataZoom: [{ |
||||
|
show: true, |
||||
|
xAxisIndex: [ |
||||
|
0 |
||||
|
], |
||||
|
bottom: 30, |
||||
|
start: 10, |
||||
|
end: 80, |
||||
|
handleIcon: 'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z', |
||||
|
handleSize: '110%', |
||||
|
handleStyle: { |
||||
|
color: '#d3dee5' |
||||
|
|
||||
|
}, |
||||
|
textStyle: { |
||||
|
color: '#fff' |
||||
|
}, |
||||
|
borderColor: '#90979c' |
||||
|
}, { |
||||
|
type: 'inside', |
||||
|
show: true, |
||||
|
start: 1, |
||||
|
end: 35 |
||||
|
}], |
||||
|
series: [{ |
||||
|
name: 'female', |
||||
|
type: 'bar', |
||||
|
stack: 'total', |
||||
|
barMaxWidth: 35, |
||||
|
barGap: '10%', |
||||
|
itemStyle: { |
||||
|
color: 'rgba(255,144,128,1)', |
||||
|
label: { |
||||
|
show: true, |
||||
|
textStyle: { |
||||
|
color: '#fff' |
||||
|
}, |
||||
|
position: 'insideTop', |
||||
|
formatter(p: any) { |
||||
|
return p.value > 0 ? p.value : '' |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data: [ |
||||
|
709, |
||||
|
1917, |
||||
|
2455, |
||||
|
2610, |
||||
|
1719, |
||||
|
1433, |
||||
|
1544, |
||||
|
3285, |
||||
|
5208, |
||||
|
3372, |
||||
|
2484, |
||||
|
4078 |
||||
|
] |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: 'male', |
||||
|
type: 'bar', |
||||
|
stack: 'total', |
||||
|
itemStyle: { |
||||
|
color: 'rgba(0,191,183,1)', |
||||
|
barBorderRadius: 0, |
||||
|
label: { |
||||
|
show: true, |
||||
|
position: 'top', |
||||
|
formatter(p: any) { |
||||
|
return p.value > 0 ? p.value : '' |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data: [ |
||||
|
327, |
||||
|
1776, |
||||
|
507, |
||||
|
1200, |
||||
|
800, |
||||
|
482, |
||||
|
204, |
||||
|
1390, |
||||
|
1001, |
||||
|
951, |
||||
|
381, |
||||
|
220 |
||||
|
] |
||||
|
}, { |
||||
|
name: 'average', |
||||
|
type: 'line', |
||||
|
stack: 'total', |
||||
|
symbolSize: 10, |
||||
|
symbol: 'circle', |
||||
|
itemStyle: { |
||||
|
color: 'rgba(252,230,48,1)', |
||||
|
barBorderRadius: 0, |
||||
|
label: { |
||||
|
show: true, |
||||
|
position: 'top', |
||||
|
formatter(p: any) { |
||||
|
return p.value > 0 ? p.value : '' |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data: [ |
||||
|
1036, |
||||
|
3693, |
||||
|
2962, |
||||
|
3810, |
||||
|
2519, |
||||
|
1915, |
||||
|
1748, |
||||
|
4675, |
||||
|
6209, |
||||
|
4323, |
||||
|
2865, |
||||
|
4298 |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
} as EChartOption<EChartOption.SeriesLine | EChartOption.SeriesBar>) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,67 @@ |
|||||
|
import { ECharts } from 'echarts' |
||||
|
import { Component, Vue } from 'vue-property-decorator' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'ResizeMixin' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
protected chart!: ECharts | null |
||||
|
private sidebarElm?: Element |
||||
|
|
||||
|
mounted() { |
||||
|
this.initResizeEvent() |
||||
|
this.initSidebarResizeEvent() |
||||
|
} |
||||
|
|
||||
|
beforeDestroy() { |
||||
|
this.destroyResizeEvent() |
||||
|
this.destroySidebarResizeEvent() |
||||
|
} |
||||
|
|
||||
|
activated() { |
||||
|
this.initResizeEvent() |
||||
|
this.initSidebarResizeEvent() |
||||
|
} |
||||
|
|
||||
|
deactivated() { |
||||
|
this.destroyResizeEvent() |
||||
|
this.destroySidebarResizeEvent() |
||||
|
} |
||||
|
|
||||
|
private chartResizeHandler() { |
||||
|
if (this.chart) { |
||||
|
this.chart.resize() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private sidebarResizeHandler(e: TransitionEvent) { |
||||
|
if (e.propertyName === 'width') { |
||||
|
this.chartResizeHandler() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private initResizeEvent() { |
||||
|
if (this.chartResizeHandler) { |
||||
|
window.addEventListener('resize', this.chartResizeHandler) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private destroyResizeEvent() { |
||||
|
if (this.chartResizeHandler) { |
||||
|
window.removeEventListener('resize', this.chartResizeHandler) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private initSidebarResizeEvent() { |
||||
|
this.sidebarElm = document.getElementsByClassName('sidebar-container')[0] |
||||
|
if (this.sidebarElm) { |
||||
|
this.sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler as EventListener) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private destroySidebarResizeEvent() { |
||||
|
if (this.sidebarElm) { |
||||
|
this.sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler as EventListener) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,83 @@ |
|||||
|
<template> |
||||
|
<div class="board-column"> |
||||
|
<div class="board-column-header"> |
||||
|
{{ headerText }} |
||||
|
</div> |
||||
|
<draggable |
||||
|
:list="list" |
||||
|
v-bind="$attrs" |
||||
|
class="board-column-content" |
||||
|
> |
||||
|
<div |
||||
|
v-for="element in list" |
||||
|
:key="element.id" |
||||
|
class="board-item" |
||||
|
> |
||||
|
{{ element.name }} {{ element.id }} |
||||
|
</div> |
||||
|
</draggable> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import Draggable from 'vuedraggable' |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'DraggableKanban', |
||||
|
components: { |
||||
|
Draggable |
||||
|
} |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ default: 'header' }) private headerText!: string |
||||
|
@Prop({ default: () => [] }) private list!: any[] |
||||
|
@Prop({ default: () => null }) private options!: object |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.board-column { |
||||
|
min-width: 300px; |
||||
|
min-height: 100px; |
||||
|
height: auto; |
||||
|
overflow: hidden; |
||||
|
background: #f0f0f0; |
||||
|
border-radius: 3px; |
||||
|
|
||||
|
.board-column-header { |
||||
|
height: 50px; |
||||
|
line-height: 50px; |
||||
|
overflow: hidden; |
||||
|
padding: 0 20px; |
||||
|
text-align: center; |
||||
|
background: #333; |
||||
|
color: #fff; |
||||
|
border-radius: 3px 3px 0 0; |
||||
|
} |
||||
|
|
||||
|
.board-column-content { |
||||
|
height: auto; |
||||
|
overflow: hidden; |
||||
|
border: 10px solid transparent; |
||||
|
min-height: 60px; |
||||
|
display: flex; |
||||
|
justify-content: flex-start; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
|
||||
|
.board-item { |
||||
|
cursor: pointer; |
||||
|
width: 100%; |
||||
|
height: 64px; |
||||
|
margin: 5px 0; |
||||
|
background-color: #fff; |
||||
|
text-align: left; |
||||
|
line-height: 54px; |
||||
|
padding: 5px 10px; |
||||
|
box-sizing: border-box; |
||||
|
box-shadow: 0px 1px 3px 0 rgba(0, 0, 0, 0.2); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,180 @@ |
|||||
|
<template> |
||||
|
<div class="draggableList"> |
||||
|
<div |
||||
|
:style="{width: list1width}" |
||||
|
class="draggableList-list" |
||||
|
> |
||||
|
<h3>{{ list1Title }}</h3> |
||||
|
<draggable |
||||
|
:list="list1" |
||||
|
group="article" |
||||
|
class="dragArea" |
||||
|
> |
||||
|
<div |
||||
|
v-for="element in list1" |
||||
|
:key="element.id" |
||||
|
class="list-complete-item" |
||||
|
> |
||||
|
<div class="list-complete-item-handle"> |
||||
|
{{ element.id }}[{{ element.author }}] {{ element.title }} |
||||
|
</div> |
||||
|
<div style="position:absolute;right:0px;"> |
||||
|
<span |
||||
|
style="float: right ;margin-top: -20px;margin-right:5px;" |
||||
|
@click="deleteEle(element)" |
||||
|
> |
||||
|
<i |
||||
|
style="color:#ff4949" |
||||
|
class="el-icon-delete" |
||||
|
/> |
||||
|
</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</draggable> |
||||
|
</div> |
||||
|
<div |
||||
|
:style="{width: list2width}" |
||||
|
class="draggableList-list" |
||||
|
> |
||||
|
<h3>{{ list2Title }}</h3> |
||||
|
<draggable |
||||
|
:list="list2" |
||||
|
group="article" |
||||
|
class="dragArea" |
||||
|
> |
||||
|
<div |
||||
|
v-for="element in list2" |
||||
|
:key="element.id" |
||||
|
class="list-complete-item" |
||||
|
> |
||||
|
<div |
||||
|
class="list-complete-item-handle2" |
||||
|
@click="pushEle(element)" |
||||
|
> |
||||
|
{{ element.id }} [{{ element.author }}] {{ element.title }} |
||||
|
</div> |
||||
|
</div> |
||||
|
</draggable> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import Draggable from 'vuedraggable' |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
import { IArticleData } from '@/api/types' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'DraggableList', |
||||
|
components: { |
||||
|
Draggable |
||||
|
} |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ default: () => [] }) private list1!: IArticleData[] |
||||
|
@Prop({ default: () => [] }) private list2!: IArticleData[] |
||||
|
@Prop({ default: 'list1' }) private list1Title!: string |
||||
|
@Prop({ default: 'list2' }) private list2Title!: string |
||||
|
@Prop({ default: '48%' }) private list1width!: string |
||||
|
@Prop({ default: '48%' }) private list2width!: string |
||||
|
|
||||
|
private isNotInList1(v: IArticleData) { |
||||
|
return this.list1.every(k => v.id !== k.id) |
||||
|
} |
||||
|
|
||||
|
private isNotInList2(v: IArticleData) { |
||||
|
return this.list2.every(k => v.id !== k.id) |
||||
|
} |
||||
|
|
||||
|
private deleteEle(ele: IArticleData) { |
||||
|
for (const item of this.list1) { |
||||
|
if (item.id === ele.id) { |
||||
|
const index = this.list1.indexOf(item) |
||||
|
this.list1.splice(index, 1) |
||||
|
break |
||||
|
} |
||||
|
} |
||||
|
if (this.isNotInList2(ele)) { |
||||
|
this.list2.unshift(ele) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private pushEle(ele: IArticleData) { |
||||
|
for (const item of this.list2) { |
||||
|
if (item.id === ele.id) { |
||||
|
const index = this.list2.indexOf(item) |
||||
|
this.list2.splice(index, 1) |
||||
|
break |
||||
|
} |
||||
|
} |
||||
|
if (this.isNotInList1(ele)) { |
||||
|
this.list1.push(ele) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.draggableList { |
||||
|
background: #fff; |
||||
|
padding-bottom: 40px; |
||||
|
|
||||
|
&:after { |
||||
|
content: ""; |
||||
|
display: table; |
||||
|
clear: both; |
||||
|
} |
||||
|
|
||||
|
.draggableList-list { |
||||
|
float: left; |
||||
|
padding-bottom: 30px; |
||||
|
|
||||
|
&:first-of-type { |
||||
|
margin-right: 2%; |
||||
|
} |
||||
|
|
||||
|
.dragArea { |
||||
|
margin-top: 15px; |
||||
|
min-height: 50px; |
||||
|
padding-bottom: 30px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.list-complete-item { |
||||
|
cursor: pointer; |
||||
|
position: relative; |
||||
|
font-size: 14px; |
||||
|
padding: 5px 12px; |
||||
|
margin-top: 4px; |
||||
|
border: 1px solid #bfcbd9; |
||||
|
transition: all 1s; |
||||
|
} |
||||
|
|
||||
|
.list-complete-item-handle { |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
white-space: nowrap; |
||||
|
margin-right: 50px; |
||||
|
} |
||||
|
|
||||
|
.list-complete-item-handle2 { |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
white-space: nowrap; |
||||
|
margin-right: 20px; |
||||
|
} |
||||
|
|
||||
|
.list-complete-item.sortable-chosen { |
||||
|
background: #4AB7BD; |
||||
|
} |
||||
|
|
||||
|
.list-complete-item.sortable-ghost { |
||||
|
background: #30B08F; |
||||
|
} |
||||
|
|
||||
|
.list-complete-enter, |
||||
|
.list-complete-leave-active { |
||||
|
opacity: 0; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,65 @@ |
|||||
|
<template> |
||||
|
<el-select |
||||
|
ref="draggableSelect" |
||||
|
v-model="selectVal" |
||||
|
v-bind="$attrs" |
||||
|
class="draggable-select" |
||||
|
multiple |
||||
|
v-on="$listeners" |
||||
|
> |
||||
|
<slot /> |
||||
|
</el-select> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import Sortable from 'sortablejs' |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
import { Select } from 'element-ui' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'DraggableSelect' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ required: true }) private value!: string[] |
||||
|
|
||||
|
private sortable: Sortable | null = null |
||||
|
|
||||
|
get selectVal() { |
||||
|
return [...this.value] |
||||
|
} |
||||
|
|
||||
|
set selectVal(value) { |
||||
|
this.$emit('input', [...value]) |
||||
|
} |
||||
|
|
||||
|
mounted() { |
||||
|
this.setSort() |
||||
|
} |
||||
|
|
||||
|
private setSort() { |
||||
|
const draggableSelect = this.$refs.draggableSelect as Select |
||||
|
const el = draggableSelect.$el.querySelectorAll('.el-select__tags > span')[0] as HTMLElement |
||||
|
this.sortable = Sortable.create(el, { |
||||
|
ghostClass: 'sortable-ghost', // Class name for the drop placeholder |
||||
|
onEnd: evt => { |
||||
|
if (typeof (evt.oldIndex) !== 'undefined' && typeof (evt.newIndex) !== 'undefined') { |
||||
|
const targetRow = this.value.splice(evt.oldIndex, 1)[0] |
||||
|
this.value.splice(evt.newIndex, 0, targetRow) |
||||
|
} |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.draggable-select .sortable-ghost { |
||||
|
opacity: .8; |
||||
|
color: #fff!important; |
||||
|
background: #42b983!important; |
||||
|
} |
||||
|
|
||||
|
.draggable-select .el-tag { |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,116 @@ |
|||||
|
<template> |
||||
|
<div |
||||
|
:class="{active: isActive}" |
||||
|
class="share-dropdown-menu" |
||||
|
> |
||||
|
<div class="share-dropdown-menu-wrapper"> |
||||
|
<span |
||||
|
class="share-dropdown-menu-title" |
||||
|
@click.self="clickTitle" |
||||
|
>{{ title }}</span> |
||||
|
<div |
||||
|
v-for="(item, index) of items" |
||||
|
:key="index" |
||||
|
class="share-dropdown-menu-item" |
||||
|
> |
||||
|
<a |
||||
|
v-if="item.href" |
||||
|
:href="item.href" |
||||
|
target="_blank" |
||||
|
>{{ item.title }}</a> |
||||
|
<span v-else>{{ item.title }}</span> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'DropdownMenu' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ default: () => [] }) private items!: any[] |
||||
|
@Prop({ default: 'vue' }) private title!: string |
||||
|
|
||||
|
private isActive = false |
||||
|
|
||||
|
private clickTitle() { |
||||
|
this.isActive = !this.isActive |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
$item-length: 10; // Should be no less than items.length |
||||
|
$transition-time: .1s; |
||||
|
|
||||
|
.share-dropdown-menu { |
||||
|
width: 250px; |
||||
|
position: relative; |
||||
|
z-index: 1; |
||||
|
height: auto!important; |
||||
|
|
||||
|
&-title { |
||||
|
width: 100%; |
||||
|
display: block; |
||||
|
cursor: pointer; |
||||
|
background: black; |
||||
|
color: white; |
||||
|
height: 60px; |
||||
|
line-height: 60px; |
||||
|
font-size: 20px; |
||||
|
text-align: center; |
||||
|
z-index: 2; |
||||
|
transform: translate3d(0,0,0); |
||||
|
} |
||||
|
|
||||
|
&-wrapper { |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
&-item { |
||||
|
text-align: center; |
||||
|
position: absolute; |
||||
|
width: 100%; |
||||
|
background: #e0e0e0; |
||||
|
color: black; |
||||
|
line-height: 60px; |
||||
|
height: 60px; |
||||
|
cursor: pointer; |
||||
|
font-size: 18px; |
||||
|
overflow: hidden; |
||||
|
opacity: 1; |
||||
|
transition: transform 0.28s ease; |
||||
|
|
||||
|
&:hover { |
||||
|
background: black; |
||||
|
color: white; |
||||
|
} |
||||
|
|
||||
|
@for $i from 1 through $item-length { |
||||
|
&:nth-of-type(#{$i}) { |
||||
|
z-index: -1; |
||||
|
transition-delay: $i*$transition-time; |
||||
|
transform: translate3d(0, -60px, 0); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.active { |
||||
|
.share-dropdown-menu-wrapper { |
||||
|
z-index: 1; |
||||
|
} |
||||
|
|
||||
|
.share-dropdown-menu-item { |
||||
|
@for $i from 1 through $item-length { |
||||
|
&:nth-of-type(#{$i}) { |
||||
|
transition-delay: ($item-length - $i)*$transition-time; |
||||
|
transform: translate3d(0, ($i - 1)*60px, 0); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,97 @@ |
|||||
|
<template> |
||||
|
<vue-dropzone |
||||
|
:id="id" |
||||
|
:options="dropzoneOptions" |
||||
|
:use-custom-slot="true" |
||||
|
@vdropzone-removed-file="dropzoneRemovedFile" |
||||
|
@vdropzone-success="dropzoneSuccess" |
||||
|
> |
||||
|
<div class="dropzone-custom-content"> |
||||
|
<h3 |
||||
|
class="dropzone-custom-title" |
||||
|
:style="{color: themeColor}" |
||||
|
> |
||||
|
Drag and drop to upload content! |
||||
|
</h3> |
||||
|
<div class="subtitle"> |
||||
|
...or click to select a file from your computer |
||||
|
</div> |
||||
|
</div> |
||||
|
</vue-dropzone> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import VueDropzone from 'vue2-dropzone' |
||||
|
import 'vue2-dropzone/dist/vue2Dropzone.min.css' |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
import { SettingsModule } from '@/store/modules/settings' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'Dropzone', |
||||
|
components: { |
||||
|
VueDropzone |
||||
|
} |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
// You can add more Prop, see: https://www.dropzonejs.com/#configuration |
||||
|
@Prop({ required: true }) private id!: string |
||||
|
@Prop({ required: true }) private url!: string |
||||
|
@Prop({ default: 200 }) private thumbnailHeight!: number |
||||
|
@Prop({ default: 200 }) private thumbnailWidth!: number |
||||
|
@Prop({ default: 4 }) private maxFiles!: number |
||||
|
@Prop({ default: 5 }) private maxFilesize!: number // In MB |
||||
|
@Prop({ default: true }) private autoProcessQueue!: boolean |
||||
|
@Prop({ default: true }) private addRemoveLinks!: boolean |
||||
|
@Prop({ default: 'Drop files here to upload' }) private dictDefaultMessage!: string |
||||
|
@Prop({ default: 'Your broswer does not support dropzone.js' }) private dictFallbackMessage!: string |
||||
|
@Prop({ default: 'Remove' }) private dictRemoveFile!: string |
||||
|
@Prop({ default: 'Max Files Exceeded' }) private dictMaxFilesExceeded!: string |
||||
|
|
||||
|
get dropzoneOptions() { |
||||
|
return { |
||||
|
url: this.url, |
||||
|
thumbnailWidth: this.thumbnailWidth, |
||||
|
thumbnailHeight: this.thumbnailHeight, |
||||
|
maxFiles: this.maxFiles, |
||||
|
maxFilesize: this.maxFilesize, |
||||
|
autoProcessQueue: this.autoProcessQueue, |
||||
|
addRemoveLinks: this.addRemoveLinks, |
||||
|
dictDefaultMessage: this.dictDefaultMessage, |
||||
|
dictFallbackMessage: this.dictFallbackMessage, |
||||
|
dictRemoveFile: this.dictRemoveFile, |
||||
|
dictMaxFilesExceeded: this.dictMaxFilesExceeded |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
get themeColor() { |
||||
|
return SettingsModule.theme |
||||
|
} |
||||
|
|
||||
|
// You can add more Event handler, see: https://rowanwins.github.io/vue-dropzone/docs/dist/#/events |
||||
|
private dropzoneSuccess(file: File, response: any) { |
||||
|
this.$emit('dropzone-success', file, response) |
||||
|
} |
||||
|
|
||||
|
private dropzoneRemovedFile(file: File, error: Error, xhr: XMLHttpRequest) { |
||||
|
this.$emit('dropzone-removed-file', file, error, xhr) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.dropzone-custom-content { |
||||
|
position: absolute; |
||||
|
top: 55%; |
||||
|
left: 50%; |
||||
|
transform: translate(-50%, -50%); |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.subtitle { |
||||
|
color: #314b5f; |
||||
|
} |
||||
|
|
||||
|
.dropzone { |
||||
|
min-height: 250px; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,105 @@ |
|||||
|
<template> |
||||
|
<div v-if="errorLogs.length>0"> |
||||
|
<el-badge |
||||
|
:is-dot="true" |
||||
|
style="line-height: 25px; margin-top: -5px;" |
||||
|
@click.native="dialogTableVisible=true" |
||||
|
> |
||||
|
<el-button |
||||
|
style="padding: 8px 10px;" |
||||
|
size="small" |
||||
|
type="danger" |
||||
|
> |
||||
|
<svg-icon name="bug" /> |
||||
|
</el-button> |
||||
|
</el-badge> |
||||
|
|
||||
|
<el-dialog |
||||
|
:visible.sync="dialogTableVisible" |
||||
|
width="80%" |
||||
|
append-to-body |
||||
|
> |
||||
|
<div slot="title"> |
||||
|
<span style="padding-right: 10px;">Error Log</span> |
||||
|
<el-button |
||||
|
size="mini" |
||||
|
type="primary" |
||||
|
icon="el-icon-delete" |
||||
|
@click="clearAll" |
||||
|
> |
||||
|
Clear All |
||||
|
</el-button> |
||||
|
</div> |
||||
|
<el-table |
||||
|
:data="errorLogs" |
||||
|
border |
||||
|
> |
||||
|
<el-table-column label="Message"> |
||||
|
<template slot-scope="{row}"> |
||||
|
<div> |
||||
|
<span class="message-title">Msg:</span> |
||||
|
<el-tag type="danger"> |
||||
|
{{ row.err.message }} |
||||
|
</el-tag> |
||||
|
</div> |
||||
|
<br> |
||||
|
<div> |
||||
|
<span |
||||
|
class="message-title" |
||||
|
style="padding-right: 10px;" |
||||
|
>Info: </span> |
||||
|
<el-tag type="warning"> |
||||
|
{{ row.vm.$vnode.tag }} error in {{ row.info }} |
||||
|
</el-tag> |
||||
|
</div> |
||||
|
<br> |
||||
|
<div> |
||||
|
<span |
||||
|
class="message-title" |
||||
|
style="padding-right: 16px;" |
||||
|
>Url: </span> |
||||
|
<el-tag type="success"> |
||||
|
{{ row.url }} |
||||
|
</el-tag> |
||||
|
</div> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
<el-table-column label="Stack"> |
||||
|
<template slot-scope="{row}"> |
||||
|
{{ row.err.stack }} |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Vue } from 'vue-property-decorator' |
||||
|
import { ErrorLogModule } from '@/store/modules/error-log' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'ErrorLog' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
private dialogTableVisible = false |
||||
|
|
||||
|
get errorLogs() { |
||||
|
return ErrorLogModule.logs |
||||
|
} |
||||
|
|
||||
|
private clearAll() { |
||||
|
this.dialogTableVisible = false |
||||
|
ErrorLogModule.ClearErrorLog() |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.message-title { |
||||
|
font-size: 16px; |
||||
|
color: #333; |
||||
|
font-weight: bold; |
||||
|
padding-right: 8px; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,71 @@ |
|||||
|
<template> |
||||
|
<a |
||||
|
href="https://github.com/armour/vue-typescript-admin-template" |
||||
|
target="_blank" |
||||
|
class="github-corner" |
||||
|
aria-label="View source on Github" |
||||
|
> |
||||
|
<svg |
||||
|
width="80" |
||||
|
height="80" |
||||
|
viewBox="0 0 250 250" |
||||
|
style="fill:#40c9c6; color:#fff;" |
||||
|
aria-hidden="true" |
||||
|
> |
||||
|
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z" /> |
||||
|
<path |
||||
|
d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" |
||||
|
fill="currentColor" |
||||
|
style="transform-origin: 130px 106px;" |
||||
|
class="octo-arm" |
||||
|
/> |
||||
|
<path |
||||
|
d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" |
||||
|
fill="currentColor" |
||||
|
class="octo-body" |
||||
|
/> |
||||
|
</svg> |
||||
|
</a> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Vue } from 'vue-property-decorator' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'GithubCorner' |
||||
|
}) |
||||
|
export default class extends Vue {} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.github-corner:hover .octo-arm { |
||||
|
animation: octocat-wave 560ms ease-in-out |
||||
|
} |
||||
|
|
||||
|
@keyframes octocat-wave { |
||||
|
0%, |
||||
|
100% { |
||||
|
transform: rotate(0) |
||||
|
} |
||||
|
|
||||
|
20%, |
||||
|
60% { |
||||
|
transform: rotate(-25deg) |
||||
|
} |
||||
|
|
||||
|
40%, |
||||
|
80% { |
||||
|
transform: rotate(10deg) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@media (max-width:500px) { |
||||
|
.github-corner:hover .octo-arm { |
||||
|
animation: none |
||||
|
} |
||||
|
|
||||
|
.github-corner .octo-arm { |
||||
|
animation: octocat-wave 560ms ease-in-out |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,37 @@ |
|||||
|
<template> |
||||
|
<div |
||||
|
:class="[{'is-active': isActive}]" |
||||
|
@click="toggleClick" |
||||
|
> |
||||
|
<svg-icon |
||||
|
name="hamburger" |
||||
|
width="20" |
||||
|
height="20" |
||||
|
/> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'Hamburger' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ default: false }) private isActive!: boolean |
||||
|
|
||||
|
private toggleClick() { |
||||
|
this.$emit('toggleClick') |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.svg-icon { |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
|
||||
|
.is-active { |
||||
|
transform: rotate(180deg); |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,218 @@ |
|||||
|
<template> |
||||
|
<div |
||||
|
id="header-search" |
||||
|
:class="{'show': show}" |
||||
|
class="header-search" |
||||
|
> |
||||
|
<svg-icon |
||||
|
class="search-icon" |
||||
|
name="search" |
||||
|
@click.stop="click" |
||||
|
/> |
||||
|
<el-select |
||||
|
ref="headerSearchSelect" |
||||
|
v-model="search" |
||||
|
:remote-method="querySearch" |
||||
|
filterable |
||||
|
default-first-option |
||||
|
remote |
||||
|
placeholder="Search" |
||||
|
class="header-search-select" |
||||
|
@change="change" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="item in options" |
||||
|
:key="item.path" |
||||
|
:value="item" |
||||
|
:label="item.meta.title.join(' > ')" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import path from 'path' |
||||
|
import Fuse from 'fuse.js' // A lightweight fuzzy-search module |
||||
|
import { Component, Vue, Watch } from 'vue-property-decorator' |
||||
|
import { RouteConfig } from 'vue-router' |
||||
|
import { AppModule } from '@/store/modules/app' |
||||
|
import { PermissionModule } from '@/store/modules/permission' |
||||
|
import i18n from '@/lang' // Internationalization |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'HeaderSearch' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
private search = '' |
||||
|
private show = false |
||||
|
private options: RouteConfig[] = [] |
||||
|
private searchPool: RouteConfig[] = [] |
||||
|
private fuse?: Fuse<RouteConfig, Fuse.IFuseOptions<RouteConfig>> |
||||
|
|
||||
|
get routes() { |
||||
|
return PermissionModule.routes |
||||
|
} |
||||
|
|
||||
|
get lang() { |
||||
|
return AppModule.language |
||||
|
} |
||||
|
|
||||
|
@Watch('lang') |
||||
|
private onLangChange() { |
||||
|
this.searchPool = this.generateRoutes(this.routes) |
||||
|
} |
||||
|
|
||||
|
@Watch('routes') |
||||
|
private onRoutesChange() { |
||||
|
this.searchPool = this.generateRoutes(this.routes) |
||||
|
} |
||||
|
|
||||
|
@Watch('searchPool') |
||||
|
private onSearchPoolChange(value: RouteConfig[]) { |
||||
|
this.initFuse(value) |
||||
|
} |
||||
|
|
||||
|
@Watch('show') |
||||
|
private onShowChange(value: boolean) { |
||||
|
if (value) { |
||||
|
document.body.addEventListener('click', this.close) |
||||
|
} else { |
||||
|
document.body.removeEventListener('click', this.close) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
mounted() { |
||||
|
this.searchPool = this.generateRoutes(this.routes) |
||||
|
} |
||||
|
|
||||
|
private click() { |
||||
|
this.show = !this.show |
||||
|
if (this.show) { |
||||
|
this.$refs.headerSearchSelect && (this.$refs.headerSearchSelect as HTMLElement).focus() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private close() { |
||||
|
this.$refs.headerSearchSelect && (this.$refs.headerSearchSelect as HTMLElement).blur() |
||||
|
this.options = [] |
||||
|
this.show = false |
||||
|
} |
||||
|
|
||||
|
private change(route: RouteConfig) { |
||||
|
this.$router.push(route.path) |
||||
|
this.search = '' |
||||
|
this.options = [] |
||||
|
this.$nextTick(() => { |
||||
|
this.show = false |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
private initFuse(list: RouteConfig[]) { |
||||
|
this.fuse = new Fuse(list, { |
||||
|
shouldSort: true, |
||||
|
threshold: 0.4, |
||||
|
location: 0, |
||||
|
distance: 100, |
||||
|
maxPatternLength: 32, |
||||
|
minMatchCharLength: 1, |
||||
|
keys: [{ |
||||
|
name: 'title', |
||||
|
weight: 0.7 |
||||
|
}, { |
||||
|
name: 'path', |
||||
|
weight: 0.3 |
||||
|
}] |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// Filter out the routes that can be displayed in the sidebar |
||||
|
// And generate the internationalized title |
||||
|
private generateRoutes(routes: RouteConfig[], basePath = '/', prefixTitle: string[] = []) { |
||||
|
let res: RouteConfig[] = [] |
||||
|
|
||||
|
for (const router of routes) { |
||||
|
// skip hidden router |
||||
|
if (router.meta && router.meta.hidden) { |
||||
|
continue |
||||
|
} |
||||
|
|
||||
|
const data: RouteConfig = { |
||||
|
path: path.resolve(basePath, router.path), |
||||
|
meta: { |
||||
|
title: [...prefixTitle] |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (router.meta && router.meta.title) { |
||||
|
// generate internationalized title |
||||
|
const i18ntitle = i18n.t(`route.${router.meta.title}`).toString() |
||||
|
data.meta.title = [...data.meta.title, i18ntitle] |
||||
|
if (router.redirect !== 'noRedirect') { |
||||
|
// only push the routes with title |
||||
|
// special case: need to exclude parent router without redirect |
||||
|
res.push(data) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// recursive child routes |
||||
|
if (router.children) { |
||||
|
const tempRoutes = this.generateRoutes(router.children, data.path, data.meta.title) |
||||
|
if (tempRoutes.length >= 1) { |
||||
|
res = [...res, ...tempRoutes] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return res |
||||
|
} |
||||
|
|
||||
|
private querySearch(query: string) { |
||||
|
if (query !== '') { |
||||
|
if (this.fuse) { |
||||
|
this.options = this.fuse.search(query).map((result) => result.item) |
||||
|
} |
||||
|
} else { |
||||
|
this.options = [] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.header-search { |
||||
|
font-size: 0 !important; |
||||
|
|
||||
|
.search-icon { |
||||
|
cursor: pointer; |
||||
|
font-size: 18px; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
|
||||
|
.header-search-select { |
||||
|
font-size: 18px; |
||||
|
transition: width 0.2s; |
||||
|
width: 0; |
||||
|
overflow: hidden; |
||||
|
background: transparent; |
||||
|
border-radius: 0; |
||||
|
display: inline-block; |
||||
|
vertical-align: middle; |
||||
|
|
||||
|
.el-input__inner { |
||||
|
border-radius: 0; |
||||
|
border: 0; |
||||
|
padding-left: 0; |
||||
|
padding-right: 0; |
||||
|
box-shadow: none !important; |
||||
|
border-bottom: 1px solid #d9d9d9; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&.show { |
||||
|
.header-search-select { |
||||
|
width: 210px; |
||||
|
margin-left: 10px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,91 @@ |
|||||
|
<template> |
||||
|
<div class="json-editor"> |
||||
|
<textarea ref="textarea" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import CodeMirror, { Editor } from 'codemirror' |
||||
|
import 'codemirror/addon/lint/lint.css' |
||||
|
import 'codemirror/lib/codemirror.css' |
||||
|
import 'codemirror/theme/rubyblue.css' |
||||
|
import 'codemirror/mode/javascript/javascript' |
||||
|
import 'codemirror/addon/lint/lint' |
||||
|
import 'codemirror/addon/lint/json-lint' |
||||
|
import { Component, Prop, Vue, Watch } from 'vue-property-decorator' |
||||
|
|
||||
|
// HACK: have to use script-loader to load jsonlint |
||||
|
/* eslint-disable import/no-webpack-loader-syntax */ |
||||
|
require('script-loader!jsonlint') |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'JsonEditor' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ required: true }) private value!: string |
||||
|
|
||||
|
private jsonEditor?: Editor |
||||
|
|
||||
|
@Watch('value') |
||||
|
private onValueChange(value: string) { |
||||
|
if (this.jsonEditor) { |
||||
|
const editorValue = this.jsonEditor.getValue() |
||||
|
if (value !== editorValue) { |
||||
|
this.jsonEditor.setValue(JSON.stringify(this.value, null, 2)) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
mounted() { |
||||
|
this.jsonEditor = CodeMirror.fromTextArea(this.$refs.textarea as HTMLTextAreaElement, { |
||||
|
lineNumbers: true, |
||||
|
mode: 'application/json', |
||||
|
gutters: ['CodeMirror-lint-markers'], |
||||
|
theme: 'rubyblue', |
||||
|
lint: true |
||||
|
}) |
||||
|
|
||||
|
this.jsonEditor.setValue(JSON.stringify(this.value, null, 2)) |
||||
|
this.jsonEditor.on('change', editor => { |
||||
|
this.$emit('changed', editor.getValue()) |
||||
|
this.$emit('input', editor.getValue()) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
public setValue(value: string) { |
||||
|
if (this.jsonEditor) { |
||||
|
this.jsonEditor.setValue(value) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public getValue() { |
||||
|
if (this.jsonEditor) { |
||||
|
return this.jsonEditor.getValue() |
||||
|
} |
||||
|
return '' |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.CodeMirror { |
||||
|
height: auto; |
||||
|
min-height: 300px; |
||||
|
font-family: inherit; |
||||
|
} |
||||
|
|
||||
|
.CodeMirror-scroll { |
||||
|
min-height: 300px; |
||||
|
} |
||||
|
|
||||
|
.cm span.cm-string { |
||||
|
color: #F08047; |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.json-editor { |
||||
|
height: 100%; |
||||
|
position: relative; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,69 @@ |
|||||
|
<template> |
||||
|
<el-dropdown |
||||
|
trigger="click" |
||||
|
class="international" |
||||
|
@command="handleSetLanguage" |
||||
|
> |
||||
|
<div> |
||||
|
<svg-icon |
||||
|
name="language" |
||||
|
class="international-icon" |
||||
|
/> |
||||
|
</div> |
||||
|
<el-dropdown-menu slot="dropdown"> |
||||
|
<el-dropdown-item |
||||
|
:disabled="language==='zh'" |
||||
|
command="zh" |
||||
|
> |
||||
|
中文 |
||||
|
</el-dropdown-item> |
||||
|
<el-dropdown-item |
||||
|
:disabled="language==='en'" |
||||
|
command="en" |
||||
|
> |
||||
|
English |
||||
|
</el-dropdown-item> |
||||
|
<el-dropdown-item |
||||
|
:disabled="language==='es'" |
||||
|
command="es" |
||||
|
> |
||||
|
Español |
||||
|
</el-dropdown-item> |
||||
|
<el-dropdown-item |
||||
|
:disabled="language==='ja'" |
||||
|
command="ja" |
||||
|
> |
||||
|
日本語 |
||||
|
</el-dropdown-item> |
||||
|
<el-dropdown-item |
||||
|
:disabled="language==='ko'" |
||||
|
command="ko" |
||||
|
> |
||||
|
한국어 |
||||
|
</el-dropdown-item> |
||||
|
</el-dropdown-menu> |
||||
|
</el-dropdown> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Vue } from 'vue-property-decorator' |
||||
|
import { AppModule } from '@/store/modules/app' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'Login' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
get language() { |
||||
|
return AppModule.language |
||||
|
} |
||||
|
|
||||
|
private handleSetLanguage(lang: string) { |
||||
|
this.$i18n.locale = lang |
||||
|
AppModule.SetLanguage(lang) |
||||
|
this.$message({ |
||||
|
message: 'Switch Language Success', |
||||
|
type: 'success' |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,27 @@ |
|||||
|
// Doc: https://nhn.github.io/tui.editor/api/latest/ToastUIEditor.html#ToastUIEditor
|
||||
|
export default { |
||||
|
previewStyle: 'vertical', |
||||
|
usageStatistics: false, |
||||
|
toolbarItems: [ |
||||
|
'heading', |
||||
|
'bold', |
||||
|
'italic', |
||||
|
'strike', |
||||
|
'divider', |
||||
|
'hr', |
||||
|
'quote', |
||||
|
'divider', |
||||
|
'ul', |
||||
|
'ol', |
||||
|
'task', |
||||
|
'indent', |
||||
|
'outdent', |
||||
|
'divider', |
||||
|
'table', |
||||
|
'image', |
||||
|
'link', |
||||
|
'divider', |
||||
|
'code', |
||||
|
'codeblock' |
||||
|
] |
||||
|
} |
||||
@ -0,0 +1,130 @@ |
|||||
|
<template> |
||||
|
<div :id="id" /> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import 'codemirror/lib/codemirror.css' // codemirror |
||||
|
import 'tui-editor/dist/tui-editor.css' // editor ui |
||||
|
import 'tui-editor/dist/tui-editor-contents.css' // editor content |
||||
|
import { Component, Prop, Vue, Watch } from 'vue-property-decorator' |
||||
|
import defaultOptions from './default-options' |
||||
|
import TuiEditor from 'tui-editor' |
||||
|
|
||||
|
const defaultId = () => 'markdown-editor-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '') |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'MarkdownEditor' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ required: true }) private value!: string |
||||
|
@Prop({ default: defaultId }) private id!: string |
||||
|
@Prop({ default: () => defaultOptions }) private options!: tuiEditor.IEditorOptions |
||||
|
@Prop({ default: 'markdown' }) private mode!: string |
||||
|
@Prop({ default: '300px' }) private height!: string |
||||
|
// https://github.com/nhnent/tui.editor/tree/master/src/js/langs |
||||
|
@Prop({ default: 'en_US' }) private language!: string |
||||
|
|
||||
|
private markdownEditor?: tuiEditor.Editor |
||||
|
|
||||
|
get editorOptions() { |
||||
|
const options = Object.assign({}, defaultOptions, this.options) |
||||
|
options.initialEditType = this.mode |
||||
|
options.height = this.height |
||||
|
options.language = this.language |
||||
|
return options |
||||
|
} |
||||
|
|
||||
|
@Watch('value') |
||||
|
private onValueChange(value: string, oldValue: string) { |
||||
|
if (this.markdownEditor) { |
||||
|
if (value !== oldValue && value !== this.markdownEditor.getValue()) { |
||||
|
this.markdownEditor.setValue(value) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Watch('language') |
||||
|
private onLanguageChange() { |
||||
|
this.destroyEditor() |
||||
|
this.initEditor() |
||||
|
} |
||||
|
|
||||
|
@Watch('height') |
||||
|
private onHeightChange(value: string) { |
||||
|
if (this.markdownEditor) { |
||||
|
this.markdownEditor.height(value) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Watch('mode') |
||||
|
private onModeChange(value: string) { |
||||
|
if (this.markdownEditor) { |
||||
|
this.markdownEditor.changeMode(value) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
mounted() { |
||||
|
this.initEditor() |
||||
|
} |
||||
|
|
||||
|
destroyed() { |
||||
|
this.destroyEditor() |
||||
|
} |
||||
|
|
||||
|
private initEditor() { |
||||
|
const editorElement = document.getElementById(this.id) |
||||
|
if (!editorElement) return |
||||
|
this.markdownEditor = new TuiEditor({ |
||||
|
el: editorElement, |
||||
|
...this.editorOptions |
||||
|
}) |
||||
|
if (this.value) { |
||||
|
this.markdownEditor.setValue(this.value) |
||||
|
} |
||||
|
this.markdownEditor.on('change', () => { |
||||
|
if (this.markdownEditor !== undefined) { |
||||
|
this.$emit('input', this.markdownEditor.getValue()) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
private destroyEditor() { |
||||
|
if (!this.markdownEditor) return |
||||
|
this.markdownEditor.off('change') |
||||
|
this.markdownEditor.remove() |
||||
|
this.markdownEditor = undefined |
||||
|
} |
||||
|
|
||||
|
public focus() { |
||||
|
if (this.markdownEditor) { |
||||
|
this.markdownEditor.focus() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public setValue(value: string) { |
||||
|
if (this.markdownEditor) { |
||||
|
this.markdownEditor.setValue(value) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public getValue() { |
||||
|
if (this.markdownEditor) { |
||||
|
return this.markdownEditor.getValue() |
||||
|
} |
||||
|
return '' |
||||
|
} |
||||
|
|
||||
|
public setHtml(value: string) { |
||||
|
if (this.markdownEditor) { |
||||
|
this.markdownEditor.setHtml(value) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public getHtml() { |
||||
|
if (this.markdownEditor) { |
||||
|
return this.markdownEditor.getHtml() |
||||
|
} |
||||
|
return '' |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,381 @@ |
|||||
|
<template> |
||||
|
<div |
||||
|
:class="computedClasses" |
||||
|
class="material-input__component" |
||||
|
> |
||||
|
<div :class="{iconClass: icon}"> |
||||
|
<i |
||||
|
v-if="icon" |
||||
|
:class="['el-icon-' + icon]" |
||||
|
class="el-input__icon material-input__icon" |
||||
|
/> |
||||
|
<input |
||||
|
v-if="type === 'email'" |
||||
|
:id="id" |
||||
|
v-model="valueCopy" |
||||
|
type="email" |
||||
|
class="material-input" |
||||
|
:name="name" |
||||
|
:placeholder="filledPlaceholder" |
||||
|
:readonly="readonly" |
||||
|
:disabled="disabled" |
||||
|
:autocomplete="autoComplete" |
||||
|
:required="required" |
||||
|
@focus="handleFocus" |
||||
|
@blur="handleBlur" |
||||
|
@input="handleInput" |
||||
|
> |
||||
|
<input |
||||
|
v-if="type === 'url'" |
||||
|
:id="id" |
||||
|
v-model="valueCopy" |
||||
|
type="url" |
||||
|
class="material-input" |
||||
|
:name="name" |
||||
|
:placeholder="filledPlaceholder" |
||||
|
:readonly="readonly" |
||||
|
:disabled="disabled" |
||||
|
:autocomplete="autoComplete" |
||||
|
:required="required" |
||||
|
@focus="handleFocus" |
||||
|
@blur="handleBlur" |
||||
|
@input="handleInput" |
||||
|
> |
||||
|
<input |
||||
|
v-if="type === 'number'" |
||||
|
:id="id" |
||||
|
v-model="valueCopy" |
||||
|
type="number" |
||||
|
class="material-input" |
||||
|
:name="name" |
||||
|
:placeholder="filledPlaceholder" |
||||
|
:readonly="readonly" |
||||
|
:disabled="disabled" |
||||
|
:autocomplete="autoComplete" |
||||
|
:max="max" |
||||
|
:min="min" |
||||
|
:step="step" |
||||
|
:minlength="minlength" |
||||
|
:maxlength="maxlength" |
||||
|
:required="required" |
||||
|
@focus="handleFocus" |
||||
|
@blur="handleBlur" |
||||
|
@input="handleInput" |
||||
|
> |
||||
|
<input |
||||
|
v-if="type === 'password'" |
||||
|
:id="id" |
||||
|
v-model="valueCopy" |
||||
|
type="password" |
||||
|
class="material-input" |
||||
|
:name="name" |
||||
|
:placeholder="filledPlaceholder" |
||||
|
:readonly="readonly" |
||||
|
:disabled="disabled" |
||||
|
:autocomplete="autoComplete" |
||||
|
:max="max" |
||||
|
:min="min" |
||||
|
:step="step" |
||||
|
:required="required" |
||||
|
@focus="handleFocus" |
||||
|
@blur="handleBlur" |
||||
|
@input="handleInput" |
||||
|
> |
||||
|
<input |
||||
|
v-if="type === 'tel'" |
||||
|
:id="id" |
||||
|
v-model="valueCopy" |
||||
|
type="tel" |
||||
|
class="material-input" |
||||
|
:name="name" |
||||
|
:placeholder="filledPlaceholder" |
||||
|
:readonly="readonly" |
||||
|
:disabled="disabled" |
||||
|
:autocomplete="autoComplete" |
||||
|
:required="required" |
||||
|
@focus="handleFocus" |
||||
|
@blur="handleBlur" |
||||
|
@input="handleInput" |
||||
|
> |
||||
|
<input |
||||
|
v-if="type === 'text'" |
||||
|
:id="id" |
||||
|
v-model="valueCopy" |
||||
|
type="text" |
||||
|
class="material-input" |
||||
|
:name="name" |
||||
|
:placeholder="filledPlaceholder" |
||||
|
:readonly="readonly" |
||||
|
:disabled="disabled" |
||||
|
:autocomplete="autoComplete" |
||||
|
:minlength="minlength" |
||||
|
:maxlength="maxlength" |
||||
|
:required="required" |
||||
|
@focus="handleFocus" |
||||
|
@blur="handleBlur" |
||||
|
@input="handleInput" |
||||
|
> |
||||
|
<span class="material-input-bar" /> |
||||
|
<label class="material-label"> |
||||
|
<slot /> |
||||
|
</label> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
// Source: https://github.com/wemake-services/vue-material-input/blob/master/src/components/MaterialInput.vue |
||||
|
import { Component, Prop, Vue, Watch } from 'vue-property-decorator' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'MaterialInput' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ required: true }) private value!: any |
||||
|
@Prop({ default: 'text' }) private type!: string |
||||
|
@Prop({ default: '' }) private id!: string |
||||
|
@Prop({ default: '' }) private icon!: string |
||||
|
@Prop({ default: '' }) private name!: string |
||||
|
@Prop({ default: '' }) private placeholder!: string |
||||
|
@Prop({ default: false }) private readonly!: boolean |
||||
|
@Prop({ default: false }) private disabled!: boolean |
||||
|
@Prop({ default: true }) private required!: boolean |
||||
|
@Prop({ default: 'off' }) private autoComplete!: string |
||||
|
@Prop({ default: 0 }) private min!: number | Date |
||||
|
@Prop({ default: 10000 }) private max!: number | Date |
||||
|
@Prop({ default: 1 }) private step!: number |
||||
|
@Prop({ default: 0 }) private minlength!: number |
||||
|
@Prop({ default: 20 }) private maxlength!: number |
||||
|
@Prop({ default: true }) private validateEvent!: boolean |
||||
|
|
||||
|
private valueCopy = this.value |
||||
|
private focus = false |
||||
|
|
||||
|
@Watch('value') |
||||
|
private onValueChange(value: any) { |
||||
|
this.valueCopy = value |
||||
|
} |
||||
|
|
||||
|
get computedClasses() { |
||||
|
return { |
||||
|
'material--active': this.focus, |
||||
|
'material--disabled': this.disabled, |
||||
|
'material--raised': Boolean(this.focus || this.valueCopy) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
get filledPlaceholder() { |
||||
|
if (this.focus) { |
||||
|
return this.placeholder |
||||
|
} |
||||
|
return '' |
||||
|
} |
||||
|
|
||||
|
private handleInput(event: KeyboardEvent) { |
||||
|
const value = (event.target as HTMLInputElement).value |
||||
|
this.$emit('input', value) |
||||
|
if (this.$parent.$options.name === 'ElFormItem') { |
||||
|
if (this.validateEvent) { |
||||
|
this.$parent.$emit('el.form.change', [value]) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private handleFocus(event: FocusEvent) { |
||||
|
this.focus = true |
||||
|
this.$emit('focus', event) |
||||
|
} |
||||
|
|
||||
|
private handleBlur(event: FocusEvent) { |
||||
|
this.focus = false |
||||
|
this.$emit('blur', event) |
||||
|
if (this.$parent.$options.name === 'ElFormItem') { |
||||
|
if (this.validateEvent) { |
||||
|
this.$parent.$emit('el.form.blur', [this.valueCopy]) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
// Fonts: |
||||
|
$font-size-base: 16px; |
||||
|
$font-size-small: 14px; |
||||
|
$font-size-smallest: 12px; |
||||
|
$font-weight-normal: normal; |
||||
|
$font-weight-bold: bold; |
||||
|
|
||||
|
// Utils |
||||
|
$spacer: 10px; |
||||
|
$transition: 0.2s ease all; |
||||
|
$index-has-icon: 30px; |
||||
|
|
||||
|
// Theme: |
||||
|
$color-white: white; |
||||
|
$color-grey: #9E9E9E; |
||||
|
$color-grey-light: #E0E0E0; |
||||
|
$color-blue: #2196F3; |
||||
|
$color-red: #F44336; |
||||
|
$color-black: black; |
||||
|
|
||||
|
// Base clases: |
||||
|
%base-bar-pseudo { |
||||
|
content: ''; |
||||
|
height: 1px; |
||||
|
width: 0; |
||||
|
bottom: 0; |
||||
|
position: absolute; |
||||
|
transition: $transition; |
||||
|
} |
||||
|
|
||||
|
// Mixins: |
||||
|
@mixin slided-top() { |
||||
|
top: - ($font-size-base + $spacer); |
||||
|
left: 0; |
||||
|
font-size: $font-size-base; |
||||
|
font-weight: $font-weight-bold; |
||||
|
} |
||||
|
|
||||
|
// Component: |
||||
|
.material-input__component { |
||||
|
margin-top: 45px; |
||||
|
position: relative; |
||||
|
|
||||
|
* { |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.iconClass { |
||||
|
.material-input__icon { |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
line-height: $font-size-base; |
||||
|
color: $color-blue; |
||||
|
top: $spacer; |
||||
|
width: $index-has-icon; |
||||
|
height: $font-size-base; |
||||
|
font-size: $font-size-base; |
||||
|
font-weight: $font-weight-normal; |
||||
|
pointer-events: none; |
||||
|
} |
||||
|
|
||||
|
.material-label { |
||||
|
left: $index-has-icon; |
||||
|
} |
||||
|
|
||||
|
.material-input { |
||||
|
text-indent: $index-has-icon; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.material-input { |
||||
|
font-size: $font-size-base; |
||||
|
padding: $spacer $spacer $spacer $spacer / 2; |
||||
|
display: block; |
||||
|
width: 100%; |
||||
|
border: none; |
||||
|
border-radius: 0; |
||||
|
|
||||
|
&:focus { |
||||
|
outline: none; |
||||
|
border: none; |
||||
|
border-bottom: 1px solid transparent; // fixes the height issue |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.material-label { |
||||
|
font-size: $font-size-small; |
||||
|
font-weight: $font-weight-normal; |
||||
|
position: absolute; |
||||
|
pointer-events: none; |
||||
|
left: 0; |
||||
|
top: 0; |
||||
|
transition: $transition; |
||||
|
} |
||||
|
|
||||
|
.material-input-bar { |
||||
|
position: relative; |
||||
|
display: block; |
||||
|
width: 100%; |
||||
|
|
||||
|
&:before { |
||||
|
@extend %base-bar-pseudo; |
||||
|
left: 50%; |
||||
|
} |
||||
|
|
||||
|
&:after { |
||||
|
@extend %base-bar-pseudo; |
||||
|
right: 50%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Disabled state: |
||||
|
&.material--disabled { |
||||
|
.material-input { |
||||
|
border-bottom-style: dashed; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Raised state: |
||||
|
&.material--raised { |
||||
|
.material-label { |
||||
|
@include slided-top(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Active state: |
||||
|
&.material--active { |
||||
|
.material-input-bar { |
||||
|
&:before, |
||||
|
&:after { |
||||
|
width: 50%; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Errors: |
||||
|
.material-errors { |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
|
||||
|
.material-error { |
||||
|
font-size: $font-size-smallest; |
||||
|
line-height: $font-size-smallest + 2px; |
||||
|
overflow: hidden; |
||||
|
margin-top: 0; |
||||
|
padding-top: $spacer / 2; |
||||
|
padding-right: $spacer / 2; |
||||
|
padding-left: 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.material-input__component { |
||||
|
background: $color-white; |
||||
|
|
||||
|
.material-input { |
||||
|
background: none; |
||||
|
color: $color-black; |
||||
|
border-bottom: 1px solid $color-grey-light; |
||||
|
} |
||||
|
|
||||
|
.material-label { |
||||
|
color: $color-grey; |
||||
|
} |
||||
|
|
||||
|
.material-input-bar { |
||||
|
&:before, |
||||
|
&:after { |
||||
|
background: $color-blue; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Active state: |
||||
|
&.material--active { |
||||
|
.material-label { |
||||
|
color: $color-blue; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,78 @@ |
|||||
|
<template> |
||||
|
<div |
||||
|
:class="{'hidden': hidden}" |
||||
|
class="pagination-container" |
||||
|
> |
||||
|
<el-pagination |
||||
|
:background="background" |
||||
|
:current-page.sync="currentPage" |
||||
|
:page-size.sync="pageSize" |
||||
|
:layout="layout" |
||||
|
:page-sizes="pageSizes" |
||||
|
:total="total" |
||||
|
v-bind="$attrs" |
||||
|
@size-change="handleSizeChange" |
||||
|
@current-change="handleCurrentChange" |
||||
|
/> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
import { scrollTo } from '@/utils/scroll-to' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'Pagination' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ required: true }) private total!: number |
||||
|
@Prop({ default: 1 }) private page!: number |
||||
|
@Prop({ default: 20 }) private limit!: number |
||||
|
@Prop({ default: () => [10, 20, 30, 50] }) private pageSizes!: number[] |
||||
|
@Prop({ default: 'total, sizes, prev, pager, next, jumper' }) private layout!: string |
||||
|
@Prop({ default: true }) private background!: boolean |
||||
|
@Prop({ default: true }) private autoScroll!: boolean |
||||
|
@Prop({ default: false }) private hidden!: boolean |
||||
|
|
||||
|
get currentPage() { |
||||
|
return this.page |
||||
|
} |
||||
|
|
||||
|
set currentPage(value) { |
||||
|
this.$emit('update:page', value) |
||||
|
} |
||||
|
|
||||
|
get pageSize() { |
||||
|
return this.limit |
||||
|
} |
||||
|
|
||||
|
set pageSize(value) { |
||||
|
this.$emit('update:limit', value) |
||||
|
} |
||||
|
|
||||
|
handleSizeChange(value: number) { |
||||
|
this.$emit('pagination', { page: this.currentPage, limit: value }) |
||||
|
if (this.autoScroll) { |
||||
|
scrollTo(0, 800) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
handleCurrentChange(value: number) { |
||||
|
this.$emit('pagination', { page: value, limit: this.pageSize }) |
||||
|
if (this.autoScroll) { |
||||
|
scrollTo(0, 800) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.pagination-container { |
||||
|
background: #fff; |
||||
|
padding: 32px 16px; |
||||
|
} |
||||
|
|
||||
|
.pagination-container.hidden { |
||||
|
display: none; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,124 @@ |
|||||
|
<template> |
||||
|
<div |
||||
|
:style="{zIndex: zIndex, height: height, width: width}" |
||||
|
class="pan-item" |
||||
|
> |
||||
|
<div class="pan-info"> |
||||
|
<div class="pan-info-roles-container"> |
||||
|
<slot /> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div |
||||
|
:style="{backgroundImage: `url(${image})`}" |
||||
|
class="pan-thumb" |
||||
|
/> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'PanThumb' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ required: true }) private image!: string |
||||
|
@Prop({ default: '150px' }) private width!: string |
||||
|
@Prop({ default: '150px' }) private height!: string |
||||
|
@Prop({ default: 1 }) private zIndex!: number |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.pan-item { |
||||
|
width: 200px; |
||||
|
height: 200px; |
||||
|
border-radius: 50%; |
||||
|
display: inline-block; |
||||
|
position: relative; |
||||
|
cursor: default; |
||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); |
||||
|
|
||||
|
&:hover .pan-thumb { |
||||
|
transform: rotate(-110deg); |
||||
|
} |
||||
|
|
||||
|
&:hover .pan-info p a { |
||||
|
opacity: 1; |
||||
|
transform: translateX(0px) rotate(0deg); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.pan-info { |
||||
|
position: absolute; |
||||
|
width: inherit; |
||||
|
height: inherit; |
||||
|
border-radius: 50%; |
||||
|
overflow: hidden; |
||||
|
box-shadow: inset 0 0 0 5px rgba(0, 0, 0, 0.05); |
||||
|
|
||||
|
.pan-info-roles-container { |
||||
|
padding: 20px; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
h3 { |
||||
|
color: #fff; |
||||
|
text-transform: uppercase; |
||||
|
position: relative; |
||||
|
letter-spacing: 2px; |
||||
|
font-size: 18px; |
||||
|
margin: 0 60px; |
||||
|
padding: 22px 0 0 0; |
||||
|
height: 85px; |
||||
|
font-family: 'Open Sans', Arial, sans-serif; |
||||
|
text-shadow: 0 0 1px #fff, 0 1px 2px rgba(0, 0, 0, 0.3); |
||||
|
} |
||||
|
|
||||
|
p { |
||||
|
color: #fff; |
||||
|
padding: 10px 5px; |
||||
|
font-style: italic; |
||||
|
margin: 0 30px; |
||||
|
font-size: 12px; |
||||
|
border-top: 1px solid rgba(255, 255, 255, 0.5); |
||||
|
|
||||
|
a { |
||||
|
display: block; |
||||
|
color: #333; |
||||
|
width: 80px; |
||||
|
height: 80px; |
||||
|
background: rgba(255, 255, 255, 0.3); |
||||
|
border-radius: 50%; |
||||
|
color: #fff; |
||||
|
font-style: normal; |
||||
|
font-weight: 700; |
||||
|
text-transform: uppercase; |
||||
|
font-size: 9px; |
||||
|
letter-spacing: 1px; |
||||
|
padding-top: 24px; |
||||
|
margin: 7px auto 0; |
||||
|
font-family: 'Open Sans', Arial, sans-serif; |
||||
|
opacity: 0; |
||||
|
transition: transform 0.3s ease-in-out 0.2s, opacity 0.3s ease-in-out 0.2s, background 0.2s linear 0s; |
||||
|
transform: translateX(60px) rotate(90deg); |
||||
|
|
||||
|
&:hover { |
||||
|
background: rgba(255, 255, 255, 0.5); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.pan-thumb { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
background-position: center center; |
||||
|
background-size: cover; |
||||
|
border-radius: 50%; |
||||
|
overflow: hidden; |
||||
|
position: absolute; |
||||
|
transform-origin: 95% 40%; |
||||
|
transition: all 0.3s ease-in-out; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,151 @@ |
|||||
|
<template> |
||||
|
<div |
||||
|
ref="rightPanel" |
||||
|
:class="{show: show}" |
||||
|
class="rightPanel-container" |
||||
|
> |
||||
|
<div class="rightPanel-background" /> |
||||
|
<div class="rightPanel"> |
||||
|
<div |
||||
|
class="handle-button" |
||||
|
:style="{'top': buttonTop+'px','background-color': theme}" |
||||
|
@click="show=!show" |
||||
|
> |
||||
|
<i :class="show?'el-icon-close':'el-icon-setting'" /> |
||||
|
</div> |
||||
|
<div class="rightPanel-items"> |
||||
|
<slot /> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Prop, Vue, Watch } from 'vue-property-decorator' |
||||
|
import { addClass, removeClass } from '@/utils' |
||||
|
import { SettingsModule } from '@/store/modules/settings' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'RightPanel' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ default: false }) private clickNotClose!: boolean |
||||
|
@Prop({ default: 250 }) private buttonTop!: number |
||||
|
|
||||
|
private show = false |
||||
|
|
||||
|
get theme() { |
||||
|
return SettingsModule.theme |
||||
|
} |
||||
|
|
||||
|
@Watch('show') |
||||
|
private onShowChange(value: boolean) { |
||||
|
if (value && !this.clickNotClose) { |
||||
|
this.addEventClick() |
||||
|
} |
||||
|
if (value) { |
||||
|
addClass(document.body, 'showRightPanel') |
||||
|
} else { |
||||
|
removeClass(document.body, 'showRightPanel') |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
mounted() { |
||||
|
this.insertToBody() |
||||
|
} |
||||
|
|
||||
|
beforeDestroy() { |
||||
|
const elx = this.$refs.rightPanel as Element |
||||
|
elx.remove() |
||||
|
} |
||||
|
|
||||
|
private addEventClick() { |
||||
|
window.addEventListener('click', this.closeSidebar) |
||||
|
} |
||||
|
|
||||
|
private closeSidebar(ev: MouseEvent) { |
||||
|
const parent = (ev.target as HTMLElement).closest('.rightPanel') |
||||
|
if (!parent) { |
||||
|
this.show = false |
||||
|
window.removeEventListener('click', this.closeSidebar) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private insertToBody() { |
||||
|
const elx = this.$refs.rightPanel as Element |
||||
|
const body = document.querySelector('body') |
||||
|
if (body) { |
||||
|
body.insertBefore(elx, body.firstChild) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.showRightPanel { |
||||
|
overflow: hidden; |
||||
|
position: relative; |
||||
|
width: calc(100% - 15px); |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.rightPanel-background { |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
opacity: 0; |
||||
|
transition: opacity .3s cubic-bezier(.7, .3, .1, 1); |
||||
|
background: rgba(0, 0, 0, .2); |
||||
|
z-index: -1; |
||||
|
} |
||||
|
|
||||
|
.rightPanel { |
||||
|
width: 100%; |
||||
|
max-width: 260px; |
||||
|
height: 100vh; |
||||
|
position: fixed; |
||||
|
top: 0; |
||||
|
right: 0; |
||||
|
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05); |
||||
|
transition: all .25s cubic-bezier(.7, .3, .1, 1); |
||||
|
transform: translate(100%); |
||||
|
background: #fff; |
||||
|
z-index: 40000; |
||||
|
} |
||||
|
|
||||
|
.show { |
||||
|
transition: all .3s cubic-bezier(.7, .3, .1, 1); |
||||
|
|
||||
|
.rightPanel-background { |
||||
|
z-index: 20000; |
||||
|
opacity: 1; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.rightPanel { |
||||
|
transform: translate(0); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.handle-button { |
||||
|
width: 48px; |
||||
|
height: 48px; |
||||
|
position: absolute; |
||||
|
left: -48px; |
||||
|
text-align: center; |
||||
|
font-size: 24px; |
||||
|
border-radius: 6px 0 0 6px !important; |
||||
|
z-index: 0; |
||||
|
cursor: pointer; |
||||
|
pointer-events: auto; |
||||
|
color: #fff; |
||||
|
line-height: 48px; |
||||
|
|
||||
|
i { |
||||
|
font-size: 24px; |
||||
|
line-height: 48px; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,51 @@ |
|||||
|
<template> |
||||
|
<div id="screenfull"> |
||||
|
<svg-icon |
||||
|
:name="isFullscreen? 'exit-fullscreen': 'fullscreen'" |
||||
|
@click="click" |
||||
|
/> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import screenfull from 'screenfull' |
||||
|
import { Component, Vue } from 'vue-property-decorator' |
||||
|
|
||||
|
const sf = screenfull |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'Screenfull' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
private isFullscreen = false |
||||
|
|
||||
|
mounted() { |
||||
|
if (sf.isEnabled) { |
||||
|
sf.on('change', this.change) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
beforeDestory() { |
||||
|
if (sf.isEnabled) { |
||||
|
sf.off('change', this.change) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private change() { |
||||
|
if (sf.isEnabled) { |
||||
|
this.isFullscreen = sf.isFullscreen |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private click() { |
||||
|
if (!sf.isEnabled) { |
||||
|
this.$message({ |
||||
|
message: 'you browser can not work', |
||||
|
type: 'warning' |
||||
|
}) |
||||
|
return false |
||||
|
} |
||||
|
sf.toggle() |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,68 @@ |
|||||
|
<template> |
||||
|
<el-dropdown |
||||
|
id="size-select" |
||||
|
trigger="click" |
||||
|
@command="handleSetSize" |
||||
|
> |
||||
|
<div> |
||||
|
<svg-icon |
||||
|
class="size-icon" |
||||
|
name="size" |
||||
|
/> |
||||
|
</div> |
||||
|
<el-dropdown-menu slot="dropdown"> |
||||
|
<el-dropdown-item |
||||
|
v-for="item of sizeOptions" |
||||
|
:key="item.value" |
||||
|
:disabled="size===item.value" |
||||
|
:command="item.value" |
||||
|
> |
||||
|
{{ |
||||
|
item.label }} |
||||
|
</el-dropdown-item> |
||||
|
</el-dropdown-menu> |
||||
|
</el-dropdown> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Vue } from 'vue-property-decorator' |
||||
|
import { AppModule } from '@/store/modules/app' |
||||
|
import { TagsViewModule } from '@/store/modules/tags-view' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'SizeSelect' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
private sizeOptions = [ |
||||
|
{ label: 'Default', value: 'default' }, |
||||
|
{ label: 'Medium', value: 'medium' }, |
||||
|
{ label: 'Small', value: 'small' }, |
||||
|
{ label: 'Mini', value: 'mini' } |
||||
|
] |
||||
|
|
||||
|
get size() { |
||||
|
return AppModule.size |
||||
|
} |
||||
|
|
||||
|
private handleSetSize(size: string) { |
||||
|
(this as any).$ELEMENT.size = size |
||||
|
AppModule.SetSize(size) |
||||
|
this.refreshView() |
||||
|
this.$message({ |
||||
|
message: 'Switch Size Success', |
||||
|
type: 'success' |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
private refreshView() { |
||||
|
// In order to make the cached page re-rendered |
||||
|
TagsViewModule.delAllCachedViews() |
||||
|
const { fullPath } = this.$route |
||||
|
this.$nextTick(() => { |
||||
|
this.$router.replace({ |
||||
|
path: '/redirect' + fullPath |
||||
|
}) |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,83 @@ |
|||||
|
<template> |
||||
|
<div :style="{height: height, zIndex: zIndex}"> |
||||
|
<div |
||||
|
:class="className" |
||||
|
:style="{top: (isSticky ? stickyTop +'px' : ''), zIndex: zIndex, position: position, width: width, height: height}" |
||||
|
> |
||||
|
<slot> |
||||
|
<div>sticky</div> |
||||
|
</slot> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'Sticky' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ default: 0 }) private stickyTop!: number |
||||
|
@Prop({ default: 1 }) private zIndex!: number |
||||
|
@Prop({ default: '' }) private className!: string |
||||
|
|
||||
|
private active = false |
||||
|
private position = '' |
||||
|
private isSticky = false |
||||
|
private width = 'auto' |
||||
|
private height = 'auto' |
||||
|
|
||||
|
mounted() { |
||||
|
this.height = this.$el.getBoundingClientRect().height.toString() + 'px' |
||||
|
window.addEventListener('scroll', this.handleScroll) |
||||
|
window.addEventListener('resize', this.handleResize) |
||||
|
} |
||||
|
|
||||
|
activated() { |
||||
|
this.handleScroll() |
||||
|
} |
||||
|
|
||||
|
destroyed() { |
||||
|
window.removeEventListener('scroll', this.handleScroll) |
||||
|
window.removeEventListener('resize', this.handleResize) |
||||
|
} |
||||
|
|
||||
|
private sticky() { |
||||
|
if (this.active) { |
||||
|
return |
||||
|
} |
||||
|
this.position = 'fixed' |
||||
|
this.active = true |
||||
|
this.width = this.width + 'px' |
||||
|
this.isSticky = true |
||||
|
} |
||||
|
|
||||
|
private handleReset() { |
||||
|
if (!this.active) { |
||||
|
return |
||||
|
} |
||||
|
this.position = '' |
||||
|
this.width = 'auto' |
||||
|
this.active = false |
||||
|
this.isSticky = false |
||||
|
} |
||||
|
|
||||
|
private handleScroll() { |
||||
|
const width = this.$el.getBoundingClientRect().width |
||||
|
this.width = (width.toString() + 'px') || 'auto' |
||||
|
const offsetTop = this.$el.getBoundingClientRect().top |
||||
|
if (offsetTop < this.stickyTop) { |
||||
|
this.sticky() |
||||
|
return |
||||
|
} |
||||
|
this.handleReset() |
||||
|
} |
||||
|
|
||||
|
private handleResize() { |
||||
|
if (this.isSticky) { |
||||
|
this.width = this.$el.getBoundingClientRect().width.toString() + 'px' |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,114 @@ |
|||||
|
<template> |
||||
|
<a |
||||
|
:class="className" |
||||
|
class="link--mallki" |
||||
|
href="#" |
||||
|
> |
||||
|
{{ text }} |
||||
|
<span :data-letters="text" /> |
||||
|
<span :data-letters="text" /> |
||||
|
</a> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'Mallki' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ default: '' }) private className!: string |
||||
|
@Prop({ default: 'vue-typescript-admin' }) private text!: string |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
/* Mallki */ |
||||
|
|
||||
|
.link--mallki { |
||||
|
font-weight: 800; |
||||
|
color: #4dd9d5; |
||||
|
font-family: 'Dosis', sans-serif; |
||||
|
-webkit-transition: color 0.5s 0.25s; |
||||
|
transition: color 0.5s 0.25s; |
||||
|
overflow: hidden; |
||||
|
position: relative; |
||||
|
display: inline-block; |
||||
|
line-height: 1; |
||||
|
outline: none; |
||||
|
text-decoration: none; |
||||
|
|
||||
|
&:hover { |
||||
|
-webkit-transition: none; |
||||
|
transition: none; |
||||
|
color: transparent; |
||||
|
|
||||
|
&::before { |
||||
|
-webkit-transform: translate3d(100%, 0, 0); |
||||
|
transform: translate3d(100%, 0, 0); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&::before { |
||||
|
content: ''; |
||||
|
width: 100%; |
||||
|
height: 6px; |
||||
|
margin: -3px 0 0 0; |
||||
|
background: #3888fa; |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
top: 50%; |
||||
|
-webkit-transform: translate3d(-100%, 0, 0); |
||||
|
transform: translate3d(-100%, 0, 0); |
||||
|
-webkit-transition: -webkit-transform 0.4s; |
||||
|
transition: transform 0.4s; |
||||
|
-webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); |
||||
|
transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1); |
||||
|
} |
||||
|
|
||||
|
span { |
||||
|
position: absolute; |
||||
|
height: 50%; |
||||
|
width: 100%; |
||||
|
left: 0; |
||||
|
top: 0; |
||||
|
overflow: hidden; |
||||
|
|
||||
|
&::before { |
||||
|
content: attr(data-letters); |
||||
|
color: red; |
||||
|
position: absolute; |
||||
|
left: 0; |
||||
|
width: 100%; |
||||
|
color: #3888fa; |
||||
|
-webkit-transition: -webkit-transform 0.5s; |
||||
|
transition: transform 0.5s; |
||||
|
} |
||||
|
|
||||
|
&:nth-child(2) { |
||||
|
top: 50%; |
||||
|
} |
||||
|
|
||||
|
&:first-child::before { |
||||
|
top: 0; |
||||
|
-webkit-transform: translate3d(0, 100%, 0); |
||||
|
transform: translate3d(0, 100%, 0); |
||||
|
} |
||||
|
|
||||
|
&:nth-child(2)::before { |
||||
|
bottom: 0; |
||||
|
-webkit-transform: translate3d(0, -100%, 0); |
||||
|
transform: translate3d(0, -100%, 0); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.link--mallki:hover span::before { |
||||
|
-webkit-transition-delay: 0.3s; |
||||
|
transition-delay: 0.3s; |
||||
|
-webkit-transform: translate3d(0, 0, 0); |
||||
|
transform: translate3d(0, 0, 0); |
||||
|
-webkit-transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); |
||||
|
transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1); |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,158 @@ |
|||||
|
<template> |
||||
|
<el-color-picker |
||||
|
v-model="theme" |
||||
|
:predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d']" |
||||
|
class="theme-picker" |
||||
|
popper-class="theme-picker-dropdown" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Vue, Watch } from 'vue-property-decorator' |
||||
|
import { SettingsModule } from '@/store/modules/settings' |
||||
|
|
||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires |
||||
|
const version = require('element-ui/package.json').version // element-ui version from node_modules |
||||
|
const ORIGINAL_THEME = '#409EFF' // default color |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'ThemePicker' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
private chalk = '' // The content of theme-chalk css |
||||
|
private theme = '' |
||||
|
|
||||
|
get defaultTheme() { |
||||
|
return SettingsModule.theme |
||||
|
} |
||||
|
|
||||
|
@Watch('defaultTheme', { immediate: true }) |
||||
|
private onDefaultThemeChange(value: string) { |
||||
|
this.theme = value |
||||
|
} |
||||
|
|
||||
|
@Watch('theme') |
||||
|
private async onThemeChange(value: string) { |
||||
|
if (!value) return |
||||
|
const oldValue = this.chalk ? this.theme : ORIGINAL_THEME |
||||
|
const themeCluster = this.getThemeCluster(value.replace('#', '')) |
||||
|
const originalCluster = this.getThemeCluster(oldValue.replace('#', '')) |
||||
|
const message = this.$message({ |
||||
|
message: ' Compiling the theme', |
||||
|
customClass: 'theme-message', |
||||
|
type: 'success', |
||||
|
duration: 0, |
||||
|
iconClass: 'el-icon-loading' |
||||
|
}) |
||||
|
|
||||
|
if (!this.chalk) { |
||||
|
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css` |
||||
|
await this.getCSSString(url, 'chalk') |
||||
|
} |
||||
|
|
||||
|
const getHandler = (variable: string, id: string) => { |
||||
|
return () => { |
||||
|
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', '')) |
||||
|
const newStyle = this.updateStyle((this as any)[variable], originalCluster, themeCluster) |
||||
|
|
||||
|
let styleTag = document.getElementById(id) |
||||
|
if (!styleTag) { |
||||
|
styleTag = document.createElement('style') |
||||
|
styleTag.setAttribute('id', id) |
||||
|
document.head.appendChild(styleTag) |
||||
|
} |
||||
|
styleTag.innerText = newStyle |
||||
|
} |
||||
|
} |
||||
|
const chalkHandler = getHandler('chalk', 'chalk-style') |
||||
|
chalkHandler() |
||||
|
|
||||
|
let styles: HTMLElement[] = [].slice.call(document.querySelectorAll('style')) |
||||
|
styles = styles |
||||
|
.filter(style => { |
||||
|
const text = style.innerText |
||||
|
return new RegExp(oldValue, 'i').test(text) && !/Chalk Variables/.test(text) |
||||
|
}) |
||||
|
styles.forEach(style => { |
||||
|
const { innerText } = style |
||||
|
if (typeof innerText !== 'string') return |
||||
|
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster) |
||||
|
}) |
||||
|
|
||||
|
this.$emit('change', value) |
||||
|
message.close() |
||||
|
} |
||||
|
|
||||
|
private updateStyle(style: string, oldCluster: string[], newCluster: string[]) { |
||||
|
let newStyle = style |
||||
|
oldCluster.forEach((color, index) => { |
||||
|
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index]) |
||||
|
}) |
||||
|
return newStyle |
||||
|
} |
||||
|
|
||||
|
private getCSSString(url: string, variable: string) { |
||||
|
return new Promise(resolve => { |
||||
|
const xhr = new XMLHttpRequest() |
||||
|
xhr.onreadystatechange = () => { |
||||
|
if (xhr.readyState === 4 && xhr.status === 200) { |
||||
|
(this as any)[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '') |
||||
|
resolve() |
||||
|
} |
||||
|
} |
||||
|
xhr.open('GET', url) |
||||
|
xhr.send() |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
private getThemeCluster(theme: string) { |
||||
|
const tintColor = (color: string, tint: number) => { |
||||
|
let red = parseInt(color.slice(0, 2), 16) |
||||
|
let green = parseInt(color.slice(2, 4), 16) |
||||
|
let blue = parseInt(color.slice(4, 6), 16) |
||||
|
if (tint === 0) { // when primary color is in its rgb space |
||||
|
return [red, green, blue].join(',') |
||||
|
} else { |
||||
|
red += Math.round(tint * (255 - red)) |
||||
|
green += Math.round(tint * (255 - green)) |
||||
|
blue += Math.round(tint * (255 - blue)) |
||||
|
return `#${red.toString(16)}${green.toString(16)}${blue.toString(16)}` |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const shadeColor = (color: string, shade: number) => { |
||||
|
let red = parseInt(color.slice(0, 2), 16) |
||||
|
let green = parseInt(color.slice(2, 4), 16) |
||||
|
let blue = parseInt(color.slice(4, 6), 16) |
||||
|
red = Math.round((1 - shade) * red) |
||||
|
green = Math.round((1 - shade) * green) |
||||
|
blue = Math.round((1 - shade) * blue) |
||||
|
return `#${red.toString(16)}${green.toString(16)}${blue.toString(16)}` |
||||
|
} |
||||
|
|
||||
|
const clusters = [theme] |
||||
|
for (let i = 0; i <= 9; i++) { |
||||
|
clusters.push(tintColor(theme, Number((i / 10).toFixed(2)))) |
||||
|
} |
||||
|
clusters.push(shadeColor(theme, 0.1)) |
||||
|
return clusters |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.theme-message, |
||||
|
.theme-picker-dropdown { |
||||
|
z-index: 99999 !important; |
||||
|
} |
||||
|
|
||||
|
.theme-picker .el-color-picker__trigger { |
||||
|
height: 26px !important; |
||||
|
width: 26px !important; |
||||
|
padding: 2px; |
||||
|
} |
||||
|
|
||||
|
.theme-picker-dropdown .el-color-dropdown__link-btn { |
||||
|
display: none; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,134 @@ |
|||||
|
<template> |
||||
|
<div class="upload-container"> |
||||
|
<el-button |
||||
|
:style="{background: color, borderColor: color}" |
||||
|
icon="el-icon-upload" |
||||
|
size="mini" |
||||
|
type="primary" |
||||
|
@click=" dialogVisible=true" |
||||
|
> |
||||
|
upload |
||||
|
</el-button> |
||||
|
<el-dialog :visible.sync="dialogVisible"> |
||||
|
<el-upload |
||||
|
:multiple="true" |
||||
|
:file-list="defaultFileList" |
||||
|
:show-file-list="true" |
||||
|
:on-remove="handleRemove" |
||||
|
:on-success="handleSuccess" |
||||
|
:before-upload="beforeUpload" |
||||
|
class="editor-slide-upload" |
||||
|
action="https://httpbin.org/post" |
||||
|
list-type="picture-card" |
||||
|
> |
||||
|
<el-button |
||||
|
size="small" |
||||
|
type="primary" |
||||
|
> |
||||
|
Click upload |
||||
|
</el-button> |
||||
|
</el-upload> |
||||
|
<el-button @click="dialogVisible = false"> |
||||
|
Cancel |
||||
|
</el-button> |
||||
|
<el-button |
||||
|
type="primary" |
||||
|
@click="handleSubmit" |
||||
|
> |
||||
|
Confirm |
||||
|
</el-button> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
import { ElUploadInternalRawFile } from 'element-ui/types/upload' |
||||
|
|
||||
|
export interface IUploadObject { |
||||
|
hasSuccess: boolean |
||||
|
uid: number |
||||
|
url: string |
||||
|
width: number |
||||
|
height: number |
||||
|
} |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'EditorImageUpload' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ required: true }) private color!: string |
||||
|
|
||||
|
private dialogVisible = false |
||||
|
private listObj: { [key: string]: IUploadObject } = {} |
||||
|
private defaultFileList = [] |
||||
|
|
||||
|
private checkAllSuccess() { |
||||
|
return Object.keys(this.listObj).every(item => this.listObj[item].hasSuccess) |
||||
|
} |
||||
|
|
||||
|
private handleSubmit() { |
||||
|
const arr = Object.keys(this.listObj).map(v => this.listObj[v]) |
||||
|
if (!this.checkAllSuccess()) { |
||||
|
this.$message('Please wait for all images to be uploaded successfully. If there is a network problem, please refresh the page and upload again!') |
||||
|
return |
||||
|
} |
||||
|
this.$emit('successCBK', arr) |
||||
|
this.listObj = {} |
||||
|
this.defaultFileList = [] |
||||
|
this.dialogVisible = false |
||||
|
} |
||||
|
|
||||
|
private handleSuccess(response: any, file: ElUploadInternalRawFile) { |
||||
|
const uid = file.uid |
||||
|
const objKeyArr = Object.keys(this.listObj) |
||||
|
for (let i = 0, len = objKeyArr.length; i < len; i++) { |
||||
|
if (this.listObj[objKeyArr[i]].uid === uid) { |
||||
|
this.listObj[objKeyArr[i]].url = response.files.file |
||||
|
this.listObj[objKeyArr[i]].hasSuccess = true |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private handleRemove(file: ElUploadInternalRawFile) { |
||||
|
const uid = file.uid |
||||
|
const objKeyArr = Object.keys(this.listObj) |
||||
|
for (let i = 0, len = objKeyArr.length; i < len; i++) { |
||||
|
if (this.listObj[objKeyArr[i]].uid === uid) { |
||||
|
delete this.listObj[objKeyArr[i]] |
||||
|
return |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private beforeUpload(file: ElUploadInternalRawFile) { |
||||
|
const fileName = file.uid |
||||
|
const img = new Image() |
||||
|
img.src = window.URL.createObjectURL(file) |
||||
|
img.onload = () => { |
||||
|
this.listObj[fileName] = { |
||||
|
hasSuccess: false, |
||||
|
uid: file.uid, |
||||
|
url: '', |
||||
|
width: img.width, |
||||
|
height: img.height |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.editor-slide-upload { |
||||
|
.el-upload--picture-card { |
||||
|
width: 100%; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.editor-slide-upload { |
||||
|
margin-bottom: 20px; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,8 @@ |
|||||
|
// Import plugins that you want to use
|
||||
|
// Detail plugins list see: https://www.tinymce.com/docs/plugins/
|
||||
|
// Custom builds see: https://www.tinymce.com/download/custom-builds/
|
||||
|
export const plugins = ['advlist anchor autolink autosave code codesample directionality emoticons fullscreen hr image imagetools insertdatetime link lists media nonbreaking noneditable pagebreak paste preview print save searchreplace spellchecker tabfocus table template textpattern visualblocks visualchars wordcount'] |
||||
|
|
||||
|
// Here is the list of toolbar control components
|
||||
|
// Details see: https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols
|
||||
|
export const toolbar = ['searchreplace bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript code codesample', 'hr bullist numlist link image charmap preview anchor pagebreak insertdatetime media table emoticons forecolor backcolor fullscreen'] |
||||
@ -0,0 +1,222 @@ |
|||||
|
<template> |
||||
|
<div |
||||
|
:class="{fullscreen: fullscreen}" |
||||
|
class="tinymce-container" |
||||
|
:style="{width: containerWidth}" |
||||
|
> |
||||
|
<tinymce-editor |
||||
|
:id="id" |
||||
|
v-model="tinymceContent" |
||||
|
:init="initOptions" |
||||
|
/> |
||||
|
<div class="editor-custom-btn-container"> |
||||
|
<editor-image-upload |
||||
|
:color="uploadButtonColor" |
||||
|
class="editor-upload-btn" |
||||
|
@successCBK="imageSuccessCBK" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
// Docs: https://www.tiny.cloud/docs/advanced/usage-with-module-loaders/ |
||||
|
// Import TinyMCE |
||||
|
import 'tinymce/tinymce' |
||||
|
// Default icons are required for TinyMCE 5.3 or above |
||||
|
import 'tinymce/icons/default' |
||||
|
// Import themes |
||||
|
import 'tinymce/themes/silver' |
||||
|
import 'tinymce/themes/mobile' |
||||
|
// Any plugins you want to use has to be imported |
||||
|
import 'tinymce/plugins/advlist' |
||||
|
import 'tinymce/plugins/anchor' |
||||
|
import 'tinymce/plugins/autolink' |
||||
|
import 'tinymce/plugins/autosave' |
||||
|
import 'tinymce/plugins/code' |
||||
|
import 'tinymce/plugins/codesample' |
||||
|
import 'tinymce/plugins/directionality' |
||||
|
import 'tinymce/plugins/emoticons' |
||||
|
import 'tinymce/plugins/fullscreen' |
||||
|
import 'tinymce/plugins/hr' |
||||
|
import 'tinymce/plugins/image' |
||||
|
import 'tinymce/plugins/imagetools' |
||||
|
import 'tinymce/plugins/insertdatetime' |
||||
|
import 'tinymce/plugins/link' |
||||
|
import 'tinymce/plugins/lists' |
||||
|
import 'tinymce/plugins/media' |
||||
|
import 'tinymce/plugins/nonbreaking' |
||||
|
import 'tinymce/plugins/noneditable' |
||||
|
import 'tinymce/plugins/pagebreak' |
||||
|
import 'tinymce/plugins/paste' |
||||
|
import 'tinymce/plugins/preview' |
||||
|
import 'tinymce/plugins/print' |
||||
|
import 'tinymce/plugins/save' |
||||
|
import 'tinymce/plugins/searchreplace' |
||||
|
import 'tinymce/plugins/spellchecker' |
||||
|
import 'tinymce/plugins/tabfocus' |
||||
|
import 'tinymce/plugins/table' |
||||
|
import 'tinymce/plugins/template' |
||||
|
import 'tinymce/plugins/textpattern' |
||||
|
import 'tinymce/plugins/visualblocks' |
||||
|
import 'tinymce/plugins/visualchars' |
||||
|
import 'tinymce/plugins/wordcount' |
||||
|
import TinymceEditor from '@tinymce/tinymce-vue' // TinyMCE vue wrapper |
||||
|
import { Component, Prop, Vue, Watch } from 'vue-property-decorator' |
||||
|
import { AppModule } from '@/store/modules/app' |
||||
|
import { SettingsModule } from '@/store/modules/settings' |
||||
|
import EditorImageUpload, { IUploadObject } from './components/EditorImage.vue' |
||||
|
import { plugins, toolbar } from './config' |
||||
|
|
||||
|
const defaultId = () => 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '') |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'Tinymce', |
||||
|
components: { |
||||
|
EditorImageUpload, |
||||
|
TinymceEditor |
||||
|
} |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ required: true }) private value!: string |
||||
|
@Prop({ default: defaultId }) private id!: string |
||||
|
@Prop({ default: () => [] }) private toolbar!: string[] |
||||
|
@Prop({ default: 'file edit insert view format table' }) private menubar!: string |
||||
|
@Prop({ default: '360px' }) private height!: string | number |
||||
|
@Prop({ default: 'auto' }) private width!: string | number |
||||
|
|
||||
|
private hasChange = false |
||||
|
private hasInit = false |
||||
|
private fullscreen = false |
||||
|
// https://www.tiny.cloud/docs/configure/localization/#language |
||||
|
// and also see langs files under public/tinymce/langs folder |
||||
|
private languageTypeList: { [key: string]: string } = { |
||||
|
en: 'en', |
||||
|
zh: 'zh_CN', |
||||
|
es: 'es', |
||||
|
ja: 'ja', |
||||
|
ko: 'ko_KR' |
||||
|
} |
||||
|
|
||||
|
get language() { |
||||
|
return this.languageTypeList[AppModule.language] |
||||
|
} |
||||
|
|
||||
|
get uploadButtonColor() { |
||||
|
return SettingsModule.theme |
||||
|
} |
||||
|
|
||||
|
get tinymceContent() { |
||||
|
return this.value |
||||
|
} |
||||
|
|
||||
|
set tinymceContent(value) { |
||||
|
this.$emit('input', value) |
||||
|
} |
||||
|
|
||||
|
get containerWidth() { |
||||
|
const width = this.width |
||||
|
// Test matches `100`, `'100'` |
||||
|
if (/^[\d]+(\.[\d]+)?$/.test(width.toString())) { |
||||
|
return `${width}px` |
||||
|
} |
||||
|
return width |
||||
|
} |
||||
|
|
||||
|
get initOptions() { |
||||
|
return { |
||||
|
selector: `#${this.id}`, |
||||
|
height: this.height, |
||||
|
body_class: 'panel-body ', |
||||
|
object_resizing: false, |
||||
|
toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar, |
||||
|
menubar: this.menubar, |
||||
|
plugins: plugins, |
||||
|
language: this.language, |
||||
|
language_url: this.language === 'en' ? '' : `${process.env.BASE_URL}tinymce/langs/${this.language}.js`, |
||||
|
skin_url: `${process.env.BASE_URL}tinymce/skins/`, |
||||
|
emoticons_database_url: `${process.env.BASE_URL}tinymce/emojis.min.js`, |
||||
|
end_container_on_empty_block: true, |
||||
|
powerpaste_word_import: 'clean', |
||||
|
code_dialog_height: 450, |
||||
|
code_dialog_width: 1000, |
||||
|
advlist_bullet_styles: 'square', |
||||
|
advlist_number_styles: 'default', |
||||
|
imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'], |
||||
|
default_link_target: '_blank', |
||||
|
link_title: false, |
||||
|
// inserting nonbreaking space need Nonbreaking Space Plugin |
||||
|
nonbreaking_force_tab: true, |
||||
|
// 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, |
||||
|
init_instance_callback: (editor: any) => { |
||||
|
if (this.value) { |
||||
|
editor.setContent(this.value) |
||||
|
} |
||||
|
this.hasInit = true |
||||
|
editor.on('NodeChange Change KeyUp SetContent', () => { |
||||
|
this.hasChange = true |
||||
|
this.$emit('input', editor.getContent()) |
||||
|
}) |
||||
|
}, |
||||
|
setup: (editor: any) => { |
||||
|
editor.on('FullscreenStateChanged', (e: any) => { |
||||
|
this.fullscreen = e.state |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Watch('language') |
||||
|
private onLanguageChange() { |
||||
|
const tinymceManager = (window as any).tinymce |
||||
|
const tinymceInstance = tinymceManager.get(this.id) |
||||
|
if (this.fullscreen) { |
||||
|
tinymceInstance.execCommand('mceFullScreen') |
||||
|
} |
||||
|
if (tinymceInstance) { |
||||
|
tinymceInstance.destroy() |
||||
|
} |
||||
|
this.$nextTick(() => tinymceManager.init(this.initOptions)) |
||||
|
} |
||||
|
|
||||
|
private imageSuccessCBK(arr: IUploadObject[]) { |
||||
|
const tinymce = (window as any).tinymce.get(this.id) |
||||
|
arr.forEach(v => { |
||||
|
tinymce.insertContent(`<img class="wscnph" src="${v.url}" >`) |
||||
|
}) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.tinymce-container { |
||||
|
position: relative; |
||||
|
line-height: normal; |
||||
|
|
||||
|
.mce-fullscreen { |
||||
|
z-index: 10000; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.editor-custom-btn-container { |
||||
|
position: absolute; |
||||
|
right: 6px; |
||||
|
top: 6px; |
||||
|
|
||||
|
&.fullscreen { |
||||
|
z-index: 10000; |
||||
|
position: fixed; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.editor-upload-btn { |
||||
|
display: inline-block; |
||||
|
} |
||||
|
|
||||
|
textarea { |
||||
|
visibility: hidden; |
||||
|
z-index: -1; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,164 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<input |
||||
|
ref="excel-upload-input" |
||||
|
class="excel-upload-input" |
||||
|
type="file" |
||||
|
accept=".xlsx, .xls" |
||||
|
@change="handleClick" |
||||
|
> |
||||
|
<div |
||||
|
class="drop" |
||||
|
@drop="handleDrop" |
||||
|
@dragover="handleDragover" |
||||
|
@dragenter="handleDragover" |
||||
|
> |
||||
|
Drop excel file here or |
||||
|
<el-button |
||||
|
:loading="loading" |
||||
|
style="margin-left:16px;" |
||||
|
size="mini" |
||||
|
type="primary" |
||||
|
@click="handleUpload" |
||||
|
> |
||||
|
Browse |
||||
|
</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
import XLSX from 'xlsx' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'UploadExcel' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ required: true }) private beforeUpload!: Function |
||||
|
@Prop({ required: true }) private onSuccess!: Function |
||||
|
|
||||
|
private loading = false |
||||
|
private excelData = { |
||||
|
header: null, |
||||
|
results: null |
||||
|
} |
||||
|
|
||||
|
private generateData(header: any, results: any) { |
||||
|
this.excelData.header = header |
||||
|
this.excelData.results = results |
||||
|
this.onSuccess && this.onSuccess(this.excelData) |
||||
|
} |
||||
|
|
||||
|
private handleDrop(e: DragEvent) { |
||||
|
e.stopPropagation() |
||||
|
e.preventDefault() |
||||
|
if (this.loading) return |
||||
|
if (!e.dataTransfer) return |
||||
|
const files = e.dataTransfer.files |
||||
|
if (files.length !== 1) { |
||||
|
this.$message.error('Only support uploading one file!') |
||||
|
return |
||||
|
} |
||||
|
const rawFile = files[0] // only use files[0] |
||||
|
|
||||
|
if (!this.isExcel(rawFile)) { |
||||
|
this.$message.error('Only supports upload .xlsx, .xls, .csv suffix files') |
||||
|
return false |
||||
|
} |
||||
|
this.upload(rawFile) |
||||
|
e.stopPropagation() |
||||
|
e.preventDefault() |
||||
|
} |
||||
|
|
||||
|
private handleDragover(e: DragEvent) { |
||||
|
e.stopPropagation() |
||||
|
e.preventDefault() |
||||
|
if (e.dataTransfer) { |
||||
|
e.dataTransfer.dropEffect = 'copy' |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private handleUpload() { |
||||
|
(this.$refs['excel-upload-input'] as HTMLInputElement).click() |
||||
|
} |
||||
|
|
||||
|
private handleClick(e: MouseEvent) { |
||||
|
const files = (e.target as HTMLInputElement).files |
||||
|
if (files) { |
||||
|
const rawFile = files[0] // only use files[0] |
||||
|
this.upload(rawFile) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private upload(rawFile: File) { |
||||
|
(this.$refs['excel-upload-input'] as HTMLInputElement).value = '' // Fixes can't select the same excel |
||||
|
if (!this.beforeUpload) { |
||||
|
this.readerData(rawFile) |
||||
|
return |
||||
|
} |
||||
|
const before = this.beforeUpload(rawFile) |
||||
|
if (before) { |
||||
|
this.readerData(rawFile) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private readerData(rawFile: File) { |
||||
|
this.loading = true |
||||
|
const reader = new FileReader() |
||||
|
reader.onload = e => { |
||||
|
const data = (e.target as FileReader).result |
||||
|
const workbook = XLSX.read(data, { type: 'array' }) |
||||
|
const firstSheetName = workbook.SheetNames[0] |
||||
|
const worksheet = workbook.Sheets[firstSheetName] |
||||
|
const header = this.getHeaderRow(worksheet) |
||||
|
const results = XLSX.utils.sheet_to_json(worksheet) |
||||
|
this.generateData(header, results) |
||||
|
this.loading = false |
||||
|
} |
||||
|
reader.readAsArrayBuffer(rawFile) |
||||
|
} |
||||
|
|
||||
|
private getHeaderRow(sheet: { [key: string ]: any }) { |
||||
|
const headers: string[] = [] |
||||
|
const range = XLSX.utils.decode_range(sheet['!ref']) |
||||
|
const R = range.s.r |
||||
|
// start in the first row |
||||
|
for (let C = range.s.c; C <= range.e.c; ++C) { // walk every column in the range |
||||
|
const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })] |
||||
|
// find the cell in the first row |
||||
|
let hdr = '' |
||||
|
if (cell && cell.t) hdr = XLSX.utils.format_cell(cell) |
||||
|
if (hdr === '') { |
||||
|
hdr = 'UNKNOWN ' + C // replace with your desired default |
||||
|
} |
||||
|
headers.push(hdr) |
||||
|
} |
||||
|
return headers |
||||
|
} |
||||
|
|
||||
|
private isExcel(file: File) { |
||||
|
return /\.(xlsx|xls|csv)$/.test(file.name) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.excel-upload-input { |
||||
|
display: none; |
||||
|
z-index: -9999; |
||||
|
} |
||||
|
|
||||
|
.drop { |
||||
|
border: 2px dashed #bbb; |
||||
|
width: 600px; |
||||
|
height: 160px; |
||||
|
line-height: 160px; |
||||
|
margin: 0 auto; |
||||
|
font-size: 24px; |
||||
|
border-radius: 5px; |
||||
|
text-align: center; |
||||
|
color: #bbb; |
||||
|
position: relative; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,155 @@ |
|||||
|
<template> |
||||
|
<div class="upload-container"> |
||||
|
<el-upload |
||||
|
:data="dataObj" |
||||
|
:multiple="false" |
||||
|
:show-file-list="false" |
||||
|
:on-success="handleImageSuccess" |
||||
|
class="image-uploader" |
||||
|
drag |
||||
|
action="https://httpbin.org/post" |
||||
|
> |
||||
|
<i class="el-icon-upload" /> |
||||
|
<div class="el-upload__text"> |
||||
|
将文件拖到此处,或<em>点击上传</em> |
||||
|
</div> |
||||
|
</el-upload> |
||||
|
<div class="image-preview image-app-preview"> |
||||
|
<div |
||||
|
v-show="imageUrl.length>1" |
||||
|
class="image-preview-wrapper" |
||||
|
> |
||||
|
<img :src="imageUrl"> |
||||
|
<div class="image-preview-action"> |
||||
|
<i |
||||
|
class="el-icon-delete" |
||||
|
@click="rmImage" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="image-preview"> |
||||
|
<div |
||||
|
v-show="imageUrl.length>1" |
||||
|
class="image-preview-wrapper" |
||||
|
> |
||||
|
<img :src="imageUrl"> |
||||
|
<div class="image-preview-action"> |
||||
|
<i |
||||
|
class="el-icon-delete" |
||||
|
@click="rmImage" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Prop, Vue } from 'vue-property-decorator' |
||||
|
|
||||
|
@Component({ |
||||
|
name: 'UploadImage' |
||||
|
}) |
||||
|
export default class extends Vue { |
||||
|
@Prop({ default: '' }) private value!: string |
||||
|
|
||||
|
private tempUrl = '' |
||||
|
private dataObj = { token: '', key: '' } |
||||
|
|
||||
|
get imageUrl() { |
||||
|
return this.value |
||||
|
} |
||||
|
|
||||
|
private emitInput(value: string) { |
||||
|
this.$emit('input', value) |
||||
|
} |
||||
|
|
||||
|
private rmImage() { |
||||
|
this.emitInput('') |
||||
|
} |
||||
|
|
||||
|
private handleImageSuccess(res: any) { |
||||
|
this.emitInput(res.files.file) |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.upload-container { |
||||
|
width: 100%; |
||||
|
position: relative; |
||||
|
@include clearfix; |
||||
|
|
||||
|
.image-uploader { |
||||
|
width: 35%; |
||||
|
float: left; |
||||
|
} |
||||
|
|
||||
|
.image-preview { |
||||
|
width: 200px; |
||||
|
height: 200px; |
||||
|
position: relative; |
||||
|
border: 1px dashed #d9d9d9; |
||||
|
float: left; |
||||
|
margin-left: 50px; |
||||
|
|
||||
|
.image-preview-wrapper { |
||||
|
position: relative; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
|
||||
|
img { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.image-preview-action { |
||||
|
position: absolute; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
left: 0; |
||||
|
top: 0; |
||||
|
cursor: default; |
||||
|
text-align: center; |
||||
|
color: #fff; |
||||
|
opacity: 0; |
||||
|
font-size: 20px; |
||||
|
background-color: rgba(0, 0, 0, .5); |
||||
|
transition: opacity .3s; |
||||
|
cursor: pointer; |
||||
|
text-align: center; |
||||
|
line-height: 200px; |
||||
|
|
||||
|
.el-icon-delete { |
||||
|
font-size: 36px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
&:hover { |
||||
|
.image-preview-action { |
||||
|
opacity: 1; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.image-app-preview { |
||||
|
width: 320px; |
||||
|
height: 180px; |
||||
|
position: relative; |
||||
|
border: 1px dashed #d9d9d9; |
||||
|
float: left; |
||||
|
margin-left: 50px; |
||||
|
|
||||
|
.app-fake-conver { |
||||
|
height: 44px; |
||||
|
position: absolute; |
||||
|
width: 100%; // background: rgba(0, 0, 0, .1); |
||||
|
text-align: center; |
||||
|
line-height: 64px; |
||||
|
color: #fff; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,60 @@ |
|||||
|
// Inspired by https://github.com/Inndy/vue-clipboard2
|
||||
|
import Clipboard from 'clipboard' |
||||
|
import { DirectiveOptions } from 'vue' |
||||
|
|
||||
|
if (!Clipboard) { |
||||
|
throw new Error('you should npm install `clipboard` --save at first ') |
||||
|
} |
||||
|
|
||||
|
let successCallback: Function | null |
||||
|
let errorCallback: Function | null |
||||
|
let clipboardInstance: Clipboard | null |
||||
|
|
||||
|
export const clipboard: DirectiveOptions = { |
||||
|
bind(el, binding) { |
||||
|
if (binding.arg === 'success') { |
||||
|
successCallback = binding.value |
||||
|
} else if (binding.arg === 'error') { |
||||
|
errorCallback = binding.value |
||||
|
} else { |
||||
|
clipboardInstance = new Clipboard(el, { |
||||
|
text() { return binding.value }, |
||||
|
action() { return binding.arg === 'cut' ? 'cut' : 'copy' } |
||||
|
}) |
||||
|
clipboardInstance.on('success', e => { |
||||
|
const callback = successCallback |
||||
|
callback && callback(e) |
||||
|
}) |
||||
|
clipboardInstance.on('error', e => { |
||||
|
const callback = errorCallback |
||||
|
callback && callback(e) |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
update(el, binding) { |
||||
|
if (binding.arg === 'success') { |
||||
|
successCallback = binding.value |
||||
|
} else if (binding.arg === 'error') { |
||||
|
errorCallback = binding.value |
||||
|
} else { |
||||
|
clipboardInstance = new Clipboard(el, { |
||||
|
text() { return binding.value }, |
||||
|
action() { return binding.arg === 'cut' ? 'cut' : 'copy' } |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
unbind(_, binding) { |
||||
|
if (binding.arg === 'success') { |
||||
|
successCallback = null |
||||
|
} else if (binding.arg === 'error') { |
||||
|
errorCallback = null |
||||
|
} else { |
||||
|
if (clipboardInstance) { |
||||
|
clipboardInstance.destroy() |
||||
|
} |
||||
|
clipboardInstance = null |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,75 @@ |
|||||
|
import { DirectiveOptions } from 'vue' |
||||
|
|
||||
|
export const elDraggableDialog: DirectiveOptions = { |
||||
|
bind(el, _, vnode) { |
||||
|
const dragDom = el.querySelector('.el-dialog') as HTMLElement |
||||
|
const dialogHeaderEl = el.querySelector('.el-dialog__header') as HTMLElement |
||||
|
dragDom.style.cssText += ';top:0px;' |
||||
|
dialogHeaderEl.style.cssText += ';cursor:move;' |
||||
|
|
||||
|
dialogHeaderEl.onmousedown = (e) => { |
||||
|
const disX = e.clientX - dialogHeaderEl.offsetLeft |
||||
|
const disY = e.clientY - dialogHeaderEl.offsetTop |
||||
|
|
||||
|
const dragDomWidth = dragDom.offsetWidth |
||||
|
const dragDomHeight = dragDom.offsetHeight |
||||
|
|
||||
|
const screenWidth = document.body.clientWidth |
||||
|
const screenHeight = document.body.clientHeight |
||||
|
|
||||
|
const minDragDomLeft = dragDom.offsetLeft |
||||
|
const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth |
||||
|
|
||||
|
const minDragDomTop = dragDom.offsetTop |
||||
|
const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeight |
||||
|
|
||||
|
const styleLeftStr = getComputedStyle(dragDom).left |
||||
|
const styleTopStr = getComputedStyle(dragDom).top |
||||
|
if (!styleLeftStr || !styleTopStr) return |
||||
|
let styleLeft: number |
||||
|
let styleTop: number |
||||
|
|
||||
|
// Format may be "##%" or "##px"
|
||||
|
if (styleLeftStr.includes('%')) { |
||||
|
styleLeft = +document.body.clientWidth * (+styleLeftStr.replace(/%/g, '') / 100) |
||||
|
styleTop = +document.body.clientHeight * (+styleTopStr.replace(/%/g, '') / 100) |
||||
|
} else { |
||||
|
styleLeft = +styleLeftStr.replace(/px/g, '') |
||||
|
styleTop = +styleTopStr.replace(/px/g, '') |
||||
|
} |
||||
|
|
||||
|
document.onmousemove = (e) => { |
||||
|
let left = e.clientX - disX |
||||
|
let top = e.clientY - disY |
||||
|
|
||||
|
// Handle edge cases
|
||||
|
if (-(left) > minDragDomLeft) { |
||||
|
left = -minDragDomLeft |
||||
|
} else if (left > maxDragDomLeft) { |
||||
|
left = maxDragDomLeft |
||||
|
} |
||||
|
if (-(top) > minDragDomTop) { |
||||
|
top = -minDragDomTop |
||||
|
} else if (top > maxDragDomTop) { |
||||
|
top = maxDragDomTop |
||||
|
} |
||||
|
|
||||
|
// Move current element
|
||||
|
dragDom.style.cssText += `;left:${left + styleLeft}px;top:${top + styleTop}px;` |
||||
|
|
||||
|
// Emit onDialogDrag event
|
||||
|
// See https://stackoverflow.com/questions/49264426/vuejs-custom-directive-emit-event
|
||||
|
if (vnode.componentInstance) { |
||||
|
vnode.componentInstance.$emit('onDialogDrag') |
||||
|
} else if (vnode.elm) { |
||||
|
vnode.elm.dispatchEvent(new CustomEvent('onDialogDrag')) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
document.onmouseup = () => { |
||||
|
document.onmousemove = null |
||||
|
document.onmouseup = null |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,4 @@ |
|||||
|
export * from './clipboard' |
||||
|
export * from './el-draggable-dialog' |
||||
|
export * from './permission' |
||||
|
export * from './waves' |
||||
@ -0,0 +1,20 @@ |
|||||
|
import { DirectiveOptions } from 'vue' |
||||
|
import { UserModule } from '@/store/modules/user' |
||||
|
|
||||
|
export const permission: DirectiveOptions = { |
||||
|
inserted(el, binding) { |
||||
|
const { value } = binding |
||||
|
const roles = UserModule.roles |
||||
|
if (value && value instanceof Array && value.length > 0) { |
||||
|
const permissionRoles = value |
||||
|
const hasPermission = roles.some(role => { |
||||
|
return permissionRoles.includes(role) |
||||
|
}) |
||||
|
if (!hasPermission) { |
||||
|
el.style.display = 'none' |
||||
|
} |
||||
|
} else { |
||||
|
throw new Error('need roles! Like v-permission="[\'admin\',\'editor\']"') |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
import './waves.css' |
||||
|
import { DirectiveOptions } from 'vue' |
||||
|
|
||||
|
export const waves: DirectiveOptions = { |
||||
|
bind(el, binding) { |
||||
|
el.addEventListener('click', e => { |
||||
|
const customOpts = Object.assign({}, binding.value) |
||||
|
const opts = Object.assign({ |
||||
|
ele: el, // 波纹作用元素
|
||||
|
type: 'hit', // hit 点击位置扩散 center中心点扩展
|
||||
|
color: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
|
||||
|
}, customOpts) |
||||
|
const target: HTMLElement = opts.ele |
||||
|
if (target) { |
||||
|
target.style.position = 'relative' |
||||
|
target.style.overflow = 'hidden' |
||||
|
const rect = target.getBoundingClientRect() |
||||
|
let ripple = target.querySelector('.waves-ripple') as HTMLElement |
||||
|
if (!ripple) { |
||||
|
ripple = document.createElement('span') |
||||
|
ripple.className = 'waves-ripple' |
||||
|
ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px' |
||||
|
target.appendChild(ripple) |
||||
|
} else { |
||||
|
ripple.className = 'waves-ripple' |
||||
|
} |
||||
|
switch (opts.type) { |
||||
|
case 'center': |
||||
|
ripple.style.top = rect.height / 2 - ripple.offsetHeight / 2 + 'px' |
||||
|
ripple.style.left = rect.width / 2 - ripple.offsetWidth / 2 + 'px' |
||||
|
break |
||||
|
default: |
||||
|
ripple.style.top = |
||||
|
(e.pageY - rect.top - ripple.offsetHeight / 2 - document.documentElement.scrollTop || |
||||
|
document.body.scrollTop) + 'px' |
||||
|
ripple.style.left = |
||||
|
(e.pageX - rect.left - ripple.offsetWidth / 2 - document.documentElement.scrollLeft || |
||||
|
document.body.scrollLeft) + 'px' |
||||
|
} |
||||
|
ripple.style.backgroundColor = opts.color |
||||
|
ripple.className = 'waves-ripple z-active' |
||||
|
return false |
||||
|
} |
||||
|
}, false) |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
.waves-ripple { |
||||
|
position: absolute; |
||||
|
border-radius: 100%; |
||||
|
background-color: rgba(0, 0, 0, 0.15); |
||||
|
background-clip: padding-box; |
||||
|
pointer-events: none; |
||||
|
-webkit-user-select: none; |
||||
|
-moz-user-select: none; |
||||
|
-ms-user-select: none; |
||||
|
user-select: none; |
||||
|
-webkit-transform: scale(0); |
||||
|
-ms-transform: scale(0); |
||||
|
transform: scale(0); |
||||
|
opacity: 1; |
||||
|
} |
||||
|
|
||||
|
.waves-ripple.z-active { |
||||
|
opacity: 0; |
||||
|
-webkit-transform: scale(2); |
||||
|
-ms-transform: scale(2); |
||||
|
transform: scale(2); |
||||
|
-webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out; |
||||
|
transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out; |
||||
|
transition: opacity 1.2s ease-out, transform 0.6s ease-out; |
||||
|
transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out; |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
// Set utils function parseTime to filter
|
||||
|
export { parseTime } from '@/utils' |
||||
|
|
||||
|
// Filter for article status
|
||||
|
export const articleStatusFilter = (status: string) => { |
||||
|
const statusMap: { [key: string]: string } = { |
||||
|
published: 'success', |
||||
|
draft: 'info', |
||||
|
deleted: 'danger' |
||||
|
} |
||||
|
return statusMap[status] |
||||
|
} |
||||
|
|
||||
|
// Filter to uppercase the first character
|
||||
|
export const uppercaseFirstChar = (str: string) => { |
||||
|
return str.charAt(0).toUpperCase() + str.slice(1) |
||||
|
} |
||||