Refonte du front en VueJS
parent
8f06c3d639
commit
1495c12307
1
Gemfile
1
Gemfile
|
@ -7,6 +7,7 @@ gem 'puma'
|
|||
gem 'webpacker'
|
||||
gem 'uglifier'
|
||||
gem 'bootsnap', require: false
|
||||
gem 'js-routes'
|
||||
|
||||
gem 'pg'
|
||||
|
||||
|
|
|
@ -133,6 +133,9 @@ GEM
|
|||
rainbow (>= 2.0.0)
|
||||
i18n (1.8.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
js-routes (1.4.9)
|
||||
railties (>= 4)
|
||||
sprockets-rails
|
||||
listen (3.2.1)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
|
@ -287,6 +290,7 @@ DEPENDENCIES
|
|||
guard-rails
|
||||
http
|
||||
httplog
|
||||
js-routes
|
||||
listen
|
||||
net-ping
|
||||
openssl
|
||||
|
|
|
@ -8,6 +8,8 @@ yarn add jquery
|
|||
yarn add popper.js
|
||||
yarn add bootstrap
|
||||
yarn add @fortawesome/fontawesome-free
|
||||
bin/rails webpacker:install:vue
|
||||
yarn add vue-router
|
||||
bin/rails db:create db:migrate
|
||||
bin/webpack-dev-server
|
||||
```
|
||||
|
|
|
@ -2,5 +2,40 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
def main
|
||||
@services = Service.all
|
||||
@checks = Check.all
|
||||
end
|
||||
|
||||
def sidebar
|
||||
@services = Service.all
|
||||
sidebar = []
|
||||
percent = 100
|
||||
@services.each do |s|
|
||||
ref = nil
|
||||
unless s.config[:http].nil?
|
||||
ref = s.config[:http]
|
||||
end
|
||||
sidebar.push(
|
||||
{
|
||||
percent: percent,
|
||||
type: s.type,
|
||||
ref: ref,
|
||||
name: s.name,
|
||||
error: nil
|
||||
})
|
||||
percent -= 10
|
||||
end
|
||||
render json: sidebar
|
||||
end
|
||||
|
||||
def dashboard
|
||||
@services = Service.all
|
||||
@checks = Check.all
|
||||
dashboard = {
|
||||
total_services: @services.size,
|
||||
total_checks: @checks.size,
|
||||
stats: @services
|
||||
}
|
||||
render json: dashboard
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -2,26 +2,38 @@ class ServicesController < ApplicationController
|
|||
before_action :set_service, only: [:show, :edit, :update, :destroy]
|
||||
|
||||
def show
|
||||
render json: @service
|
||||
end
|
||||
|
||||
def new
|
||||
@service = Service.new
|
||||
end
|
||||
|
||||
CONFIG_PARAMS = {
|
||||
ping: %i[host],
|
||||
http: %i[url code],
|
||||
tcp: %i[host port],
|
||||
udp: %i[host port]
|
||||
}
|
||||
|
||||
def create
|
||||
@service = Service.new(service_params)
|
||||
if @service.save
|
||||
redirect_to @service, notice: t('notice.service.created', service: @service.name)
|
||||
else
|
||||
render :new
|
||||
end
|
||||
type = params[:service][:type].to_sym
|
||||
config = params[:service].slice *CONFIG_PARAMS[type]
|
||||
p = { name: params[:service][:name], type: type, config: config }
|
||||
|
||||
@service = Service.create! **p
|
||||
redirect_to @service, notice: t('notice.service.created', service: @service.name)
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
if @service.update(mission_params)
|
||||
type = params[:service][:type].to_sym
|
||||
config = params[:service].slice *CONFIG_PARAMS[type]
|
||||
p = { id: params[:id], name: params[:service][:name], type: type, config: config }
|
||||
|
||||
if @service.update(p)
|
||||
redirect_to @service, notice: t('notice.service.updated', service: @service.name)
|
||||
else
|
||||
render :edit
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<template>
|
||||
<main class="container-fluid">
|
||||
<div id="container" class="row">
|
||||
<Sidebar/>
|
||||
<div id="content" class="col-sm-10">
|
||||
<router-view/>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Sidebar from '../components/Sidebar.vue'
|
||||
export default {
|
||||
components: {
|
||||
Sidebar
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
flex-grow: 1;
|
||||
}
|
||||
#container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
flex-grow: 1;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,10 @@
|
|||
<template>
|
||||
<footer class="bg-dark text-light text-center p-4">
|
||||
<div>
|
||||
Monit is a free web application to monitor your servers, developped by
|
||||
<a href="https://imirhil.fr/">Aeris</a> (backend) and <a href="https://norore.fr">Norore</a> (frontend) under A-GPL
|
||||
<br>
|
||||
Icon made by <a href="https://norore.fr">Norore</a> under A-GPL
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
|
@ -0,0 +1,42 @@
|
|||
<template>
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-dark" id="mainmenu" role="navigation">
|
||||
<a class="navbar-brand" href="/"><img src="../../assets/images/logo.png" height="30px" alt="Monit logo"></a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse"
|
||||
data-target="#navbarNav" aria-controls="navbarNavDropdown"
|
||||
aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
</ul>
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown"
|
||||
role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
EN
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
<div class="dropdown-item" v-for="locale in locales">
|
||||
{{ locale.lang }}
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
locales: [
|
||||
{lang: 'English', abbr: 'EN'},
|
||||
{lang: 'French', abbr: 'FR'}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,47 @@
|
|||
<template>
|
||||
<aside id="aside" class="col-sm-2">
|
||||
<a href="/services/new" class="mx-0 add">
|
||||
<i class="fa fa-plus"></i> Add a service
|
||||
</a>
|
||||
|
||||
<div v-for="service in sidebar" class="m-0 mt-1 row bg-light">
|
||||
<div class="col-sm-2">
|
||||
<span class="badge badge-secondary">{{ service.percent }}%</span>
|
||||
</div>
|
||||
<div class="col-sm-2">
|
||||
<span class="badge badge-pill badge-secondary">
|
||||
{{ service.type }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
{{ service.name }}
|
||||
</div>
|
||||
<div class="col-sm-2 text-right">
|
||||
<small>{{ service.error }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const axios = require('axios')
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
sidebar: null
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
axios
|
||||
.get(Routes.sidebar_path())
|
||||
.then(response => {
|
||||
this.sidebar = response.data
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error)
|
||||
this.errored = true
|
||||
})
|
||||
.finally(() => this.loading = false)
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,5 +1,13 @@
|
|||
$dark: #111;
|
||||
$light: #ccc;
|
||||
$dark: #33383b;
|
||||
$light: #e7edf4;
|
||||
|
||||
$link-color: #ff9400;
|
||||
$link-hover-color: lighten($link-color, 10%);
|
||||
$link-color: #003554;
|
||||
$link-hover-color: lighten($link-color, 10%);
|
||||
|
||||
$table-bg: $light;
|
||||
$table-border-color: $dark;
|
||||
|
||||
$input-bg: #D2D7DE;
|
||||
|
||||
$btn-primary-bg: #0084D1;
|
||||
$btn-secondary-bg: #454D52;
|
|
@ -18,10 +18,69 @@ body {
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: wrap;
|
||||
flex-grow: 1;
|
||||
}
|
||||
#container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* End of the trick
|
||||
*/
|
||||
*/
|
||||
|
||||
a {
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
footer a {
|
||||
color: #78fd00;
|
||||
&:hover {
|
||||
color: #acfc65;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
border: .15em solid $dark;
|
||||
}
|
||||
|
||||
aside {
|
||||
//min-height: 84vh;
|
||||
background-color: $dark;
|
||||
//margin: 0 auto;
|
||||
}
|
||||
|
||||
aside a.add {
|
||||
color: $light;
|
||||
&:hover {
|
||||
color: $light;
|
||||
}
|
||||
}
|
||||
|
||||
main {
|
||||
background-color: $light;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forms
|
||||
*/
|
||||
|
||||
label {
|
||||
font-weight: bold;
|
||||
color: $dark;
|
||||
}
|
||||
|
||||
input {
|
||||
border: none;
|
||||
//background-color: ;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
<template>
|
||||
<v-app>
|
||||
<v-content>
|
||||
<Header/>
|
||||
<Container/>
|
||||
<Footer/>
|
||||
</v-content>
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Header from '../components/Header'
|
||||
import Container from '../components/Container'
|
||||
import Footer from '../components/Footer'
|
||||
export default {
|
||||
name: 'App',
|
||||
components: {
|
||||
Header,
|
||||
Container,
|
||||
Footer
|
||||
},
|
||||
data: () => ({
|
||||
//
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
v-content {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: auto;
|
||||
}
|
||||
</style>
|
|
@ -1,6 +1,23 @@
|
|||
require("jquery")
|
||||
require("vue")
|
||||
require("bootstrap")
|
||||
require('@fortawesome/fontawesome-free')
|
||||
|
||||
import 'css/application'
|
||||
import 'bootstrap'
|
||||
import 'bootstrap'
|
||||
|
||||
import Routes from '../routes/index.js.erb';
|
||||
window.Routes = Routes;
|
||||
|
||||
import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router.js'
|
||||
import 'axios'
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const app = new Vue({
|
||||
router,
|
||||
render: h => h(App)
|
||||
}).$mount()
|
||||
document.body.appendChild(app.$el)
|
||||
})
|
|
@ -0,0 +1,33 @@
|
|||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import Login from '../views/Login.vue'
|
||||
import Dashboard from '../views/Dashboard.vue'
|
||||
import Service from '../views/Service.vue'
|
||||
import NewService from '../views/NewService.vue'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
export default new Router({
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: Dashboard
|
||||
},
|
||||
{
|
||||
path: '/service',
|
||||
name: 'service',
|
||||
component: Service
|
||||
},
|
||||
{
|
||||
path: '/service/new',
|
||||
name: 'newservice',
|
||||
component: NewService
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: Login
|
||||
}
|
||||
]
|
||||
})
|
|
@ -0,0 +1 @@
|
|||
<%= JsRoutes.generate() %>
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
|
||||
// show form elements in function of type of check
|
||||
// window.createConfig = function (element) {
|
||||
// const type = element.selectedOptions[0].value
|
||||
// const host = document.getElementById("host")
|
||||
// const port = document.getElementById("port")
|
||||
// const link = document.getElementById("link")
|
||||
// const code = document.getElementById("code")
|
||||
// switch (type) {
|
||||
// case 'ping':
|
||||
// host.style.display = 'block'
|
||||
// port.style.display = 'none'
|
||||
// link.style.display = 'none'
|
||||
// code.style.display = 'none'
|
||||
// break
|
||||
// case 'http':
|
||||
// host.style.display = 'none'
|
||||
// port.style.display = 'none'
|
||||
// link.style.display = 'block'
|
||||
// code.style.display = 'block'
|
||||
// break
|
||||
// case 'tcp':
|
||||
// case 'udp':
|
||||
// host.style.display = 'block'
|
||||
// port.style.display = 'block'
|
||||
// link.style.display = 'none'
|
||||
// code.style.display = 'none'
|
||||
// break
|
||||
// default:
|
||||
// host.style.display = 'none'
|
||||
// port.style.display = 'none'
|
||||
// link.style.display = 'none'
|
||||
// code.style.display = 'none'
|
||||
// break
|
||||
// }
|
||||
// }
|
|
@ -0,0 +1,73 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1>Dashboard</h1>
|
||||
|
||||
<h2>Quick stats</h2>
|
||||
|
||||
<p>You have defined {{ total_services }} services.</p>
|
||||
|
||||
<p>A total of {{ total_checks }} checks were performed.</p>
|
||||
|
||||
<h2 class="text-dark">Latest events for all services</h2>
|
||||
|
||||
<table class="table">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th>Event</th>
|
||||
<th>Type</th>
|
||||
<th>Service</th>
|
||||
<th>Last update datetime</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="service in stats">
|
||||
<td></td>
|
||||
<td>{{ service.type }}</td>
|
||||
<td><a :href="'#/service#' + service.id">{{ service.name }}</a></td>
|
||||
<td>{{ formatDateTime(service.updated_at) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const axios = require('axios')
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
total_services: null,
|
||||
total_checks: null,
|
||||
stats: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatDateTime: function (str) {
|
||||
const datetime = new Date(str)
|
||||
const day = datetime.getDate()
|
||||
const month = datetime.getMonth()
|
||||
const year = datetime.getFullYear()
|
||||
const hours = datetime.getHours()
|
||||
const minutes = datetime.getMinutes()
|
||||
const seconds = datetime.getSeconds()
|
||||
|
||||
return day+"/"+month+"/"+year+" "+hours+":"+minutes+":"+seconds
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
axios
|
||||
.get(Routes.dashboard_path())
|
||||
.then(response => {
|
||||
console.log(response.data)
|
||||
this.total_services = response.data["total_services"]
|
||||
this.total_checks = response.data["total_checks"]
|
||||
this.stats = response.data["stats"]
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error)
|
||||
this.errored = true
|
||||
})
|
||||
.finally(() => this.loading = false)
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,5 @@
|
|||
<template>
|
||||
<div>
|
||||
<h2>welcome to login page</h2>
|
||||
</div>
|
||||
</template>
|
|
@ -0,0 +1,7 @@
|
|||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
</script>
|
|
@ -0,0 +1,49 @@
|
|||
<template>
|
||||
<div>
|
||||
<h1>{{ service.name }}</h1>
|
||||
|
||||
<strong>Type of service:</strong> {{ service.type }}<br>
|
||||
<strong>Config:</strong> {{ service.config }}<br>
|
||||
<strong>Created time:</strong> {{ formatDateTime(service.created_at) }}<br>
|
||||
<strong>Last updated time:</strong> {{ formatDateTime(service.updated_at) }}<br>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const axios = require('axios')
|
||||
const path = window.location.hash
|
||||
const id = path.split('#').pop()
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
service: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
formatDateTime: function (str) {
|
||||
const datetime = new Date(str)
|
||||
const day = datetime.getDate()
|
||||
const month = datetime.getMonth()
|
||||
const year = datetime.getFullYear()
|
||||
const hours = datetime.getHours()
|
||||
const minutes = datetime.getMinutes()
|
||||
const seconds = datetime.getSeconds()
|
||||
|
||||
return day+"/"+month+"/"+year+" "+hours+":"+minutes+":"+seconds
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
axios
|
||||
.get(Routes.service_path(id))
|
||||
.then(response => {
|
||||
console.log(response.data)
|
||||
this.service = response.data
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error)
|
||||
this.errored = true
|
||||
})
|
||||
.finally(() => this.loading = false)
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,26 +1,30 @@
|
|||
<h1 class="text-steal">Monitors</h1>
|
||||
<h1 class="text-steal">Dashboard</h1>
|
||||
|
||||
<%= link_to "Add a service", new_service_url %>
|
||||
<h2>Quick stats</h2>
|
||||
|
||||
<table class="table table-responsive">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Name</th>
|
||||
<th scope="col">Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @services.each do |s| %>
|
||||
<tr>
|
||||
<td><%= link_to s.name, service_url %></td>
|
||||
<td><%= s.type %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>You have defined <%= @services.size %> services.</p>
|
||||
|
||||
<h1 class="text-dark">Overall uptime</h1>
|
||||
<p>A total of <%= @checks.size %> checks were performed.</p>
|
||||
|
||||
<h1 class="text-dark">Latest downtime</h1>
|
||||
<h2 class="text-dark">Latest events for all services</h2>
|
||||
|
||||
<h1 class="text-dark">Quick stats</h1>
|
||||
<!--<table class="table">-->
|
||||
<!-- <thead class="thead-dark">-->
|
||||
<!-- <tr>-->
|
||||
<!-- <th>Event</th>-->
|
||||
<!-- <th>Type</th>-->
|
||||
<!-- <th>Service</th>-->
|
||||
<!-- <th>Datetime</th>-->
|
||||
<!-- </tr>-->
|
||||
<!-- </thead>-->
|
||||
<!-- <tbody>-->
|
||||
<%# @services.each do |service| %>
|
||||
<!-- <tr>-->
|
||||
<!-- <td></td>-->
|
||||
<!-- <td><%#= service.type %></td>-->
|
||||
<!-- <td><%#= link_to service.name, service %></td>-->
|
||||
<!-- <td><%#= service.updated_at %></td>-->
|
||||
<!-- </tr>-->
|
||||
<%# end %>
|
||||
<!-- </tbody>-->
|
||||
<!--</table>-->
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<%= link_to new_service_url, class: %i[add] do %>
|
||||
<i class="fa fa-plus"></i> Add a service
|
||||
<% end %>
|
||||
|
||||
<% @services.each do |service| %>
|
||||
<div class="m-1 row bg-light">
|
||||
<div class="col-1">
|
||||
<span class="badge badge-secondary">0%</span>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<span class="badge badge-pill badge-secondary">
|
||||
<%= service.type %>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<%= link_to service.name, service %>
|
||||
</div>
|
||||
<div class="col-2 text-right">
|
||||
<%= service.updated_at.strftime('%d/%m/%y %H:%M') %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
|
@ -11,20 +11,28 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<%= render 'layouts/header' %>
|
||||
<%#= render 'layouts/header' %>
|
||||
|
||||
<main class="mx-5">
|
||||
<% flash.each do |key, value| %>
|
||||
<div class="<%= flash_class(key) %> alert-dismissible fade show mt-4">
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
<%= value %>
|
||||
</div>
|
||||
<% end %>
|
||||
<!-- <main class="container-fluid">-->
|
||||
<!-- <div id="container" class="row">-->
|
||||
<!-- <aside id="sidebar" class="col-sm-2">-->
|
||||
<%#= render 'layouts/sidebar' %>
|
||||
<!-- </aside>-->
|
||||
|
||||
<%= yield %>
|
||||
</main>
|
||||
<%= render 'layouts/footer' %>
|
||||
<!-- <div id="content" class="col-sm-10">-->
|
||||
<%# flash.each do |key, value| %>
|
||||
<!-- <div class="<%#= flash_class(key) %> alert-dismissible fade show mt-4">-->
|
||||
<!-- <button type="button" class="close" data-dismiss="alert" aria-label="Close">-->
|
||||
<!-- <span aria-hidden="true">×</span>-->
|
||||
<!-- </button>-->
|
||||
<%#= value %>
|
||||
<!-- </div>-->
|
||||
<%# end %>
|
||||
|
||||
<%#= yield %>
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </main>-->
|
||||
<%#= render 'layouts/footer' %>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -15,34 +15,53 @@
|
|||
</div>
|
||||
<% end %>
|
||||
|
||||
<fieldset class="mb-1 p-2">
|
||||
<legend class="h4"><%= t("service.form.title") %></legend>
|
||||
<div class="form-group row">
|
||||
<%= form.label :name, t("service.form.name"), class: %i[col-sm-2 col-form-label] %>
|
||||
<div>
|
||||
<%= form.text_field :name, class: %i[form-control col-sm-10] %>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<%= form.label :name, t("service.form.name"), class: %i[col-sm-2 col-form-label] %>
|
||||
<div>
|
||||
<%= form.text_field :name, class: %i[form-control] %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<%= form.label :type, t("service.form.type"), class: %i[col-sm-2 col-form-label] %>
|
||||
<div>
|
||||
<%= form.select :type, options_for_select(
|
||||
%i[ping tcp udp http cert].collect { |n| [ t("service.form.type.#{n}"), n ] }, form.object.type
|
||||
), {}, class: %i[form-control col-sm-10] %>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<%= form.label :type, t("service.form.type"), class: %i[col-sm-2 col-form-label] %>
|
||||
<div>
|
||||
<%= form.select :type, options_for_select(
|
||||
%i[ping tcp udp http cert].collect { |n| [ t("service.form.type.#{n}"), n ] }, form.object.type
|
||||
), {}, onchange: 'createConfig(this)', class: %i[form-control] %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<%= form.label :config, t("service.form.config"), class: %i[col-sm-2 col-form-label] %>
|
||||
<div>
|
||||
<%= form.text_field :config, class: %i[form-control col-sm-10] %>
|
||||
</div>
|
||||
<!-- type of service will define config fields required by app -->
|
||||
<div id="host" class="form-group row">
|
||||
<%= form.label :host, t("service.form.host"), class: %i[col-sm-2 col-form-label] %>
|
||||
<div>
|
||||
<%= form.text_field :host, class: %i[form-control] %>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div id="port" class="form-group row">
|
||||
<%= form.label :port, t("service.form.port"), class: %i[col-sm-2 col-form-label] %>
|
||||
<div>
|
||||
<%= form.text_field :port, class: %i[form-control] %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="link" class="form-group row"> <!-- id named link for aesthetic purpose only on JS part -->
|
||||
<%= form.label :url, t("service.form.url"), class: %i[col-sm-2 col-form-label] %>
|
||||
<div>
|
||||
<%= form.text_field :url, class: %i[form-control] %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="code" class="form-group row">
|
||||
<%= form.label :code, t("service.form.code"), class: %i[col-sm-2 col-form-label] %>
|
||||
<div>
|
||||
<%= form.text_field :code, class: %i[form-control] %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="actions text-right">
|
||||
<%= link_to t('button.back'), request.referer, class: %i[btn btn-secondary] %>
|
||||
<%= link_to t('button.cancel'), root_path, class: %i[btn btn-secondary] %>
|
||||
<%= form.submit t('button.submit'), class: %i[btn btn-primary] %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
<h1><%= t('service.new.title') %></h1>
|
||||
|
||||
<%= render 'form', service: @service %>
|
||||
|
||||
<%= link_to t('home'), root_path %>
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<h1><%= @service.name %></h1>
|
||||
|
||||
<strong>Type of service:</strong> <%= @service.type %><br>
|
||||
<strong>Config:</strong> <%= @service.config %>
|
|
@ -17,4 +17,15 @@ en:
|
|||
form:
|
||||
title: Service
|
||||
name: Name
|
||||
type: Type
|
||||
type: Type
|
||||
|
||||
check:
|
||||
new:
|
||||
title: Create a new check
|
||||
|
||||
edit:
|
||||
title: Edit check %{service}
|
||||
|
||||
form:
|
||||
title: Check
|
||||
url: Address
|
|
@ -2,4 +2,9 @@ Rails.application.routes.draw do
|
|||
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
|
||||
root to: "application#main"
|
||||
resources :services
|
||||
resources :checks
|
||||
|
||||
get '/sidebar', to: 'application#sidebar', as: 'sidebar'
|
||||
get '/dashboard', to: 'application#dashboard', as: 'dashboard'
|
||||
# get '/service/id', to: 'service#view', as: 'service'
|
||||
end
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
const { environment } = require('@rails/webpacker')
|
||||
const erb = require('./loaders/erb')
|
||||
const { VueLoaderPlugin } = require('vue-loader')
|
||||
const vue = require('./loaders/vue')
|
||||
const webpack = require("webpack")
|
||||
|
||||
environment.plugins.append("Provide", new webpack.ProvidePlugin({
|
||||
|
@ -7,4 +10,7 @@ environment.plugins.append("Provide", new webpack.ProvidePlugin({
|
|||
Popper: ['popper.js', 'default']
|
||||
}))
|
||||
|
||||
environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin())
|
||||
environment.loaders.prepend('vue', vue)
|
||||
environment.loaders.prepend('erb', erb)
|
||||
module.exports = environment
|
||||
|
|
|
@ -33,6 +33,8 @@ default: &default
|
|||
- .woff2
|
||||
|
||||
extensions:
|
||||
- .erb
|
||||
- .vue
|
||||
- .mjs
|
||||
- .js
|
||||
- .sass
|
||||
|
|
|
@ -4,10 +4,16 @@
|
|||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.15.0",
|
||||
"@rails/webpacker": "5.2.1",
|
||||
"axios": "^0.21.0",
|
||||
"bootstrap": "^4.5.2",
|
||||
"jquery": "^3.5.1",
|
||||
"popper": "^1.0.1",
|
||||
"popper.js": "^1.16.1"
|
||||
"popper.js": "^1.16.1",
|
||||
"rails-erb-loader": "^5.5.2",
|
||||
"vue": "^2.6.12",
|
||||
"vue-loader": "^15.9.5",
|
||||
"vue-router": "^3.4.9",
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack-dev-server": "^3.11.0"
|
||||
|
|
117
yarn.lock
117
yarn.lock
|
@ -982,6 +982,22 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.0.tgz#fef1904e4668b6e5ecee60c52cc6a078ffa6697d"
|
||||
integrity sha512-I99sngh224D0M7XgW1s120zxCt3VYQ3IQsuw3P3jbq5GG4yc79+ZjyKznyOGIQrflfylLgcfekeZW/vk0yng6A==
|
||||
|
||||
"@vue/component-compiler-utils@^3.1.0":
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.2.0.tgz#8f85182ceed28e9b3c75313de669f83166d11e5d"
|
||||
integrity sha512-lejBLa7xAMsfiZfNp7Kv51zOzifnb29FwdnMLa96z26kXErPFioSf9BMcePVIQ6/Gc6/mC0UrPpxAWIHyae0vw==
|
||||
dependencies:
|
||||
consolidate "^0.15.1"
|
||||
hash-sum "^1.0.2"
|
||||
lru-cache "^4.1.2"
|
||||
merge-source-map "^1.1.0"
|
||||
postcss "^7.0.14"
|
||||
postcss-selector-parser "^6.0.2"
|
||||
source-map "~0.6.1"
|
||||
vue-template-es2015-compiler "^1.9.0"
|
||||
optionalDependencies:
|
||||
prettier "^1.18.2"
|
||||
|
||||
"@webassemblyjs/ast@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964"
|
||||
|
@ -1545,6 +1561,13 @@ aws4@^1.8.0:
|
|||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.1.tgz#e1e82e4f3e999e2cfd61b161280d16a111f86428"
|
||||
integrity sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==
|
||||
|
||||
axios@^0.21.0:
|
||||
version "0.21.0"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.0.tgz#26df088803a2350dff2c27f96fef99fe49442aca"
|
||||
integrity sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw==
|
||||
dependencies:
|
||||
follow-redirects "^1.10.0"
|
||||
|
||||
babel-loader@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3"
|
||||
|
@ -1658,7 +1681,7 @@ block-stream@*:
|
|||
dependencies:
|
||||
inherits "~2.0.0"
|
||||
|
||||
bluebird@^3.5.5:
|
||||
bluebird@^3.1.1, bluebird@^3.5.5:
|
||||
version "3.7.2"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
|
||||
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
|
||||
|
@ -2548,6 +2571,13 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0:
|
|||
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
|
||||
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
|
||||
|
||||
consolidate@^0.15.1:
|
||||
version "0.15.1"
|
||||
resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7"
|
||||
integrity sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==
|
||||
dependencies:
|
||||
bluebird "^3.1.1"
|
||||
|
||||
constants-browserify@^1.0.0, constants-browserify@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
|
||||
|
@ -2942,6 +2972,11 @@ dashdash@^1.12.0:
|
|||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
de-indent@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
|
||||
integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=
|
||||
|
||||
debug@2.6.9, debug@^2.2.0, debug@^2.3.3:
|
||||
version "2.6.9"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||
|
@ -3807,7 +3842,7 @@ flush-write-stream@^1.0.0:
|
|||
inherits "^2.0.3"
|
||||
readable-stream "^2.3.6"
|
||||
|
||||
follow-redirects@^1.0.0:
|
||||
follow-redirects@^1.0.0, follow-redirects@^1.10.0:
|
||||
version "1.13.0"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db"
|
||||
integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==
|
||||
|
@ -4208,6 +4243,11 @@ hash-base@^3.0.0:
|
|||
readable-stream "^3.6.0"
|
||||
safe-buffer "^5.2.0"
|
||||
|
||||
hash-sum@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-1.0.2.tgz#33b40777754c6432573c120cc3808bbd10d47f04"
|
||||
integrity sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=
|
||||
|
||||
hash.js@^1.0.0, hash.js@^1.0.3:
|
||||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
|
||||
|
@ -4216,7 +4256,7 @@ hash.js@^1.0.0, hash.js@^1.0.3:
|
|||
inherits "^2.0.3"
|
||||
minimalistic-assert "^1.0.1"
|
||||
|
||||
he@1.2.0:
|
||||
he@1.2.0, he@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
|
@ -5190,7 +5230,7 @@ loader-runner@^2.4.0:
|
|||
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
|
||||
integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==
|
||||
|
||||
loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0:
|
||||
loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613"
|
||||
integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==
|
||||
|
@ -5332,7 +5372,7 @@ loud-rejection@^1.0.0:
|
|||
currently-unhandled "^0.4.1"
|
||||
signal-exit "^3.0.0"
|
||||
|
||||
lru-cache@^4.0.1:
|
||||
lru-cache@^4.0.1, lru-cache@^4.1.2:
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
|
||||
integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
|
||||
|
@ -5471,6 +5511,13 @@ merge-descriptors@1.0.1:
|
|||
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
|
||||
integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=
|
||||
|
||||
merge-source-map@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646"
|
||||
integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==
|
||||
dependencies:
|
||||
source-map "^0.6.1"
|
||||
|
||||
merge-stream@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
||||
|
@ -7158,6 +7205,11 @@ preserve@^0.2.0:
|
|||
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
|
||||
integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=
|
||||
|
||||
prettier@^1.18.2:
|
||||
version "1.19.1"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
|
||||
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
|
||||
|
||||
process-nextick-args@~1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
|
||||
|
@ -7302,6 +7354,14 @@ querystringify@^2.1.1:
|
|||
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
|
||||
integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
|
||||
|
||||
rails-erb-loader@^5.5.2:
|
||||
version "5.5.2"
|
||||
resolved "https://registry.yarnpkg.com/rails-erb-loader/-/rails-erb-loader-5.5.2.tgz#db3fa8ac89600f09d179a1a70a2ca18c592576ea"
|
||||
integrity sha512-cjQH9SuSvRPhnWkvjmmAW/S4AFVDfAtYnQO4XpKJ8xpRdZayT73iXoE+IPc3VzN03noZXhVmyvsCvKvHj4LY6w==
|
||||
dependencies:
|
||||
loader-utils "^1.1.0"
|
||||
lodash.defaults "^4.2.0"
|
||||
|
||||
random-bytes@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b"
|
||||
|
@ -9078,6 +9138,53 @@ vm-browserify@~0.0.1:
|
|||
dependencies:
|
||||
indexof "0.0.1"
|
||||
|
||||
vue-hot-reload-api@^2.3.0:
|
||||
version "2.3.4"
|
||||
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2"
|
||||
integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==
|
||||
|
||||
vue-loader@^15.9.5:
|
||||
version "15.9.5"
|
||||
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-15.9.5.tgz#7a960dc420a3439deaacdda038fdcdbf7c432706"
|
||||
integrity sha512-oeMOs2b5o5gRqkxfds10bCx6JeXYTwivRgbb8hzOrcThD2z1+GqEKE3EX9A2SGbsYDf4rXwRg6D5n1w0jO5SwA==
|
||||
dependencies:
|
||||
"@vue/component-compiler-utils" "^3.1.0"
|
||||
hash-sum "^1.0.2"
|
||||
loader-utils "^1.1.0"
|
||||
vue-hot-reload-api "^2.3.0"
|
||||
vue-style-loader "^4.1.0"
|
||||
|
||||
vue-router@^3.4.9:
|
||||
version "3.4.9"
|
||||
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.4.9.tgz#c016f42030ae2932f14e4748b39a1d9a0e250e66"
|
||||
integrity sha512-CGAKWN44RqXW06oC+u4mPgHLQQi2t6vLD/JbGRDAXm0YpMv0bgpKuU5bBd7AvMgfTz9kXVRIWKHqRwGEb8xFkA==
|
||||
|
||||
vue-style-loader@^4.1.0:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vue-style-loader/-/vue-style-loader-4.1.2.tgz#dedf349806f25ceb4e64f3ad7c0a44fba735fcf8"
|
||||
integrity sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==
|
||||
dependencies:
|
||||
hash-sum "^1.0.2"
|
||||
loader-utils "^1.0.2"
|
||||
|
||||
vue-template-compiler@^2.6.12:
|
||||
version "2.6.12"
|
||||
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz#947ed7196744c8a5285ebe1233fe960437fcc57e"
|
||||
integrity sha512-OzzZ52zS41YUbkCBfdXShQTe69j1gQDZ9HIX8miuC9C3rBCk9wIRjLiZZLrmX9V+Ftq/YEyv1JaVr5Y/hNtByg==
|
||||
dependencies:
|
||||
de-indent "^1.0.2"
|
||||
he "^1.1.0"
|
||||
|
||||
vue-template-es2015-compiler@^1.9.0:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz#1ee3bc9a16ecbf5118be334bb15f9c46f82f5825"
|
||||
integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
|
||||
|
||||
vue@^2.6.12:
|
||||
version "2.6.12"
|
||||
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.12.tgz#f5ebd4fa6bd2869403e29a896aed4904456c9123"
|
||||
integrity sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg==
|
||||
|
||||
watchpack-chokidar2@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0"
|
||||
|
|
Loading…
Reference in New Issue