chore(webui): Migrate to Quasar 2.x and Vue.js 3.x
This commit is contained in:
parent
153765f99f
commit
f7edb394f2
65 changed files with 4374 additions and 7999 deletions
|
@ -1 +1,7 @@
|
|||
/dist
|
||||
/src-capacitor
|
||||
/src-cordova
|
||||
/.quasar
|
||||
/node_modules
|
||||
.eslintrc.cjs
|
||||
/quasar.config.*.temporary.compiled*
|
||||
|
|
|
@ -2,21 +2,24 @@ module.exports = {
|
|||
root: true,
|
||||
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint',
|
||||
sourceType: 'module'
|
||||
parser: '@babel/eslint-parser',
|
||||
ecmaVersion: 2021, // Allows for the parsing of modern ECMAScript features
|
||||
},
|
||||
|
||||
env: {
|
||||
node: true,
|
||||
browser: true,
|
||||
mocha: true
|
||||
mocha: true,
|
||||
'vue/setup-compiler-macros': true
|
||||
},
|
||||
|
||||
extends: [
|
||||
// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
|
||||
// consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
|
||||
'plugin:vue/essential',
|
||||
'@vue/standard',
|
||||
'plugin:mocha/recommended'
|
||||
'plugin:vue/vue3-essential',
|
||||
'plugin:vue/vue3-recommended',
|
||||
'plugin:mocha/recommended',
|
||||
'standard'
|
||||
],
|
||||
|
||||
// required to lint *.vue files
|
||||
|
@ -26,10 +29,16 @@ module.exports = {
|
|||
],
|
||||
|
||||
globals: {
|
||||
'ga': true, // Google Analytics
|
||||
'cordova': true,
|
||||
'__statics': true,
|
||||
'process': true
|
||||
ga: 'readonly', // Google Analytics
|
||||
cordova: 'readonly',
|
||||
__statics: 'readonly',
|
||||
__QUASAR_SSR__: 'readonly',
|
||||
__QUASAR_SSR_SERVER__: 'readonly',
|
||||
__QUASAR_SSR_CLIENT__: 'readonly',
|
||||
__QUASAR_SSR_PWA__: 'readonly',
|
||||
process: 'readonly',
|
||||
Capacitor: 'readonly',
|
||||
chrome: 'readonly'
|
||||
},
|
||||
|
||||
// add your custom rules here
|
||||
|
@ -39,6 +48,8 @@ module.exports = {
|
|||
// allow paren-less arrow functions
|
||||
'arrow-parens': 'off',
|
||||
'one-var': 'off',
|
||||
'no-void': 'off',
|
||||
'multiline-ternary': 'off',
|
||||
|
||||
'import/first': 'off',
|
||||
'import/named': 'error',
|
||||
|
@ -49,6 +60,7 @@ module.exports = {
|
|||
'import/no-unresolved': 'off',
|
||||
'import/no-extraneous-dependencies': 'off',
|
||||
'prefer-promise-reject-errors': 'off',
|
||||
'vue/multi-word-component-names': 'off',
|
||||
|
||||
// allow console.log during development only
|
||||
//'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
|
@ -56,3 +68,4 @@ module.exports = {
|
|||
//'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
|
||||
}
|
||||
}
|
||||
|
16
webui/babel.config.cjs
Normal file
16
webui/babel.config.cjs
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* eslint-disable */
|
||||
|
||||
module.exports = api => {
|
||||
return {
|
||||
presets: [
|
||||
[
|
||||
'@quasar/babel-preset-app',
|
||||
api.caller(caller => caller && caller.target === 'node')
|
||||
? { targets: { node: 'current' } }
|
||||
: {}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
module.exports = {
|
||||
presets: [
|
||||
'@quasar/babel-preset-app'
|
||||
]
|
||||
}
|
|
@ -20,7 +20,6 @@
|
|||
<link rel="apple-touch-icon" sizes="180x180" href="icons/apple-icon-180x180.png">
|
||||
</head>
|
||||
<body>
|
||||
<!-- DO NOT touch the following DIV -->
|
||||
<div id="q-app"></div>
|
||||
<!-- quasar:entry-point -->
|
||||
</body>
|
||||
</html>
|
39
webui/jsconfig.json
Normal file
39
webui/jsconfig.json
Normal file
|
@ -0,0 +1,39 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"src/*": [
|
||||
"src/*"
|
||||
],
|
||||
"app/*": [
|
||||
"*"
|
||||
],
|
||||
"components/*": [
|
||||
"src/components/*"
|
||||
],
|
||||
"layouts/*": [
|
||||
"src/layouts/*"
|
||||
],
|
||||
"pages/*": [
|
||||
"src/pages/*"
|
||||
],
|
||||
"assets/*": [
|
||||
"src/assets/*"
|
||||
],
|
||||
"boot/*": [
|
||||
"src/boot/*"
|
||||
],
|
||||
"stores/*": [
|
||||
"src/stores/*"
|
||||
],
|
||||
"vue$": [
|
||||
"node_modules/vue/dist/vue.runtime.esm-bundler.js"
|
||||
]
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
"dist",
|
||||
".quasar",
|
||||
"node_modules"
|
||||
]
|
||||
}
|
|
@ -16,42 +16,45 @@
|
|||
"build:nc": "yarn build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@quasar/extras": "^1.11.2",
|
||||
"axios": "^0.21.1",
|
||||
"bowser": "^2.5.2",
|
||||
"chart.js": "^2.8.0",
|
||||
"dot-prop": "^5.2.0",
|
||||
"@quasar/extras": "^1.16.9",
|
||||
"axios": "^1.6.7",
|
||||
"bowser": "^2.11.0",
|
||||
"chart.js": "^4.4.1",
|
||||
"core-js": "^3.35.1",
|
||||
"iframe-resizer": "^4.2.11",
|
||||
"dot-prop": "^8.0.2",
|
||||
"iframe-resizer": "^4.3.9",
|
||||
"lodash.isequal": "4.5.0",
|
||||
"moment": "^2.24.0",
|
||||
"quasar": "^1.22.10",
|
||||
"query-string": "^6.13.1",
|
||||
"moment": "^2.30.1",
|
||||
"quasar": "^2.14.3",
|
||||
"query-string": "^8.1.0",
|
||||
"vh-check": "^2.0.5",
|
||||
"vue-chartjs": "^3.4.2",
|
||||
"vuex-map-fields": "^1.3.4"
|
||||
"vue": "^3.0.0",
|
||||
"vue-chartjs": "^5.3.0",
|
||||
"vue-router": "^4.0.12",
|
||||
"vuex": "^4.1.0",
|
||||
"vuex-map-fields": "^1.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@quasar/app": "^2.4.3",
|
||||
"@vue/eslint-config-standard": "^4.0.0",
|
||||
"@vue/test-utils": "^1.0.0-beta.29",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"chai": "4.2.0",
|
||||
"eslint": "^5.10.0",
|
||||
"eslint-loader": "^2.1.1",
|
||||
"eslint-plugin-prettier": "3.1.1",
|
||||
"eslint-plugin-mocha": "6.2.1",
|
||||
"eslint-plugin-vue": "^5.0.0",
|
||||
"mocha": "^6.2.2",
|
||||
"mocha-webpack": "^2.0.0-beta.0",
|
||||
"prettier": "1.19.1"
|
||||
"@babel/core": "^7.23.9",
|
||||
"@babel/eslint-parser": "^7.23.10",
|
||||
"@quasar/app-vite": "^1.4.3",
|
||||
"@quasar/babel-preset-app": "^2.0.2",
|
||||
"@vue/test-utils": "^2.4.4",
|
||||
"autoprefixer": "^10.4.2",
|
||||
"chai": "5.0.3",
|
||||
"eslint": "^8.11.0",
|
||||
"eslint-config-standard": "^17.0.0",
|
||||
"eslint-plugin-import": "^2.19.1",
|
||||
"eslint-plugin-mocha": "^10.2.0",
|
||||
"eslint-plugin-n": "^16.6.2",
|
||||
"eslint-plugin-promise": "^6.0.0",
|
||||
"eslint-plugin-vue": "^9.0.0",
|
||||
"mocha": "^10.2.0",
|
||||
"postcss": "^8.4.14"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.9.0",
|
||||
"npm": ">= 5.6.0",
|
||||
"yarn": ">= 1.6.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"last 1 version, not dead, ie >= 11"
|
||||
]
|
||||
"node": "^20 || ^18 || ^16",
|
||||
"npm": ">= 6.13.4",
|
||||
"yarn": ">= 1.21.1"
|
||||
}
|
||||
}
|
||||
|
|
27
webui/postcss.config.cjs
Normal file
27
webui/postcss.config.cjs
Normal file
|
@ -0,0 +1,27 @@
|
|||
/* eslint-disable */
|
||||
// https://github.com/michael-ciniawsky/postcss-load-config
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
// https://github.com/postcss/autoprefixer
|
||||
require('autoprefixer')({
|
||||
overrideBrowserslist: [
|
||||
'last 4 Chrome versions',
|
||||
'last 4 Firefox versions',
|
||||
'last 4 Edge versions',
|
||||
'last 4 Safari versions',
|
||||
'last 4 Android versions',
|
||||
'last 4 ChromeAndroid versions',
|
||||
'last 4 FirefoxAndroid versions',
|
||||
'last 4 iOS versions'
|
||||
]
|
||||
})
|
||||
|
||||
// https://github.com/elchininet/postcss-rtlcss
|
||||
// If you want to support RTL css, then
|
||||
// 1. yarn/npm install postcss-rtlcss
|
||||
// 2. optionally set quasar.config.js > framework > lang to an RTL language
|
||||
// 3. uncomment the following line:
|
||||
// require('postcss-rtlcss')
|
||||
]
|
||||
}
|
|
@ -1,12 +1,18 @@
|
|||
// Configuration for your app
|
||||
// https://quasar.dev/quasar-cli/quasar-conf-js
|
||||
|
||||
module.exports = function (ctx) {
|
||||
const { configure } = require('quasar/wrappers')
|
||||
|
||||
module.exports = configure(function (ctx) {
|
||||
return {
|
||||
eslint: {
|
||||
warnings: true,
|
||||
errors: true
|
||||
},
|
||||
|
||||
// app boot file (/src/boot)
|
||||
// --> boot files are part of "main.js"
|
||||
boot: [
|
||||
'_globals',
|
||||
'api',
|
||||
'_hacks',
|
||||
'_init'
|
||||
|
@ -114,6 +120,17 @@ module.exports = function (ctx) {
|
|||
supportIE: false,
|
||||
|
||||
build: {
|
||||
viteVuePluginOptions: {
|
||||
template: {
|
||||
compilerOptions: {
|
||||
isCustomElement: (tag) => tag.startsWith('hub-')
|
||||
}
|
||||
}
|
||||
},
|
||||
target: {
|
||||
browser: ['edge88', 'firefox78', 'chrome87', 'safari13.1'],
|
||||
node: 'node20'
|
||||
},
|
||||
publicPath: process.env.APP_PUBLIC_PATH || '',
|
||||
env: process.env.APP_ENV === 'development'
|
||||
? { // staging:
|
||||
|
@ -131,22 +148,7 @@ module.exports = function (ctx) {
|
|||
}
|
||||
},
|
||||
scopeHoisting: true,
|
||||
// vueRouterMode: 'history',
|
||||
// vueCompiler: true,
|
||||
// gzip: true,
|
||||
// analyze: true,
|
||||
// extractCSS: false,
|
||||
extendWebpack (cfg) {
|
||||
cfg.module.rules.push({
|
||||
enforce: 'pre',
|
||||
test: /\.(js|vue)$/,
|
||||
loader: 'eslint-loader',
|
||||
exclude: /node_modules/,
|
||||
options: {
|
||||
formatter: require('eslint').CLIEngine.getFormatter('stylish')
|
||||
}
|
||||
})
|
||||
}
|
||||
vueRouterMode: 'hash' // available values: 'hash', 'history'
|
||||
},
|
||||
|
||||
devServer: {
|
||||
|
@ -166,16 +168,24 @@ module.exports = function (ctx) {
|
|||
animations: [],
|
||||
|
||||
ssr: {
|
||||
pwa: false
|
||||
pwa: false,
|
||||
},
|
||||
|
||||
pwa: {
|
||||
|
||||
workboxMode: 'injectManifest', // or 'generateSW'
|
||||
// workboxPluginMode: 'InjectManifest',
|
||||
// workboxOptions: {}, // only for NON InjectManifest
|
||||
workboxOptions: {
|
||||
skipWaiting: true,
|
||||
clientsClaim: true
|
||||
},
|
||||
|
||||
chainWebpackCustomSW (chain) {
|
||||
chain.plugin('eslint-webpack-plugin')
|
||||
.use(ESLintPlugin, [{ extensions: ['js'] }])
|
||||
},
|
||||
|
||||
manifest: {
|
||||
// name: 'Traefik',
|
||||
// short_name: 'Traefik',
|
||||
|
@ -247,4 +257,4 @@ module.exports = function (ctx) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -13,6 +13,11 @@ export default {
|
|||
computed: {
|
||||
...mapGetters('core', { coreVersion: 'version' })
|
||||
},
|
||||
watch: {
|
||||
'$q.dark.isActive' (val) {
|
||||
localStorage.setItem('traefik-dark', val)
|
||||
}
|
||||
},
|
||||
beforeCreate () {
|
||||
// Set vue instance
|
||||
APP.vue = () => this.$root
|
||||
|
@ -21,11 +26,6 @@ export default {
|
|||
console.log('Quasar -> ', this.$q.version)
|
||||
|
||||
this.$q.dark.set(localStorage.getItem('traefik-dark') === 'true')
|
||||
},
|
||||
watch: {
|
||||
'$q.dark.isActive' (val) {
|
||||
localStorage.setItem('traefik-dark', val)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
import Vue from 'vue'
|
||||
import iFrameResize from 'iframe-resizer/js/iframeResizer'
|
||||
import iframeResize from 'iframe-resizer/js/iframeResizer'
|
||||
|
||||
Vue.directive('resize', {
|
||||
bind: function (el, { value = {} }) {
|
||||
el.addEventListener('load', () => iFrameResize(value, el))
|
||||
const resize = {
|
||||
mounted (el, binding) {
|
||||
const options = binding.value || {}
|
||||
el.addEventListener('load', () => iframeResize(options, el))
|
||||
},
|
||||
unmounted (el) {
|
||||
const resizableEl = el
|
||||
if (resizableEl.iFrameResizer) {
|
||||
resizableEl.iFrameResizer.removeListeners()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default resize
|
||||
|
|
|
@ -22,7 +22,7 @@ class Errors {
|
|||
|
||||
static handleResponse (error) {
|
||||
console.log('handleResponse', error, error.response)
|
||||
let body = error.response.data
|
||||
const body = error.response.data
|
||||
if (error.response.status === 401) {
|
||||
// TODO - actions...
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { get } from 'dot-prop'
|
||||
import { getProperty } from 'dot-prop'
|
||||
|
||||
class Helps {
|
||||
// Getters
|
||||
|
@ -11,7 +11,7 @@ class Helps {
|
|||
// ------------------------------------------------------------------------
|
||||
|
||||
static get (obj, prop, def = undefined) {
|
||||
return get(obj, prop, def)
|
||||
return getProperty(obj, prop, def)
|
||||
}
|
||||
|
||||
static hasIn (obj, prop) {
|
||||
|
@ -39,13 +39,12 @@ class Helps {
|
|||
}
|
||||
|
||||
static removeEmptyObjects (objects) {
|
||||
const obj = {}
|
||||
Object.entries(objects).map(item => {
|
||||
if (item[1] !== '') {
|
||||
obj[item[0]] = item[1]
|
||||
}
|
||||
})
|
||||
return obj
|
||||
Object.entries(objects)
|
||||
.filter(item => item[1] !== '')
|
||||
.reduce((acc, item) => {
|
||||
acc[item[0]] = item[1]
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
|
||||
// Helps -> Numbers
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { set, get } from 'dot-prop'
|
||||
import { setProperty, getProperty } from 'dot-prop'
|
||||
|
||||
export const withPagination = (type, opts = {}) => (state, data) => {
|
||||
const { isSameContext, statePath } = opts
|
||||
const currentState = get(state, statePath)
|
||||
const currentState = getProperty(state, statePath)
|
||||
|
||||
let newState
|
||||
|
||||
|
@ -13,7 +13,7 @@ export const withPagination = (type, opts = {}) => (state, data) => {
|
|||
loading: true
|
||||
}
|
||||
break
|
||||
case 'success':
|
||||
case 'success': {
|
||||
const { body, page } = data
|
||||
newState = {
|
||||
...currentState,
|
||||
|
@ -28,6 +28,7 @@ export const withPagination = (type, opts = {}) => (state, data) => {
|
|||
loading: false
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'failure':
|
||||
newState = {
|
||||
...currentState,
|
||||
|
@ -39,6 +40,6 @@ export const withPagination = (type, opts = {}) => (state, data) => {
|
|||
}
|
||||
|
||||
if (newState) {
|
||||
set(state, statePath, newState)
|
||||
setProperty(state, statePath, newState)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@ import Helps from '../_helpers/Helps'
|
|||
const Boot = {
|
||||
install (Vue, options) {
|
||||
Vue.mixin({
|
||||
filters: {
|
||||
capFirstLetter (value) {
|
||||
return Helps.capFirstLetter(value)
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
}
|
||||
|
@ -28,14 +33,9 @@ const Boot = {
|
|||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
filters: {
|
||||
capFirstLetter (value) {
|
||||
return Helps.capFirstLetter(value)
|
||||
}
|
||||
},
|
||||
created () {
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { get } from 'dot-prop'
|
||||
import { getProperty } from 'dot-prop'
|
||||
import { QChip } from 'quasar'
|
||||
import Chips from '../components/_commons/Chips'
|
||||
import ProviderIcon from '../components/_commons/ProviderIcon'
|
||||
import AvatarState from '../components/_commons/AvatarState'
|
||||
import TLSState from '../components/_commons/TLSState'
|
||||
import Chips from '../components/_commons/Chips.vue'
|
||||
import ProviderIcon from '../components/_commons/ProviderIcon.vue'
|
||||
import AvatarState from '../components/_commons/AvatarState.vue'
|
||||
import TLSState from '../components/_commons/TLSState.vue'
|
||||
|
||||
const allColumns = [
|
||||
{
|
||||
|
@ -141,7 +141,7 @@ const GetTablePropsMixin = {
|
|||
path: `/${type.replace('-', '/', 'gi')}/${encodeURIComponent(row.name)}`
|
||||
}),
|
||||
columns: allColumns.filter(c =>
|
||||
get(propsByType, `${type}.columns`, []).includes(c.name)
|
||||
getProperty(propsByType, `${type}.columns`, []).includes(c.name)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { get } from 'dot-prop'
|
||||
import { getProperty } from 'dot-prop'
|
||||
|
||||
export default function PaginationMixin (opts = {}) {
|
||||
const { pollingIntervalTime, rowsPerPage = 10 } = opts
|
||||
|
@ -28,7 +28,7 @@ export default function PaginationMixin (opts = {}) {
|
|||
currentPage = page
|
||||
currentLimit = limit || rowsPerPage
|
||||
|
||||
const fetchMethod = get(this, opts.fetchMethod)
|
||||
const fetchMethod = getProperty(this, opts.fetchMethod)
|
||||
|
||||
return fetchMethod({
|
||||
...params,
|
||||
|
@ -41,7 +41,7 @@ export default function PaginationMixin (opts = {}) {
|
|||
})
|
||||
},
|
||||
initFetch (params) {
|
||||
const scrollerRef = get(this.$refs, opts.scrollerRef)
|
||||
const scrollerRef = getProperty(this.$refs, opts.scrollerRef)
|
||||
|
||||
if (scrollerRef) {
|
||||
scrollerRef.stop()
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { APP } from '../_helpers/APP'
|
||||
import Boot from '../_middleware/Boot'
|
||||
|
||||
export default async ({ app, router, store, Vue }) => {
|
||||
Vue.use(Boot)
|
||||
export default async ({ app, router, store }) => {
|
||||
app.use(Boot)
|
||||
|
||||
APP.root = app
|
||||
APP.router = router
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import { APP } from '../_helpers/APP'
|
||||
import errors from '../_helpers/Errors'
|
||||
import resize from '../_directives/resize'
|
||||
|
||||
export default async ({ app, router }) => {
|
||||
// Directives
|
||||
app.directive('resize', resize)
|
||||
|
||||
export default async ({ Vue }) => {
|
||||
// Router
|
||||
// ----------------------------------------------
|
||||
APP.router.beforeEach(async (to, from, next) => {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
// Set APP
|
||||
APP.routeTo = to
|
||||
APP.routeFrom = from
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
import { boot } from 'quasar/wrappers'
|
||||
import axios from 'axios'
|
||||
|
||||
import { APP } from '../_helpers/APP'
|
||||
|
||||
// Set config defaults when creating the instance
|
||||
const API = axios.create({
|
||||
const api = axios.create({
|
||||
baseURL: APP.config.apiUrl
|
||||
})
|
||||
|
||||
export default async ({ app, Vue }) => {
|
||||
Vue.prototype.$api = app.api = APP.api = API
|
||||
}
|
||||
export default boot(({ app }) => {
|
||||
app.config.globalProperties.$axios = axios
|
||||
app.config.globalProperties.$api = api
|
||||
APP.api = api
|
||||
})
|
||||
|
||||
export { api }
|
||||
|
|
|
@ -1,16 +1,32 @@
|
|||
<template>
|
||||
<q-avatar :color="state" text-color="white">
|
||||
<q-icon v-if="state === 'positive'" name="eva-checkmark-circle-2" />
|
||||
<q-icon v-if="state === 'warning'" name="eva-alert-circle" />
|
||||
<q-icon v-if="state === 'negative'" name="eva-alert-triangle" />
|
||||
<q-avatar
|
||||
:color="state"
|
||||
text-color="white"
|
||||
>
|
||||
<q-icon
|
||||
v-if="state === 'positive'"
|
||||
name="eva-checkmark-circle-2"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="state === 'warning'"
|
||||
name="eva-alert-circle"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="state === 'negative'"
|
||||
name="eva-alert-triangle"
|
||||
/>
|
||||
</q-avatar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'AvatarState',
|
||||
props: ['state']
|
||||
}
|
||||
props: {
|
||||
state: String
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,18 +1,36 @@
|
|||
<template>
|
||||
<div class="block-right-text">
|
||||
<q-avatar :color="value ? 'positive' : 'negative'" text-color="white">
|
||||
<q-icon v-if="value" name="eva-toggle-right" />
|
||||
<q-icon v-if="!value" name="eva-toggle-left" />
|
||||
<q-avatar
|
||||
:color="value ? 'positive' : 'negative'"
|
||||
text-color="white"
|
||||
>
|
||||
<q-icon
|
||||
v-if="value"
|
||||
name="eva-toggle-right"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="!value"
|
||||
name="eva-toggle-left"
|
||||
/>
|
||||
</q-avatar>
|
||||
<div v-bind:class="['block-right-text-label', `block-right-text-label-${!!value}`]">{{value ? 'True' : 'False'}}</div>
|
||||
<div :class="['block-right-text-label', `block-right-text-label-${!!value}`]">
|
||||
{{ value ? 'True' : 'False' }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'BooleanState',
|
||||
props: ['value']
|
||||
}
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
v-for="(chip, index) in list"
|
||||
:key="index"
|
||||
:dense="dense"
|
||||
:class="classNames">
|
||||
:class="classNames"
|
||||
>
|
||||
{{ chip }}
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -12,6 +13,10 @@
|
|||
|
||||
<script>
|
||||
export default {
|
||||
props: ['dense', 'classNames', 'list']
|
||||
props: {
|
||||
dense: Boolean,
|
||||
classNames: Array[String],
|
||||
list: Array[Object]
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
<template>
|
||||
<div class="table-wrapper">
|
||||
<q-infinite-scroll @load="handleLoadMore" :offset="250" ref="scroller">
|
||||
<q-infinite-scroll
|
||||
ref="scroller"
|
||||
:offset="250"
|
||||
@load="handleLoadMore"
|
||||
>
|
||||
<q-markup-table>
|
||||
<thead>
|
||||
<tr class="table-header">
|
||||
<th
|
||||
v-for="column in columns"
|
||||
v-bind:class="`text-${column.align}`"
|
||||
v-bind:key="column.name">
|
||||
:key="column.name"
|
||||
:class="`text-${column.align}`"
|
||||
>
|
||||
{{ column.label }}
|
||||
</th>
|
||||
</tr>
|
||||
|
@ -15,16 +20,28 @@
|
|||
<tfoot v-if="!data || !data.length">
|
||||
<tr>
|
||||
<td colspan="100%">
|
||||
<q-icon name="warning" style="font-size: 1.5rem"/> No data available
|
||||
<q-icon
|
||||
name="warning"
|
||||
style="font-size: 1.5rem"
|
||||
/> No data available
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
<tbody>
|
||||
<tr v-for="row in data" :key="row.name" class="cursor-pointer" @click="onRowClick(row)">
|
||||
<tr
|
||||
v-for="row in data"
|
||||
:key="row.name"
|
||||
class="cursor-pointer"
|
||||
@click="onRowClick(row)"
|
||||
>
|
||||
<template v-for="column in columns">
|
||||
<td :key="column.name" v-if="getColumn(column.name).component" v-bind:class="`text-${getColumn(column.name).align}`">
|
||||
<td
|
||||
v-if="getColumn(column.name).component"
|
||||
:key="column.name"
|
||||
:class="`text-${getColumn(column.name).align}`"
|
||||
>
|
||||
<component
|
||||
v-bind:is="getColumn(column.name).component"
|
||||
:is="getColumn(column.name).component"
|
||||
v-bind="getColumn(column.name).fieldToProps(row)"
|
||||
>
|
||||
<template v-if="getColumn(column.name).content">
|
||||
|
@ -33,27 +50,41 @@
|
|||
</component>
|
||||
</td>
|
||||
<td
|
||||
:key="column.name"
|
||||
v-if="!getColumn(column.name).component"
|
||||
v-bind:class="`text-${getColumn(column.name).align}`"
|
||||
:key="column.name"
|
||||
:class="`text-${getColumn(column.name).align}`"
|
||||
v-bind="getColumn(column.name).fieldToProps(row)"
|
||||
>
|
||||
<span>
|
||||
{{getColumn(column.name).content ? getColumn(column.name).content(row) : row[column.name]}}
|
||||
<span>
|
||||
{{ getColumn(column.name).content ? getColumn(column.name).content(row) : row[column.name] }}
|
||||
</span>
|
||||
</td>
|
||||
</template>
|
||||
</tr>
|
||||
</tbody>
|
||||
</q-markup-table>
|
||||
<template v-slot:loading v-if="loading">
|
||||
<template
|
||||
v-if="loading"
|
||||
#loading
|
||||
>
|
||||
<div class="row justify-center q-my-md">
|
||||
<q-spinner-dots color="app-grey" size="40px" />
|
||||
<q-spinner-dots
|
||||
color="app-grey"
|
||||
size="40px"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</q-infinite-scroll>
|
||||
<q-page-scroller position="bottom" :scroll-offset="150" class="back-to-top" v-if="endReached">
|
||||
<q-btn color="primary" small>
|
||||
<q-page-scroller
|
||||
v-if="endReached"
|
||||
position="bottom"
|
||||
:scroll-offset="150"
|
||||
class="back-to-top"
|
||||
>
|
||||
<q-btn
|
||||
color="primary"
|
||||
small
|
||||
>
|
||||
Back to top
|
||||
</q-btn>
|
||||
</q-page-scroller>
|
||||
|
@ -61,28 +92,40 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { QMarkupTable, QInfiniteScroll, QSpinnerDots, QPageScroller } from 'quasar'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'MainTable',
|
||||
props: ['data', 'columns', 'loading', 'onLoadMore', 'endReached', 'onRowClick'],
|
||||
components: {
|
||||
QMarkupTable,
|
||||
QInfiniteScroll,
|
||||
QSpinnerDots,
|
||||
QPageScroller
|
||||
},
|
||||
props: {
|
||||
data: Object,
|
||||
columns: Array[Object],
|
||||
loading: Boolean,
|
||||
onLoadMore: Function,
|
||||
endReached: Boolean,
|
||||
onRowClick: Function
|
||||
},
|
||||
methods: {
|
||||
getColumn (columnName) {
|
||||
return this.columns.find(c => c.name === columnName) || {}
|
||||
},
|
||||
handleLoadMore (index, done) {
|
||||
this.onLoadMore({ page: index })
|
||||
.then(() => done())
|
||||
.catch(() => done(true))
|
||||
if (!this?.onLoadMore) {
|
||||
done()
|
||||
} else {
|
||||
this.onLoadMore({ page: index })
|
||||
.then(() => done())
|
||||
.catch(() => done(true))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<q-page>
|
||||
<slot/>
|
||||
<slot />
|
||||
</q-page>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,21 +1,40 @@
|
|||
<template>
|
||||
<q-card flat bordered v-bind:class="['panel-health-check', {'panel-health-check-dense':isDense}]">
|
||||
<q-scroll-area :thumb-style="appThumbStyle" style="height:100%;">
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
:class="['panel-health-check', {'panel-health-check-dense':isDense}]"
|
||||
>
|
||||
<q-scroll-area
|
||||
:thumb-style="appThumbStyle"
|
||||
style="height:100%;"
|
||||
>
|
||||
<q-card-section v-if="data.scheme || data.interval">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col" v-if="data.scheme">
|
||||
<div class="text-subtitle2">SCHEME</div>
|
||||
<div
|
||||
v-if="data.scheme"
|
||||
class="col"
|
||||
>
|
||||
<div class="text-subtitle2">
|
||||
SCHEME
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-options">
|
||||
class="app-chip app-chip-options"
|
||||
>
|
||||
{{ data.scheme }}
|
||||
</q-chip>
|
||||
</div>
|
||||
<div class="col" v-if="data.interval">
|
||||
<div class="text-subtitle2">INTERVAL</div>
|
||||
<div
|
||||
v-if="data.interval"
|
||||
class="col"
|
||||
>
|
||||
<div class="text-subtitle2">
|
||||
INTERVAL
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-interval">
|
||||
class="app-chip app-chip-interval"
|
||||
>
|
||||
{{ data.interval }}
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -23,19 +42,31 @@
|
|||
</q-card-section>
|
||||
<q-card-section v-if="data.path || data.timeout">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col" v-if="data.path">
|
||||
<div class="text-subtitle2">PATH</div>
|
||||
<div
|
||||
v-if="data.path"
|
||||
class="col"
|
||||
>
|
||||
<div class="text-subtitle2">
|
||||
PATH
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-entry-points">
|
||||
class="app-chip app-chip-entry-points"
|
||||
>
|
||||
{{ data.path }}
|
||||
</q-chip>
|
||||
</div>
|
||||
<div class="col" v-if="data.timeout">
|
||||
<div class="text-subtitle2">TIMEOUT</div>
|
||||
<div
|
||||
v-if="data.timeout"
|
||||
class="col"
|
||||
>
|
||||
<div class="text-subtitle2">
|
||||
TIMEOUT
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-interval">
|
||||
class="app-chip app-chip-interval"
|
||||
>
|
||||
{{ data.timeout }}
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -43,19 +74,31 @@
|
|||
</q-card-section>
|
||||
<q-card-section v-if="data.port || data.hostname">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col" v-if="data.port">
|
||||
<div class="text-subtitle2">PORT</div>
|
||||
<div
|
||||
v-if="data.port"
|
||||
class="col"
|
||||
>
|
||||
<div class="text-subtitle2">
|
||||
PORT
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-name">
|
||||
class="app-chip app-chip-name"
|
||||
>
|
||||
{{ data.port }}
|
||||
</q-chip>
|
||||
</div>
|
||||
<div class="col" v-if="data.hostname">
|
||||
<div class="text-subtitle2">HOSTNAME</div>
|
||||
<div
|
||||
v-if="data.hostname"
|
||||
class="col"
|
||||
>
|
||||
<div class="text-subtitle2">
|
||||
HOSTNAME
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-rule">
|
||||
class="app-chip app-chip-rule"
|
||||
>
|
||||
{{ data.hostname }}
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -64,12 +107,19 @@
|
|||
<q-card-section v-if="data.headers">
|
||||
<div class="row items-start">
|
||||
<div class="col-12">
|
||||
<div class="text-subtitle2">HEADERS</div>
|
||||
<div class="text-subtitle2">
|
||||
HEADERS
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="(header, index) in data.headers" :key="index" class="col-12">
|
||||
<div
|
||||
v-for="(header, index) in data.headers"
|
||||
:key="index"
|
||||
class="col-12"
|
||||
>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-wrap app-chip-service">
|
||||
class="app-chip app-chip-wrap app-chip-service"
|
||||
>
|
||||
{{ index }}: {{ header }}
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -82,15 +132,18 @@
|
|||
<script>
|
||||
export default {
|
||||
name: 'PanelHealthCheck',
|
||||
props: ['data', 'dense'],
|
||||
components: {
|
||||
},
|
||||
filters: {
|
||||
},
|
||||
props: {
|
||||
data: Object,
|
||||
dense: Boolean
|
||||
},
|
||||
computed: {
|
||||
isDense () {
|
||||
return this.dense !== undefined
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,29 +1,52 @@
|
|||
<template>
|
||||
<q-card flat bordered v-bind:class="['panel-services', {'panel-services-dense':isDense}]">
|
||||
<q-scroll-area :thumb-style="appThumbStyle" style="height:100%;">
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
:class="['panel-services', {'panel-services-dense':isDense}]"
|
||||
>
|
||||
<q-scroll-area
|
||||
:thumb-style="appThumbStyle"
|
||||
style="height:100%;"
|
||||
>
|
||||
<q-card-section>
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col-6">
|
||||
<div class="text-subtitle2 text-table">Name</div>
|
||||
<div class="text-subtitle2 text-table">
|
||||
Name
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="text-subtitle2 text-table" style="text-align: right">Percent</div>
|
||||
<div
|
||||
class="text-subtitle2 text-table"
|
||||
style="text-align: right"
|
||||
>
|
||||
Percent
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="text-subtitle2 text-table" style="text-align: right">Provider</div>
|
||||
<div
|
||||
class="text-subtitle2 text-table"
|
||||
style="text-align: right"
|
||||
>
|
||||
Provider
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<div v-for="(service, index) in data.mirroring.mirrors" :key="index">
|
||||
<div
|
||||
v-for="(service, index) in data.mirroring.mirrors"
|
||||
:key="index"
|
||||
>
|
||||
<q-card-section>
|
||||
<div class="row items-center no-wrap">
|
||||
<div class="col-6">
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-rule app-chip-overflow">
|
||||
class="app-chip app-chip-rule app-chip-overflow"
|
||||
>
|
||||
{{ service.name }}
|
||||
<q-tooltip>{{service.name}}</q-tooltip>
|
||||
<q-tooltip>{{ service.name }}</q-tooltip>
|
||||
</q-chip>
|
||||
</div>
|
||||
<div class="col-3 text-right">
|
||||
|
@ -46,8 +69,10 @@
|
|||
|
||||
export default {
|
||||
name: 'PanelMirroringServices',
|
||||
props: ['data', 'dense'],
|
||||
components: {},
|
||||
props: {
|
||||
data: Object,
|
||||
dense: Boolean
|
||||
},
|
||||
computed: {
|
||||
isDense () {
|
||||
return this.dense !== undefined
|
||||
|
@ -70,13 +95,13 @@ export default {
|
|||
return 'providers/plugin.svg'
|
||||
}
|
||||
if (name.startsWith('consul-')) {
|
||||
return `providers/consul.svg`
|
||||
return 'providers/consul.svg'
|
||||
}
|
||||
if (name.startsWith('consulcatalog-')) {
|
||||
return `providers/consulcatalog.svg`
|
||||
return 'providers/consulcatalog.svg'
|
||||
}
|
||||
if (name.startsWith('nomad-')) {
|
||||
return `providers/nomad.svg`
|
||||
return 'providers/nomad.svg'
|
||||
}
|
||||
|
||||
return `providers/${name}.svg`
|
||||
|
|
|
@ -1,22 +1,37 @@
|
|||
<template>
|
||||
<q-card flat bordered v-bind:class="['panel-router-details']">
|
||||
<q-scroll-area :thumb-style="appThumbStyle" style="height:100%;">
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
:class="['panel-router-details']"
|
||||
>
|
||||
<q-scroll-area
|
||||
:thumb-style="appThumbStyle"
|
||||
style="height:100%;"
|
||||
>
|
||||
<q-card-section>
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">STATUS</div>
|
||||
<div class="text-subtitle2">
|
||||
STATUS
|
||||
</div>
|
||||
<div class="block-right-text">
|
||||
<avatar-state :state="data.status | status "/>
|
||||
<div v-bind:class="['block-right-text-label', `block-right-text-label-${data.status}`]">{{data.status | statusLabel}}</div>
|
||||
<avatar-state :state="status(data.status)" />
|
||||
<div :class="['block-right-text-label', `block-right-text-label-${data.status}`]">
|
||||
{{ statusLabel(data.status) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">PROVIDER</div>
|
||||
<div class="text-subtitle2">
|
||||
PROVIDER
|
||||
</div>
|
||||
<div class="block-right-text">
|
||||
<q-avatar class="provider-logo">
|
||||
<q-icon :name="`img:${getProviderLogoPath}`" />
|
||||
</q-avatar>
|
||||
<div class="block-right-text-label">{{data.provider}}</div>
|
||||
<div class="block-right-text-label">
|
||||
{{ data.provider }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -24,10 +39,13 @@
|
|||
<q-card-section v-if="data.rule">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">RULE</div>
|
||||
<div class="text-subtitle2">
|
||||
RULE
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-wrap app-chip-rule">
|
||||
class="app-chip app-chip-wrap app-chip-rule"
|
||||
>
|
||||
{{ data.rule }}
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -36,10 +54,13 @@
|
|||
<q-card-section v-if="data.name">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">NAME</div>
|
||||
<div class="text-subtitle2">
|
||||
NAME
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-wrap app-chip-name">
|
||||
class="app-chip app-chip-wrap app-chip-name"
|
||||
>
|
||||
{{ data.name }}
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -48,11 +69,15 @@
|
|||
<q-card-section v-if="data.using">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">ENTRYPOINTS</div>
|
||||
<div class="text-subtitle2">
|
||||
ENTRYPOINTS
|
||||
</div>
|
||||
<q-chip
|
||||
v-for="(entryPoint, index) in data.using" :key="index"
|
||||
v-for="(entryPoint, index) in data.using"
|
||||
:key="index"
|
||||
dense
|
||||
class="app-chip app-chip-entry-points">
|
||||
class="app-chip app-chip-entry-points"
|
||||
>
|
||||
{{ entryPoint }}
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -61,12 +86,15 @@
|
|||
<q-card-section v-if="data.service">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">SERVICE</div>
|
||||
<div class="text-subtitle2">
|
||||
SERVICE
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
clickable
|
||||
@click.native="$router.push({ path: `/${protocol}/services/${getServiceId()}`})"
|
||||
class="app-chip app-chip-wrap app-chip-service app-chip-overflow">
|
||||
class="app-chip app-chip-wrap app-chip-service app-chip-overflow"
|
||||
@click="$router.push({ path: `/${protocol}/services/${getServiceId()}`})"
|
||||
>
|
||||
{{ data.service }}
|
||||
<q-tooltip>{{ data.service }}</q-tooltip>
|
||||
</q-chip>
|
||||
|
@ -76,10 +104,14 @@
|
|||
<q-card-section v-if="data.error">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">ERRORS</div>
|
||||
<div class="text-subtitle2">
|
||||
ERRORS
|
||||
</div>
|
||||
<q-chip
|
||||
v-for="(errorMsg, index) in data.error" :key="index"
|
||||
class="app-chip app-chip-error">
|
||||
v-for="(errorMsg, index) in data.error"
|
||||
:key="index"
|
||||
class="app-chip app-chip-error"
|
||||
>
|
||||
{{ errorMsg }}
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -90,14 +122,38 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import AvatarState from './AvatarState'
|
||||
import { defineComponent } from 'vue'
|
||||
import AvatarState from './AvatarState.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PanelRouterDetails',
|
||||
props: ['data', 'protocol'],
|
||||
components: {
|
||||
AvatarState
|
||||
},
|
||||
props: {
|
||||
data: Object,
|
||||
protocol: String
|
||||
},
|
||||
computed: {
|
||||
getProviderLogoPath () {
|
||||
const name = this.data.provider.toLowerCase()
|
||||
|
||||
if (name.startsWith('plugin-')) {
|
||||
return 'providers/plugin.svg'
|
||||
}
|
||||
if (name.startsWith('consul-')) {
|
||||
return 'providers/consul.svg'
|
||||
}
|
||||
if (name.startsWith('consulcatalog-')) {
|
||||
return 'providers/consulcatalog.svg'
|
||||
}
|
||||
if (name.startsWith('nomad-')) {
|
||||
return 'providers/nomad.svg'
|
||||
}
|
||||
|
||||
return `providers/${name}.svg`
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getServiceId () {
|
||||
const words = this.data.service.split('@')
|
||||
|
@ -106,9 +162,7 @@ export default {
|
|||
}
|
||||
|
||||
return `${this.data.service}@${this.data.provider}`
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
},
|
||||
status (value) {
|
||||
if (value === 'enabled') {
|
||||
return 'positive'
|
||||
|
@ -127,28 +181,8 @@ export default {
|
|||
}
|
||||
return value
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getProviderLogoPath () {
|
||||
const name = this.data.provider.toLowerCase()
|
||||
|
||||
if (name.startsWith('plugin-')) {
|
||||
return 'providers/plugin.svg'
|
||||
}
|
||||
if (name.startsWith('consul-')) {
|
||||
return `providers/consul.svg`
|
||||
}
|
||||
if (name.startsWith('consulcatalog-')) {
|
||||
return `providers/consulcatalog.svg`
|
||||
}
|
||||
if (name.startsWith('nomad-')) {
|
||||
return `providers/nomad.svg`
|
||||
}
|
||||
|
||||
return `providers/${name}.svg`
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,31 +1,59 @@
|
|||
<template>
|
||||
<q-card flat bordered v-bind:class="['panel-servers', {'panel-servers-dense':isDense}]">
|
||||
<q-scroll-area v-if="data.loadBalancer.servers" :thumb-style="appThumbStyle" style="height:100%;">
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
:class="['panel-servers', {'panel-servers-dense':isDense}]"
|
||||
>
|
||||
<q-scroll-area
|
||||
v-if="data.loadBalancer.servers"
|
||||
:thumb-style="appThumbStyle"
|
||||
style="height:100%;"
|
||||
>
|
||||
<q-card-section>
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col-3" v-if="showStatus">
|
||||
<div class="text-subtitle2 text-table">Status</div>
|
||||
<div
|
||||
v-if="showStatus"
|
||||
class="col-3"
|
||||
>
|
||||
<div class="text-subtitle2 text-table">
|
||||
Status
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<div class="text-subtitle2 text-table">URL</div>
|
||||
<div class="text-subtitle2 text-table">
|
||||
URL
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<div v-for="(server, index) in data.loadBalancer.servers" :key="index">
|
||||
<div
|
||||
v-for="(server, index) in data.loadBalancer.servers"
|
||||
:key="index"
|
||||
>
|
||||
<q-card-section>
|
||||
<div class="row items-center no-wrap">
|
||||
<div class="col-3" v-if="showStatus">
|
||||
<div
|
||||
v-if="showStatus"
|
||||
class="col-3"
|
||||
>
|
||||
<div class="block-right-text">
|
||||
<avatar-state v-if="data.serverStatus" :state="data.serverStatus[server.url || server.address] | status "/>
|
||||
<avatar-state v-if="!data.serverStatus" :state="'DOWN' | status"/>
|
||||
<avatar-state
|
||||
v-if="data.serverStatus"
|
||||
:state="status(data.serverStatus[server.url || server.address])"
|
||||
/>
|
||||
<avatar-state
|
||||
v-if="!data.serverStatus"
|
||||
:state="status('DOWN')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-rule">
|
||||
{{ server.url || server.address}}
|
||||
class="app-chip app-chip-rule"
|
||||
>
|
||||
{{ server.url || server.address }}
|
||||
</q-chip>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -33,30 +61,51 @@
|
|||
<q-separator />
|
||||
</div>
|
||||
</q-scroll-area>
|
||||
<q-card-section v-else style="height: 100%">
|
||||
<div class="row items-center" style="height: 100%">
|
||||
<div class="col-12">
|
||||
<div class="block-empty"></div>
|
||||
<div class="q-pb-lg block-empty-logo">
|
||||
<img v-if="$q.dark.isActive" alt="empty" src="~assets/middlewares-empty-dark.svg">
|
||||
<img v-else alt="empty" src="~assets/middlewares-empty.svg">
|
||||
</div>
|
||||
<div class="block-empty-label">There is no<br>Server available</div>
|
||||
<q-card-section
|
||||
v-else
|
||||
style="height: 100%"
|
||||
>
|
||||
<div
|
||||
class="row items-center"
|
||||
style="height: 100%"
|
||||
>
|
||||
<div class="col-12">
|
||||
<div class="block-empty" />
|
||||
<div class="q-pb-lg block-empty-logo">
|
||||
<img
|
||||
v-if="$q.dark.isActive"
|
||||
alt="empty"
|
||||
src="~assets/middlewares-empty-dark.svg"
|
||||
>
|
||||
<img
|
||||
v-else
|
||||
alt="empty"
|
||||
src="~assets/middlewares-empty.svg"
|
||||
>
|
||||
</div>
|
||||
<div class="block-empty-label">
|
||||
There is no<br>Server available
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AvatarState from './AvatarState'
|
||||
import { defineComponent } from 'vue'
|
||||
import AvatarState from './AvatarState.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PanelServers',
|
||||
props: ['data', 'dense', 'hasStatus'],
|
||||
components: {
|
||||
AvatarState
|
||||
},
|
||||
props: {
|
||||
data: Object,
|
||||
dense: Boolean,
|
||||
hasStatus: Boolean
|
||||
},
|
||||
computed: {
|
||||
isDense () {
|
||||
return this.dense !== undefined
|
||||
|
@ -65,7 +114,7 @@ export default {
|
|||
return this.hasStatus !== undefined
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
methods: {
|
||||
status (value) {
|
||||
if (value === 'UP') {
|
||||
return 'positive'
|
||||
|
@ -73,7 +122,7 @@ export default {
|
|||
return 'negative'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,23 +1,40 @@
|
|||
<template>
|
||||
<q-card flat bordered v-bind:class="['panel-service-details', {'panel-service-details-dense':isDense}]">
|
||||
<q-scroll-area :thumb-style="appThumbStyle" style="height:100%;">
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
:class="['panel-service-details', {'panel-service-details-dense':isDense}]"
|
||||
>
|
||||
<q-scroll-area
|
||||
:thumb-style="appThumbStyle"
|
||||
style="height:100%;"
|
||||
>
|
||||
<q-card-section>
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col" v-if="data.type">
|
||||
<div class="text-subtitle2">TYPE</div>
|
||||
<div
|
||||
v-if="data.type"
|
||||
class="col"
|
||||
>
|
||||
<div class="text-subtitle2">
|
||||
TYPE
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-entry-points">
|
||||
class="app-chip app-chip-entry-points"
|
||||
>
|
||||
{{ data.type }}
|
||||
</q-chip>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">PROVIDER</div>
|
||||
<div class="text-subtitle2">
|
||||
PROVIDER
|
||||
</div>
|
||||
<div class="block-right-text">
|
||||
<q-avatar class="provider-logo">
|
||||
<q-icon :name="`img:${getProviderLogoPath}`" />
|
||||
</q-avatar>
|
||||
<div class="block-right-text-label">{{data.provider}}</div>
|
||||
<div class="block-right-text-label">
|
||||
{{ data.provider }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -25,10 +42,14 @@
|
|||
<q-card-section>
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">STATUS</div>
|
||||
<div class="text-subtitle2">
|
||||
STATUS
|
||||
</div>
|
||||
<div class="block-right-text">
|
||||
<avatar-state :state="data.status | status "/>
|
||||
<div v-bind:class="['block-right-text-label', `block-right-text-label-${data.status}`]">{{data.status | statusLabel}}</div>
|
||||
<avatar-state :state="status(data.status)" />
|
||||
<div :class="['block-right-text-label', `block-right-text-label-${data.status}`]">
|
||||
{{ statusLabel(data.status) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -36,10 +57,13 @@
|
|||
<q-card-section v-if="data.mirroring">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">Main Service</div>
|
||||
<div class="text-subtitle2">
|
||||
Main Service
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-name app-chip-overflow">
|
||||
class="app-chip app-chip-name app-chip-overflow"
|
||||
>
|
||||
{{ data.mirroring.service }}
|
||||
<q-tooltip>{{ data.mirroring.service }}</q-tooltip>
|
||||
</q-chip>
|
||||
|
@ -49,8 +73,10 @@
|
|||
<q-card-section v-if="data.loadBalancer && $route.meta.protocol !== 'tcp'">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">Pass Host Header</div>
|
||||
<boolean-state :value="data.loadBalancer.passHostHeader"/>
|
||||
<div class="text-subtitle2">
|
||||
Pass Host Header
|
||||
</div>
|
||||
<boolean-state :value="data.loadBalancer.passHostHeader" />
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
@ -58,10 +84,13 @@
|
|||
<q-card-section v-if="data.loadBalancer && data.loadBalancer.terminationDelay">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">Termination Delay</div>
|
||||
<div class="text-subtitle2">
|
||||
Termination Delay
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-name">
|
||||
class="app-chip app-chip-name"
|
||||
>
|
||||
{{ data.loadBalancer.terminationDelay }} ms
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -71,10 +100,13 @@
|
|||
<q-card-section v-if="data.loadBalancer && data.loadBalancer.proxyProtocol">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">Proxy Protocol</div>
|
||||
<div class="text-subtitle2">
|
||||
Proxy Protocol
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-name">
|
||||
class="app-chip app-chip-name"
|
||||
>
|
||||
Version {{ data.loadBalancer.proxyProtocol.version }}
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -84,10 +116,13 @@
|
|||
<q-card-section v-if="data.failover && data.failover.service">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">Main Service</div>
|
||||
<div class="text-subtitle2">
|
||||
Main Service
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-name app-chip-overflow">
|
||||
class="app-chip app-chip-name app-chip-overflow"
|
||||
>
|
||||
{{ data.failover.service }}
|
||||
<q-tooltip>{{ data.failover.service }}</q-tooltip>
|
||||
</q-chip>
|
||||
|
@ -98,10 +133,13 @@
|
|||
<q-card-section v-if="data.failover && data.failover.fallback">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">Fallback Service</div>
|
||||
<div class="text-subtitle2">
|
||||
Fallback Service
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-name app-chip-overflow">
|
||||
class="app-chip app-chip-name app-chip-overflow"
|
||||
>
|
||||
{{ data.failover.fallback }}
|
||||
<q-tooltip>{{ data.failover.fallback }}</q-tooltip>
|
||||
</q-chip>
|
||||
|
@ -110,24 +148,32 @@
|
|||
</q-card-section>
|
||||
|
||||
<q-separator v-if="sticky" />
|
||||
<StickyServiceDetails v-if="sticky" :sticky="sticky" :dense="dense"/>
|
||||
<StickyServiceDetails
|
||||
v-if="sticky"
|
||||
:sticky="sticky"
|
||||
:dense="dense"
|
||||
/>
|
||||
</q-scroll-area>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AvatarState from './AvatarState'
|
||||
import BooleanState from './BooleanState'
|
||||
import StickyServiceDetails from './StickyServiceDetails'
|
||||
import { defineComponent } from 'vue'
|
||||
import AvatarState from './AvatarState.vue'
|
||||
import BooleanState from './BooleanState.vue'
|
||||
import StickyServiceDetails from './StickyServiceDetails.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PanelServiceDetails',
|
||||
props: ['data', 'dense'],
|
||||
components: {
|
||||
BooleanState,
|
||||
AvatarState,
|
||||
StickyServiceDetails
|
||||
},
|
||||
props: {
|
||||
data: Object,
|
||||
dense: Boolean
|
||||
},
|
||||
computed: {
|
||||
isDense () {
|
||||
return this.dense !== undefined
|
||||
|
@ -150,19 +196,19 @@ export default {
|
|||
return 'providers/plugin.svg'
|
||||
}
|
||||
if (name.startsWith('consul-')) {
|
||||
return `providers/consul.svg`
|
||||
return 'providers/consul.svg'
|
||||
}
|
||||
if (name.startsWith('consulcatalog-')) {
|
||||
return `providers/consulcatalog.svg`
|
||||
return 'providers/consulcatalog.svg'
|
||||
}
|
||||
if (name.startsWith('nomad-')) {
|
||||
return `providers/nomad.svg`
|
||||
return 'providers/nomad.svg'
|
||||
}
|
||||
|
||||
return `providers/${name}.svg`
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
methods: {
|
||||
status (value) {
|
||||
if (value === 'enabled') {
|
||||
return 'positive'
|
||||
|
@ -182,7 +228,7 @@ export default {
|
|||
return value || 'error'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,21 +1,34 @@
|
|||
<template>
|
||||
<q-card flat bordered v-bind:class="['panel-tls']">
|
||||
<q-scroll-area v-if="data" :thumb-style="appThumbStyle" style="height:100%;">
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
:class="['panel-tls']"
|
||||
>
|
||||
<q-scroll-area
|
||||
v-if="data"
|
||||
:thumb-style="appThumbStyle"
|
||||
style="height:100%;"
|
||||
>
|
||||
<q-card-section v-if="data">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">TLS</div>
|
||||
<boolean-state :value="!!data"/>
|
||||
<div class="text-subtitle2">
|
||||
TLS
|
||||
</div>
|
||||
<boolean-state :value="!!data" />
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section v-if="data.options">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">OPTIONS</div>
|
||||
<div class="text-subtitle2">
|
||||
OPTIONS
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-options">
|
||||
class="app-chip app-chip-options"
|
||||
>
|
||||
{{ data.options }}
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -24,18 +37,23 @@
|
|||
<q-card-section v-if="protocol === 'tcp'">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">PASSTHROUGH</div>
|
||||
<boolean-state :value="data.passthrough"></boolean-state>
|
||||
<div class="text-subtitle2">
|
||||
PASSTHROUGH
|
||||
</div>
|
||||
<boolean-state :value="data.passthrough" />
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section v-if="data.certResolver">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">CERTIFICATE RESOLVER</div>
|
||||
<div class="text-subtitle2">
|
||||
CERTIFICATE RESOLVER
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-service">
|
||||
class="app-chip app-chip-service"
|
||||
>
|
||||
{{ data.certResolver }}
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -44,17 +62,26 @@
|
|||
<q-card-section v-if="data.domains">
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">DOMAINS</div>
|
||||
<div v-for="(domain, key) in data.domains" :key="key" class="flex">
|
||||
<div class="text-subtitle2">
|
||||
DOMAINS
|
||||
</div>
|
||||
<div
|
||||
v-for="(domain, key) in data.domains"
|
||||
:key="key"
|
||||
class="flex"
|
||||
>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-rule">
|
||||
class="app-chip app-chip-rule"
|
||||
>
|
||||
{{ domain.main }}
|
||||
</q-chip>
|
||||
<q-chip
|
||||
v-for="(domain, key) in domain.sans" :key="key"
|
||||
v-for="(domain, key) in domain.sans"
|
||||
:key="key"
|
||||
dense
|
||||
class="app-chip app-chip-entry-points">
|
||||
class="app-chip app-chip-entry-points"
|
||||
>
|
||||
{{ domain }}
|
||||
</q-chip>
|
||||
</div>
|
||||
|
@ -62,15 +89,31 @@
|
|||
</div>
|
||||
</q-card-section>
|
||||
</q-scroll-area>
|
||||
<q-card-section v-else style="height: 100%">
|
||||
<div class="row items-center" style="height: 100%">
|
||||
<q-card-section
|
||||
v-else
|
||||
style="height: 100%"
|
||||
>
|
||||
<div
|
||||
class="row items-center"
|
||||
style="height: 100%"
|
||||
>
|
||||
<div class="col-12">
|
||||
<div class="block-empty"></div>
|
||||
<div class="block-empty" />
|
||||
<div class="q-pb-lg block-empty-logo">
|
||||
<img v-if="$q.dark.isActive" alt="empty" src="~assets/middlewares-empty-dark.svg">
|
||||
<img v-else alt="empty" src="~assets/middlewares-empty.svg">
|
||||
<img
|
||||
v-if="$q.dark.isActive"
|
||||
alt="empty"
|
||||
src="~assets/middlewares-empty-dark.svg"
|
||||
>
|
||||
<img
|
||||
v-else
|
||||
alt="empty"
|
||||
src="~assets/middlewares-empty.svg"
|
||||
>
|
||||
</div>
|
||||
<div class="block-empty-label">
|
||||
There is no<br>TLS configured
|
||||
</div>
|
||||
<div class="block-empty-label">There is no<br>TLS configured</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
@ -78,15 +121,19 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import BooleanState from './BooleanState'
|
||||
import { defineComponent } from 'vue'
|
||||
import BooleanState from './BooleanState.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PanelTLS',
|
||||
components: {
|
||||
BooleanState
|
||||
},
|
||||
props: ['data', 'protocol']
|
||||
}
|
||||
props: {
|
||||
data: Object,
|
||||
protocol: String
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,29 +1,46 @@
|
|||
<template>
|
||||
<q-card flat bordered v-bind:class="['panel-services', {'panel-services-dense':isDense}]">
|
||||
<q-scroll-area :thumb-style="appThumbStyle" style="height:100%;">
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
:class="['panel-services', {'panel-services-dense':isDense}]"
|
||||
>
|
||||
<q-scroll-area
|
||||
:thumb-style="appThumbStyle"
|
||||
style="height:100%;"
|
||||
>
|
||||
<q-card-section>
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col-7">
|
||||
<div class="text-subtitle2 text-table">Name</div>
|
||||
<div class="text-subtitle2 text-table">
|
||||
Name
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="text-subtitle2 text-table">Weight</div>
|
||||
<div class="text-subtitle2 text-table">
|
||||
Weight
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<div class="text-subtitle2 text-table">Provider</div>
|
||||
<div class="text-subtitle2 text-table">
|
||||
Provider
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<div v-for="(service, index) in data.weighted.services" :key="index">
|
||||
<div
|
||||
v-for="(service, index) in data.weighted.services"
|
||||
:key="index"
|
||||
>
|
||||
<q-card-section>
|
||||
<div class="row items-center no-wrap">
|
||||
<div class="col-7">
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-rule app-chip-overflow">
|
||||
class="app-chip app-chip-rule app-chip-overflow"
|
||||
>
|
||||
{{ service.name }}
|
||||
<q-tooltip>{{service.name}}</q-tooltip>
|
||||
<q-tooltip>{{ service.name }}</q-tooltip>
|
||||
</q-chip>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
|
@ -43,11 +60,15 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PanelWeightedServices',
|
||||
props: ['data', 'dense'],
|
||||
components: {},
|
||||
props: {
|
||||
data: Object,
|
||||
dense: Boolean
|
||||
},
|
||||
computed: {
|
||||
isDense () {
|
||||
return this.dense !== undefined
|
||||
|
@ -70,19 +91,19 @@ export default {
|
|||
return 'providers/plugin.svg'
|
||||
}
|
||||
if (name.startsWith('consul-')) {
|
||||
return `providers/consul.svg`
|
||||
return 'providers/consul.svg'
|
||||
}
|
||||
if (name.startsWith('consulcatalog-')) {
|
||||
return `providers/consulcatalog.svg`
|
||||
return 'providers/consulcatalog.svg'
|
||||
}
|
||||
if (name.startsWith('nomad-')) {
|
||||
return `providers/nomad.svg`
|
||||
return 'providers/nomad.svg'
|
||||
}
|
||||
|
||||
return `providers/${name}.svg`
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -5,8 +5,12 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['name'],
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
name: String
|
||||
},
|
||||
computed: {
|
||||
getLogoPath () {
|
||||
const name = this.name.toLowerCase()
|
||||
|
@ -15,19 +19,19 @@ export default {
|
|||
return 'providers/plugin.svg'
|
||||
}
|
||||
if (name.startsWith('consul-')) {
|
||||
return `providers/consul.svg`
|
||||
return 'providers/consul.svg'
|
||||
}
|
||||
if (name.startsWith('consulcatalog-')) {
|
||||
return `providers/consulcatalog.svg`
|
||||
return 'providers/consulcatalog.svg'
|
||||
}
|
||||
if (name.startsWith('nomad-')) {
|
||||
return `providers/nomad.svg`
|
||||
return 'providers/nomad.svg'
|
||||
}
|
||||
|
||||
return `providers/${name}.svg`
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,27 +1,34 @@
|
|||
<template>
|
||||
<div class="panel">
|
||||
<div
|
||||
v-if="isOpen"
|
||||
class="panel-backdrop"
|
||||
@click="close"
|
||||
v-if="isOpen"
|
||||
></div>
|
||||
/>
|
||||
<transition name="slide">
|
||||
<div v-if="isOpen" class="panel-content">
|
||||
<slot></slot>
|
||||
<div
|
||||
v-if="isOpen"
|
||||
class="panel-content"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
export default {
|
||||
props: ['isOpen'],
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
isOpen: Boolean
|
||||
},
|
||||
methods: {
|
||||
close () {
|
||||
this.$emit('onClose')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
<template>
|
||||
<span
|
||||
:style="{ height, width: computedWidth }"
|
||||
v-bind:class="['SkeletonBox']"
|
||||
:class="['SkeletonBox']"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: `SkeletonBox`,
|
||||
name: 'SkeletonBox',
|
||||
props: {
|
||||
maxWidth: {
|
||||
default: 100,
|
||||
|
@ -18,7 +18,7 @@ export default {
|
|||
type: Number
|
||||
},
|
||||
height: {
|
||||
default: `2em`,
|
||||
default: '2em',
|
||||
type: String
|
||||
},
|
||||
width: {
|
||||
|
|
|
@ -1,49 +1,66 @@
|
|||
<template>
|
||||
<div>
|
||||
<q-card-section>
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="text-subtitle1">Sticky: Cookie </div>
|
||||
<div>
|
||||
<q-card-section>
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="text-subtitle1">
|
||||
Sticky: Cookie
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col" v-if="sticky.cookie && sticky.cookie.name">
|
||||
<div class="text-subtitle2">NAME</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-entry-points">
|
||||
{{ sticky.cookie.name }}
|
||||
</q-chip>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<div class="row items-start no-wrap">
|
||||
<div
|
||||
v-if="sticky.cookie && sticky.cookie.name"
|
||||
class="col"
|
||||
>
|
||||
<div class="text-subtitle2">
|
||||
NAME
|
||||
</div>
|
||||
<q-chip
|
||||
dense
|
||||
class="app-chip app-chip-entry-points"
|
||||
>
|
||||
{{ sticky.cookie.name }}
|
||||
</q-chip>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">SECURE</div>
|
||||
<boolean-state :value="sticky.cookie.secure"/>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<div class="row items-start no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">
|
||||
SECURE
|
||||
</div>
|
||||
<boolean-state :value="sticky.cookie.secure" />
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">HTTP Only</div>
|
||||
<boolean-state :value="sticky.cookie.httpOnly"/>
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">
|
||||
HTTP Only
|
||||
</div>
|
||||
<boolean-state :value="sticky.cookie.httpOnly" />
|
||||
</div>
|
||||
</q-card-section>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BooleanState from './BooleanState'
|
||||
import { defineComponent } from 'vue'
|
||||
import BooleanState from './BooleanState.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'StickyServiceDetails',
|
||||
components: {
|
||||
BooleanState
|
||||
},
|
||||
props: ['sticky', 'dense']
|
||||
}
|
||||
props: {
|
||||
sticky: Object,
|
||||
dense: Boolean
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "../../css/sass/variables";
|
||||
|
||||
|
|
|
@ -1,14 +1,21 @@
|
|||
<template>
|
||||
<q-avatar text-color="dark">
|
||||
<q-icon v-if="isTLS" name="eva-shield" />
|
||||
<q-icon
|
||||
v-if="isTLS"
|
||||
name="eva-shield"
|
||||
/>
|
||||
</q-avatar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'TLSState',
|
||||
props: ['isTLS']
|
||||
}
|
||||
props: {
|
||||
isTLS: Boolean
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,23 +1,57 @@
|
|||
<template>
|
||||
<q-toolbar class="row no-wrap items-center">
|
||||
<q-tabs align="left" inline-label indicator-color="transparent" stretch>
|
||||
<q-route-tab :to="`/${protocol}/routers`" no-caps :label="`${protocolLabel} Routers`">
|
||||
<q-badge v-if="routerTotal !== 0" align="middle" :label="routerTotal" class="q-ml-sm"/>
|
||||
<q-tabs
|
||||
align="left"
|
||||
inline-label
|
||||
indicator-color="transparent"
|
||||
stretch
|
||||
>
|
||||
<q-route-tab
|
||||
:to="`/${protocol}/routers`"
|
||||
no-caps
|
||||
:label="`${protocolLabel} Routers`"
|
||||
>
|
||||
<q-badge
|
||||
v-if="routerTotal !== 0"
|
||||
align="middle"
|
||||
:label="routerTotal"
|
||||
class="q-ml-sm"
|
||||
/>
|
||||
</q-route-tab>
|
||||
<q-route-tab :to="`/${protocol}/services`" no-caps :label="`${protocolLabel} Services`">
|
||||
<q-badge v-if="servicesTotal !== 0" align="middle" :label="servicesTotal" class="q-ml-sm"/>
|
||||
<q-route-tab
|
||||
:to="`/${protocol}/services`"
|
||||
no-caps
|
||||
:label="`${protocolLabel} Services`"
|
||||
>
|
||||
<q-badge
|
||||
v-if="servicesTotal !== 0"
|
||||
align="middle"
|
||||
:label="servicesTotal"
|
||||
class="q-ml-sm"
|
||||
/>
|
||||
</q-route-tab>
|
||||
<q-route-tab v-if="protocol !== 'udp'" :to="`/${protocol}/middlewares`" no-caps :label="`${protocolLabel} Middlewares`">
|
||||
<q-badge v-if="middlewaresTotal !== 0" align="middle" :label="middlewaresTotal" class="q-ml-sm"/>
|
||||
<q-route-tab
|
||||
v-if="protocol !== 'udp'"
|
||||
:to="`/${protocol}/middlewares`"
|
||||
no-caps
|
||||
:label="`${protocolLabel} Middlewares`"
|
||||
>
|
||||
<q-badge
|
||||
v-if="middlewaresTotal !== 0"
|
||||
align="middle"
|
||||
:label="middlewaresTotal"
|
||||
class="q-ml-sm"
|
||||
/>
|
||||
</q-route-tab>
|
||||
</q-tabs>
|
||||
</q-toolbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import { defineComponent } from 'vue'
|
||||
import { useStore, mapActions, mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'ToolBar',
|
||||
data () {
|
||||
return {
|
||||
|
@ -47,6 +81,16 @@ export default {
|
|||
return (data && data.middlewares && data.middlewares.total) || 0
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.refreshAll()
|
||||
this.intervalRefresh = setInterval(this.onGetAll, this.intervalRefreshTime)
|
||||
},
|
||||
beforeUnmount () {
|
||||
const $store = useStore()
|
||||
|
||||
clearInterval(this.intervalRefresh)
|
||||
$store.commit('core/getOverviewClear')
|
||||
},
|
||||
methods: {
|
||||
...mapActions('core', { getOverview: 'getOverview' }),
|
||||
refreshAll () {
|
||||
|
@ -64,16 +108,8 @@ export default {
|
|||
console.log('Error -> toolbar/overview', error)
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.refreshAll()
|
||||
this.intervalRefresh = setInterval(this.onGetAll, this.intervalRefreshTime)
|
||||
},
|
||||
beforeDestroy () {
|
||||
clearInterval(this.intervalRefresh)
|
||||
this.$store.commit('core/getOverviewClear')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -10,15 +10,25 @@
|
|||
rounded
|
||||
unelevated
|
||||
:options="[
|
||||
{label: 'All Status', value: ''},
|
||||
{label: 'Success', value: 'enabled'},
|
||||
{label: 'Warnings', value: 'warning'},
|
||||
{label: 'Errors', value: 'disabled'}
|
||||
]"
|
||||
{label: 'All Status', value: ''},
|
||||
{label: 'Success', value: 'enabled'},
|
||||
{label: 'Warnings', value: 'warning'},
|
||||
{label: 'Errors', value: 'disabled'}
|
||||
]"
|
||||
/>
|
||||
<q-space />
|
||||
<q-input v-model="getFilter" rounded dense outlined type="search" debounce="500" placeholder="Search" :bg-color="$q.dark.isActive ? undefined : 'white'" class="bar-search">
|
||||
<template v-slot:append>
|
||||
<q-input
|
||||
v-model="getFilter"
|
||||
rounded
|
||||
dense
|
||||
outlined
|
||||
type="search"
|
||||
debounce="500"
|
||||
placeholder="Search"
|
||||
:bg-color="$q.dark.isActive ? undefined : 'white'"
|
||||
class="bar-search"
|
||||
>
|
||||
<template #append>
|
||||
<q-icon name="eva-search-outline" />
|
||||
</template>
|
||||
</q-input>
|
||||
|
@ -26,20 +36,14 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import Helps from '../../_helpers/Helps'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'ToolBarTable',
|
||||
props: ['status', 'filter'],
|
||||
components: {
|
||||
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.routeToState(this.$route)
|
||||
props: {
|
||||
status: String,
|
||||
filter: String
|
||||
},
|
||||
computed: {
|
||||
getStatus: {
|
||||
|
@ -66,6 +70,9 @@ export default {
|
|||
this.routeToState(to)
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.routeToState(this.$route)
|
||||
},
|
||||
methods: {
|
||||
routeToState (route) {
|
||||
for (const query in route.query) {
|
||||
|
@ -81,11 +88,8 @@ export default {
|
|||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,58 +1,98 @@
|
|||
<template>
|
||||
<q-card flat bordered>
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
>
|
||||
<q-card-section>
|
||||
<div class="row items-center no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-h6 text-weight-bold">{{getName}}</div>
|
||||
<div class="text-h6 text-weight-bold">
|
||||
{{ getName }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<q-btn :to="getUrl" color="accent" dense flat icon-right="eva-arrow-forward-outline" no-caps label="Explore" size="md" class="text-weight-bold"/>
|
||||
<q-btn
|
||||
:to="getUrl"
|
||||
color="accent"
|
||||
dense
|
||||
flat
|
||||
icon-right="eva-arrow-forward-outline"
|
||||
no-caps
|
||||
label="Explore"
|
||||
size="md"
|
||||
class="text-weight-bold"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<div class="row items-center q-col-gutter-md">
|
||||
<div class="col-12 col-sm-6">
|
||||
<ChartDoughnut
|
||||
:chartdata="getChartdata()"
|
||||
:options="options"/>
|
||||
<Doughnut
|
||||
:data="getChartdata()"
|
||||
:options="options"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6">
|
||||
<q-list>
|
||||
<q-item class="label-state">
|
||||
<q-item-section avatar>
|
||||
<avatar-state state="positive"/>
|
||||
<avatar-state state="positive" />
|
||||
</q-item-section>
|
||||
<q-item-section class="label-state-text">
|
||||
<q-item-label>Success</q-item-label>
|
||||
<q-item-label caption lines="1">{{getSuccess(true)}}%</q-item-label>
|
||||
<q-item-label
|
||||
caption
|
||||
lines="1"
|
||||
>
|
||||
{{ getSuccess(true) }}%
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side class="label-state-side">
|
||||
{{getSuccess()}}
|
||||
<q-item-section
|
||||
side
|
||||
class="label-state-side"
|
||||
>
|
||||
{{ getSuccess() }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="label-state">
|
||||
<q-item-section avatar>
|
||||
<avatar-state state="warning"/>
|
||||
<avatar-state state="warning" />
|
||||
</q-item-section>
|
||||
<q-item-section class="label-state-text">
|
||||
<q-item-label>Warnings</q-item-label>
|
||||
<q-item-label caption lines="1">{{getWarnings(true)}}%</q-item-label>
|
||||
<q-item-label
|
||||
caption
|
||||
lines="1"
|
||||
>
|
||||
{{ getWarnings(true) }}%
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side class="label-state-side">
|
||||
{{getWarnings()}}
|
||||
<q-item-section
|
||||
side
|
||||
class="label-state-side"
|
||||
>
|
||||
{{ getWarnings() }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
<q-item class="label-state">
|
||||
<q-item-section avatar>
|
||||
<avatar-state state="negative"/>
|
||||
<avatar-state state="negative" />
|
||||
</q-item-section>
|
||||
<q-item-section class="label-state-text">
|
||||
<q-item-label>Errors</q-item-label>
|
||||
<q-item-label caption lines="1">{{getErrors(true)}}%</q-item-label>
|
||||
<q-item-label
|
||||
caption
|
||||
lines="1"
|
||||
>
|
||||
{{ getErrors(true) }}%
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section side class="label-state-side">
|
||||
{{getErrors()}}
|
||||
<q-item-section
|
||||
side
|
||||
class="label-state-side"
|
||||
>
|
||||
{{ getErrors() }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
|
@ -63,23 +103,33 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import Helps from '../../_helpers/Helps'
|
||||
import ChartDoughnut from '../_commons/ChartDoughnut'
|
||||
import AvatarState from '../_commons/AvatarState'
|
||||
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js'
|
||||
import { Doughnut } from 'vue-chartjs'
|
||||
import AvatarState from '../_commons/AvatarState.vue'
|
||||
|
||||
export default {
|
||||
ChartJS.register(ArcElement, Tooltip, Legend)
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PanelChart',
|
||||
props: ['name', 'data', 'type'],
|
||||
components: {
|
||||
ChartDoughnut,
|
||||
Doughnut,
|
||||
AvatarState
|
||||
},
|
||||
props: {
|
||||
name: String,
|
||||
data: Object,
|
||||
type: String
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
loading: true,
|
||||
options: {
|
||||
legend: {
|
||||
display: false
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false
|
||||
}
|
||||
},
|
||||
animation: {
|
||||
duration: 1000
|
||||
|
@ -171,7 +221,7 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,26 +1,40 @@
|
|||
<template>
|
||||
<q-card flat bordered v-bind:class="['panel-entry', {'panel-entry-detail':type === 'detail'}, {'panel-entry-focus':focus}, {'panel-entry-ex-size':exSize}]">
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
:class="['panel-entry', {'panel-entry-detail':type === 'detail'}, {'panel-entry-focus':focus}, {'panel-entry-ex-size':exSize}]"
|
||||
>
|
||||
<q-card-section>
|
||||
<div class="row items-center no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">{{name}}</div>
|
||||
<div class="text-subtitle2">
|
||||
{{ name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<div class="text-h3 text-center text-weight-bold ellipsis">
|
||||
<span>{{address}}</span>
|
||||
<q-tooltip>{{address}}</q-tooltip>
|
||||
<span>{{ address }}</span>
|
||||
<q-tooltip>{{ address }}</q-tooltip>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PanelEntry',
|
||||
props: ['address', 'name', 'type', 'focus', 'exSize']
|
||||
}
|
||||
props: {
|
||||
address: String,
|
||||
name: String,
|
||||
type: String,
|
||||
focus: Boolean,
|
||||
exSize: Number
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,17 +1,24 @@
|
|||
<template>
|
||||
<q-card flat bordered v-bind:class="['panel-feature']">
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
:class="['panel-feature']"
|
||||
>
|
||||
<q-card-section>
|
||||
<div class="row items-center no-wrap">
|
||||
<div class="col">
|
||||
<div class="text-subtitle2">{{featureKey}}</div>
|
||||
<div class="text-subtitle2">
|
||||
{{ featureKey }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<div class="text-h3 text-center text-weight-bold">
|
||||
<q-chip
|
||||
v-bind:class="['feature-chip', {'feature-chip-string':isString}, {'feature-chip-boolean':isBoolean}, {'feature-chip-boolean-true':isTrue}]">
|
||||
{{getVal}}
|
||||
:class="['feature-chip', {'feature-chip-string':isString}, {'feature-chip-boolean':isBoolean}, {'feature-chip-boolean-true':isTrue}]"
|
||||
>
|
||||
{{ getVal }}
|
||||
</q-chip>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<template>
|
||||
<q-card flat bordered>
|
||||
<q-card
|
||||
flat
|
||||
bordered
|
||||
>
|
||||
<q-card-section>
|
||||
<div class="row items-center no-wrap">
|
||||
<div class="col text-center">
|
||||
|
@ -11,16 +14,20 @@
|
|||
</q-card-section>
|
||||
<q-card-section>
|
||||
<div class="text-h6 text-center text-weight-bold">
|
||||
{{getName}}
|
||||
{{ getName }}
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
import { defineComponent } from 'vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PanelProvider',
|
||||
props: ['name'],
|
||||
props: {
|
||||
name: String
|
||||
},
|
||||
computed: {
|
||||
getName () {
|
||||
return this.name
|
||||
|
@ -32,19 +39,19 @@ export default {
|
|||
return 'providers/plugin.svg'
|
||||
}
|
||||
if (name.startsWith('consul-')) {
|
||||
return `providers/consul.svg`
|
||||
return 'providers/consul.svg'
|
||||
}
|
||||
if (name.startsWith('consulcatalog-')) {
|
||||
return `providers/consulcatalog.svg`
|
||||
return 'providers/consulcatalog.svg'
|
||||
}
|
||||
if (name.startsWith('nomad-')) {
|
||||
return `providers/nomad.svg`
|
||||
return 'providers/nomad.svg'
|
||||
}
|
||||
|
||||
return `providers/${name}.svg`
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
// to match your app's branding.
|
||||
// Tip: Use the "Theme Builder" on Quasar's documentation website.
|
||||
|
||||
$primary = #06102a
|
||||
$secondary = #2A2A2B
|
||||
$accent = #1e54d5
|
||||
$primary : #06102a;
|
||||
$secondary : #2A2A2B;
|
||||
$accent : #1e54d5;
|
||||
|
||||
$positive = #00a697
|
||||
$negative = #ff0039
|
||||
$info = #31CCEC
|
||||
$warning = #db7d11
|
||||
$positive : #00a697;
|
||||
$negative : #ff0039;
|
||||
$info : #31CCEC;
|
||||
$warning : #db7d11;
|
||||
|
||||
$separator-color = rgba(0, 0, 0, .12)
|
||||
$separator-dark-color = rgba(255, 255, 255, .28)
|
||||
$separator-color : rgba(0, 0, 0, .12);
|
||||
$separator-dark-color : rgba(255, 255, 255, .28);
|
|
@ -1,6 +1,5 @@
|
|||
<template>
|
||||
<q-layout view="hHh lpR fFf">
|
||||
|
||||
<nav-bar>
|
||||
<router-view name="NavBar" />
|
||||
</nav-bar>
|
||||
|
@ -8,12 +7,11 @@
|
|||
<q-page-container>
|
||||
<router-view />
|
||||
</q-page-container>
|
||||
|
||||
</q-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NavBar from '../components/_commons/NavBar'
|
||||
import NavBar from '../components/_commons/NavBar.vue'
|
||||
|
||||
export default {
|
||||
name: 'Default',
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
<template>
|
||||
<div class="fixed-center text-center q-pa-md">
|
||||
<h1 class="q-ma-md"><strong>404</strong></h1>
|
||||
<h5 class="q-ma-md">I'm sorry, nothing around here ...</h5>
|
||||
<h1 class="q-ma-md">
|
||||
<strong>404</strong>
|
||||
</h1>
|
||||
<h5 class="q-ma-md">
|
||||
I'm sorry, nothing around here ...
|
||||
</h5>
|
||||
<q-btn
|
||||
color="secondary"
|
||||
style="width:200px;"
|
||||
@click="$router.push('/')"
|
||||
>Go back</q-btn>
|
||||
>
|
||||
Go back
|
||||
</q-btn>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,82 +1,121 @@
|
|||
<template>
|
||||
<page-default>
|
||||
|
||||
<section v-if="!loading" class="app-section">
|
||||
<section
|
||||
v-if="!loading"
|
||||
class="app-section"
|
||||
>
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-xl q-pb-sm">
|
||||
<div v-if="middlewareByName.item" class="row no-wrap items-center app-title">
|
||||
<div class="app-title-label" style="font-size: 26px">{{ middlewareByName.item.name }}</div>
|
||||
<div
|
||||
v-if="middlewareByName.item"
|
||||
class="row no-wrap items-center app-title"
|
||||
>
|
||||
<div
|
||||
class="app-title-label"
|
||||
style="font-size: 26px"
|
||||
>
|
||||
{{ middlewareByName.item.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-sm q-pb-lg">
|
||||
<div v-if="!loading" class="row items-start q-col-gutter-md">
|
||||
|
||||
<div v-if="middlewareByName.item" class="col-12 col-md-4 q-mb-lg path-block">
|
||||
<div
|
||||
v-if="!loading"
|
||||
class="row items-start q-col-gutter-md"
|
||||
>
|
||||
<div
|
||||
v-if="middlewareByName.item"
|
||||
class="col-12 col-md-4 q-mb-lg path-block"
|
||||
>
|
||||
<div class="row items-start q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
<div class="row items-start q-col-gutter-md">
|
||||
<div class="col-12">
|
||||
<panel-middlewares dense :data="[middlewareByName.item]" />
|
||||
<panel-middlewares
|
||||
dense
|
||||
:data="[middlewareByName.item]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-else class="row items-start q-mt-xl">
|
||||
<div
|
||||
v-else
|
||||
class="row items-start q-mt-xl"
|
||||
>
|
||||
<div class="col-12">
|
||||
<p v-for="n in 4" :key="n" class="flex">
|
||||
<SkeletonBox :min-width="15" :max-width="15" style="margin-right: 2%"/> <SkeletonBox :min-width="50" :max-width="83"/>
|
||||
<p
|
||||
v-for="n in 4"
|
||||
:key="n"
|
||||
class="flex"
|
||||
>
|
||||
<SkeletonBox
|
||||
:min-width="15"
|
||||
:max-width="15"
|
||||
style="margin-right: 2%"
|
||||
/> <SkeletonBox
|
||||
:min-width="50"
|
||||
:max-width="83"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section v-if="!loading && allRouters.length" class="app-section">
|
||||
<section
|
||||
v-if="!loading && allRouters.length"
|
||||
class="app-section"
|
||||
>
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-lg q-pb-xl">
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<div class="app-title-label">Used by Routers</div>
|
||||
<div class="app-title-label">
|
||||
Used by Routers
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-center q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
<main-table
|
||||
:data="allRouters"
|
||||
v-bind="getTableProps({ type: `${protocol}-routers` })"
|
||||
v-model:pagination="routersPagination"
|
||||
:data="allRouters"
|
||||
:request="()=>{}"
|
||||
:loading="routersLoading"
|
||||
:pagination.sync="routersPagination"
|
||||
:filter="routersFilter"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</page-default>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import GetTablePropsMixin from '../../_mixins/GetTableProps'
|
||||
import PageDefault from '../../components/_commons/PageDefault'
|
||||
import SkeletonBox from '../../components/_commons/SkeletonBox'
|
||||
import PanelMiddlewares from '../../components/_commons/PanelMiddlewares'
|
||||
import MainTable from '../../components/_commons/MainTable'
|
||||
import PageDefault from '../../components/_commons/PageDefault.vue'
|
||||
import SkeletonBox from '../../components/_commons/SkeletonBox.vue'
|
||||
import PanelMiddlewares from '../../components/_commons/PanelMiddlewares.vue'
|
||||
import MainTable from '../../components/_commons/MainTable.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PageMiddlewareDetail',
|
||||
props: ['name', 'type'],
|
||||
mixins: [GetTablePropsMixin],
|
||||
components: {
|
||||
PageDefault,
|
||||
SkeletonBox,
|
||||
PanelMiddlewares,
|
||||
MainTable
|
||||
},
|
||||
mixins: [GetTablePropsMixin],
|
||||
props: {
|
||||
name: String,
|
||||
type: String
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
loading: true,
|
||||
|
@ -110,6 +149,14 @@ export default {
|
|||
return this[`${this.protocol}_getRouterByName`]
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.refreshAll()
|
||||
},
|
||||
beforeUnmount () {
|
||||
clearInterval(this.timeOutGetAll)
|
||||
this.$store.commit('http/getMiddlewareByNameClear')
|
||||
this.$store.commit('tcp/getMiddlewareByNameClear')
|
||||
},
|
||||
methods: {
|
||||
...mapActions('http', { http_getMiddlewareByName: 'getMiddlewareByName', http_getRouterByName: 'getRouterByName' }),
|
||||
...mapActions('tcp', { tcp_getMiddlewareByName: 'getMiddlewareByName', tcp_getRouterByName: 'getRouterByName' }),
|
||||
|
@ -129,7 +176,7 @@ export default {
|
|||
// Get routers
|
||||
if (body.usedBy) {
|
||||
for (const router in body.usedBy) {
|
||||
if (body.usedBy.hasOwnProperty(router)) {
|
||||
if (Object.getOwnPropertyDescriptor(body.usedBy, router)) {
|
||||
this.getRouterByName(body.usedBy[router])
|
||||
.then(body => {
|
||||
if (body) {
|
||||
|
@ -152,19 +199,8 @@ export default {
|
|||
console.log('Error -> middleware/byName', error)
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.refreshAll()
|
||||
},
|
||||
mounted () {
|
||||
|
||||
},
|
||||
beforeDestroy () {
|
||||
clearInterval(this.timeOutGetAll)
|
||||
this.$store.commit('http/getMiddlewareByNameClear')
|
||||
this.$store.commit('tcp/getMiddlewareByNameClear')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,90 +1,158 @@
|
|||
<template>
|
||||
<page-default>
|
||||
|
||||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-xl q-pb-xl">
|
||||
<div v-if="!loading" class="row items-start">
|
||||
|
||||
<div v-if="entryPoints.length" class="col-12 col-md-3 q-mb-lg path-block">
|
||||
<div
|
||||
v-if="!loading"
|
||||
class="row items-start"
|
||||
>
|
||||
<div
|
||||
v-if="entryPoints.length"
|
||||
class="col-12 col-md-3 q-mb-lg path-block"
|
||||
>
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-log-in-outline"></q-icon>
|
||||
<div class="app-title-label">Entrypoints</div>
|
||||
<q-icon name="eva-log-in-outline" />
|
||||
<div class="app-title-label">
|
||||
Entrypoints
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-start q-col-gutter-lg">
|
||||
<div class="col-12 col-md-8">
|
||||
<div class="row items-start q-col-gutter-md">
|
||||
<div v-for="(entryPoint, index) in entryPoints" :key="index" class="col-12">
|
||||
<panel-entry type="detail" exSize="true" :name="entryPoint.name" :address="entryPoint.address"/>
|
||||
<div
|
||||
v-for="(entryPoint, index) in entryPoints"
|
||||
:key="index"
|
||||
class="col-12"
|
||||
>
|
||||
<panel-entry
|
||||
type="detail"
|
||||
ex-size="true"
|
||||
:name="entryPoint.name"
|
||||
:address="entryPoint.address"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-4 xs-hide sm-hide">
|
||||
<q-icon name="eva-arrow-forward-outline" class="arrow"></q-icon>
|
||||
<q-icon
|
||||
name="eva-arrow-forward-outline"
|
||||
class="arrow"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="routerByName.item.name" class="col-12 col-md-3 q-mb-lg path-block">
|
||||
<div
|
||||
v-if="routerByName.item.name"
|
||||
class="col-12 col-md-3 q-mb-lg path-block"
|
||||
>
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-globe-outline"></q-icon>
|
||||
<div class="app-title-label">{{ routerType }}</div>
|
||||
<q-icon name="eva-globe-outline" />
|
||||
<div class="app-title-label">
|
||||
{{ routerType }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-start q-col-gutter-lg">
|
||||
<div class="col-12 col-md-8">
|
||||
<div class="row items-start q-col-gutter-md">
|
||||
<div class="col-12">
|
||||
<panel-entry focus="true" type="detail" name="router" :address="routerByName.item.name"/>
|
||||
<panel-entry
|
||||
focus="true"
|
||||
type="detail"
|
||||
name="router"
|
||||
:address="routerByName.item.name"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-4 xs-hide sm-hide">
|
||||
<q-icon name="eva-arrow-forward-outline" class="arrow"></q-icon>
|
||||
<q-icon
|
||||
name="eva-arrow-forward-outline"
|
||||
class="arrow"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="hasMiddlewares" class="col-12 col-md-3 q-mb-lg path-block">
|
||||
<div
|
||||
v-if="hasMiddlewares"
|
||||
class="col-12 col-md-3 q-mb-lg path-block"
|
||||
>
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-layers"></q-icon>
|
||||
<div class="app-title-label">{{ middlewareType }}</div>
|
||||
<q-icon name="eva-layers" />
|
||||
<div class="app-title-label">
|
||||
{{ middlewareType }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-start q-col-gutter-lg">
|
||||
<div class="col-12 col-md-8">
|
||||
<div class="row items-start q-col-gutter-md">
|
||||
<div v-for="(middleware, index) in middlewares" :key="index" class="col-12">
|
||||
<panel-entry type="detail" name="Middleware" :address="middleware.type"/>
|
||||
<div
|
||||
v-for="(middleware, index) in middlewares"
|
||||
:key="index"
|
||||
class="col-12"
|
||||
>
|
||||
<panel-entry
|
||||
type="detail"
|
||||
name="Middleware"
|
||||
:address="middleware.type"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-4 xs-hide sm-hide">
|
||||
<q-icon name="eva-arrow-forward-outline" class="arrow"></q-icon>
|
||||
<q-icon
|
||||
name="eva-arrow-forward-outline"
|
||||
class="arrow"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="routerByName.item.service"
|
||||
class="service col-12 col-md-3 q-mb-lg path-block"
|
||||
@click="$router.push({ path: `/${protocol}/services/${getServiceId(routerByName.item)}`})">
|
||||
<div
|
||||
v-if="routerByName.item.service"
|
||||
class="service col-12 col-md-3 q-mb-lg path-block"
|
||||
@click="$router.push({ path: `/${protocol}/services/${getServiceId(routerByName.item)}`})"
|
||||
>
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-flash"></q-icon>
|
||||
<div class="app-title-label">Service</div>
|
||||
<q-icon name="eva-flash" />
|
||||
<div class="app-title-label">
|
||||
Service
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-start q-col-gutter-lg">
|
||||
<div class="col-12 col-md-8">
|
||||
<div class="row items-start q-col-gutter-md">
|
||||
<div class="col-12">
|
||||
<panel-entry type="detail" name="Service" :address="routerByName.item.service"/>
|
||||
<panel-entry
|
||||
type="detail"
|
||||
name="Service"
|
||||
:address="routerByName.item.service"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-else class="row items-start">
|
||||
<div
|
||||
v-else
|
||||
class="row items-start"
|
||||
>
|
||||
<div class="col-12">
|
||||
<p v-for="n in 4" :key="n" class="flex">
|
||||
<SkeletonBox :min-width="15" :max-width="15" style="margin-right: 2%"/> <SkeletonBox :min-width="50" :max-width="83"/>
|
||||
<p
|
||||
v-for="n in 4"
|
||||
:key="n"
|
||||
class="flex"
|
||||
>
|
||||
<SkeletonBox
|
||||
:min-width="15"
|
||||
:max-width="15"
|
||||
style="margin-right: 2%"
|
||||
/> <SkeletonBox
|
||||
:min-width="50"
|
||||
:max-width="83"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -93,82 +161,117 @@
|
|||
|
||||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-xl q-pb-xl">
|
||||
<div v-if="!loading" class="row items-start q-col-gutter-md">
|
||||
|
||||
<div v-if="routerByName.item" class="col-12 col-md-4 q-mb-lg path-block">
|
||||
<div
|
||||
v-if="!loading"
|
||||
class="row items-start q-col-gutter-md"
|
||||
>
|
||||
<div
|
||||
v-if="routerByName.item"
|
||||
class="col-12 col-md-4 q-mb-lg path-block"
|
||||
>
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-info"></q-icon>
|
||||
<div class="app-title-label">Router Details</div>
|
||||
<q-icon name="eva-info" />
|
||||
<div class="app-title-label">
|
||||
Router Details
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-start q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
<div class="row items-start q-col-gutter-md">
|
||||
<div class="col-12">
|
||||
<panel-router-details :data="routerByName.item" :protocol="protocol"/>
|
||||
<panel-router-details
|
||||
:data="routerByName.item"
|
||||
:protocol="protocol"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-4 q-mb-lg path-block" v-if="protocol !== 'udp'">
|
||||
<div
|
||||
v-if="protocol !== 'udp'"
|
||||
class="col-12 col-md-4 q-mb-lg path-block"
|
||||
>
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-shield"></q-icon>
|
||||
<div class="app-title-label">TLS</div>
|
||||
<q-icon name="eva-shield" />
|
||||
<div class="app-title-label">
|
||||
TLS
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-start q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
<div class="row items-start q-col-gutter-md">
|
||||
<div class="col-12">
|
||||
<panel-t-l-s :data="routerByName.item.tls" :protocol="protocol"/>
|
||||
<panel-t-l-s
|
||||
:data="routerByName.item.tls"
|
||||
:protocol="protocol"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-md-4 q-mb-lg path-block" v-if="protocol !== 'udp'">
|
||||
<div
|
||||
v-if="protocol !== 'udp'"
|
||||
class="col-12 col-md-4 q-mb-lg path-block"
|
||||
>
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-layers"></q-icon>
|
||||
<div class="app-title-label">Middlewares</div>
|
||||
<q-icon name="eva-layers" />
|
||||
<div class="app-title-label">
|
||||
Middlewares
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-start q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
<div class="row items-start q-col-gutter-md">
|
||||
<div class="col-12">
|
||||
<panel-middlewares :data="middlewares"/>
|
||||
<panel-middlewares :data="middlewares" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-else class="row items-start">
|
||||
<div
|
||||
v-else
|
||||
class="row items-start"
|
||||
>
|
||||
<div class="col-12">
|
||||
<p v-for="n in 4" :key="n" class="flex">
|
||||
<SkeletonBox :min-width="15" :max-width="15" style="margin-right: 2%"/> <SkeletonBox :min-width="50" :max-width="83"/>
|
||||
<p
|
||||
v-for="n in 4"
|
||||
:key="n"
|
||||
class="flex"
|
||||
>
|
||||
<SkeletonBox
|
||||
:min-width="15"
|
||||
:max-width="15"
|
||||
style="margin-right: 2%"
|
||||
/> <SkeletonBox
|
||||
:min-width="50"
|
||||
:max-width="83"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</page-default>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import PageDefault from '../../components/_commons/PageDefault'
|
||||
import SkeletonBox from '../../components/_commons/SkeletonBox'
|
||||
import PanelEntry from '../../components/dashboard/PanelEntry'
|
||||
import PanelRouterDetails from '../../components/_commons/PanelRouterDetails'
|
||||
import PanelTLS from '../../components/_commons/PanelTLS'
|
||||
import PanelMiddlewares from '../../components/_commons/PanelMiddlewares'
|
||||
import PageDefault from '../../components/_commons/PageDefault.vue'
|
||||
import SkeletonBox from '../../components/_commons/SkeletonBox.vue'
|
||||
import PanelEntry from '../../components/dashboard/PanelEntry.vue'
|
||||
import PanelRouterDetails from '../../components/_commons/PanelRouterDetails.vue'
|
||||
import PanelTLS from '../../components/_commons/PanelTLS.vue'
|
||||
import PanelMiddlewares from '../../components/_commons/PanelMiddlewares.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PageRouterDetail',
|
||||
props: ['name', 'type'],
|
||||
components: {
|
||||
PageDefault,
|
||||
SkeletonBox,
|
||||
|
@ -177,6 +280,10 @@ export default {
|
|||
PanelTLS,
|
||||
PanelMiddlewares
|
||||
},
|
||||
props: {
|
||||
name: String,
|
||||
type: String
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
loading: true,
|
||||
|
@ -214,6 +321,15 @@ export default {
|
|||
return this[`${this.protocol}_getMiddlewareByName`]
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.refreshAll()
|
||||
},
|
||||
beforeUnmount () {
|
||||
clearInterval(this.timeOutGetAll)
|
||||
this.$store.commit('http/getRouterByNameClear')
|
||||
this.$store.commit('tcp/getRouterByNameClear')
|
||||
this.$store.commit('udp/getRouterByNameClear')
|
||||
},
|
||||
methods: {
|
||||
...mapActions('http', { http_getRouterByName: 'getRouterByName', http_getMiddlewareByName: 'getMiddlewareByName' }),
|
||||
...mapActions('tcp', { tcp_getRouterByName: 'getRouterByName', tcp_getMiddlewareByName: 'getMiddlewareByName' }),
|
||||
|
@ -235,7 +351,7 @@ export default {
|
|||
// Get entryPoints
|
||||
if (body.using) {
|
||||
for (const entryPoint in body.using) {
|
||||
if (body.using.hasOwnProperty(entryPoint)) {
|
||||
if (Object.getOwnPropertyDescriptor(body.using, entryPoint)) {
|
||||
this.getEntrypointsByName(body.using[entryPoint])
|
||||
.then(body => {
|
||||
if (body) {
|
||||
|
@ -251,7 +367,7 @@ export default {
|
|||
// Get middlewares
|
||||
if (body.middlewares) {
|
||||
for (const middleware in body.middlewares) {
|
||||
if (body.middlewares.hasOwnProperty(middleware)) {
|
||||
if (Object.getOwnPropertyDescriptor(body.middlewares, middleware)) {
|
||||
this.getMiddlewareByName(body.middlewares[middleware])
|
||||
.then(body => {
|
||||
if (body) {
|
||||
|
@ -281,20 +397,8 @@ export default {
|
|||
|
||||
return `${encodeURIComponent(data.service)}@${data.provider}`
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.refreshAll()
|
||||
},
|
||||
mounted () {
|
||||
|
||||
},
|
||||
beforeDestroy () {
|
||||
clearInterval(this.timeOutGetAll)
|
||||
this.$store.commit('http/getRouterByNameClear')
|
||||
this.$store.commit('tcp/getRouterByNameClear')
|
||||
this.$store.commit('udp/getRouterByNameClear')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,148 +1,217 @@
|
|||
<template>
|
||||
<page-default>
|
||||
|
||||
<section v-if="!loading" class="app-section">
|
||||
<section
|
||||
v-if="!loading"
|
||||
class="app-section"
|
||||
>
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-xl q-pb-lg">
|
||||
<div v-if="serviceByName.item" class="row no-wrap items-center app-title">
|
||||
<div class="app-title-label" style="font-size: 26px">{{ serviceByName.item.name }}</div>
|
||||
<div
|
||||
v-if="serviceByName.item"
|
||||
class="row no-wrap items-center app-title"
|
||||
>
|
||||
<div
|
||||
class="app-title-label"
|
||||
style="font-size: 26px"
|
||||
>
|
||||
{{ serviceByName.item.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-lg q-pb-lg">
|
||||
<div v-if="!loading" class="row items-start q-col-gutter-md">
|
||||
|
||||
<div v-if="serviceByName.item" class="col-12 col-md-4 q-mb-lg path-block">
|
||||
<div
|
||||
v-if="!loading"
|
||||
class="row items-start q-col-gutter-md"
|
||||
>
|
||||
<div
|
||||
v-if="serviceByName.item"
|
||||
class="col-12 col-md-4 q-mb-lg path-block"
|
||||
>
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-info"></q-icon>
|
||||
<div class="app-title-label">Service Details</div>
|
||||
<q-icon name="eva-info" />
|
||||
<div class="app-title-label">
|
||||
Service Details
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-start q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
<div class="row items-start q-col-gutter-md">
|
||||
<div class="col-12">
|
||||
<panel-service-details dense :data="serviceByName.item" />
|
||||
<panel-service-details
|
||||
dense
|
||||
:data="serviceByName.item"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="serviceByName.item.loadBalancer && serviceByName.item.loadBalancer.healthCheck" class="col-12 col-md-4 q-mb-lg path-block">
|
||||
<div
|
||||
v-if="serviceByName.item.loadBalancer && serviceByName.item.loadBalancer.healthCheck"
|
||||
class="col-12 col-md-4 q-mb-lg path-block"
|
||||
>
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-shield"></q-icon>
|
||||
<div class="app-title-label">Health Check</div>
|
||||
<q-icon name="eva-shield" />
|
||||
<div class="app-title-label">
|
||||
Health Check
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-start q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
<div class="row items-start q-col-gutter-md">
|
||||
<div class="col-12">
|
||||
<panel-health-check dense :data="serviceByName.item.loadBalancer.healthCheck"/>
|
||||
<panel-health-check
|
||||
dense
|
||||
:data="serviceByName.item.loadBalancer.healthCheck"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="serviceByName.item.loadBalancer" class="col-12 col-md-4 q-mb-lg path-block">
|
||||
<div
|
||||
v-if="serviceByName.item.loadBalancer"
|
||||
class="col-12 col-md-4 q-mb-lg path-block"
|
||||
>
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-globe-outline"></q-icon>
|
||||
<div class="app-title-label">Servers</div>
|
||||
<q-icon name="eva-globe-outline" />
|
||||
<div class="app-title-label">
|
||||
Servers
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-start q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
<div class="row items-start q-col-gutter-md">
|
||||
<div class="col-12">
|
||||
<panel-servers dense :data="serviceByName.item" :hasStatus="serviceByName.item.serverStatus"/>
|
||||
<panel-servers
|
||||
dense
|
||||
:data="serviceByName.item"
|
||||
:has-status="serviceByName.item.serverStatus"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="serviceByName.item.weighted && serviceByName.item.weighted.services" class="col-12 col-md-4 q-mb-lg path-block">
|
||||
<div
|
||||
v-if="serviceByName.item.weighted && serviceByName.item.weighted.services"
|
||||
class="col-12 col-md-4 q-mb-lg path-block"
|
||||
>
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-globe-outline"></q-icon>
|
||||
<div class="app-title-label">Services</div>
|
||||
<q-icon name="eva-globe-outline" />
|
||||
<div class="app-title-label">
|
||||
Services
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-start q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
<div class="row items-start q-col-gutter-md">
|
||||
<div class="col-12">
|
||||
<panel-weighted-services dense :data="serviceByName.item"/>
|
||||
<panel-weighted-services
|
||||
dense
|
||||
:data="serviceByName.item"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="serviceByName.item.mirroring && serviceByName.item.mirroring.mirrors" class="col-12 col-md-4 q-mb-lg path-block">
|
||||
<div
|
||||
v-if="serviceByName.item.mirroring && serviceByName.item.mirroring.mirrors"
|
||||
class="col-12 col-md-4 q-mb-lg path-block"
|
||||
>
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-globe-outline"></q-icon>
|
||||
<div class="app-title-label">Mirror Services</div>
|
||||
<q-icon name="eva-globe-outline" />
|
||||
<div class="app-title-label">
|
||||
Mirror Services
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-start q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
<div class="row items-start q-col-gutter-md">
|
||||
<div class="col-12">
|
||||
<panel-mirroring-services dense :data="serviceByName.item"/>
|
||||
<panel-mirroring-services
|
||||
dense
|
||||
:data="serviceByName.item"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-else class="row items-start q-mt-xl">
|
||||
<div
|
||||
v-else
|
||||
class="row items-start q-mt-xl"
|
||||
>
|
||||
<div class="col-12">
|
||||
<p v-for="n in 4" :key="n" class="flex">
|
||||
<SkeletonBox :min-width="15" :max-width="15" style="margin-right: 2%"/> <SkeletonBox :min-width="50" :max-width="83"/>
|
||||
<p
|
||||
v-for="n in 4"
|
||||
:key="n"
|
||||
class="flex"
|
||||
>
|
||||
<SkeletonBox
|
||||
:min-width="15"
|
||||
:max-width="15"
|
||||
style="margin-right: 2%"
|
||||
/> <SkeletonBox
|
||||
:min-width="50"
|
||||
:max-width="83"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section v-if="!loading && allRouters.length" class="app-section">
|
||||
<section
|
||||
v-if="!loading && allRouters.length"
|
||||
class="app-section"
|
||||
>
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-lg q-pb-xl">
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<div class="app-title-label">Used by Routers</div>
|
||||
<div class="app-title-label">
|
||||
Used by Routers
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-center q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
<main-table
|
||||
:data="allRouters"
|
||||
v-bind="getTableProps({ type: `${protocol}-routers` })"
|
||||
v-model:pagination="routersPagination"
|
||||
:data="allRouters"
|
||||
:request="()=>{}"
|
||||
:loading="routersLoading"
|
||||
:pagination.sync="routersPagination"
|
||||
:filter="routersFilter"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</page-default>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import GetTablePropsMixin from '../../_mixins/GetTableProps'
|
||||
import PageDefault from '../../components/_commons/PageDefault'
|
||||
import SkeletonBox from '../../components/_commons/SkeletonBox'
|
||||
import PanelServiceDetails from '../../components/_commons/PanelServiceDetails'
|
||||
import PanelHealthCheck from '../../components/_commons/PanelHealthCheck'
|
||||
import PanelServers from '../../components/_commons/PanelServers'
|
||||
import MainTable from '../../components/_commons/MainTable'
|
||||
import PanelWeightedServices from '../../components/_commons/PanelWeightedServices'
|
||||
import PanelMirroringServices from '../../components/_commons/PanelMirroringServices'
|
||||
import PageDefault from '../../components/_commons/PageDefault.vue'
|
||||
import SkeletonBox from '../../components/_commons/SkeletonBox.vue'
|
||||
import PanelServiceDetails from '../../components/_commons/PanelServiceDetails.vue'
|
||||
import PanelHealthCheck from '../../components/_commons/PanelHealthCheck.vue'
|
||||
import PanelServers from '../../components/_commons/PanelServers.vue'
|
||||
import MainTable from '../../components/_commons/MainTable.vue'
|
||||
import PanelWeightedServices from '../../components/_commons/PanelWeightedServices.vue'
|
||||
import PanelMirroringServices from '../../components/_commons/PanelMirroringServices.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PageServiceDetail',
|
||||
props: ['name', 'type'],
|
||||
mixins: [GetTablePropsMixin],
|
||||
components: {
|
||||
PanelMirroringServices,
|
||||
PanelWeightedServices,
|
||||
|
@ -153,6 +222,11 @@ export default {
|
|||
PanelServers,
|
||||
MainTable
|
||||
},
|
||||
mixins: [GetTablePropsMixin],
|
||||
props: {
|
||||
name: String,
|
||||
type: String
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
loading: true,
|
||||
|
@ -187,6 +261,15 @@ export default {
|
|||
return this[`${this.protocol}_getRouterByName`]
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.refreshAll()
|
||||
},
|
||||
beforeUnmount () {
|
||||
clearInterval(this.timeOutGetAll)
|
||||
this.$store.commit('http/getServiceByNameClear')
|
||||
this.$store.commit('tcp/getServiceByNameClear')
|
||||
this.$store.commit('udp/getServiceByNameClear')
|
||||
},
|
||||
methods: {
|
||||
...mapActions('http', { http_getServiceByName: 'getServiceByName', http_getRouterByName: 'getRouterByName' }),
|
||||
...mapActions('tcp', { tcp_getServiceByName: 'getServiceByName', tcp_getRouterByName: 'getRouterByName' }),
|
||||
|
@ -207,7 +290,7 @@ export default {
|
|||
// Get routers
|
||||
if (body.usedBy) {
|
||||
for (const router in body.usedBy) {
|
||||
if (body.usedBy.hasOwnProperty(router)) {
|
||||
if (Object.getOwnPropertyDescriptor(body.usedBy, router)) {
|
||||
this.getRouterByName(body.usedBy[router])
|
||||
.then(body => {
|
||||
if (body) {
|
||||
|
@ -230,20 +313,8 @@ export default {
|
|||
console.log('Error -> service/byName', error)
|
||||
})
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.refreshAll()
|
||||
},
|
||||
mounted () {
|
||||
|
||||
},
|
||||
beforeDestroy () {
|
||||
clearInterval(this.timeOutGetAll)
|
||||
this.$store.commit('http/getServiceByNameClear')
|
||||
this.$store.commit('tcp/getServiceByNameClear')
|
||||
this.$store.commit('udp/getServiceByNameClear')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -3,20 +3,44 @@
|
|||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-xl q-pb-lg">
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-log-in-outline"></q-icon>
|
||||
<div class="app-title-label">Entrypoints</div>
|
||||
</div>
|
||||
<div v-if="!loadingEntryGetAll" class="row items-center q-col-gutter-lg">
|
||||
<div
|
||||
v-for="(entryItems, index) in entryAll.items" :key="index"
|
||||
class="col-12 col-sm-6 col-md-2">
|
||||
<panel-entry :name="entryItems.name" :address="entryItems.address"/>
|
||||
<q-icon name="eva-log-in-outline" />
|
||||
<div class="app-title-label">
|
||||
Entrypoints
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="row items-center q-col-gutter-lg">
|
||||
<div
|
||||
v-if="!loadingEntryGetAll"
|
||||
class="row items-center q-col-gutter-lg"
|
||||
>
|
||||
<div
|
||||
v-for="(entryItems, index) in entryAll.items"
|
||||
:key="index"
|
||||
class="col-12 col-sm-6 col-md-2"
|
||||
>
|
||||
<panel-entry
|
||||
:name="entryItems.name"
|
||||
:address="entryItems.address"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="row items-center q-col-gutter-lg"
|
||||
>
|
||||
<div class="col-12 col-sm-6 col-md-2">
|
||||
<p v-for="n in 3" :key="n" class="flex">
|
||||
<SkeletonBox :min-width="15" :max-width="15" style="margin-right: 2%"/> <SkeletonBox :min-width="50" :max-width="83"/>
|
||||
<p
|
||||
v-for="n in 3"
|
||||
:key="n"
|
||||
class="flex"
|
||||
>
|
||||
<SkeletonBox
|
||||
:min-width="15"
|
||||
:max-width="15"
|
||||
style="margin-right: 2%"
|
||||
/> <SkeletonBox
|
||||
:min-width="50"
|
||||
:max-width="83"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -26,20 +50,45 @@
|
|||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-lg q-pb-lg">
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-globe-outline"></q-icon>
|
||||
<div class="app-title-label">HTTP</div>
|
||||
</div>
|
||||
<div v-if="!loadingOverview" class="row items-center q-col-gutter-lg">
|
||||
<div
|
||||
v-for="(overviewHTTP, index) in allHTTP" :key="index"
|
||||
class="col-12 col-sm-6 col-md-4">
|
||||
<panel-chart :name="index" :data="overviewHTTP" type="http"/>
|
||||
<q-icon name="eva-globe-outline" />
|
||||
<div class="app-title-label">
|
||||
HTTP
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="row items-center q-col-gutter-lg">
|
||||
<div
|
||||
v-if="!loadingOverview"
|
||||
class="row items-center q-col-gutter-lg"
|
||||
>
|
||||
<div
|
||||
v-for="(overviewHTTP, index) in allHTTP"
|
||||
:key="index"
|
||||
class="col-12 col-sm-6 col-md-4"
|
||||
>
|
||||
<panel-chart
|
||||
:name="index"
|
||||
:data="overviewHTTP"
|
||||
type="http"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="row items-center q-col-gutter-lg"
|
||||
>
|
||||
<div class="col-12 col-sm-6 col-md-4">
|
||||
<p v-for="n in 6" :key="n" class="flex">
|
||||
<SkeletonBox :min-width="15" :max-width="15" style="margin-right: 2%"/> <SkeletonBox :min-width="50" :max-width="83"/>
|
||||
<p
|
||||
v-for="n in 6"
|
||||
:key="n"
|
||||
class="flex"
|
||||
>
|
||||
<SkeletonBox
|
||||
:min-width="15"
|
||||
:max-width="15"
|
||||
style="margin-right: 2%"
|
||||
/> <SkeletonBox
|
||||
:min-width="50"
|
||||
:max-width="83"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -49,20 +98,45 @@
|
|||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-lg q-pb-lg">
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-globe-3"></q-icon>
|
||||
<div class="app-title-label">TCP</div>
|
||||
</div>
|
||||
<div v-if="!loadingOverview" class="row items-center q-col-gutter-lg">
|
||||
<div
|
||||
v-for="(overviewTCP, index) in allTCP" :key="index"
|
||||
class="col-12 col-sm-6 col-md-4">
|
||||
<panel-chart :name="index" :data="overviewTCP" type="tcp"/>
|
||||
<q-icon name="eva-globe-3" />
|
||||
<div class="app-title-label">
|
||||
TCP
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="row items-center q-col-gutter-lg">
|
||||
<div
|
||||
v-if="!loadingOverview"
|
||||
class="row items-center q-col-gutter-lg"
|
||||
>
|
||||
<div
|
||||
v-for="(overviewTCP, index) in allTCP"
|
||||
:key="index"
|
||||
class="col-12 col-sm-6 col-md-4"
|
||||
>
|
||||
<panel-chart
|
||||
:name="index"
|
||||
:data="overviewTCP"
|
||||
type="tcp"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="row items-center q-col-gutter-lg"
|
||||
>
|
||||
<div class="col-12 col-sm-6 col-md-4">
|
||||
<p v-for="n in 6" :key="n" class="flex">
|
||||
<SkeletonBox :min-width="15" :max-width="15" style="margin-right: 2%"/> <SkeletonBox :min-width="50" :max-width="83"/>
|
||||
<p
|
||||
v-for="n in 6"
|
||||
:key="n"
|
||||
class="flex"
|
||||
>
|
||||
<SkeletonBox
|
||||
:min-width="15"
|
||||
:max-width="15"
|
||||
style="margin-right: 2%"
|
||||
/> <SkeletonBox
|
||||
:min-width="50"
|
||||
:max-width="83"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -72,20 +146,45 @@
|
|||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-lg q-pb-lg">
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-globe-3"></q-icon>
|
||||
<div class="app-title-label">UDP</div>
|
||||
</div>
|
||||
<div v-if="!loadingOverview" class="row items-center q-col-gutter-lg">
|
||||
<div
|
||||
v-for="(overviewUDP, index) in allUDP" :key="index"
|
||||
class="col-12 col-sm-6 col-md-4">
|
||||
<panel-chart :name="index" :data="overviewUDP" type="udp"/>
|
||||
<q-icon name="eva-globe-3" />
|
||||
<div class="app-title-label">
|
||||
UDP
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="row items-center q-col-gutter-lg">
|
||||
<div
|
||||
v-if="!loadingOverview"
|
||||
class="row items-center q-col-gutter-lg"
|
||||
>
|
||||
<div
|
||||
v-for="(overviewUDP, index) in allUDP"
|
||||
:key="index"
|
||||
class="col-12 col-sm-6 col-md-4"
|
||||
>
|
||||
<panel-chart
|
||||
:name="index"
|
||||
:data="overviewUDP"
|
||||
type="udp"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="row items-center q-col-gutter-lg"
|
||||
>
|
||||
<div class="col-12 col-sm-6 col-md-4">
|
||||
<p v-for="n in 6" :key="n" class="flex">
|
||||
<SkeletonBox :min-width="15" :max-width="15" style="margin-right: 2%"/> <SkeletonBox :min-width="50" :max-width="83"/>
|
||||
<p
|
||||
v-for="n in 6"
|
||||
:key="n"
|
||||
class="flex"
|
||||
>
|
||||
<SkeletonBox
|
||||
:min-width="15"
|
||||
:max-width="15"
|
||||
style="margin-right: 2%"
|
||||
/> <SkeletonBox
|
||||
:min-width="50"
|
||||
:max-width="83"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -95,20 +194,44 @@
|
|||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-lg q-pb-lg">
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-toggle-right"></q-icon>
|
||||
<div class="app-title-label">Features</div>
|
||||
</div>
|
||||
<div v-if="!loadingOverview" class="row items-center q-col-gutter-lg">
|
||||
<div
|
||||
v-for="(overviewFeature, index) in allFeatures" :key="index"
|
||||
class="col-12 col-sm-6 col-md-2">
|
||||
<panel-feature :feature-key="index" :feature-val="overviewFeature"/>
|
||||
<q-icon name="eva-toggle-right" />
|
||||
<div class="app-title-label">
|
||||
Features
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="row items-center q-col-gutter-lg">
|
||||
<div
|
||||
v-if="!loadingOverview"
|
||||
class="row items-center q-col-gutter-lg"
|
||||
>
|
||||
<div
|
||||
v-for="(overviewFeature, index) in allFeatures"
|
||||
:key="index"
|
||||
class="col-12 col-sm-6 col-md-2"
|
||||
>
|
||||
<panel-feature
|
||||
:feature-key="index"
|
||||
:feature-val="overviewFeature"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="row items-center q-col-gutter-lg"
|
||||
>
|
||||
<div class="col-12 col-sm-6 col-md-2">
|
||||
<p v-for="n in 3" :key="n" class="flex">
|
||||
<SkeletonBox :min-width="15" :max-width="15" style="margin-right: 2%"/> <SkeletonBox :min-width="50" :max-width="83"/>
|
||||
<p
|
||||
v-for="n in 3"
|
||||
:key="n"
|
||||
class="flex"
|
||||
>
|
||||
<SkeletonBox
|
||||
:min-width="15"
|
||||
:max-width="15"
|
||||
style="margin-right: 2%"
|
||||
/> <SkeletonBox
|
||||
:min-width="50"
|
||||
:max-width="83"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -118,39 +241,60 @@
|
|||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-lg q-pb-xl">
|
||||
<div class="row no-wrap items-center q-mb-lg app-title">
|
||||
<q-icon name="eva-cube"></q-icon>
|
||||
<div class="app-title-label">Providers</div>
|
||||
</div>
|
||||
<div v-if="!loadingOverview" class="row items-center q-col-gutter-lg">
|
||||
<div
|
||||
v-for="(overviewProvider, index) in allProviders" :key="index"
|
||||
class="col-12 col-sm-6 col-md-2">
|
||||
<panel-provider :name="overviewProvider"/>
|
||||
<q-icon name="eva-cube" />
|
||||
<div class="app-title-label">
|
||||
Providers
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="row items-center q-col-gutter-lg">
|
||||
<div
|
||||
v-if="!loadingOverview"
|
||||
class="row items-center q-col-gutter-lg"
|
||||
>
|
||||
<div
|
||||
v-for="(overviewProvider, index) in allProviders"
|
||||
:key="index"
|
||||
class="col-12 col-sm-6 col-md-2"
|
||||
>
|
||||
<panel-provider :name="overviewProvider" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="row items-center q-col-gutter-lg"
|
||||
>
|
||||
<div class="col-12 col-sm-6 col-md-2">
|
||||
<p v-for="n in 3" :key="n" class="flex">
|
||||
<SkeletonBox :min-width="15" :max-width="15" style="margin-right: 2%"/> <SkeletonBox :min-width="50" :max-width="83"/>
|
||||
<p
|
||||
v-for="n in 3"
|
||||
:key="n"
|
||||
class="flex"
|
||||
>
|
||||
<SkeletonBox
|
||||
:min-width="15"
|
||||
:max-width="15"
|
||||
style="margin-right: 2%"
|
||||
/> <SkeletonBox
|
||||
:min-width="50"
|
||||
:max-width="83"
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</page-default>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import PageDefault from '../../components/_commons/PageDefault'
|
||||
import SkeletonBox from '../../components/_commons/SkeletonBox'
|
||||
import PanelEntry from '../../components/dashboard/PanelEntry'
|
||||
import PanelChart from '../../components/dashboard/PanelChart'
|
||||
import PanelFeature from '../../components/dashboard/PanelFeature'
|
||||
import PanelProvider from '../../components/dashboard/PanelProvider'
|
||||
import PageDefault from '../../components/_commons/PageDefault.vue'
|
||||
import SkeletonBox from '../../components/_commons/SkeletonBox.vue'
|
||||
import PanelEntry from '../../components/dashboard/PanelEntry.vue'
|
||||
import PanelChart from '../../components/dashboard/PanelChart.vue'
|
||||
import PanelFeature from '../../components/dashboard/PanelFeature.vue'
|
||||
import PanelProvider from '../../components/dashboard/PanelProvider.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PageDashboardIndex',
|
||||
components: {
|
||||
PageDefault,
|
||||
|
@ -189,6 +333,17 @@ export default {
|
|||
return this.overviewAll.items.providers
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.fetchAll()
|
||||
this.intervalRefresh = setInterval(this.fetchOverview, this.intervalRefreshTime)
|
||||
},
|
||||
beforeUnmount () {
|
||||
clearInterval(this.intervalRefresh)
|
||||
clearTimeout(this.timeOutEntryGetAll)
|
||||
clearTimeout(this.timeOutOverviewAll)
|
||||
this.$store.commit('entrypoints/getAllClear')
|
||||
this.$store.commit('core/getOverviewClear')
|
||||
},
|
||||
methods: {
|
||||
...mapActions('entrypoints', { entryGetAll: 'getAll' }),
|
||||
...mapActions('core', { getOverview: 'getOverview' }),
|
||||
|
@ -222,19 +377,8 @@ export default {
|
|||
this.fetchEntries()
|
||||
this.fetchOverview()
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.fetchAll()
|
||||
this.intervalRefresh = setInterval(this.fetchOverview, this.intervalRefreshTime)
|
||||
},
|
||||
beforeDestroy () {
|
||||
clearInterval(this.intervalRefresh)
|
||||
clearTimeout(this.timeOutEntryGetAll)
|
||||
clearTimeout(this.timeOutOverviewAll)
|
||||
this.$store.commit('entrypoints/getAllClear')
|
||||
this.$store.commit('core/getOverviewClear')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<template>
|
||||
<page-default>
|
||||
|
||||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-xl q-pb-xl">
|
||||
<div class="row no-wrap items-center q-mb-lg">
|
||||
<tool-bar-table :status.sync="status" :filter.sync="filter"/>
|
||||
<tool-bar-table
|
||||
v-model:status="status"
|
||||
v-model:filter="filter"
|
||||
/>
|
||||
</div>
|
||||
<div class="row items-center q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
|
@ -12,28 +14,33 @@
|
|||
ref="mainTable"
|
||||
v-bind="getTableProps({ type: 'http-middlewares' })"
|
||||
:data="allMiddlewares.items"
|
||||
:onLoadMore="handleLoadMore"
|
||||
:endReached="allMiddlewares.endReached"
|
||||
:on-load-more="handleLoadMore"
|
||||
:end-reached="allMiddlewares.endReached"
|
||||
:loading="allMiddlewares.loading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</page-default>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import GetTablePropsMixin from '../../_mixins/GetTableProps'
|
||||
import PaginationMixin from '../../_mixins/Pagination'
|
||||
import PageDefault from '../../components/_commons/PageDefault'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable'
|
||||
import MainTable from '../../components/_commons/MainTable'
|
||||
import PageDefault from '../../components/_commons/PageDefault.vue'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable.vue'
|
||||
import MainTable from '../../components/_commons/MainTable.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PageHTTPMiddlewares',
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
mixins: [
|
||||
GetTablePropsMixin,
|
||||
PaginationMixin({
|
||||
|
@ -42,11 +49,6 @@ export default {
|
|||
pollingIntervalTime: 5000
|
||||
})
|
||||
],
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
filter: '',
|
||||
|
@ -56,6 +58,17 @@ export default {
|
|||
computed: {
|
||||
...mapGetters('http', { allMiddlewares: 'allMiddlewares' })
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeUnmount () {
|
||||
this.$store.commit('http/getAllMiddlewaresClear')
|
||||
},
|
||||
methods: {
|
||||
...mapActions('http', { getAllMiddlewares: 'getAllMiddlewares' }),
|
||||
getAllMiddlewaresWithParams (params) {
|
||||
|
@ -75,19 +88,8 @@ export default {
|
|||
handleLoadMore ({ page = 1 } = {}) {
|
||||
return this.fetchMore({ page })
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.$store.commit('http/getAllMiddlewaresClear')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<template>
|
||||
<page-default>
|
||||
|
||||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-xl q-pb-xl">
|
||||
<div class="row no-wrap items-center q-mb-lg">
|
||||
<tool-bar-table :status.sync="status" :filter.sync="filter"/>
|
||||
<tool-bar-table
|
||||
v-model:status="status"
|
||||
v-model:filter="filter"
|
||||
/>
|
||||
</div>
|
||||
<div class="row items-center q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
|
@ -12,28 +14,33 @@
|
|||
ref="mainTable"
|
||||
v-bind="getTableProps({ type: 'http-routers' })"
|
||||
:data="allRouters.items"
|
||||
:onLoadMore="handleLoadMore"
|
||||
:endReached="allRouters.endReached"
|
||||
:on-load-more="handleLoadMore"
|
||||
:end-reached="allRouters.endReached"
|
||||
:loading="allRouters.loading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</page-default>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import GetTablePropsMixin from '../../_mixins/GetTableProps'
|
||||
import PaginationMixin from '../../_mixins/Pagination'
|
||||
import PageDefault from '../../components/_commons/PageDefault'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable'
|
||||
import MainTable from '../../components/_commons/MainTable'
|
||||
import PageDefault from '../../components/_commons/PageDefault.vue'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable.vue'
|
||||
import MainTable from '../../components/_commons/MainTable.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PageHTTPRouters',
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
mixins: [
|
||||
GetTablePropsMixin,
|
||||
PaginationMixin({
|
||||
|
@ -42,11 +49,6 @@ export default {
|
|||
pollingIntervalTime: 5000
|
||||
})
|
||||
],
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
filter: '',
|
||||
|
@ -56,6 +58,17 @@ export default {
|
|||
computed: {
|
||||
...mapGetters('http', { allRouters: 'allRouters' })
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeUnmount () {
|
||||
this.$store.commit('http/getAllRoutersClear')
|
||||
},
|
||||
methods: {
|
||||
...mapActions('http', { getAllRouters: 'getAllRouters' }),
|
||||
getAllRoutersWithParams (params) {
|
||||
|
@ -75,19 +88,8 @@ export default {
|
|||
handleLoadMore ({ page = 1 } = {}) {
|
||||
return this.fetchMore({ page })
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.$store.commit('http/getAllRoutersClear')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<template>
|
||||
<page-default>
|
||||
|
||||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-xl q-pb-xl">
|
||||
<div class="row no-wrap items-center q-mb-lg">
|
||||
<tool-bar-table :status.sync="status" :filter.sync="filter"/>
|
||||
<tool-bar-table
|
||||
v-model:status="status"
|
||||
v-model:filter="filter"
|
||||
/>
|
||||
</div>
|
||||
<div class="row items-center q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
|
@ -12,28 +14,33 @@
|
|||
ref="mainTable"
|
||||
v-bind="getTableProps({ type: 'http-services' })"
|
||||
:data="allServices.items"
|
||||
:onLoadMore="handleLoadMore"
|
||||
:endReached="allServices.endReached"
|
||||
:on-load-more="handleLoadMore"
|
||||
:end-reached="allServices.endReached"
|
||||
:loading="allServices.loading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</page-default>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import GetTablePropsMixin from '../../_mixins/GetTableProps'
|
||||
import PaginationMixin from '../../_mixins/Pagination'
|
||||
import PageDefault from '../../components/_commons/PageDefault'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable'
|
||||
import MainTable from '../../components/_commons/MainTable'
|
||||
import PageDefault from '../../components/_commons/PageDefault.vue'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable.vue'
|
||||
import MainTable from '../../components/_commons/MainTable.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PageHTTPServices',
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
mixins: [
|
||||
GetTablePropsMixin,
|
||||
PaginationMixin({
|
||||
|
@ -42,11 +49,6 @@ export default {
|
|||
pollingIntervalTime: 5000
|
||||
})
|
||||
],
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
filter: '',
|
||||
|
@ -56,6 +58,17 @@ export default {
|
|||
computed: {
|
||||
...mapGetters('http', { allServices: 'allServices' })
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeUnmount () {
|
||||
this.$store.commit('http/getAllServicesClear')
|
||||
},
|
||||
methods: {
|
||||
...mapActions('http', { getAllServices: 'getAllServices' }),
|
||||
getAllServicesWithParams (params) {
|
||||
|
@ -75,19 +88,8 @@ export default {
|
|||
handleLoadMore ({ page = 1 } = {}) {
|
||||
return this.fetchMore({ page })
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.$store.commit('http/getAllServicesClear')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<template>
|
||||
<page-default>
|
||||
|
||||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-xl q-pb-xl">
|
||||
<div class="row no-wrap items-center q-mb-lg">
|
||||
<tool-bar-table :status.sync="status" :filter.sync="filter"/>
|
||||
<tool-bar-table
|
||||
v-model:status="status"
|
||||
v-model:filter="filter"
|
||||
/>
|
||||
</div>
|
||||
<div class="row items-center q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
|
@ -12,28 +14,33 @@
|
|||
ref="mainTable"
|
||||
v-bind="getTableProps({ type: 'tcp-middlewares' })"
|
||||
:data="allMiddlewares.items"
|
||||
:onLoadMore="handleLoadMore"
|
||||
:endReached="allMiddlewares.endReached"
|
||||
:on-load-more="handleLoadMore"
|
||||
:end-reached="allMiddlewares.endReached"
|
||||
:loading="allMiddlewares.loading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</page-default>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import GetTablePropsMixin from '../../_mixins/GetTableProps'
|
||||
import PaginationMixin from '../../_mixins/Pagination'
|
||||
import PageDefault from '../../components/_commons/PageDefault'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable'
|
||||
import MainTable from '../../components/_commons/MainTable'
|
||||
import PageDefault from '../../components/_commons/PageDefault.vue'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable.vue'
|
||||
import MainTable from '../../components/_commons/MainTable.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PageTCPMiddlewares',
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
mixins: [
|
||||
GetTablePropsMixin,
|
||||
PaginationMixin({
|
||||
|
@ -42,11 +49,6 @@ export default {
|
|||
pollingIntervalTime: 5000
|
||||
})
|
||||
],
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
filter: '',
|
||||
|
@ -56,6 +58,17 @@ export default {
|
|||
computed: {
|
||||
...mapGetters('tcp', { allMiddlewares: 'allMiddlewares' })
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeUnmount () {
|
||||
this.$store.commit('tcp/getAllMiddlewaresClear')
|
||||
},
|
||||
methods: {
|
||||
...mapActions('tcp', { getAllMiddlewares: 'getAllMiddlewares' }),
|
||||
getAllMiddlewaresWithParams (params) {
|
||||
|
@ -75,19 +88,8 @@ export default {
|
|||
handleLoadMore ({ page = 1 } = {}) {
|
||||
return this.fetchMore({ page })
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.$store.commit('tcp/getAllMiddlewaresClear')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<template>
|
||||
<page-default>
|
||||
|
||||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-xl q-pb-xl">
|
||||
<div class="row no-wrap items-center q-mb-lg">
|
||||
<tool-bar-table :status.sync="status" :filter.sync="filter"/>
|
||||
<tool-bar-table
|
||||
v-model:status="status"
|
||||
v-model:filter="filter"
|
||||
/>
|
||||
</div>
|
||||
<div class="row items-center q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
|
@ -12,28 +14,33 @@
|
|||
ref="mainTable"
|
||||
v-bind="getTableProps({ type: 'tcp-routers' })"
|
||||
:data="allRouters.items"
|
||||
:onLoadMore="handleLoadMore"
|
||||
:endReached="allRouters.endReached"
|
||||
:on-load-more="handleLoadMore"
|
||||
:end-reached="allRouters.endReached"
|
||||
:loading="allRouters.loading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</page-default>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import GetTablePropsMixin from '../../_mixins/GetTableProps'
|
||||
import PaginationMixin from '../../_mixins/Pagination'
|
||||
import PageDefault from '../../components/_commons/PageDefault'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable'
|
||||
import MainTable from '../../components/_commons/MainTable'
|
||||
import PageDefault from '../../components/_commons/PageDefault.vue'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable.vue'
|
||||
import MainTable from '../../components/_commons/MainTable.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PageTCPRouters',
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
mixins: [
|
||||
GetTablePropsMixin,
|
||||
PaginationMixin({
|
||||
|
@ -42,11 +49,6 @@ export default {
|
|||
pollingIntervalTime: 5000
|
||||
})
|
||||
],
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
filter: '',
|
||||
|
@ -56,6 +58,17 @@ export default {
|
|||
computed: {
|
||||
...mapGetters('tcp', { allRouters: 'allRouters' })
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeUnmount () {
|
||||
this.$store.commit('tcp/getAllRoutersClear')
|
||||
},
|
||||
methods: {
|
||||
...mapActions('tcp', { getAllRouters: 'getAllRouters' }),
|
||||
getAllRoutersWithParams (params) {
|
||||
|
@ -75,19 +88,8 @@ export default {
|
|||
handleLoadMore ({ page = 1 } = {}) {
|
||||
return this.fetchMore({ page })
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.$store.commit('tcp/getAllRoutersClear')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<template>
|
||||
<page-default>
|
||||
|
||||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-xl q-pb-xl">
|
||||
<div class="row no-wrap items-center q-mb-lg">
|
||||
<tool-bar-table :status.sync="status" :filter.sync="filter"/>
|
||||
<tool-bar-table
|
||||
v-model:status="status"
|
||||
v-model:filter="filter"
|
||||
/>
|
||||
</div>
|
||||
<div class="row items-center q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
|
@ -12,15 +14,14 @@
|
|||
ref="mainTable"
|
||||
v-bind="getTableProps({ type: 'tcp-services' })"
|
||||
:data="allServices.items"
|
||||
:onLoadMore="handleLoadMore"
|
||||
:endReached="allServices.endReached"
|
||||
:on-load-more="handleLoadMore"
|
||||
:end-reached="allServices.endReached"
|
||||
:loading="allServices.loading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</page-default>
|
||||
</template>
|
||||
|
||||
|
@ -28,12 +29,17 @@
|
|||
import { mapActions, mapGetters } from 'vuex'
|
||||
import GetTablePropsMixin from '../../_mixins/GetTableProps'
|
||||
import PaginationMixin from '../../_mixins/Pagination'
|
||||
import PageDefault from '../../components/_commons/PageDefault'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable'
|
||||
import MainTable from '../../components/_commons/MainTable'
|
||||
import PageDefault from '../../components/_commons/PageDefault.vue'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable.vue'
|
||||
import MainTable from '../../components/_commons/MainTable.vue'
|
||||
|
||||
export default {
|
||||
name: 'PageTCPServices',
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
mixins: [
|
||||
GetTablePropsMixin,
|
||||
PaginationMixin({
|
||||
|
@ -42,11 +48,6 @@ export default {
|
|||
pollingIntervalTime: 5000
|
||||
})
|
||||
],
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
filter: '',
|
||||
|
@ -56,6 +57,17 @@ export default {
|
|||
computed: {
|
||||
...mapGetters('tcp', { allServices: 'allServices' })
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeUnmount () {
|
||||
this.$store.commit('tcp/getAllServicesClear')
|
||||
},
|
||||
methods: {
|
||||
...mapActions('tcp', { getAllServices: 'getAllServices' }),
|
||||
getAllServicesWithParams (params) {
|
||||
|
@ -75,17 +87,6 @@ export default {
|
|||
handleLoadMore ({ page = 1 } = {}) {
|
||||
return this.fetchMore({ page })
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.$store.commit('tcp/getAllServicesClear')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -3,7 +3,10 @@
|
|||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-xl q-pb-xl">
|
||||
<div class="row no-wrap items-center q-mb-lg">
|
||||
<tool-bar-table :status.sync="status" :filter.sync="filter"/>
|
||||
<tool-bar-table
|
||||
v-model:status="status"
|
||||
v-model:filter="filter"
|
||||
/>
|
||||
</div>
|
||||
<div class="row items-center q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
|
@ -11,28 +14,33 @@
|
|||
ref="mainTable"
|
||||
v-bind="getTableProps({ type: 'udp-routers' })"
|
||||
:data="allRouters.items"
|
||||
:onLoadMore="handleLoadMore"
|
||||
:endReached="allRouters.endReached"
|
||||
:on-load-more="handleLoadMore"
|
||||
:end-reached="allRouters.endReached"
|
||||
:loading="allRouters.loading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</page-default>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import GetTablePropsMixin from '../../_mixins/GetTableProps'
|
||||
import PaginationMixin from '../../_mixins/Pagination'
|
||||
import PageDefault from '../../components/_commons/PageDefault'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable'
|
||||
import MainTable from '../../components/_commons/MainTable'
|
||||
import PageDefault from '../../components/_commons/PageDefault.vue'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable.vue'
|
||||
import MainTable from '../../components/_commons/MainTable.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PageUDPRouters',
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
mixins: [
|
||||
GetTablePropsMixin,
|
||||
PaginationMixin({
|
||||
|
@ -41,11 +49,6 @@ export default {
|
|||
pollingIntervalTime: 5000
|
||||
})
|
||||
],
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
filter: '',
|
||||
|
@ -55,6 +58,17 @@ export default {
|
|||
computed: {
|
||||
...mapGetters('udp', { allRouters: 'allRouters' })
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeUnmount () {
|
||||
this.$store.commit('udp/getAllRoutersClear')
|
||||
},
|
||||
methods: {
|
||||
...mapActions('udp', { getAllRouters: 'getAllRouters' }),
|
||||
getAllRoutersWithParams (params) {
|
||||
|
@ -74,19 +88,8 @@ export default {
|
|||
handleLoadMore ({ page = 1 } = {}) {
|
||||
return this.fetchMore({ page })
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.$store.commit('udp/getAllRoutersClear')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<template>
|
||||
<page-default>
|
||||
|
||||
<section class="app-section">
|
||||
<div class="app-section-wrap app-boxed app-boxed-xl q-pl-md q-pr-md q-pt-xl q-pb-xl">
|
||||
<div class="row no-wrap items-center q-mb-lg">
|
||||
<tool-bar-table :status.sync="status" :filter.sync="filter"/>
|
||||
<tool-bar-table
|
||||
v-model:status="status"
|
||||
v-model:filter="filter"
|
||||
/>
|
||||
</div>
|
||||
<div class="row items-center q-col-gutter-lg">
|
||||
<div class="col-12">
|
||||
|
@ -12,28 +14,33 @@
|
|||
ref="mainTable"
|
||||
v-bind="getTableProps({ type: 'udp-services' })"
|
||||
:data="allServices.items"
|
||||
:onLoadMore="handleLoadMore"
|
||||
:endReached="allServices.endReached"
|
||||
:on-load-more="handleLoadMore"
|
||||
:end-reached="allServices.endReached"
|
||||
:loading="allServices.loading"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</page-default>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent } from 'vue'
|
||||
import { mapActions, mapGetters } from 'vuex'
|
||||
import GetTablePropsMixin from '../../_mixins/GetTableProps'
|
||||
import PaginationMixin from '../../_mixins/Pagination'
|
||||
import PageDefault from '../../components/_commons/PageDefault'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable'
|
||||
import MainTable from '../../components/_commons/MainTable'
|
||||
import PageDefault from '../../components/_commons/PageDefault.vue'
|
||||
import ToolBarTable from '../../components/_commons/ToolBarTable.vue'
|
||||
import MainTable from '../../components/_commons/MainTable.vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'PageUDPServices',
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
mixins: [
|
||||
GetTablePropsMixin,
|
||||
PaginationMixin({
|
||||
|
@ -42,11 +49,6 @@ export default {
|
|||
pollingIntervalTime: 5000
|
||||
})
|
||||
],
|
||||
components: {
|
||||
PageDefault,
|
||||
ToolBarTable,
|
||||
MainTable
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
filter: '',
|
||||
|
@ -56,6 +58,17 @@ export default {
|
|||
computed: {
|
||||
...mapGetters('udp', { allServices: 'allServices' })
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeUnmount () {
|
||||
this.$store.commit('udp/getAllServicesClear')
|
||||
},
|
||||
methods: {
|
||||
...mapActions('udp', { getAllServices: 'getAllServices' }),
|
||||
getAllServicesWithParams (params) {
|
||||
|
@ -75,19 +88,8 @@ export default {
|
|||
handleLoadMore ({ page = 1 } = {}) {
|
||||
return this.fetchMore({ page })
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'status' () {
|
||||
this.refreshAll()
|
||||
},
|
||||
'filter' () {
|
||||
this.refreshAll()
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
this.$store.commit('udp/getAllServicesClear')
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
@ -1,26 +1,18 @@
|
|||
import Vue from 'vue'
|
||||
import VueRouter from 'vue-router'
|
||||
|
||||
import { route } from 'quasar/wrappers'
|
||||
import { createRouter, createMemoryHistory, createWebHistory, createWebHashHistory } from 'vue-router'
|
||||
import routes from './routes'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
export default route(function (/* { store, ssrContext } */) {
|
||||
const createHistory = process.env.SERVER
|
||||
? createMemoryHistory
|
||||
: (process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory)
|
||||
|
||||
/*
|
||||
* If not building with SSR mode, you can
|
||||
* directly export the Router instantiation
|
||||
*/
|
||||
|
||||
export default function (/* { store, ssrContext } */) {
|
||||
const Router = new VueRouter({
|
||||
scrollBehavior: () => ({ x: 0, y: 0 }),
|
||||
const Router = createRouter({
|
||||
scrollBehavior: () => ({ left: 0, top: 0 }),
|
||||
routes,
|
||||
|
||||
// Leave these as is and change from quasar.conf.js instead!
|
||||
// quasar.conf.js -> build -> vueRouterMode
|
||||
// quasar.conf.js -> build -> publicPath
|
||||
mode: process.env.VUE_ROUTER_MODE,
|
||||
base: process.env.VUE_ROUTER_BASE
|
||||
history: createHistory(process.env.MODE === 'ssr' ? undefined : process.env.VUE_ROUTER_BASE)
|
||||
})
|
||||
|
||||
return Router
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import Error404 from 'pages/_commons/Error404.vue'
|
||||
|
||||
const LayoutDefault = () => import('layouts/Default.vue')
|
||||
|
||||
const routes = [
|
||||
|
@ -249,8 +251,8 @@ const routes = [
|
|||
// Always leave this as last one
|
||||
if (process.env.MODE !== 'ssr') {
|
||||
routes.push({
|
||||
path: '*',
|
||||
component: () => import('pages/_commons/Error404.vue'),
|
||||
path: '/:catchAll(.*)*',
|
||||
component: Error404,
|
||||
meta: {
|
||||
title: '404'
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import { createStore } from 'vuex'
|
||||
import { store } from 'quasar/wrappers'
|
||||
|
||||
import core from './core'
|
||||
import entrypoints from './entrypoints'
|
||||
|
@ -8,15 +8,13 @@ import tcp from './tcp'
|
|||
import udp from './udp'
|
||||
import platform from './platform'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
/*
|
||||
* If not building with SSR mode, you can
|
||||
* directly export the Store instantiation
|
||||
*/
|
||||
|
||||
export default function (/* { ssrContext } */) {
|
||||
const Store = new Vuex.Store({
|
||||
export default store((/* { ssrContext } */) => {
|
||||
const Store = createStore({
|
||||
modules: {
|
||||
core,
|
||||
entrypoints,
|
||||
|
@ -32,4 +30,4 @@ export default function (/* { ssrContext } */) {
|
|||
})
|
||||
|
||||
return Store
|
||||
}
|
||||
})
|
||||
|
|
8364
webui/yarn.lock
8364
webui/yarn.lock
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue