mirror of https://github.com/statping/statping
vue
parent
978bc17768
commit
d7fbc91b78
|
@ -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"
|
||||||
|
]
|
||||||
|
}
|
|
@ -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"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
NODE_ENV: 'development'
|
||||||
|
};
|
|
@ -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);
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = {
|
||||||
|
NODE_ENV: 'production'
|
||||||
|
};
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -4,43 +4,62 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve",
|
"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"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@babel/polyfill": "~7.2",
|
||||||
"apexcharts": "^3.15.0",
|
"apexcharts": "^3.15.0",
|
||||||
"axios": "^0.19.1",
|
"axios": "^0.19.1",
|
||||||
"core-js": "^3.4.4",
|
"core-js": "^3.4.4",
|
||||||
"querystring": "^0.2.0",
|
"querystring": "^0.2.0",
|
||||||
"vue": "^2.6.10",
|
"vue": "^2.6.10",
|
||||||
"vue-apexcharts": "^1.5.2",
|
"vue-apexcharts": "^1.5.2",
|
||||||
"vue-router": "^3.1.3"
|
"vue-router": "~3.0",
|
||||||
|
"vuex": "^3.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"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-babel": "^4.1.0",
|
||||||
"@vue/cli-plugin-eslint": "^4.1.0",
|
"babel-eslint": "~10.0",
|
||||||
"@vue/cli-service": "^4.1.0",
|
"babel-loader": "~8.0",
|
||||||
"babel-eslint": "^10.0.3",
|
"compression-webpack-plugin": "~2.0",
|
||||||
"eslint": "^5.16.0",
|
"cross-env": "~5.2",
|
||||||
"eslint-plugin-vue": "^5.0.0",
|
"css-loader": "~2.1",
|
||||||
"vue-template-compiler": "^2.6.10"
|
"eslint": "~5.16",
|
||||||
},
|
"eslint-config-standard": "~10.2",
|
||||||
"eslintConfig": {
|
"eslint-friendly-formatter": "~3.0",
|
||||||
"root": true,
|
"eslint-loader": "~2.1",
|
||||||
"env": {
|
"eslint-plugin-html": "~3.0",
|
||||||
"node": true
|
"eslint-plugin-import": "~2.14",
|
||||||
},
|
"eslint-plugin-node": "~4.2",
|
||||||
"extends": [
|
"eslint-plugin-promise": "~3.5",
|
||||||
"plugin:vue/essential",
|
"eslint-plugin-standard": "~3.0",
|
||||||
"eslint:recommended"
|
"eslint-plugin-vue": "~5.1",
|
||||||
],
|
"file-loader": "^5.0.2",
|
||||||
"rules": {},
|
"friendly-errors-webpack-plugin": "~1.7",
|
||||||
"parserOptions": {
|
"html-webpack-plugin": "~3.2",
|
||||||
"parser": "babel-eslint"
|
"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"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
"> 1%",
|
|
||||||
"last 2 versions"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, maximum-scale=1.0, user-scalable=0">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, maximum-scale=1.0, user-scalable=0">
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
|
||||||
<title>Statping</title>
|
<title>Statping</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -6,13 +6,52 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import Api from './components/API';
|
||||||
import Footer from "./components/Footer";
|
import Footer from "./components/Footer";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'app',
|
name: 'app',
|
||||||
components: {
|
components: {
|
||||||
Footer
|
Footer
|
||||||
},
|
},
|
||||||
|
created () {
|
||||||
|
if (!this.$store.getters.hasPublicData) {
|
||||||
|
this.setAllObjects()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
this.$store.commit('setHasPublicData', true)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async setAllObjects () {
|
||||||
|
await this.setCore()
|
||||||
|
await this.setToken()
|
||||||
|
await this.setServices()
|
||||||
|
await this.setGroups()
|
||||||
|
await this.setMessages()
|
||||||
|
this.$store.commit('setHasPublicData', true)
|
||||||
|
},
|
||||||
|
async setCore () {
|
||||||
|
const core = await Api.core()
|
||||||
|
this.$store.commit('setCore', core)
|
||||||
|
},
|
||||||
|
async setToken () {
|
||||||
|
const token = await Api.token()
|
||||||
|
this.$store.commit('setToken', token)
|
||||||
|
},
|
||||||
|
async setServices () {
|
||||||
|
const services = await Api.services()
|
||||||
|
this.$store.commit('setServices', services)
|
||||||
|
},
|
||||||
|
async setGroups () {
|
||||||
|
const groups = await Api.groups()
|
||||||
|
this.$store.commit('setGroups', groups)
|
||||||
|
},
|
||||||
|
async setMessages () {
|
||||||
|
const messages = await Api.messages()
|
||||||
|
this.$store.commit('setMessages', messages)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ class Api {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async root () {
|
async core () {
|
||||||
return axios.get('/api').then(response => (response.data))
|
return axios.get('/api').then(response => (response.data))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
<div class="row stats_area mb-5">
|
<div class="row stats_area mb-5">
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<span class="lg_number">{{services.length}}</span>
|
<span class="lg_number">{{$store.getters.services.length}}</span>
|
||||||
Total Services
|
Total Services
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
|
@ -11,12 +11,12 @@
|
||||||
Failures last 24 Hours
|
Failures last 24 Hours
|
||||||
</div>
|
</div>
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<span class="lg_number">7</span>
|
<span class="lg_number">{{$store.getters.onlineServices(true).length}}</span>
|
||||||
Online Services
|
Online Services
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-for="(service, index) in services" v-bind:key="index">
|
<div v-for="(service, index) in $store.getters.services" v-bind:key="index">
|
||||||
<ServiceInfo :service=service />
|
<ServiceInfo :service=service />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -30,9 +30,6 @@
|
||||||
components: {
|
components: {
|
||||||
ServiceInfo
|
ServiceInfo
|
||||||
},
|
},
|
||||||
props: {
|
|
||||||
services: Array
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,11 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
||||||
<tr v-for="(message, index) in messages" v-bind:key="index">
|
<tr v-for="(message, index) in $store.getters.messages" v-bind:key="index">
|
||||||
<td>{{message.title}}</td>
|
<td>{{message.title}}</td>
|
||||||
<td class="d-none d-md-table-cell"><a href="service/1">{{message.service}}</a></td>
|
<td class="d-none d-md-table-cell">
|
||||||
|
<router-link to="/service/${service(message.service).id}">{{service(message.service).name}}</router-link>
|
||||||
|
</td>
|
||||||
<td class="d-none d-md-table-cell">{{message.start_on}}</td>
|
<td class="d-none d-md-table-cell">{{message.start_on}}</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
|
@ -162,15 +164,15 @@
|
||||||
name: 'DashboardMessages',
|
name: 'DashboardMessages',
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
messages: null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getMessages()
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getMessages () {
|
service (id) {
|
||||||
this.messages = await Api.messages()
|
return this.$store.getters.serviceById(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<h1 class="text-black-50">Services <a href="service/create" class="btn btn-outline-success mt-1 float-right">
|
<h1 class="text-black-50">Services
|
||||||
<i class="fas fa-plus"></i> Create</a>
|
<router-link to="/service/create" class="btn btn-outline-success mt-1 float-right"><i class="fas fa-plus"></i> Create</router-link>
|
||||||
</h1>
|
</h1>
|
||||||
<table class="table">
|
<table class="table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="sortable" id="services_table">
|
<tbody class="sortable" id="services_table">
|
||||||
|
|
||||||
<tr v-for="(service, index) in services" v-bind:key="index">
|
<tr v-for="(service, index) in $store.getters.services" v-bind:key="index">
|
||||||
<td><span class="drag_icon d-none d-md-inline"><i class="fas fa-bars"></i></span> {{service.name}}</td>
|
<td><span class="drag_icon d-none d-md-inline"><i class="fas fa-bars"></i></span> {{service.name}}</td>
|
||||||
<td class="d-none d-md-table-cell"><span class="badge badge-success">ONLINE</span>
|
<td class="d-none d-md-table-cell"><span class="badge badge-success">ONLINE</span>
|
||||||
<i class="toggle-service fas fa-toggle-on text-success" data-online="true" data-id="1"></i>
|
<i class="toggle-service fas fa-toggle-on text-success" data-online="true" data-id="1"></i>
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody class="sortable_groups" id="groups_table">
|
<tbody class="sortable_groups" id="groups_table">
|
||||||
|
|
||||||
<tr v-for="(group, index) in groups" v-bind:key="index">
|
<tr v-for="(group, index) in $store.getters.groups" v-bind:key="index">
|
||||||
<td><span class="drag_icon d-none d-md-inline"><i class="fas fa-bars"></i></span>{{group.name}}</td>
|
<td><span class="drag_icon d-none d-md-inline"><i class="fas fa-bars"></i></span>{{group.name}}</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td><span class="badge badge-secondary">PRIVATE</span></td>
|
<td><span class="badge badge-secondary">PRIVATE</span></td>
|
||||||
|
@ -123,10 +123,6 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'DashboardServices',
|
name: 'DashboardServices',
|
||||||
props: {
|
|
||||||
services: Array,
|
|
||||||
groups: Array,
|
|
||||||
},
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="users_table">
|
<tbody id="users_table">
|
||||||
|
|
||||||
<tr v-for="(user, index) in users" v-bind:key="index" >
|
<tr v-for="(user, index) in $store.getters.users" v-bind:key="index" >
|
||||||
<td>{{user.username}}</td>
|
<td>{{user.username}}</td>
|
||||||
<td class="text-right">
|
<td class="text-right">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
|
@ -95,16 +95,13 @@
|
||||||
name: 'DashboardUsers',
|
name: 'DashboardUsers',
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
users: null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getUsers()
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getUsers () {
|
|
||||||
this.users = await Api.users()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
<template>
|
||||||
|
<div class="col-12">
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<form class="ajax_form" action="api/services" data-redirect="services" method="POST">
|
||||||
|
<h4 class="mb-5 text-muted">Basic Information</h4>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_name" class="col-sm-4 col-form-label">Service Name</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" name="name" class="form-control" id="service_name" value="" placeholder="Name" required spellcheck="false" autocorrect="off">
|
||||||
|
<small class="form-text text-muted">Give your service a name you can recognize</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_type" class="col-sm-4 col-form-label">Service Type</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<select name="type" class="form-control" id="service_type" value="" >
|
||||||
|
<option value="http" >HTTP Service</option>
|
||||||
|
<option value="tcp" >TCP Service</option>
|
||||||
|
<option value="udp" >UDP Service</option>
|
||||||
|
<option value="icmp" >ICMP Ping</option>
|
||||||
|
</select>
|
||||||
|
<small class="form-text text-muted">Use HTTP if you are checking a website or use TCP if you are checking a server</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_url" class="col-sm-4 col-form-label">Application Endpoint (URL)</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" name="domain" class="form-control" id="service_url" value="" placeholder="https://google.com" required autocapitalize="none" spellcheck="false">
|
||||||
|
<small class="form-text text-muted">Statping will attempt to connect to this URL</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_type" class="col-sm-4 col-form-label">Group</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<select name="group_id" class="form-control" id="group_id">
|
||||||
|
<option value="0" selected>None</option>
|
||||||
|
|
||||||
|
<option value="1" >JSON Test Servers</option>
|
||||||
|
|
||||||
|
<option value="2" >Google Servers</option>
|
||||||
|
|
||||||
|
<option value="3" >Statping Servers</option>
|
||||||
|
|
||||||
|
</select>
|
||||||
|
<small class="form-text text-muted">Attach this service to a group</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 class="mt-5 mb-5 text-muted">Request Details</h4>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_check_type" class="col-sm-4 col-form-label">Service Check Type</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<select name="method" class="form-control" id="service_check_type" value="">
|
||||||
|
<option value="GET" >GET</option>
|
||||||
|
<option value="POST" >POST</option>
|
||||||
|
<option value="DELETE" >DELETE</option>
|
||||||
|
<option value="PATCH" >PATCH</option>
|
||||||
|
<option value="PUT" >PUT</option>
|
||||||
|
</select>
|
||||||
|
<small class="form-text text-muted">A GET request will simply request the endpoint, you can also send data with POST.</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row d-none">
|
||||||
|
<label for="post_data" class="col-sm-4 col-form-label">Optional Post Data (JSON)</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<textarea name="post_data" class="form-control" id="post_data" rows="3" autocapitalize="none" spellcheck="false" placeholder='{"data": { "method": "success", "id": 148923 } }'></textarea>
|
||||||
|
<small class="form-text text-muted">Insert a JSON string to send data to the endpoint.</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="headers" class="col-sm-4 col-form-label">HTTP Headers</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input name="headers" class="form-control" id="headers" autocapitalize="none" spellcheck="false" placeholder='Authorization=1010101,Content-Type=application/json' value="">
|
||||||
|
<small class="form-text text-muted">Comma delimited list of HTTP Headers (KEY=VALUE,KEY=VALUE)</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_response" class="col-sm-4 col-form-label">Expected Response (Regex)</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<textarea name="expected" class="form-control" id="service_response" rows="3" autocapitalize="none" spellcheck="false" placeholder='(method)": "((\\"|[success])*)"'></textarea>
|
||||||
|
<small class="form-text text-muted">You can use plain text or insert <a target="_blank" href="https://regex101.com/r/I5bbj9/1">Regex</a> to validate the response</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_response_code" class="col-sm-4 col-form-label">Expected Status Code</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" name="expected_status" class="form-control" value="200" placeholder="200" id="service_response_code">
|
||||||
|
<small class="form-text text-muted">A status code of 200 is success, or view all the <a target="_blank" href="https://www.restapitutorial.com/httpstatuscodes.html">HTTP Status Codes</a></small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row d-none">
|
||||||
|
<label for="port" class="col-sm-4 col-form-label">TCP Port</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" name="port" class="form-control" value="" id="service_port" placeholder="8080">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 class="mt-5 mb-5 text-muted">Additional Options</h4>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_interval" class="col-sm-4 col-form-label">Check Interval (Seconds)</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" name="check_interval" class="form-control" value="60" min="1" id="service_interval" required>
|
||||||
|
<small id="interval" class="form-text text-muted">10,000+ will be checked in Microseconds (1 millisecond = 1000 microseconds).</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_timeout" class="col-sm-4 col-form-label">Timeout in Seconds</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" name="timeout" class="form-control" value="15" placeholder="15" id="service_timeout" min="1">
|
||||||
|
<small class="form-text text-muted">If the endpoint does not respond within this time it will be considered to be offline</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="post_data" class="col-sm-4 col-form-label">Permalink URL</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" name="permalink" class="form-control" value="" id="permalink" autocapitalize="none" spellcheck="true" placeholder='awesome_service'>
|
||||||
|
<small class="form-text text-muted">Use text for the service URL rather than the service number.</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row d-none">
|
||||||
|
<label for="order" class="col-sm-4 col-form-label">List Order</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" name="order" class="form-control" min="0" value="0" id="order">
|
||||||
|
<small class="form-text text-muted">You can also drag and drop services to reorder on the Services tab.</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="order" class="col-sm-4 col-form-label">Verify SSL</label>
|
||||||
|
<div class="col-8 mt-1">
|
||||||
|
<span class="switch float-left">
|
||||||
|
<input type="checkbox" name="verify_ssl-option" class="switch" id="switch-verify-ssl" checked>
|
||||||
|
<label for="switch-verify-ssl">Verify SSL Certificate for this service</label>
|
||||||
|
<input type="hidden" name="verify_ssl" id="switch-verify-ssl-value" value="true">
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="order" class="col-sm-4 col-form-label">Notifications</label>
|
||||||
|
<div class="col-8 mt-1">
|
||||||
|
<span class="switch float-left">
|
||||||
|
<input type="checkbox" name="allow_notifications-option" class="switch" id="switch-notifications" checked>
|
||||||
|
<label for="switch-notifications">Allow notifications to be sent for this service</label>
|
||||||
|
<input type="hidden" name="allow_notifications" id="switch-notifications-value" value="true">
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="order" class="col-sm-4 col-form-label">Visible</label>
|
||||||
|
<div class="col-8 mt-1">
|
||||||
|
<span class="switch float-left">
|
||||||
|
<input type="checkbox" name="public-option" class="switch" id="switch-public" checked>
|
||||||
|
<label for="switch-public">Show service details to the public</label>
|
||||||
|
<input type="hidden" name="public" id="switch-public-value" value="true">
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-12">
|
||||||
|
<button type="submit" class="btn btn-success btn-block">Create Service</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-danger d-none" id="alerter" role="alert"></div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'ServiceForm',
|
||||||
|
props: {
|
||||||
|
service: Object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
|
@ -26,7 +26,10 @@
|
||||||
export default {
|
export default {
|
||||||
name: 'ServiceInfo',
|
name: 'ServiceInfo',
|
||||||
props: {
|
props: {
|
||||||
service: Object
|
service: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -50,6 +50,8 @@
|
||||||
methods: {
|
methods: {
|
||||||
async logout () {
|
async logout () {
|
||||||
await Api.logout()
|
await Api.logout()
|
||||||
|
this.$store.commit('setHasAllData', false)
|
||||||
|
this.$store.commit('setToken', null)
|
||||||
await this.$router.push('/')
|
await this.$router.push('/')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,31 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="col-12 full-col-12">
|
<div class="col-12 full-col-12">
|
||||||
<h4 class="group_header">{{group.name}}</h4>
|
<h4 v-if="group.name !== 'Empty Group'" class="group_header">{{group.name}}</h4>
|
||||||
<div class="list-group online_list mb-3">
|
<div class="list-group online_list mb-3">
|
||||||
|
|
||||||
<GroupedService/>
|
<a v-for="(service, index) in $store.getters.servicesInGroup(group.id)" v-bind:key="index" href="#" class="service_li list-group-item list-group-item-action " data-id="7">
|
||||||
|
{{service.name}}
|
||||||
|
<span class="badge bg-success float-right pulse-glow">{{service.online ? "ONLINE" : "OFFLINE"}}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import GroupedService from './GroupedService'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Group',
|
name: 'Group',
|
||||||
components: {
|
components: {
|
||||||
GroupedService
|
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
group: Object
|
group: Object
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
serviceBadge (s) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
<template>
|
|
||||||
<a href="#" class="service_li list-group-item list-group-item-action " data-id="7">
|
|
||||||
Statping API
|
|
||||||
<span class="badge bg-success float-right pulse-glow">ONLINE</span>
|
|
||||||
</a>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'GroupedService',
|
|
||||||
props: {
|
|
||||||
service: Object
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
</style>
|
|
|
@ -1,16 +1,13 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<h1 class="col-12 text-center mb-4 mt-sm-3 header-title">{{core.name}}</h1>
|
<h1 class="col-12 text-center mb-4 mt-sm-3 header-title">{{$store.getters.core.name}}</h1>
|
||||||
<h5 class="col-12 text-center mb-5 header-desc">{{core.description}}</h5>
|
<h5 class="col-12 text-center mb-5 header-desc">{{$store.getters.core.description}}</h5>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'Header',
|
name: 'Header',
|
||||||
props: {
|
|
||||||
core: Object
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
class Time {
|
||||||
|
now () {
|
||||||
|
return new Date();
|
||||||
|
}
|
||||||
|
utc () {
|
||||||
|
return new Date().getUTCDate();
|
||||||
|
}
|
||||||
|
utcToLocal (utc) {
|
||||||
|
let u = new Date().setUTCDate(utc)
|
||||||
|
return u.toLocaleString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const time = new Time()
|
||||||
|
export default time
|
|
@ -0,0 +1,121 @@
|
||||||
|
<template>
|
||||||
|
<form @submit="saveSettings" method="POST" action="settings">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Project Name</label>
|
||||||
|
<input v-model="core.name" type="text" class="form-control" placeholder="Great Uptime">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Project Description</label>
|
||||||
|
<input v-model="core.description" type="text" class="form-control" placeholder="Great Uptime">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-8 col-sm-9">
|
||||||
|
<label>Domain</label>
|
||||||
|
<input v-model="core.domain" type="url" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="col-4 col-sm-3 mt-sm-1 mt-0">
|
||||||
|
<label class="d-inline d-sm-none">Enable CDN</label>
|
||||||
|
<label class="d-none d-sm-block">Enable CDN</label>
|
||||||
|
<span class="switch">
|
||||||
|
<input v-model="core.using_cdn" type="checkbox" class="switch" v-bind:disabled="core.using_cdn">
|
||||||
|
<label class="mt-2 mt-sm-0"></label>
|
||||||
|
</span>
|
||||||
|
<input v-model="core.using_cdn" type="hidden" name="enable_cdn" id="switch-normal-value" value="false">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Custom Footer</label>
|
||||||
|
<textarea rows="4" class="form-control">{{core.footer}}</textarea>
|
||||||
|
<small class="form-text text-muted">HTML is allowed inside the footer</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="timezone">Timezone</label><span class="mt-1 small float-right">Current: {{now}}</span>
|
||||||
|
<select class="form-control" name="timezone" id="timezone">
|
||||||
|
<option value="-12.0" >(GMT -12:00) Eniwetok, Kwajalein</option>
|
||||||
|
<option value="-11.0" >(GMT -11:00) Midway Island, Samoa</option>
|
||||||
|
<option value="-10.0" >(GMT -10:00) Hawaii</option>
|
||||||
|
<option value="-9.0" >(GMT -9:00) Alaska</option>
|
||||||
|
<option value="-8.0" selected>(GMT -8:00) Pacific Time (US & Canada)</option>
|
||||||
|
<option value="-7.0" >(GMT -7:00) Mountain Time (US & Canada)</option>
|
||||||
|
<option value="-6.0" >(GMT -6:00) Central Time (US & Canada), Mexico City</option>
|
||||||
|
<option value="-5.0" >(GMT -5:00) Eastern Time (US & Canada), Bogota, Lima</option>
|
||||||
|
<option value="-4.0" >(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz</option>
|
||||||
|
<option value="-3.5" >(GMT -3:30) Newfoundland</option>
|
||||||
|
<option value="-3.0" >(GMT -3:00) Brazil, Buenos Aires, Georgetown</option>
|
||||||
|
<option value="-2.0" >(GMT -2:00) Mid-Atlantic</option>
|
||||||
|
<option value="-1.0" >(GMT -1:00 hour) Azores, Cape Verde Islands</option>
|
||||||
|
<option value="0.0" >(GMT) Western Europe Time, London, Lisbon, Casablanca</option>
|
||||||
|
<option value="1.0" >(GMT +1:00 hour) Brussels, Copenhagen, Madrid, Paris</option>
|
||||||
|
<option value="2.0" >(GMT +2:00) Kaliningrad, South Africa</option>
|
||||||
|
<option value="3.0" >(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg</option>
|
||||||
|
<option value="3.5" >(GMT +3:30) Tehran</option>
|
||||||
|
<option value="4.0" >(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi</option>
|
||||||
|
<option value="4.5" >(GMT +4:30) Kabul</option>
|
||||||
|
<option value="5.0" >(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent</option>
|
||||||
|
<option value="5.5" >(GMT +5:30) Bombay, Calcutta, Madras, New Delhi</option>
|
||||||
|
<option value="5.75" >(GMT +5:45) Kathmandu</option>
|
||||||
|
<option value="6.0" >(GMT +6:00) Almaty, Dhaka, Colombo</option>
|
||||||
|
<option value="7.0" >(GMT +7:00) Bangkok, Hanoi, Jakarta</option>
|
||||||
|
<option value="8.0" >(GMT +8:00) Beijing, Perth, Singapore, Hong Kong</option>
|
||||||
|
<option value="9.0" >(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk</option>
|
||||||
|
<option value="9.5" >(GMT +9:30) Adelaide, Darwin</option>
|
||||||
|
<option value="10.0" >(GMT +10:00) Eastern Australia, Guam, Vladivostok</option>
|
||||||
|
<option value="11.0" >(GMT +11:00) Magadan, Solomon Islands, New Caledonia</option>
|
||||||
|
<option value="12.0" >(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary btn-block">Save Settings</button>
|
||||||
|
|
||||||
|
<div class="form-group row mt-3">
|
||||||
|
<label for="api_key" class="col-sm-3 col-form-label">API Key</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control select-input" value="9e657102489b63946908a084befc187e6e506eb0" id="api_key" readonly>
|
||||||
|
<small class="form-text text-muted">API Key can be used for read only routes</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="api_secret" class="col-sm-3 col-form-label">API Secret</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" class="form-control select-input" value="6b05b48f4b3a1460f3864c31b26cab6a27dbaff9" id="api_secret" readonly>
|
||||||
|
<small class="form-text text-muted">API Secret is used for read, create, update and delete routes</small>
|
||||||
|
<small class="form-text text-muted">You can <a class="confirm_btn" data-msg="Are you sure you want to reset the API keys?" href="api/renew">Regenerate API Keys</a> if you need to.</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import time from '../components/Time'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CoreSettings',
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
core: this.$store.getters.core,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
now () {
|
||||||
|
return time.now()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
saveSettings () {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
|
@ -0,0 +1,178 @@
|
||||||
|
<template>
|
||||||
|
<form class="ajax_form" action="api/services" data-redirect="services" method="POST">
|
||||||
|
<h4 class="mb-5 text-muted">Basic Information</h4>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_name" class="col-sm-4 col-form-label">Service Name</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" name="name" class="form-control" id="service_name" value="" placeholder="Name" required spellcheck="false" autocorrect="off">
|
||||||
|
<small class="form-text text-muted">Give your service a name you can recognize</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_type" class="col-sm-4 col-form-label">Service Type</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<select name="type" class="form-control" id="service_type" value="" >
|
||||||
|
<option value="http" >HTTP Service</option>
|
||||||
|
<option value="tcp" >TCP Service</option>
|
||||||
|
<option value="udp" >UDP Service</option>
|
||||||
|
<option value="icmp" >ICMP Ping</option>
|
||||||
|
</select>
|
||||||
|
<small class="form-text text-muted">Use HTTP if you are checking a website or use TCP if you are checking a server</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_url" class="col-sm-4 col-form-label">Application Endpoint (URL)</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" name="domain" class="form-control" id="service_url" value="" placeholder="https://google.com" required autocapitalize="none" spellcheck="false">
|
||||||
|
<small class="form-text text-muted">Statping will attempt to connect to this URL</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_type" class="col-sm-4 col-form-label">Group</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<select name="group_id" class="form-control" id="group_id">
|
||||||
|
<option value="0" selected>None</option>
|
||||||
|
|
||||||
|
<option value="1" >JSON Test Servers</option>
|
||||||
|
|
||||||
|
<option value="2" >Google Servers</option>
|
||||||
|
|
||||||
|
<option value="3" >Statping Servers</option>
|
||||||
|
|
||||||
|
</select>
|
||||||
|
<small class="form-text text-muted">Attach this service to a group</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 class="mt-5 mb-5 text-muted">Request Details</h4>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_check_type" class="col-sm-4 col-form-label">Service Check Type</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<select name="method" class="form-control" id="service_check_type" value="">
|
||||||
|
<option value="GET" >GET</option>
|
||||||
|
<option value="POST" >POST</option>
|
||||||
|
<option value="DELETE" >DELETE</option>
|
||||||
|
<option value="PATCH" >PATCH</option>
|
||||||
|
<option value="PUT" >PUT</option>
|
||||||
|
</select>
|
||||||
|
<small class="form-text text-muted">A GET request will simply request the endpoint, you can also send data with POST.</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row d-none">
|
||||||
|
<label for="post_data" class="col-sm-4 col-form-label">Optional Post Data (JSON)</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<textarea name="post_data" class="form-control" id="post_data" rows="3" autocapitalize="none" spellcheck="false" placeholder='{"data": { "method": "success", "id": 148923 } }'></textarea>
|
||||||
|
<small class="form-text text-muted">Insert a JSON string to send data to the endpoint.</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="headers" class="col-sm-4 col-form-label">HTTP Headers</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input name="headers" class="form-control" id="headers" autocapitalize="none" spellcheck="false" placeholder='Authorization=1010101,Content-Type=application/json' value="">
|
||||||
|
<small class="form-text text-muted">Comma delimited list of HTTP Headers (KEY=VALUE,KEY=VALUE)</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_response" class="col-sm-4 col-form-label">Expected Response (Regex)</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<textarea name="expected" class="form-control" id="service_response" rows="3" autocapitalize="none" spellcheck="false" placeholder='(method)": "((\\"|[success])*)"'></textarea>
|
||||||
|
<small class="form-text text-muted">You can use plain text or insert <a target="_blank" href="https://regex101.com/r/I5bbj9/1">Regex</a> to validate the response</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_response_code" class="col-sm-4 col-form-label">Expected Status Code</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" name="expected_status" class="form-control" value="200" placeholder="200" id="service_response_code">
|
||||||
|
<small class="form-text text-muted">A status code of 200 is success, or view all the <a target="_blank" href="https://www.restapitutorial.com/httpstatuscodes.html">HTTP Status Codes</a></small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row d-none">
|
||||||
|
<label for="port" class="col-sm-4 col-form-label">TCP Port</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" name="port" class="form-control" value="" id="service_port" placeholder="8080">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 class="mt-5 mb-5 text-muted">Additional Options</h4>
|
||||||
|
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_interval" class="col-sm-4 col-form-label">Check Interval (Seconds)</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" name="check_interval" class="form-control" value="60" min="1" id="service_interval" required>
|
||||||
|
<small id="interval" class="form-text text-muted">10,000+ will be checked in Microseconds (1 millisecond = 1000 microseconds).</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="service_timeout" class="col-sm-4 col-form-label">Timeout in Seconds</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" name="timeout" class="form-control" value="15" placeholder="15" id="service_timeout" min="1">
|
||||||
|
<small class="form-text text-muted">If the endpoint does not respond within this time it will be considered to be offline</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="post_data" class="col-sm-4 col-form-label">Permalink URL</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" name="permalink" class="form-control" value="" id="permalink" autocapitalize="none" spellcheck="true" placeholder='awesome_service'>
|
||||||
|
<small class="form-text text-muted">Use text for the service URL rather than the service number.</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row d-none">
|
||||||
|
<label for="order" class="col-sm-4 col-form-label">List Order</label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="number" name="order" class="form-control" min="0" value="0" id="order">
|
||||||
|
<small class="form-text text-muted">You can also drag and drop services to reorder on the Services tab.</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="order" class="col-sm-4 col-form-label">Verify SSL</label>
|
||||||
|
<div class="col-8 mt-1">
|
||||||
|
<span class="switch float-left">
|
||||||
|
<input type="checkbox" name="verify_ssl-option" class="switch" id="switch-verify-ssl" checked>
|
||||||
|
<label for="switch-verify-ssl">Verify SSL Certificate for this service</label>
|
||||||
|
<input type="hidden" name="verify_ssl" id="switch-verify-ssl-value" value="true">
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="order" class="col-sm-4 col-form-label">Notifications</label>
|
||||||
|
<div class="col-8 mt-1">
|
||||||
|
<span class="switch float-left">
|
||||||
|
<input type="checkbox" name="allow_notifications-option" class="switch" id="switch-notifications" checked>
|
||||||
|
<label for="switch-notifications">Allow notifications to be sent for this service</label>
|
||||||
|
<input type="hidden" name="allow_notifications" id="switch-notifications-value" value="true">
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="order" class="col-sm-4 col-form-label">Visible</label>
|
||||||
|
<div class="col-8 mt-1">
|
||||||
|
<span class="switch float-left">
|
||||||
|
<input type="checkbox" name="public-option" class="switch" id="switch-public" checked>
|
||||||
|
<label for="switch-public">Show service details to the public</label>
|
||||||
|
<input type="hidden" name="public" id="switch-public-value" value="true">
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-12">
|
||||||
|
<button type="submit" class="btn btn-success btn-block">Create Service</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-danger d-none" id="alerter" role="alert"></div>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'FormService',
|
||||||
|
props: {
|
||||||
|
service: Object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
|
@ -1,15 +1,18 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import App from './App.vue'
|
|
||||||
import VueRouter from 'vue-router'
|
import VueRouter from 'vue-router'
|
||||||
import Index from "./pages/Index";
|
|
||||||
import Dashboard from "./pages/Dashboard";
|
|
||||||
import Login from "./pages/Login";
|
|
||||||
import Settings from "./pages/Settings";
|
|
||||||
import Services from "./pages/Services";
|
|
||||||
import Service from "./pages/Service";
|
|
||||||
|
|
||||||
require("./assets/css/bootstrap.min.css")
|
import App from '@/App.vue'
|
||||||
require("./assets/css/base.css")
|
import store from '@/store'
|
||||||
|
|
||||||
|
const Index = () => import("@/pages/Index");
|
||||||
|
const Dashboard = () => import("@/pages/Dashboard");
|
||||||
|
const Login = () => import("@/pages/Login");
|
||||||
|
const Settings = () => import("@/pages/Settings");
|
||||||
|
const Services = () => import("@/pages/Services");
|
||||||
|
const Service = () => import("@/pages/Service");
|
||||||
|
|
||||||
|
require("@/assets/css/bootstrap.min.css")
|
||||||
|
require("@/assets/css/base.css")
|
||||||
|
|
||||||
// require("./assets/js/bootstrap.min")
|
// require("./assets/js/bootstrap.min")
|
||||||
// require("./assets/js/flatpickr")
|
// require("./assets/js/flatpickr")
|
||||||
|
@ -27,7 +30,8 @@ const routes = [
|
||||||
path: '/dashboard',
|
path: '/dashboard',
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
component: Dashboard,
|
component: Dashboard,
|
||||||
alias: ['/dashboard/settings', '/dashboard/services', '/dashboard/messages', '/dashboard/groups', '/dashboard/users', '/dashboard/logs', '/dashboard/help']
|
alias: ['/dashboard/settings', '/dashboard/services', '/dashboard/messages', '/dashboard/groups', '/dashboard/users', '/dashboard/logs', '/dashboard/help',
|
||||||
|
'/service/create']
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/login',
|
path: '/login',
|
||||||
|
@ -63,5 +67,6 @@ Vue.use(VueRouter);
|
||||||
Vue.config.productionTip = false
|
Vue.config.productionTip = false
|
||||||
new Vue({
|
new Vue({
|
||||||
router,
|
router,
|
||||||
|
store,
|
||||||
render: h => h(App),
|
render: h => h(App),
|
||||||
}).$mount('#app')
|
}).$mount('#app')
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<Login v-show="token === null"/>
|
<Login v-show="$store.getters.token === null"/>
|
||||||
|
|
||||||
<div v-show="token !== null" class="container col-md-7 col-sm-12 mt-md-5 bg-light">
|
<div v-show="$store.getters.token !== null" class="container col-md-7 col-sm-12 mt-md-5 bg-light">
|
||||||
|
|
||||||
<TopNav :changeView="changeView"/>
|
<TopNav :changeView="changeView"/>
|
||||||
|
|
||||||
<DashboardIndex v-show="view === 'DashboardIndex'" :services="services"/>
|
<DashboardIndex v-show="view === 'DashboardIndex'"/>
|
||||||
|
|
||||||
<DashboardServices v-show="view === 'DashboardServices'" :services="services"/>
|
<DashboardServices v-show="view === 'DashboardServices'"/>
|
||||||
|
|
||||||
<DashboardUsers v-show="view === 'DashboardUsers'" :services="services"/>
|
<DashboardUsers v-show="view === 'DashboardUsers'"/>
|
||||||
|
|
||||||
<DashboardMessages v-show="view === 'DashboardMessages'" :services="services"/>
|
<DashboardMessages v-show="view === 'DashboardMessages'"/>
|
||||||
|
|
||||||
<Settings v-show="view === 'Settings'" :services="services"/>
|
<Settings v-show="view === 'Settings'"/>
|
||||||
|
|
||||||
|
<ServiceForm v-show="view === 'ServiceForm'"/>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -22,6 +24,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Api from "../components/API"
|
import Api from "../components/API"
|
||||||
|
import ServiceForm from '../components/Dashboard/ServiceForm';
|
||||||
import Login from "./Login";
|
import Login from "./Login";
|
||||||
import TopNav from "../components/Dashboard/TopNav";
|
import TopNav from "../components/Dashboard/TopNav";
|
||||||
import DashboardIndex from "../components/Dashboard/DashboardIndex";
|
import DashboardIndex from "../components/Dashboard/DashboardIndex";
|
||||||
|
@ -33,6 +36,7 @@
|
||||||
export default {
|
export default {
|
||||||
name: 'Dashboard',
|
name: 'Dashboard',
|
||||||
components: {
|
components: {
|
||||||
|
ServiceForm,
|
||||||
Settings,
|
Settings,
|
||||||
DashboardMessages,
|
DashboardMessages,
|
||||||
DashboardUsers,
|
DashboardUsers,
|
||||||
|
@ -43,17 +47,13 @@
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
services: null,
|
|
||||||
groups: null,
|
|
||||||
core: null,
|
|
||||||
token: null,
|
|
||||||
view: "DashboardIndex",
|
view: "DashboardIndex",
|
||||||
|
authenticated: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.pathView(this.$route.path)
|
this.pathView(this.$route.path)
|
||||||
this.token = Api.token()
|
this.isAuthenticated()
|
||||||
this.loadAll()
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
pathView (path) {
|
pathView (path) {
|
||||||
|
@ -70,6 +70,9 @@
|
||||||
case "/dashboard/services":
|
case "/dashboard/services":
|
||||||
this.view = "DashboardServices"
|
this.view = "DashboardServices"
|
||||||
break
|
break
|
||||||
|
case "/service/create":
|
||||||
|
this.view = "ServiceForm"
|
||||||
|
break
|
||||||
default:
|
default:
|
||||||
this.view = "DashboardIndex"
|
this.view = "DashboardIndex"
|
||||||
}
|
}
|
||||||
|
@ -78,11 +81,25 @@
|
||||||
this.view = v
|
this.view = v
|
||||||
this.$router.push('/'+name)
|
this.$router.push('/'+name)
|
||||||
},
|
},
|
||||||
async loadAll () {
|
isAuthenticated () {
|
||||||
this.token = await Api.token()
|
const token = this.$store.getters.token
|
||||||
this.core = await Api.root()
|
if (token.token) {
|
||||||
this.groups = await Api.groups()
|
this.authenticated = true
|
||||||
this.services = await Api.services()
|
if (!this.$store.getters.hasAllData) {
|
||||||
|
this.loadAllData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async loadAllData () {
|
||||||
|
const users = await Api.users()
|
||||||
|
const groups = await Api.groups()
|
||||||
|
const messages = await Api.messages()
|
||||||
|
const notifiers = await Api.notifiers()
|
||||||
|
this.$store.commit('setMessages', messages)
|
||||||
|
this.$store.commit('setUsers', users)
|
||||||
|
this.$store.commit('setGroups', groups)
|
||||||
|
this.$store.commit('setNotifiers', notifiers)
|
||||||
|
this.$store.commit('setHasAllData', true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-show="core" class="container col-md-7 col-sm-12 mt-2 sm-container">
|
<div class="container col-md-7 col-sm-12 mt-2 sm-container">
|
||||||
|
|
||||||
<Header :core="core"/>
|
<Header/>
|
||||||
|
|
||||||
<div v-for="(group, index) in groups" v-bind:key="index">
|
<div v-for="(group, index) in $store.getters.groups" v-bind:key="index">
|
||||||
<Group :group=group />
|
<Group :group=group />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
<div class="col-12 full-col-12">
|
<div class="col-12 full-col-12">
|
||||||
|
|
||||||
<div v-for="(service, index) in services" v-bind:key="index">
|
<div v-for="(service, index) in $store.getters.services" v-bind:key="index">
|
||||||
<ServiceBlock :service=service />
|
<ServiceBlock :service=service />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -22,13 +22,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ServiceBlock from '../components/Service/ServiceBlock.vue'
|
const Header = () => import("@/components/Index/Header");
|
||||||
import MessageBlock from "../components/Index/MessageBlock";
|
const ServiceBlock = () => import("@/components/Service/ServiceBlock.vue");
|
||||||
import Group from "../components/Index/Group";
|
const MessageBlock = () => import("@/components/Index/MessageBlock");
|
||||||
import Header from "../components/Index/Header";
|
const Group = () => import("@/components/Index/Group");
|
||||||
import Api from "../components/API"
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Index',
|
name: 'Index',
|
||||||
components: {
|
components: {
|
||||||
Header,
|
Header,
|
||||||
|
@ -38,26 +37,17 @@
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
services: null,
|
|
||||||
groups: null,
|
|
||||||
core: null,
|
|
||||||
auth: null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.auth = Api.authToken()
|
|
||||||
this.core = Api.root()
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.loadAll()
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadAll () {
|
|
||||||
this.auth = Api.authToken()
|
|
||||||
this.core = await Api.root()
|
|
||||||
this.groups = await Api.groups()
|
|
||||||
this.services = await Api.services()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -2,9 +2,8 @@
|
||||||
<div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
|
<div class="container col-md-7 col-sm-12 mt-md-5 bg-light">
|
||||||
<div class="col-10 offset-1 col-md-8 offset-md-2 mt-md-2">
|
<div class="col-10 offset-1 col-md-8 offset-md-2 mt-md-2">
|
||||||
<div class="col-12 col-md-8 offset-md-2 mb-4">
|
<div class="col-12 col-md-8 offset-md-2 mb-4">
|
||||||
<img class="col-12 mt-5 mt-md-0" :src="require(`@/assets/banner.png`)">
|
<img class="col-12 mt-5 mt-md-0" src="../assets/banner.png">
|
||||||
</div>
|
</div>
|
||||||
{{auth}}
|
|
||||||
<form id="login_form" @submit="login" method="post">
|
<form id="login_form" @submit="login" method="post">
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label for="username" class="col-sm-2 col-form-label">Username</label>
|
<label for="username" class="col-sm-2 col-form-label">Username</label>
|
||||||
|
@ -20,7 +19,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<button type="submit" class="btn btn-primary btn-block mb-3">Sign in</button>
|
<button v-on:click="login" type="submit" class="btn btn-primary btn-block mb-3">Sign in</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -49,7 +48,8 @@
|
||||||
const auth = await Api.login(this.username, this.password)
|
const auth = await Api.login(this.username, this.password)
|
||||||
if (auth.token !== null) {
|
if (auth.token !== null) {
|
||||||
this.auth = Api.saveToken(this.username, auth.token)
|
this.auth = Api.saveToken(this.username, auth.token)
|
||||||
await this.$router.push('/dashboard')
|
this.$store.commit('setToken', auth)
|
||||||
|
this.$router.push('/dashboard')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
<h6 class="mt-4 text-muted">Notifiers</h6>
|
<h6 class="mt-4 text-muted">Notifiers</h6>
|
||||||
|
|
||||||
<a v-for="(notifier, index) in notifiers" v-bind:key="index" v-on:click="changeTab" class="nav-link text-capitalize" v-bind:class="{active: liClass(`v-pills-${notifier.method.toLowerCase()}-tab`)}" v-bind:id="`v-pills-${notifier.method.toLowerCase()}-tab`" data-toggle="pill" v-bind:href="`#v-pills-${notifier.method.toLowerCase()}`" role="tab" v-bind:aria-controls="`v-pills-${notifier.method.toLowerCase()}`" aria-selected="false"><i class="fas fa-terminal"></i> {{notifier.method}}</a>
|
<a v-for="(notifier, index) in $store.getters.notifiers" v-bind:key="index" v-on:click="changeTab" class="nav-link text-capitalize" v-bind:class="{active: liClass(`v-pills-${notifier.method.toLowerCase()}-tab`)}" v-bind:id="`v-pills-${notifier.method.toLowerCase()}-tab`" data-toggle="pill" v-bind:href="`#v-pills-${notifier.method.toLowerCase()}`" role="tab" v-bind:aria-controls="`v-pills-${notifier.method.toLowerCase()}`" aria-selected="false"><i class="fas fa-terminal"></i> {{notifier.method}}</a>
|
||||||
|
|
||||||
<h6 class="mt-4 text-muted">Integrations (beta)</h6>
|
<h6 class="mt-4 text-muted">Integrations (beta)</h6>
|
||||||
|
|
||||||
|
@ -28,98 +28,8 @@
|
||||||
|
|
||||||
<div class="tab-content" id="v-pills-tabContent">
|
<div class="tab-content" id="v-pills-tabContent">
|
||||||
<div class="tab-pane fade" v-bind:class="{active: liClass('v-pills-home-tab'), show: liClass('v-pills-home-tab')}" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab">
|
<div class="tab-pane fade" v-bind:class="{active: liClass('v-pills-home-tab'), show: liClass('v-pills-home-tab')}" id="v-pills-home" role="tabpanel" aria-labelledby="v-pills-home-tab">
|
||||||
<form method="POST" action="settings">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="project">Project Name</label>
|
|
||||||
<input type="text" name="project" class="form-control" value="Statup Demo" id="project" placeholder="Great Uptime">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
<CoreSettings/>
|
||||||
<label for="description">Project Description</label>
|
|
||||||
<input type="text" name="description" class="form-control" value="An Awesome Demo of Statping running on Docker" id="description" placeholder="Great Uptime">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group row">
|
|
||||||
<div class="col-8 col-sm-9">
|
|
||||||
<label for="domain">Domain</label>
|
|
||||||
<input type="url" name="domain" class="form-control" value="https://demo.statping.com" id="domain">
|
|
||||||
</div>
|
|
||||||
<div class="col-4 col-sm-3 mt-sm-1 mt-0">
|
|
||||||
<label for="enable_cdn" class="d-inline d-sm-none">Enable CDN</label>
|
|
||||||
<label for="enable_cdn" class="d-none d-sm-block">Enable CDN</label>
|
|
||||||
<span class="switch">
|
|
||||||
<input type="checkbox" name="enable_cdn-option" class="switch" id="switch-normal" disabled>
|
|
||||||
<label for="switch-normal" class="mt-2 mt-sm-0"></label>
|
|
||||||
</span>
|
|
||||||
<input type="hidden" name="enable_cdn" id="switch-normal-value" value="false">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="footer">Custom Footer</label>
|
|
||||||
<textarea rows="4" name="footer" class="form-control" id="footer"></textarea>
|
|
||||||
<small class="form-text text-muted">HTML is allowed inside the footer</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="timezone">Timezone</label><span class="mt-1 small float-right">Current: Wednesday 08:03:24 PM</span>
|
|
||||||
<select class="form-control" name="timezone" id="timezone">
|
|
||||||
<option value="-12.0" >(GMT -12:00) Eniwetok, Kwajalein</option>
|
|
||||||
<option value="-11.0" >(GMT -11:00) Midway Island, Samoa</option>
|
|
||||||
<option value="-10.0" >(GMT -10:00) Hawaii</option>
|
|
||||||
<option value="-9.0" >(GMT -9:00) Alaska</option>
|
|
||||||
<option value="-8.0" selected>(GMT -8:00) Pacific Time (US & Canada)</option>
|
|
||||||
<option value="-7.0" >(GMT -7:00) Mountain Time (US & Canada)</option>
|
|
||||||
<option value="-6.0" >(GMT -6:00) Central Time (US & Canada), Mexico City</option>
|
|
||||||
<option value="-5.0" >(GMT -5:00) Eastern Time (US & Canada), Bogota, Lima</option>
|
|
||||||
<option value="-4.0" >(GMT -4:00) Atlantic Time (Canada), Caracas, La Paz</option>
|
|
||||||
<option value="-3.5" >(GMT -3:30) Newfoundland</option>
|
|
||||||
<option value="-3.0" >(GMT -3:00) Brazil, Buenos Aires, Georgetown</option>
|
|
||||||
<option value="-2.0" >(GMT -2:00) Mid-Atlantic</option>
|
|
||||||
<option value="-1.0" >(GMT -1:00 hour) Azores, Cape Verde Islands</option>
|
|
||||||
<option value="0.0" >(GMT) Western Europe Time, London, Lisbon, Casablanca</option>
|
|
||||||
<option value="1.0" >(GMT +1:00 hour) Brussels, Copenhagen, Madrid, Paris</option>
|
|
||||||
<option value="2.0" >(GMT +2:00) Kaliningrad, South Africa</option>
|
|
||||||
<option value="3.0" >(GMT +3:00) Baghdad, Riyadh, Moscow, St. Petersburg</option>
|
|
||||||
<option value="3.5" >(GMT +3:30) Tehran</option>
|
|
||||||
<option value="4.0" >(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi</option>
|
|
||||||
<option value="4.5" >(GMT +4:30) Kabul</option>
|
|
||||||
<option value="5.0" >(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent</option>
|
|
||||||
<option value="5.5" >(GMT +5:30) Bombay, Calcutta, Madras, New Delhi</option>
|
|
||||||
<option value="5.75" >(GMT +5:45) Kathmandu</option>
|
|
||||||
<option value="6.0" >(GMT +6:00) Almaty, Dhaka, Colombo</option>
|
|
||||||
<option value="7.0" >(GMT +7:00) Bangkok, Hanoi, Jakarta</option>
|
|
||||||
<option value="8.0" >(GMT +8:00) Beijing, Perth, Singapore, Hong Kong</option>
|
|
||||||
<option value="9.0" >(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk</option>
|
|
||||||
<option value="9.5" >(GMT +9:30) Adelaide, Darwin</option>
|
|
||||||
<option value="10.0" >(GMT +10:00) Eastern Australia, Guam, Vladivostok</option>
|
|
||||||
<option value="11.0" >(GMT +11:00) Magadan, Solomon Islands, New Caledonia</option>
|
|
||||||
<option value="12.0" >(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="btn btn-primary btn-block">Save Settings</button>
|
|
||||||
|
|
||||||
<div class="form-group row mt-3">
|
|
||||||
<label for="api_key" class="col-sm-3 col-form-label">API Key</label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input type="text" class="form-control select-input" value="9e657102489b63946908a084befc187e6e506eb0" id="api_key" readonly>
|
|
||||||
<small class="form-text text-muted">API Key can be used for read only routes</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group row">
|
|
||||||
<label for="api_secret" class="col-sm-3 col-form-label">API Secret</label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<input type="text" class="form-control select-input" value="6b05b48f4b3a1460f3864c31b26cab6a27dbaff9" id="api_secret" readonly>
|
|
||||||
<small class="form-text text-muted">API Secret is used for read, create, update and delete routes</small>
|
|
||||||
<small class="form-text text-muted">You can <a class="confirm_btn" data-msg="Are you sure you want to reset the API keys?" href="api/renew">Regenerate API Keys</a> if you need to.</small>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<h2 class="mt-5">Bulk Import Services</h2>
|
<h2 class="mt-5">Bulk Import Services</h2>
|
||||||
You can import multiple services based on a CSV file with the format shown on the <a href="https://github.com/hunterlong/statping/wiki/Bulk-Import-Services" target="_blank">Bulk Import Wiki</a>.
|
You can import multiple services based on a CSV file with the format shown on the <a href="https://github.com/hunterlong/statping/wiki/Bulk-Import-Services" target="_blank">Bulk Import Wiki</a>.
|
||||||
|
@ -214,210 +124,6 @@
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/1/data?start=1577923728&end=9999999999&group=hour</td>
|
|
||||||
<td>14129</td>
|
|
||||||
<td>2020-01-15 16:09:20 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/1/data?start=1577923878&end=9999999999&group=hour</td>
|
|
||||||
<td>14129</td>
|
|
||||||
<td>2020-01-15 16:11:49 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/1/data?start=1577935040&end=9999999999&group=hour</td>
|
|
||||||
<td>14255</td>
|
|
||||||
<td>2020-01-15 19:17:52 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/1/data?start=1577935058&end=9999999999&group=hour</td>
|
|
||||||
<td>14255</td>
|
|
||||||
<td>2020-01-15 19:18:10 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/1/data?start=1577937580&end=9999999999&group=hour</td>
|
|
||||||
<td>14255</td>
|
|
||||||
<td>2020-01-15 20:00:11 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/2/data?start=1577923728&end=9999999999&group=hour</td>
|
|
||||||
<td>14165</td>
|
|
||||||
<td>2020-01-15 16:09:21 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/2/data?start=1577923878&end=9999999999&group=hour</td>
|
|
||||||
<td>14165</td>
|
|
||||||
<td>2020-01-15 16:11:49 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/2/data?start=1577935040&end=9999999999&group=hour</td>
|
|
||||||
<td>14291</td>
|
|
||||||
<td>2020-01-15 19:17:53 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/2/data?start=1577935058&end=9999999999&group=hour</td>
|
|
||||||
<td>14291</td>
|
|
||||||
<td>2020-01-15 19:18:11 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/2/data?start=1577937580&end=9999999999&group=hour</td>
|
|
||||||
<td>14291</td>
|
|
||||||
<td>2020-01-15 20:00:11 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/3/data?start=1577923728&end=9999999999&group=hour</td>
|
|
||||||
<td>13941</td>
|
|
||||||
<td>2020-01-15 16:09:21 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/3/data?start=1577923878&end=9999999999&group=hour</td>
|
|
||||||
<td>13941</td>
|
|
||||||
<td>2020-01-15 16:11:50 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/3/data?start=1577935040&end=9999999999&group=hour</td>
|
|
||||||
<td>14064</td>
|
|
||||||
<td>2020-01-15 19:17:54 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/3/data?start=1577935058&end=9999999999&group=hour</td>
|
|
||||||
<td>14064</td>
|
|
||||||
<td>2020-01-15 19:18:12 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/3/data?start=1577937580&end=9999999999&group=hour</td>
|
|
||||||
<td>14064</td>
|
|
||||||
<td>2020-01-15 20:00:11 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/4/data?start=1577923728&end=9999999999&group=hour</td>
|
|
||||||
<td>14229</td>
|
|
||||||
<td>2020-01-15 16:09:22 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/4/data?start=1577923878&end=9999999999&group=hour</td>
|
|
||||||
<td>14229</td>
|
|
||||||
<td>2020-01-15 16:11:50 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/4/data?start=1577935040&end=9999999999&group=hour</td>
|
|
||||||
<td>14355</td>
|
|
||||||
<td>2020-01-15 19:17:54 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/4/data?start=1577935058&end=9999999999&group=hour</td>
|
|
||||||
<td>14355</td>
|
|
||||||
<td>2020-01-15 19:18:13 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/4/data?start=1577937580&end=9999999999&group=hour</td>
|
|
||||||
<td>14355</td>
|
|
||||||
<td>2020-01-15 20:00:12 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/5/data?start=1577923728&end=9999999999&group=hour</td>
|
|
||||||
<td>13491</td>
|
|
||||||
<td>2020-01-15 16:09:22 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/5/data?start=1577923878&end=9999999999&group=hour</td>
|
|
||||||
<td>13491</td>
|
|
||||||
<td>2020-01-15 16:11:50 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/5/data?start=1577935040&end=9999999999&group=hour</td>
|
|
||||||
<td>13611</td>
|
|
||||||
<td>2020-01-15 19:17:55 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/5/data?start=1577935058&end=9999999999&group=hour</td>
|
|
||||||
<td>13611</td>
|
|
||||||
<td>2020-01-15 19:18:14 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/5/data?start=1577937580&end=9999999999&group=hour</td>
|
|
||||||
<td>13611</td>
|
|
||||||
<td>2020-01-15 20:00:12 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/6/data?start=1577923728&end=9999999999&group=hour</td>
|
|
||||||
<td>13828</td>
|
|
||||||
<td>2020-01-15 16:09:19 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/6/data?start=1577923878&end=9999999999&group=hour</td>
|
|
||||||
<td>13828</td>
|
|
||||||
<td>2020-01-15 16:11:48 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/6/data?start=1577935040&end=9999999999&group=hour</td>
|
|
||||||
<td>13951</td>
|
|
||||||
<td>2020-01-15 19:17:52 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/6/data?start=1577935058&end=9999999999&group=hour</td>
|
|
||||||
<td>13951</td>
|
|
||||||
<td>2020-01-15 19:18:09 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/6/data?start=1577937580&end=9999999999&group=hour</td>
|
|
||||||
<td>13951</td>
|
|
||||||
<td>2020-01-15 20:00:10 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/7/data?start=1577923728&end=9999999999&group=hour</td>
|
|
||||||
<td>13828</td>
|
|
||||||
<td>2020-01-15 16:09:18 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/7/data?start=1577923878&end=9999999999&group=hour</td>
|
|
||||||
<td>13828</td>
|
|
||||||
<td>2020-01-15 16:11:48 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/7/data?start=1577935040&end=9999999999&group=hour</td>
|
|
||||||
<td>13951</td>
|
|
||||||
<td>2020-01-15 19:17:51 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>/api/services/7/data?start=1577935058&end=9999999999&group=hour</td>
|
|
||||||
<td>13951</td>
|
|
||||||
<td>2020-01-15 19:18:08 -0800 -0800</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>/api/services/7/data?start=1577937580&end=9999999999&group=hour</td>
|
<td>/api/services/7/data?start=1577937580&end=9999999999&group=hour</td>
|
||||||
<td>13951</td>
|
<td>13951</td>
|
||||||
|
@ -429,7 +135,7 @@
|
||||||
<a href="api/clear_cache" class="btn btn-danger btn-block">Clear Cache</a>
|
<a href="api/clear_cache" class="btn btn-danger btn-block">Clear Cache</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-for="(notifier, index) in notifiers" v-bind:key="index" class="tab-pane fade" v-bind:class="{active: liClass(`v-pills-${notifier.method.toLowerCase()}-tab`), show: liClass(`v-pills-${notifier.method.toLowerCase()}-tab`)}" v-bind:id="`v-pills-${notifier.method.toLowerCase()}-tab`" role="tabpanel" v-bind:aria-labelledby="`v-pills-${notifier.method.toLowerCase()}-tab`">
|
<div v-for="(notifier, index) in $store.getters.notifiers" v-bind:key="index" class="tab-pane fade" v-bind:class="{active: liClass(`v-pills-${notifier.method.toLowerCase()}-tab`), show: liClass(`v-pills-${notifier.method.toLowerCase()}-tab`)}" v-bind:id="`v-pills-${notifier.method.toLowerCase()}-tab`" role="tabpanel" v-bind:aria-labelledby="`v-pills-${notifier.method.toLowerCase()}-tab`">
|
||||||
|
|
||||||
<form class="ajax_form command">
|
<form class="ajax_form command">
|
||||||
<h4 class="text-capitalize">{{notifier.title}}</h4>
|
<h4 class="text-capitalize">{{notifier.title}}</h4>
|
||||||
|
@ -1368,28 +1074,26 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Api from "../components/API"
|
import Api from "../components/API"
|
||||||
|
import CoreSettings from '../forms/CoreSettings';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Settings',
|
name: 'Settings',
|
||||||
components: {
|
components: {
|
||||||
|
CoreSettings
|
||||||
|
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
tab: "v-pills-home-tab",
|
tab: "v-pills-home-tab",
|
||||||
notifiers: null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.getNotifiers()
|
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async getNotifiers () {
|
|
||||||
this.notifiers = await Api.notifiers()
|
|
||||||
},
|
|
||||||
changeTab (e) {
|
changeTab (e) {
|
||||||
this.tab = e.target.id
|
this.tab = e.target.id
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
Vue.use(Vuex)
|
||||||
|
|
||||||
|
export default new Vuex.Store({
|
||||||
|
state: {
|
||||||
|
hasAllData: false,
|
||||||
|
hasPublicData: false,
|
||||||
|
core: {},
|
||||||
|
token: null,
|
||||||
|
services: [],
|
||||||
|
groups: [],
|
||||||
|
messages: [],
|
||||||
|
users: [],
|
||||||
|
notifiers: []
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
hasAllData: state => state.hasAllData,
|
||||||
|
hasPublicData: state => state.hasPublicData,
|
||||||
|
core: state => state.core,
|
||||||
|
token: state => state.token,
|
||||||
|
services: state => state.services,
|
||||||
|
groups: state => state.groups,
|
||||||
|
messages: state => state.messages,
|
||||||
|
users: state => state.users,
|
||||||
|
notifiers: state => state.notifiers,
|
||||||
|
|
||||||
|
serviceById: (state) => (id) => {
|
||||||
|
return state.services.find(s => s.id === id)
|
||||||
|
},
|
||||||
|
serviceByName: (state) => (name) => {
|
||||||
|
return state.services.find(s => s.name === name)
|
||||||
|
},
|
||||||
|
servicesInGroup: (state) => (id) => {
|
||||||
|
return state.services.filter(s => s.group_id === id)
|
||||||
|
},
|
||||||
|
onlineServices: (state) => (online) => {
|
||||||
|
return state.services.filter(s => s.online === online)
|
||||||
|
},
|
||||||
|
groupById: (state) => (id) => {
|
||||||
|
return state.groups.find(g => g.id === id)
|
||||||
|
},
|
||||||
|
userById: (state) => (id) => {
|
||||||
|
return state.users.find(u => u.id === id)
|
||||||
|
},
|
||||||
|
messageById: (state) => (id) => {
|
||||||
|
return state.messages.find(m => m.id === id)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
setHasAllData(state, bool) {
|
||||||
|
state.hasAllData = bool
|
||||||
|
},
|
||||||
|
setHasPublicData(state, bool) {
|
||||||
|
state.hasPublicData = bool
|
||||||
|
},
|
||||||
|
setCore(state, core) {
|
||||||
|
state.core = core
|
||||||
|
},
|
||||||
|
setToken(state, token) {
|
||||||
|
state.token = token
|
||||||
|
},
|
||||||
|
setServices(state, services) {
|
||||||
|
state.services = services
|
||||||
|
},
|
||||||
|
setGroups(state, groups) {
|
||||||
|
state.groups = groups
|
||||||
|
},
|
||||||
|
setMessages(state, messages) {
|
||||||
|
state.messages = messages
|
||||||
|
},
|
||||||
|
setUsers(state, users) {
|
||||||
|
state.users = users
|
||||||
|
},
|
||||||
|
setNotifiers(state, notifiers) {
|
||||||
|
state.notifiers = notifiers
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,9 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const environment = (process.env.NODE_ENV || 'development').trim();
|
||||||
|
|
||||||
|
if (environment === 'development') {
|
||||||
|
module.exports = require('./config/webpack.config.dev');
|
||||||
|
} else {
|
||||||
|
module.exports = require('./config/webpack.config.prod');
|
||||||
|
}
|
2639
frontend/yarn.lock
2639
frontend/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue