From d7fbc91b786cb814909d54607e7335d0821a9893 Mon Sep 17 00:00:00 2001 From: hunterlong Date: Thu, 16 Jan 2020 20:55:50 -0800 Subject: [PATCH] vue --- frontend/.babelrc | 16 + frontend/.eslintrc.json | 59 + frontend/config/dev.env | 3 + frontend/config/helpers.js | 15 + frontend/config/prod.env | 3 + frontend/config/webpack.config.common.js | 68 + frontend/config/webpack.config.dev.js | 49 + frontend/config/webpack.config.prod.js | 83 + frontend/package.json | 73 +- frontend/public/index.html | 1 - frontend/src/App.vue | 41 +- frontend/src/components/API.js | 2 +- .../components/Dashboard/DashboardIndex.vue | 9 +- .../Dashboard/DashboardMessages.vue | 14 +- .../Dashboard/DashboardServices.vue | 12 +- .../components/Dashboard/DashboardUsers.vue | 9 +- .../src/components/Dashboard/ServiceForm.vue | 185 ++ .../src/components/Dashboard/ServiceInfo.vue | 5 +- frontend/src/components/Dashboard/TopNav.vue | 2 + frontend/src/components/Index/Group.vue | 17 +- .../src/components/Index/GroupedService.vue | 19 - frontend/src/components/Index/Header.vue | 7 +- frontend/src/components/Time.js | 14 + frontend/src/forms/CoreSettings.vue | 121 + frontend/src/forms/Service.vue | 178 ++ frontend/src/main.js | 25 +- frontend/src/pages/Dashboard.vue | 61 +- frontend/src/pages/Index.vue | 36 +- frontend/src/pages/Login.vue | 8 +- frontend/src/pages/Settings.vue | 308 +- frontend/src/store.js | 83 + frontend/webpack.config.js | 9 + frontend/yarn.lock | 2639 +++++++++-------- 33 files changed, 2471 insertions(+), 1703 deletions(-) create mode 100644 frontend/.babelrc create mode 100644 frontend/.eslintrc.json create mode 100644 frontend/config/dev.env create mode 100644 frontend/config/helpers.js create mode 100644 frontend/config/prod.env create mode 100644 frontend/config/webpack.config.common.js create mode 100644 frontend/config/webpack.config.dev.js create mode 100644 frontend/config/webpack.config.prod.js create mode 100644 frontend/src/components/Dashboard/ServiceForm.vue delete mode 100644 frontend/src/components/Index/GroupedService.vue create mode 100644 frontend/src/components/Time.js create mode 100644 frontend/src/forms/CoreSettings.vue create mode 100644 frontend/src/forms/Service.vue create mode 100644 frontend/src/store.js create mode 100644 frontend/webpack.config.js diff --git a/frontend/.babelrc b/frontend/.babelrc new file mode 100644 index 00000000..1c9fe721 --- /dev/null +++ b/frontend/.babelrc @@ -0,0 +1,16 @@ +{ + "presets": [ + [ + "@babel/preset-env", + { + "modules": false, + "targets": { + "browsers": ["> 1%", "last 2 versions", "not ie <= 8", "ie >= 11"] + } + } + ] + ], + "plugins": [ + "@babel/plugin-syntax-dynamic-import" + ] +} diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc.json new file mode 100644 index 00000000..11a3124d --- /dev/null +++ b/frontend/.eslintrc.json @@ -0,0 +1,59 @@ +{ + "env": { + "browser": true, + "commonjs": true, + "es6": true, + "node": true + }, + "parserOptions": { + "parser": "babel-eslint", + "sourceType": "module", + "ecmaVersion": 2018 + }, + "extends": [ + "eslint:recommended", + "plugin:vue/base", + "plugin:vue/essential", + "plugin:vue/strongly-recommended", + "plugin:vue/recommended" + ], + "rules": { + "array-bracket-spacing": [ "error", "always" ], + "arrow-spacing": "error", + "constructor-super": "error", + "curly": "error", + "indent": ["error", 4, { "SwitchCase": 1 }], + "keyword-spacing": "error", + "no-console": 0, + "no-const-assign": "error", + "no-debugger": 0, + "no-duplicate-imports": "error", + "no-multiple-empty-lines": [ 2, { "max": 2, "maxEOF": 1 } ], + "no-this-before-super": "error", + "no-unreachable": "error", + "no-unused-vars": 0, + "no-useless-escape": 0, + "no-var": "error", + "object-curly-spacing": [ "error", "always" ], + "one-var": ["error", { "var": "never", "let": "never", "const": "never" }], + "prefer-arrow-callback": "error", + "prefer-const": "error", + "quotes": [ "error", "single", { "allowTemplateLiterals": true } ], + "semi": ["error", "always"], + "sort-imports": ["error", { "ignoreDeclarationSort": true }], + "space-before-function-paren": "error", + "valid-typeof": "error", + "vue/component-name-in-template-casing": ["error", "PascalCase", + { + "ignores": [ + "router-link", + "router-view", + "transition" + ] + } + ] + }, + "plugins": [ + "vue" + ] +} diff --git a/frontend/config/dev.env b/frontend/config/dev.env new file mode 100644 index 00000000..2fa2a329 --- /dev/null +++ b/frontend/config/dev.env @@ -0,0 +1,3 @@ +module.exports = { + NODE_ENV: 'development' +}; diff --git a/frontend/config/helpers.js b/frontend/config/helpers.js new file mode 100644 index 00000000..6ce2e499 --- /dev/null +++ b/frontend/config/helpers.js @@ -0,0 +1,15 @@ +'use strict'; + +const path = require('path'); + +const _root = path.resolve(__dirname, '..'); + +exports.root = function (args) { + args = Array.prototype.slice.call(arguments, 0); + + return path.join.apply(path, [ _root ].concat(args)); +}; + +exports.assetsPath = function (_path) { + return path.posix.join('assets', _path); +}; diff --git a/frontend/config/prod.env b/frontend/config/prod.env new file mode 100644 index 00000000..c2137abd --- /dev/null +++ b/frontend/config/prod.env @@ -0,0 +1,3 @@ +module.exports = { + NODE_ENV: 'production' +}; diff --git a/frontend/config/webpack.config.common.js b/frontend/config/webpack.config.common.js new file mode 100644 index 00000000..0c700769 --- /dev/null +++ b/frontend/config/webpack.config.common.js @@ -0,0 +1,68 @@ +'use strict'; + +const VueLoaderPlugin = require('vue-loader/lib/plugin'); +const HtmlPlugin = require('html-webpack-plugin'); +const MiniCSSExtractPlugin = require('mini-css-extract-plugin'); +const helpers = require('./helpers'); +const isDev = process.env.NODE_ENV === 'development'; + +const webpackConfig = { + entry: { + polyfill: '@babel/polyfill', + main: helpers.root('src', 'main'), + }, + resolve: { + extensions: [ '.js', '.vue' ], + alias: { + 'vue$': isDev ? 'vue/dist/vue.runtime.js' : 'vue/dist/vue.runtime.min.js', + '@': helpers.root('src') + } + }, + module: { + rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + include: [ helpers.root('src') ] + }, + { + test: /\.js$/, + loader: 'babel-loader', + include: [ helpers.root('src') ] + }, + { + test: /\.css$/, + use: [ + isDev ? 'vue-style-loader' : MiniCSSExtractPlugin.loader, + { loader: 'css-loader', options: { sourceMap: isDev } }, + ] + }, + { + test: /\.scss$/, + use: [ + isDev ? 'vue-style-loader' : MiniCSSExtractPlugin.loader, + { loader: 'css-loader', options: { sourceMap: isDev } }, + { loader: 'sass-loader', options: { sourceMap: isDev } } + ] + }, + { + test: /\.sass$/, + use: [ + isDev ? 'vue-style-loader' : MiniCSSExtractPlugin.loader, + { loader: 'css-loader', options: { sourceMap: isDev } }, + { loader: 'sass-loader', options: { sourceMap: isDev } } + ] + }, + { + test: /\.(gif|svg|jpg|png)$/, + loader: "file-loader", + } + ] + }, + plugins: [ + new VueLoaderPlugin(), + new HtmlPlugin({ template: 'public/index.html', chunksSortMode: 'dependency' }) + ] +}; + +module.exports = webpackConfig; diff --git a/frontend/config/webpack.config.dev.js b/frontend/config/webpack.config.dev.js new file mode 100644 index 00000000..0f129982 --- /dev/null +++ b/frontend/config/webpack.config.dev.js @@ -0,0 +1,49 @@ +'use strict'; + +const webpack = require('webpack'); +const merge = require('webpack-merge'); +const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin'); +const helpers = require('./helpers'); +const commonConfig = require('./webpack.config.common'); +const environment = require('./dev.env'); + +const webpackConfig = merge(commonConfig, { + mode: 'development', + devtool: 'cheap-module-eval-source-map', + output: { + path: helpers.root('dist'), + publicPath: '/', + filename: 'js/[name].bundle.js', + chunkFilename: 'js/[id].chunk.js' + }, + optimization: { + runtimeChunk: 'single', + splitChunks: { + chunks: 'all' + } + }, + plugins: [ + new webpack.EnvironmentPlugin(environment), + new webpack.HotModuleReplacementPlugin(), + new FriendlyErrorsPlugin() + ], + devServer: { + compress: true, + historyApiFallback: true, + hot: true, + open: true, + overlay: true, + port: 8888, + stats: { + normal: true + }, + proxy: { + '/api': { + logLevel: 'debug', + target: 'http://0.0.0.0:8585' + } + } + } +}); + +module.exports = webpackConfig; diff --git a/frontend/config/webpack.config.prod.js b/frontend/config/webpack.config.prod.js new file mode 100644 index 00000000..80c45eec --- /dev/null +++ b/frontend/config/webpack.config.prod.js @@ -0,0 +1,83 @@ +'use strict'; + +const webpack = require('webpack'); +const merge = require('webpack-merge'); +const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin'); +const MiniCSSExtractPlugin = require('mini-css-extract-plugin'); +const UglifyJSPlugin = require('uglifyjs-webpack-plugin'); +const CompressionPlugin = require('compression-webpack-plugin'); +const helpers = require('./helpers'); +const commonConfig = require('./webpack.config.common'); +const isProd = process.env.NODE_ENV === 'production'; +const environment = require('./prod.env'); + +const webpackConfig = merge(commonConfig, { + mode: 'production', + output: { + path: helpers.root('dist'), + publicPath: '/', + filename: 'js/[hash].js', + chunkFilename: 'js/[id].[hash].chunk.js' + }, + optimization: { + runtimeChunk: 'single', + minimizer: [ + new OptimizeCSSAssetsPlugin({ + cssProcessorPluginOptions: { + preset: [ 'default', { discardComments: { removeAll: true } } ], + } + }), + new UglifyJSPlugin({ + cache: true, + parallel: true, + sourceMap: !isProd + }) + ], + splitChunks: { + chunks: 'all', + maxInitialRequests: Infinity, + minSize: 0, + cacheGroups: { + vendor: { + test: /[\\/]node_modules[\\/]/, + name (module) { + const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1]; + return `npm.${packageName.replace('@', '')}`; + } + }, + styles: { + test: /\.css$/, + name: 'styles', + chunks: 'all', + enforce: true + } + } + } + }, + plugins: [ + new webpack.EnvironmentPlugin(environment), + new MiniCSSExtractPlugin({ + filename: 'css/[name].[hash].css', + chunkFilename: 'css/[id].[hash].css' + }), + new CompressionPlugin({ + filename: '[path].gz[query]', + algorithm: 'gzip', + test: new RegExp('\\.(js|css)$'), + threshold: 10240, + minRatio: 0.8 + }), + new webpack.HashedModuleIdsPlugin() + ] +}); + +if (!isProd) { + webpackConfig.devtool = 'source-map'; + + if (process.env.npm_config_report) { + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; + webpackConfig.plugins.push(new BundleAnalyzerPlugin()); + } +} + +module.exports = webpackConfig; diff --git a/frontend/package.json b/frontend/package.json index f30bffe6..c1cc572b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -4,43 +4,62 @@ "private": true, "scripts": { "serve": "vue-cli-service serve", - "build": "vue-cli-service build", + "build": "cross-env NODE_ENV=production webpack", + "dev": "cross-env NODE_ENV=development webpack-dev-server --progress", "lint": "vue-cli-service lint" }, "dependencies": { + "@babel/polyfill": "~7.2", "apexcharts": "^3.15.0", "axios": "^0.19.1", "core-js": "^3.4.4", "querystring": "^0.2.0", "vue": "^2.6.10", "vue-apexcharts": "^1.5.2", - "vue-router": "^3.1.3" + "vue-router": "~3.0", + "vuex": "^3.1.2" }, "devDependencies": { + "@babel/core": "~7.2", + "@babel/plugin-proposal-class-properties": "~7.3", + "@babel/plugin-proposal-decorators": "~7.3", + "@babel/plugin-proposal-json-strings": "~7.2", + "@babel/plugin-syntax-dynamic-import": "~7.2", + "@babel/plugin-syntax-import-meta": "~7.2", + "@babel/preset-env": "~7.8.3", + "@vue/babel-preset-app": "^4.1.2", "@vue/cli-plugin-babel": "^4.1.0", - "@vue/cli-plugin-eslint": "^4.1.0", - "@vue/cli-service": "^4.1.0", - "babel-eslint": "^10.0.3", - "eslint": "^5.16.0", - "eslint-plugin-vue": "^5.0.0", - "vue-template-compiler": "^2.6.10" - }, - "eslintConfig": { - "root": true, - "env": { - "node": true - }, - "extends": [ - "plugin:vue/essential", - "eslint:recommended" - ], - "rules": {}, - "parserOptions": { - "parser": "babel-eslint" - } - }, - "browserslist": [ - "> 1%", - "last 2 versions" - ] + "babel-eslint": "~10.0", + "babel-loader": "~8.0", + "compression-webpack-plugin": "~2.0", + "cross-env": "~5.2", + "css-loader": "~2.1", + "eslint": "~5.16", + "eslint-config-standard": "~10.2", + "eslint-friendly-formatter": "~3.0", + "eslint-loader": "~2.1", + "eslint-plugin-html": "~3.0", + "eslint-plugin-import": "~2.14", + "eslint-plugin-node": "~4.2", + "eslint-plugin-promise": "~3.5", + "eslint-plugin-standard": "~3.0", + "eslint-plugin-vue": "~5.1", + "file-loader": "^5.0.2", + "friendly-errors-webpack-plugin": "~1.7", + "html-webpack-plugin": "~3.2", + "mini-css-extract-plugin": "~0.5", + "node-sass": "~4.12", + "optimize-css-assets-webpack-plugin": "~5.0", + "sass-loader": "~7.1", + "uglifyjs-webpack-plugin": "~1.2", + "vue-loader": "~15.6", + "vue-style-loader": "~4.1", + "vue-template-compiler": "~2.6", + "webpack": "~4.29", + "webpack-bundle-analyzer": "~3.3", + "webpack-cli": "~3.2", + "webpack-dev-server": "~3.1", + "webpack-hot-middleware": "~2.24", + "webpack-merge": "~4.2" + } } diff --git a/frontend/public/index.html b/frontend/public/index.html index 97cd816c..e16cceae 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -4,7 +4,6 @@ - Statping diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 527a5de1..9679169d 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -6,13 +6,52 @@ diff --git a/frontend/src/components/API.js b/frontend/src/components/API.js index a2ed82f4..63c93cfe 100644 --- a/frontend/src/components/API.js +++ b/frontend/src/components/API.js @@ -8,7 +8,7 @@ class Api { } - async root () { + async core () { return axios.get('/api').then(response => (response.data)) } diff --git a/frontend/src/components/Dashboard/DashboardIndex.vue b/frontend/src/components/Dashboard/DashboardIndex.vue index 063df7e8..0e557d64 100644 --- a/frontend/src/components/Dashboard/DashboardIndex.vue +++ b/frontend/src/components/Dashboard/DashboardIndex.vue @@ -3,7 +3,7 @@
- {{services.length}} + {{$store.getters.services.length}} Total Services
@@ -11,12 +11,12 @@ Failures last 24 Hours
- 7 + {{$store.getters.onlineServices(true).length}} Online Services
-
+
@@ -30,9 +30,6 @@ components: { ServiceInfo }, - props: { - services: Array - }, methods: { } diff --git a/frontend/src/components/Dashboard/DashboardMessages.vue b/frontend/src/components/Dashboard/DashboardMessages.vue index 2a7467c1..fe865d40 100644 --- a/frontend/src/components/Dashboard/DashboardMessages.vue +++ b/frontend/src/components/Dashboard/DashboardMessages.vue @@ -30,9 +30,11 @@ - + {{message.title}} - {{message.service}} + + {{service(message.service).name}} + {{message.start_on}}
@@ -162,15 +164,15 @@ name: 'DashboardMessages', data () { return { - messages: null + } }, created() { - this.getMessages() + }, methods: { - async getMessages () { - this.messages = await Api.messages() + service (id) { + return this.$store.getters.serviceById(id) } } } diff --git a/frontend/src/components/Dashboard/DashboardServices.vue b/frontend/src/components/Dashboard/DashboardServices.vue index 47eb7333..3d1d8eb9 100644 --- a/frontend/src/components/Dashboard/DashboardServices.vue +++ b/frontend/src/components/Dashboard/DashboardServices.vue @@ -18,8 +18,8 @@