Adds a Website Rebooter to reboot via AWS. (#9)
- Adds I18n to websites. - Adds feather-icons JS in replace of images. - Adds node-polyglot for client-side translations.
This commit is contained in:
parent
1f5bef0df0
commit
d9d9b466d5
1
Gemfile
1
Gemfile
@ -5,6 +5,7 @@ git_source(:github) do |repo_name|
|
||||
"https://github.com/#{repo_name}.git"
|
||||
end
|
||||
|
||||
gem 'aws-sdk', '~> 2.10'
|
||||
gem 'attr_encrypted', '~> 3.0', github: 'attr-encrypted/attr_encrypted'
|
||||
gem 'bootstrap', '4.0.0.alpha6'
|
||||
gem 'delayed_job_active_record', '~> 4.1.2'
|
||||
|
10
Gemfile.lock
10
Gemfile.lock
@ -55,6 +55,14 @@ GEM
|
||||
arel (8.0.0)
|
||||
autoprefixer-rails (7.1.2.4)
|
||||
execjs
|
||||
aws-sdk (2.10.33)
|
||||
aws-sdk-resources (= 2.10.33)
|
||||
aws-sdk-core (2.10.33)
|
||||
aws-sigv4 (~> 1.0)
|
||||
jmespath (~> 1.0)
|
||||
aws-sdk-resources (2.10.33)
|
||||
aws-sdk-core (= 2.10.33)
|
||||
aws-sigv4 (1.0.1)
|
||||
bcrypt (3.1.11)
|
||||
bindex (0.5.0)
|
||||
bootstrap (4.0.0.alpha6)
|
||||
@ -111,6 +119,7 @@ GEM
|
||||
activesupport (>= 4.2.0)
|
||||
hashdiff (0.3.5)
|
||||
i18n (0.8.6)
|
||||
jmespath (1.3.1)
|
||||
kaminari (1.0.1)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.0.1)
|
||||
@ -267,6 +276,7 @@ PLATFORMS
|
||||
|
||||
DEPENDENCIES
|
||||
attr_encrypted (~> 3.0)!
|
||||
aws-sdk (~> 2.10)
|
||||
bootstrap (= 4.0.0.alpha6)
|
||||
byebug
|
||||
capybara (~> 2.13)
|
||||
|
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#414345" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-arrow-left"><path d="M20 12H4M10 18l-6-6 6-6"/></svg>
|
Before Width: | Height: | Size: 252 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="#1d3557" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-bar-chart"><path d="M18 3h4v18h-4zM10 8h4v13h-4zM2 13h4v8H2z"/></svg>
|
Before Width: | Height: | Size: 268 B |
@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-edit"><path d="M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34"/><path d="M18 2l4 4-10 10H8v-4L18 2z"/></svg>
|
Before Width: | Height: | Size: 329 B |
@ -1,4 +1,5 @@
|
||||
//= require rails-ujs
|
||||
//= require feather-icons/dist/feather
|
||||
//= require clipboard/dist/clipboard
|
||||
//= require local-time
|
||||
//= require turbolinks
|
||||
|
@ -12,35 +12,6 @@ a.card {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
.card-deck .card-container:not(:last-child) {
|
||||
margin-right: ($spacer * 2);
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
.card-deck {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.card-container {
|
||||
display: flex;
|
||||
flex: 1 0 0;
|
||||
flex-direction: column;
|
||||
margin-bottom: ($spacer * 2);
|
||||
|
||||
.card {
|
||||
margin-bottom: 0;
|
||||
transition: all $base-duration $base-timing;
|
||||
}
|
||||
|
||||
&:hover .card {
|
||||
box-shadow: $box-shadow-hover;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
}
|
||||
|
||||
.card-link {
|
||||
transition: all $base-duration $base-timing;
|
||||
|
||||
@ -50,6 +21,23 @@ a.card {
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
.card-deck {
|
||||
display: block;
|
||||
|
||||
.card-link:not(:last-child) {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(xs) {
|
||||
.card-deck .card-link:not(:first-child) {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.card-header {
|
||||
background-color: $white;
|
||||
padding-bottom: 1.5rem;
|
||||
|
@ -19,7 +19,7 @@ module PaginatableConcern
|
||||
),
|
||||
link: (
|
||||
render_to_string(
|
||||
'websites/_next_page.html.erb',
|
||||
'websites/_next_page',
|
||||
locals: { websites: ivar },
|
||||
layout: false
|
||||
)
|
||||
|
@ -31,11 +31,27 @@ class WebsitesController < ApplicationController
|
||||
@pings = @website.pings.paginate(params).decorate
|
||||
end
|
||||
|
||||
def edit
|
||||
@website = Website.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@website = Website.find(params[:id])
|
||||
|
||||
if @website.update(website_params)
|
||||
flash[:success] = t('.success', name: @website.name)
|
||||
redirect_to(root_path)
|
||||
else
|
||||
render(:edit)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def website_params
|
||||
params.require(:website).permit(
|
||||
:name, :url, :basic_auth_username, :basic_auth_password
|
||||
:name, :url, :basic_auth_username, :basic_auth_password,
|
||||
:aws_instance_id, :aws_region
|
||||
)
|
||||
end
|
||||
end
|
||||
|
11
app/helpers/translations_helper.rb
Normal file
11
app/helpers/translations_helper.rb
Normal file
@ -0,0 +1,11 @@
|
||||
# TranslationsHelper
|
||||
module TranslationsHelper
|
||||
def i18n_phrases
|
||||
{
|
||||
pagination: {
|
||||
fetching: t('pagination.fetching'),
|
||||
failed: t('pagination.failed')
|
||||
}
|
||||
}.to_json
|
||||
end
|
||||
end
|
25
app/helpers/websites_helper.rb
Normal file
25
app/helpers/websites_helper.rb
Normal file
@ -0,0 +1,25 @@
|
||||
module WebsitesHelper
|
||||
def options_for_aws_region(selected = nil)
|
||||
options_for_select(aws_regions, selected)
|
||||
end
|
||||
|
||||
def aws_regions
|
||||
# http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/
|
||||
# using-regions-availability-zones.html#concepts-available-regions
|
||||
[
|
||||
['US East (N. Virginia) · us-east-1', 'us-east-1'],
|
||||
['US East (Ohio) · us-east-2', 'us-east-2'],
|
||||
['US West (N. California) · us-west-1', 'us-west-1'],
|
||||
['US West (Oregon) · us-west-2', 'us-west-2'],
|
||||
['Canada (Central) · ca-central-1', 'ca-central-1'],
|
||||
['EU (Ireland) · eu-west-1', 'eu-west-1'],
|
||||
['EU (London) · eu-west-1', 'eu-west-2'],
|
||||
['EU (Frankfurt) · eu-central-1', 'eu-central-1'],
|
||||
['Asia Pacific (Tokyo) · ap-northeast-1', 'ap-northeast-1'],
|
||||
['Asia Pacific (Seoul) · ap-northeast-2', 'ap-northeast-2'],
|
||||
['Asia Pacific (Singapore) · ap-southeast-1', 'ap-southeast-1'],
|
||||
['Asia Pacific (Mumbai) · ap-south-1', 'ap-south-1'],
|
||||
['South America (São Paulo) · sa-east-1', 'sa-east-1']
|
||||
]
|
||||
end
|
||||
end
|
@ -4,6 +4,7 @@ import { namespace } from './utils/namespace';
|
||||
import CopyToClipboard from './globals/CopyToClipboard';
|
||||
import Pagination from './globals/Pagination';
|
||||
import PingChart from './websites/PingChart';
|
||||
import Polyglot from 'node-polyglot';
|
||||
|
||||
class Dispatcher {
|
||||
constructor() {
|
||||
@ -23,8 +24,24 @@ class Dispatcher {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
feather() {
|
||||
feather.replace();
|
||||
}
|
||||
|
||||
translate() {
|
||||
const phrases = document
|
||||
.querySelector('[data-behavior="translations"]')
|
||||
.getAttribute('data-phrases');
|
||||
|
||||
window.polyglot = new Polyglot({ phrases: JSON.parse(phrases) });
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('turbolinks:load', () => {
|
||||
new Dispatcher().route();
|
||||
const dispatcher = new Dispatcher();
|
||||
|
||||
dispatcher.feather();
|
||||
dispatcher.route();
|
||||
dispatcher.translate();
|
||||
});
|
||||
|
@ -1,6 +1,5 @@
|
||||
import 'whatwg-fetch';
|
||||
|
||||
const loadMoreSelector = '[data-behavior="load-more"]';
|
||||
const paginationWrapperSelector = '[data-behavior="pagination-wrapper"]';
|
||||
|
||||
export default class Pagination {
|
||||
@ -55,7 +54,8 @@ export default class Pagination {
|
||||
|
||||
addLoadingText(el) {
|
||||
this.cachedText = el.textContent;
|
||||
el.textContent = 'Fetching...';
|
||||
|
||||
el.textContent = polyglot.t('pagination.fetching');
|
||||
el.setAttribute('disabled', true);
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ export default class Pagination {
|
||||
this.paginationWrapperEl.innerHTML = response.link;
|
||||
})
|
||||
.catch(ex => {
|
||||
console.log('Failed to load next page of results', ex);
|
||||
console.log(polyglot.t('pagination.failed'), ex);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -60,9 +60,8 @@ export default class PingChart {
|
||||
const { margin, tickSize, axisPadding, width, height } = this.defaults;
|
||||
|
||||
this.graph = d3.select(this.selector);
|
||||
|
||||
this.chartEl.innerHTML = '';
|
||||
d3.select('svg').remove();
|
||||
|
||||
const svg = (this.svg = this.graph
|
||||
.append('svg')
|
||||
.attr('width', width)
|
||||
|
@ -1,7 +1,7 @@
|
||||
module Paginatable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
SIZE = 12
|
||||
SIZE = 18
|
||||
|
||||
module ClassMethods
|
||||
def paginate(params)
|
||||
|
42
app/services/websites/rebooter.rb
Normal file
42
app/services/websites/rebooter.rb
Normal file
@ -0,0 +1,42 @@
|
||||
module Websites
|
||||
# Rebooter
|
||||
class Rebooter
|
||||
attr_reader(:website)
|
||||
|
||||
def initialize(website)
|
||||
@website = website
|
||||
end
|
||||
|
||||
def reboot
|
||||
website.update_attributes(rebooting: true)
|
||||
client.instance(website.aws_instance_id).reboot
|
||||
status = build_status("Rebooting: #{website.name}.")
|
||||
rescue => e
|
||||
status = build_status("Failed to reboot #{website.name}: #{e}.")
|
||||
ensure
|
||||
status
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def client
|
||||
Aws.config.update(
|
||||
region: website.aws_region,
|
||||
credentials: aws_credentials
|
||||
)
|
||||
|
||||
Aws::EC2::Resource.new
|
||||
end
|
||||
|
||||
def aws_credentials
|
||||
Aws::Credentials.new(
|
||||
Setting.first.aws_key,
|
||||
Setting.first.aws_secret
|
||||
)
|
||||
end
|
||||
|
||||
def build_status(message)
|
||||
OpenStruct.new(website: website, message: message)
|
||||
end
|
||||
end
|
||||
end
|
@ -1,8 +1,17 @@
|
||||
<div class="page-heading">
|
||||
<h4 class="page-title"><%= t "devise.invitations.new.header" %></h4>
|
||||
</div>
|
||||
|
||||
<%= link_to("Head back", users_path,
|
||||
class: "btn btn-secondary btn-sm mt-3") %>
|
||||
<div class="row">
|
||||
<div class="col-sm-4 offset-sm-4">
|
||||
<%= link_to(users_path,
|
||||
class: "card card-link") do %>
|
||||
<div class="card-block text-muted text-center d-flex align-items-center justify-content-center">
|
||||
<i class="mr-3" data-feather="arrow-left"></i>
|
||||
<h6 class="mb-0">Head back</h6>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
@ -16,5 +16,7 @@
|
||||
<div class="container">
|
||||
<div class="mt-4"><%= yield %></div>
|
||||
</div>
|
||||
|
||||
<div data-behavior="translations" data-phrases="<%= i18n_phrases %>"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="blankslate">
|
||||
<h4 class="blankslate-title">
|
||||
No <%= resource.titleize.pluralize %> have been created yet.
|
||||
<%= t('.title', resource: resource.pluralize) %>
|
||||
</h4>
|
||||
|
||||
<% if yield.present? %>
|
||||
|
@ -1,8 +1,17 @@
|
||||
<div class="page-heading">
|
||||
<h4 class="page-title">Here's your team</h4>
|
||||
</div>
|
||||
|
||||
<%= link_to("Invite member", new_user_invitation_path,
|
||||
class: "btn btn-primary btn-sm mt-3") %>
|
||||
<div class="row">
|
||||
<div class="col-sm-4 offset-sm-4">
|
||||
<%= link_to(new_user_invitation_path,
|
||||
class: "card card-link") do %>
|
||||
<div class="card-block text-muted text-center d-flex align-items-center justify-content-center">
|
||||
<i class="mr-3" data-feather="user-plus"></i>
|
||||
<h6 class="mb-0">Invite member</h6>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
53
app/views/websites/_form.html.erb
Normal file
53
app/views/websites/_form.html.erb
Normal file
@ -0,0 +1,53 @@
|
||||
<%= form_for(website) do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.label(:name) %>
|
||||
<%= f.text_field(:name,
|
||||
autofocus: true, autocomplete: :off,
|
||||
class: "form-control") %>
|
||||
<%= error_message_on(f.object, :name) %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label(:url, t('.url')) %>
|
||||
<%= f.url_field(:url, class: "form-control") %>
|
||||
<%= error_message_on(f.object, :url) %>
|
||||
</div>
|
||||
|
||||
<div class="hr-sect"><%= t('.optional') %></div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label(:basic_auth_username) %>
|
||||
<%= f.text_field(:basic_auth_username, class: "form-control") %>
|
||||
<%= error_message_on(f.object, :basic_auth_username) %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label(:basic_auth_password) %>
|
||||
<%= f.text_field(:basic_auth_password, class: "form-control") %>
|
||||
<%= error_message_on(f.object, :basic_auth_password) %>
|
||||
</div>
|
||||
|
||||
<% if (Setting.global.present? &&
|
||||
(Setting.global.aws_key.present? && Setting.global.aws_secret.present?)) %>
|
||||
<div class="hr-sect"><%= t('.aws_info') %></div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label(:aws_instance_id, t('.aws_instance_id')) %>
|
||||
<%= f.text_field(:aws_instance_id, class: "form-control") %>
|
||||
<%= error_message_on(f.object, :aws_instance_id) %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label(:aws_region, t('.aws_region')) %>
|
||||
<%= f.select(:aws_region,
|
||||
options_for_aws_region(f.object.aws_region),
|
||||
{ prompt: t('.aws_region_select') },
|
||||
{ class: "form-control" }) %>
|
||||
<%= error_message_on(f.object, :aws_region) %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="actions">
|
||||
<%= f.submit class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
@ -2,6 +2,6 @@
|
||||
<button class="btn btn-primary btn-block mb-4"
|
||||
data-url="<%= websites_url(page: websites.next_page) %>"
|
||||
data-behavior="load-more">
|
||||
Load more
|
||||
<%= t('.load_more') %>
|
||||
</button>
|
||||
<% end %>
|
||||
|
@ -1,11 +1,9 @@
|
||||
<div class="card-container">
|
||||
<%= link_to(website_path(website), class: "card") do %>
|
||||
<div class="card-block">
|
||||
<h4 class="card-title"><%= website.name %></h4>
|
||||
<%= link_to(website_path(website), class: "card card-link") do %>
|
||||
<div class="card-block">
|
||||
<h4 class="card-title"><%= website.name %></h4>
|
||||
|
||||
<div class="hr-sect">Recent Pings</div>
|
||||
<div class="hr-sect">Recent Pings</div>
|
||||
|
||||
<%= render(website.recent_pings) %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= render(website.recent_pings) %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div class="page-heading">
|
||||
<h4 class="page-title">Response Times</h4>
|
||||
<h4 class="page-title"><%= t('.title') %></h4>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
@ -7,7 +7,7 @@
|
||||
<%= link_to(website_path(@website),
|
||||
class: "card card-link") do %>
|
||||
<div class="card-block text-muted text-center d-flex align-items-center justify-content-center">
|
||||
<%= image_tag("icons/arrow-left.svg", class: "mr-3") %>
|
||||
<i class="mr-3" data-feather="arrow-left"></i>
|
||||
<h6 class="mb-0"><%= @website.name %></h6>
|
||||
</div>
|
||||
<% end %>
|
||||
|
24
app/views/websites/edit.html.erb
Normal file
24
app/views/websites/edit.html.erb
Normal file
@ -0,0 +1,24 @@
|
||||
<div class="page-heading">
|
||||
<h4 class="page-title"><%= t(".title") %></h4>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-4 offset-sm-4">
|
||||
<%= link_to(website_path(@website),
|
||||
class: "card card-link") do %>
|
||||
<div class="card-block text-muted text-center d-flex align-items-center justify-content-center">
|
||||
<i class="mr-3" data-feather="arrow-left"></i>
|
||||
<h6 class="mb-0"><%= @website.name %></h6>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 offset-md-3">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<%= render("form", website: @website) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@ -1,3 +1,19 @@
|
||||
<div class="page-heading">
|
||||
<h4 class="page-title"><%= t('.title') %></h4>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-4 offset-sm-4">
|
||||
<%= link_to(new_website_path,
|
||||
class: "card card-link") do %>
|
||||
<div class="card-block text-muted text-center d-flex align-items-center justify-content-center">
|
||||
<i class="mr-3" data-feather="link-2"></i>
|
||||
<h6 class="mb-0"><%= t('.add') %></h6>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<% if @websites.any? %>
|
||||
@ -13,9 +29,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= render("shared/blankslate", resource: "website") do %>
|
||||
<%= link_to("Add website", new_website_path, class: "btn btn-primary") %>
|
||||
<% end %>
|
||||
<%= render("shared/blankslate", resource: t('.resource')) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,44 +1,24 @@
|
||||
<div class="page-heading">
|
||||
<h4 class="page-title">Let's add a new website</h4>
|
||||
<h4 class="page-title"><%= t(".title") %></h4>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-4 offset-sm-4">
|
||||
<%= link_to(websites_path,
|
||||
class: "card card-link") do %>
|
||||
<div class="card-block text-muted text-center d-flex align-items-center justify-content-center">
|
||||
<i class="mr-3" data-feather="arrow-left"></i>
|
||||
<h6 class="mb-0"><%= t('.back') %></h6>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 offset-md-3">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<%= form_for(@website) do |f| %>
|
||||
<div class="form-group">
|
||||
<%= f.label(:name) %>
|
||||
<%= f.text_field(:name,
|
||||
autofocus: true, autocomplete: :off,
|
||||
class: "form-control") %>
|
||||
<%= error_message_on(f.object, :name) %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label(:url, "URL") %>
|
||||
<%= f.url_field(:url, class: "form-control") %>
|
||||
<%= error_message_on(f.object, :url) %>
|
||||
</div>
|
||||
|
||||
<div class="hr-sect">optional</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label(:basic_auth_username) %>
|
||||
<%= f.text_field(:basic_auth_username, class: "form-control") %>
|
||||
<%= error_message_on(f.object, :basic_auth_username) %>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<%= f.label(:basic_auth_password) %>
|
||||
<%= f.text_field(:basic_auth_password, class: "form-control") %>
|
||||
<%= error_message_on(f.object, :basic_auth_password) %>
|
||||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<%= f.submit class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= render("form", website: @website) %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,8 +7,8 @@
|
||||
<%= link_to(website_charts_response_time_index_path(@website),
|
||||
class: "card card-link") do %>
|
||||
<div class="card-block text-muted text-center d-flex align-items-center justify-content-center">
|
||||
<%= image_tag("icons/bar-chart.svg", class: "mr-3") %>
|
||||
<h6 class="mb-0">Response Times</h6>
|
||||
<i class="mr-3" data-feather="bar-chart"></i>
|
||||
<h6 class="mb-0"><%= t('.response_times') %></h6>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
@ -16,8 +16,8 @@
|
||||
<%= link_to(edit_website_path(@website),
|
||||
class: "card card-link") do %>
|
||||
<div class="card-block text-muted text-center d-flex align-items-center justify-content-center">
|
||||
<%= image_tag("icons/edit.svg", class: "mr-3") %>
|
||||
<h6 class="mb-0">Edit</h6>
|
||||
<i class="mr-3" data-feather="edit"></i>
|
||||
<h6 class="mb-0"><%= t('.edit') %></h6>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
@ -34,7 +34,7 @@
|
||||
<%= paginate(@pings) %>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= render("shared/blankslate", resource: "ping") %>
|
||||
<%= render("shared/blankslate", resource: t('.resource')) %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -30,13 +30,48 @@
|
||||
# available at http://guides.rubyonrails.org/i18n.html.
|
||||
|
||||
en:
|
||||
pagination:
|
||||
fetching: Fetching...
|
||||
failed: Failed to load next page of results
|
||||
shared:
|
||||
blankslate:
|
||||
title: No %{resource} have been created yet.
|
||||
websites:
|
||||
charts:
|
||||
response_time:
|
||||
index:
|
||||
title: Response Times
|
||||
create:
|
||||
success: >
|
||||
%{name} has been successfully added.
|
||||
edit:
|
||||
title: Let's edit your website
|
||||
form:
|
||||
aws_info: AWS Information
|
||||
aws_instance_id: AWS Instance ID
|
||||
aws_region: AWS Region
|
||||
aws_region_select: Select a region
|
||||
optional: Optional
|
||||
url: URL
|
||||
index:
|
||||
add: Add website
|
||||
resource: website
|
||||
title: Our websites
|
||||
new:
|
||||
back: Back to websites
|
||||
title: Let's add a new website
|
||||
next_page:
|
||||
load_more: Load more
|
||||
show:
|
||||
edit: Edit
|
||||
response_times: Response Times
|
||||
resource: ping
|
||||
update:
|
||||
success: >
|
||||
%{name} has been successfully updated.
|
||||
users:
|
||||
registrations:
|
||||
new:
|
||||
disable_registration: >
|
||||
If you already have an account, please sign in. Otherwise, you
|
||||
must be invited to join Storm.
|
||||
websites:
|
||||
create:
|
||||
success: >
|
||||
%{name} has been successfully added.
|
||||
|
@ -19,7 +19,7 @@ Rails.application.routes.draw do
|
||||
|
||||
resource(:settings, only: %w(edit update))
|
||||
resources(:users, only: %w(index))
|
||||
resources(:websites, only: %w(index new create show edit)) do
|
||||
resources(:websites, only: %w(index new create show edit update)) do
|
||||
scope(module: :websites) do
|
||||
namespace(:charts) do
|
||||
resources(:response_time, only: %w(index), path: 'response-time')
|
||||
|
@ -7,6 +7,9 @@ class CreateWebsites < ActiveRecord::Migration[5.1]
|
||||
t.boolean :active, index: true, default: true
|
||||
t.string :basic_auth_username
|
||||
t.string :basic_auth_password
|
||||
t.string :aws_instance_id
|
||||
t.string :aws_region
|
||||
t.boolean :rebooting, default: false
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
@ -100,6 +100,9 @@ ActiveRecord::Schema.define(version: 20170804190921) do
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.datetime "deleted_at"
|
||||
t.string "aws_instance_id"
|
||||
t.string "aws_region"
|
||||
t.boolean "rebooting", default: false
|
||||
t.index ["active"], name: "index_websites_on_active"
|
||||
t.index ["deleted_at"], name: "index_websites_on_deleted_at"
|
||||
t.index ["name"], name: "index_websites_on_name"
|
||||
|
@ -17,9 +17,11 @@
|
||||
"css-loader": "^0.28.4",
|
||||
"d3": "^4.10.2",
|
||||
"extract-text-webpack-plugin": "^3.0.0",
|
||||
"feather-icons": "^3.2.2",
|
||||
"file-loader": "^0.11.2",
|
||||
"glob": "^7.1.2",
|
||||
"js-yaml": "^3.9.0",
|
||||
"node-polyglot": "^2.2.2",
|
||||
"node-sass": "^4.5.3",
|
||||
"path-complete-extname": "^0.1.0",
|
||||
"postcss-loader": "^2.0.6",
|
||||
|
@ -5,6 +5,7 @@ class WebsitesControllerTest < ActionDispatch::IntegrationTest
|
||||
feature 'as as authenticated user' do
|
||||
before(:each) do
|
||||
@user = create(:user)
|
||||
@website = create(:website)
|
||||
sign_in(@user)
|
||||
end
|
||||
|
||||
@ -18,6 +19,19 @@ class WebsitesControllerTest < ActionDispatch::IntegrationTest
|
||||
assert_response(:success)
|
||||
end
|
||||
|
||||
test 'should get edit' do
|
||||
get(edit_website_path(@website))
|
||||
assert_response(:success)
|
||||
end
|
||||
|
||||
test 'should patch update' do
|
||||
assert_no_difference('Website.count') do
|
||||
patch(website_path(@website), params: params)
|
||||
assert_not_nil(flash[:success])
|
||||
assert_redirected_to(root_path)
|
||||
end
|
||||
end
|
||||
|
||||
test 'should post create' do
|
||||
assert_difference('Website.count') do
|
||||
post(websites_path, params: params)
|
||||
|
@ -1,5 +1,7 @@
|
||||
FactoryGirl.define do
|
||||
factory :setting do
|
||||
aws_key('aws_key')
|
||||
aws_secret('aws_secret')
|
||||
slack_url('127.0.0.1/slack')
|
||||
end
|
||||
end
|
||||
|
92
yarn.lock
92
yarn.lock
@ -1648,6 +1648,13 @@ deep-extend@~0.4.0:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
|
||||
|
||||
define-properties@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94"
|
||||
dependencies:
|
||||
foreach "^2.0.5"
|
||||
object-keys "^1.0.8"
|
||||
|
||||
defined@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
|
||||
@ -1788,6 +1795,24 @@ error-ex@^1.2.0:
|
||||
dependencies:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
es-abstract@^1.5.0:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.8.2.tgz#25103263dc4decbda60e0c737ca32313518027ee"
|
||||
dependencies:
|
||||
es-to-primitive "^1.1.1"
|
||||
function-bind "^1.1.1"
|
||||
has "^1.0.1"
|
||||
is-callable "^1.1.3"
|
||||
is-regex "^1.0.4"
|
||||
|
||||
es-to-primitive@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d"
|
||||
dependencies:
|
||||
is-callable "^1.1.1"
|
||||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.1"
|
||||
|
||||
es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14:
|
||||
version "0.10.24"
|
||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.24.tgz#a55877c9924bc0c8d9bd3c2cbe17495ac1709b14"
|
||||
@ -2011,6 +2036,10 @@ faye-websocket@~0.11.0:
|
||||
dependencies:
|
||||
websocket-driver ">=0.5.1"
|
||||
|
||||
feather-icons@^3.2.2:
|
||||
version "3.2.2"
|
||||
resolved "https://registry.yarnpkg.com/feather-icons/-/feather-icons-3.2.2.tgz#96c132e4a401d5cc18c03063c87999f47dce442b"
|
||||
|
||||
file-loader@^0.11.2:
|
||||
version "0.11.2"
|
||||
resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-0.11.2.tgz#4ff1df28af38719a6098093b88c82c71d1794a34"
|
||||
@ -2068,6 +2097,12 @@ flatten@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
|
||||
|
||||
for-each@^0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.2.tgz#2c40450b9348e97f281322593ba96704b9abd4d4"
|
||||
dependencies:
|
||||
is-function "~1.0.0"
|
||||
|
||||
for-in@^0.1.3:
|
||||
version "0.1.8"
|
||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1"
|
||||
@ -2088,6 +2123,10 @@ for-own@^1.0.0:
|
||||
dependencies:
|
||||
for-in "^1.0.1"
|
||||
|
||||
foreach@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
|
||||
|
||||
forever-agent@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||
@ -2154,6 +2193,10 @@ function-bind@^1.0.2:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771"
|
||||
|
||||
function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
|
||||
gauge@~2.7.3:
|
||||
version "2.7.4"
|
||||
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
|
||||
@ -2502,6 +2545,14 @@ is-builtin-module@^1.0.0:
|
||||
dependencies:
|
||||
builtin-modules "^1.0.0"
|
||||
|
||||
is-callable@^1.1.1, is-callable@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2"
|
||||
|
||||
is-date-object@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16"
|
||||
|
||||
is-directory@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
|
||||
@ -2544,6 +2595,10 @@ is-fullwidth-code-point@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
||||
|
||||
is-function@~1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5"
|
||||
|
||||
is-glob@^2.0.0, is-glob@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863"
|
||||
@ -2602,6 +2657,12 @@ is-primitive@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
|
||||
|
||||
is-regex@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
|
||||
dependencies:
|
||||
has "^1.0.1"
|
||||
|
||||
is-stream@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
@ -2612,6 +2673,10 @@ is-svg@^2.0.0:
|
||||
dependencies:
|
||||
html-comment-regex "^1.1.0"
|
||||
|
||||
is-symbol@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572"
|
||||
|
||||
is-typedarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
||||
@ -3164,6 +3229,15 @@ node-libs-browser@^2.0.0:
|
||||
util "^0.10.3"
|
||||
vm-browserify "0.0.4"
|
||||
|
||||
node-polyglot@^2.2.2:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/node-polyglot/-/node-polyglot-2.2.2.tgz#1a3f76d7392f836ea0823836ede817e6ea6ec26c"
|
||||
dependencies:
|
||||
for-each "^0.3.2"
|
||||
has "^1.0.1"
|
||||
string.prototype.trim "^1.1.2"
|
||||
warning "^3.0.0"
|
||||
|
||||
node-pre-gyp@^0.6.36:
|
||||
version "0.6.36"
|
||||
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.36.tgz#db604112cb74e0d477554e9b505b17abddfab786"
|
||||
@ -3273,6 +3347,10 @@ object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
|
||||
object-keys@^1.0.8:
|
||||
version "1.0.11"
|
||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d"
|
||||
|
||||
object-path@^0.9.2:
|
||||
version "0.9.2"
|
||||
resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.9.2.tgz#0fd9a74fc5fad1ae3968b586bda5c632bd6c05a5"
|
||||
@ -4661,6 +4739,14 @@ string-width@^2.0.0:
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
strip-ansi "^4.0.0"
|
||||
|
||||
string.prototype.trim@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea"
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
es-abstract "^1.5.0"
|
||||
function-bind "^1.0.2"
|
||||
|
||||
string_decoder@^0.10.25:
|
||||
version "0.10.31"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
|
||||
@ -4963,6 +5049,12 @@ vm-browserify@0.0.4:
|
||||
dependencies:
|
||||
indexof "0.0.1"
|
||||
|
||||
warning@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c"
|
||||
dependencies:
|
||||
loose-envify "^1.0.0"
|
||||
|
||||
watchpack@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac"
|
||||
|
Loading…
Reference in New Issue
Block a user