Checks listing design & responsivity

This commit is contained in:
Colin Darie 2018-07-04 12:33:50 +02:00
parent cac52c1007
commit 9279d8eed4
No known key found for this signature in database
GPG Key ID: 4FB865FDBCA4BCC4
12 changed files with 143 additions and 27 deletions

View File

@ -12,6 +12,7 @@ import Turbolinks from 'turbolinks';
import 'bootstrap/js/dist/collapse';
import 'bootstrap/js/dist/dropdown';
import 'bootstrap/js/dist/button';
import '../scss';

View File

@ -0,0 +1,10 @@
$input-placeholder-color: #adb5bd;
$enable-rounded: false;
$theme-colors: (
"primary": #259EDB,
"secondary": #565554,
"success": #42935C,
"warning": #F6AE2D,
"danger": #E94F37,
"info": #2E86AB,
);

View File

@ -1,3 +1,4 @@
@import '_variables';
@import '~bootstrap/scss/bootstrap';
@import 'layout';
@import 'icons';

View File

@ -1,4 +1,8 @@
module ApplicationHelper
def format_date(time, format: :long)
l(time.utc.to_date, format: format)
end
def format_utc(time, format: :default)
l(time.utc, format: format)
end

View File

@ -1,15 +1,11 @@
module ChecksHelper
def check_kind_label(check)
check.kind.upcase
end
def check_row_class(check)
expiry_date = check.domain_expires_at
return unless expiry_date.present?
return "table-danger" if expiry_date <= 2.weeks.from_now
return "table-warning" if expiry_date <= 30.days.from_now
return "table-danger" if expiry_date <= 3.days.from_now
return "table-warning" if expiry_date < 1.month.from_now
end
def checks_sort_links(field)
@ -19,7 +15,7 @@ module ChecksHelper
sort = "#{field}_#{direction}"
icon = direction == :asc ? "chevron-up" : "chevron-down"
html = Octicons::Octicon.new(icon).to_svg.html_safe
html = Octicons::Octicon.new(icon, class: "mx-1").to_svg.html_safe
filter_params = current_criterias.merge(sort: sort)
link_to_unless sort == current_sort_str, html, checks_path(filter_params)
@ -29,4 +25,28 @@ module ChecksHelper
def current_criterias
current_scopes.merge(sort: params[:sort])
end
def scoped_with?(scope)
name, value = scope.first
scope_value = current_scopes[name]
scope_value = scope_value.to_sym if scope_value.respond_to?(:to_sym)
scope_value == value
end
def check_button_criterias(scope)
if scoped_with?(scope)
current_criterias.except(scope.keys.first)
else
current_criterias.merge(scope)
end
end
def check_button_scope_class(scope = nil)
"btn btn-sm " << if scope && scoped_with?(scope)
"btn-info active"
else
"btn-outline-info"
end
end
end

View File

@ -61,8 +61,8 @@ class Check < ApplicationRecord
scope :kind, ->(kind) { where(kind: kind) }
scope :by_domain, ->(domain) { where("domain LIKE ?", "%#{domain}%") }
scope :recurrent_failures, -> {
where("last_run_at IS NOT NULL").
where("last_success_at IS NULL OR last_success_at <= DATE_SUB(last_run_at, INTERVAL 72 HOUR)")
where("last_run_at IS NOT NULL")
.where("last_success_at IS NULL OR last_success_at <= DATE_SUB(last_run_at, INTERVAL 3 DAY)")
}
def self.default_sort

View File

@ -0,0 +1,40 @@
<div class="row justify-content-md-end">
<div class="col-md-6 mb-3 d-flex justify-content-between justify-content-md-start">
<div class="btn-group mr-2">
<% Check.kinds.keys.map(&:to_sym).each do |kind_name| %>
<%= link_to t(".kind_#{kind_name}"),
checks_path(check_button_criterias(kind: kind_name)),
class: check_button_scope_class(kind: kind_name) %>
<% end %>
</div>
<%= link_to t(".with_error"),
checks_path(check_button_criterias(recurrent_failures: true)),
class: check_button_scope_class(recurrent_failures: true) %>
</div>
<div class="col-md-6 mb-3">
<%= form_tag(checks_path, method: :get) do %>
<div class="form-row justify-content-around">
<div class="col">
<div class="input-group">
<%= search_field_tag :by_domain, current_scopes[:by_domain], class: "form-control form-control-sm", placeholder: ".com, example.org, …" %>
<div class="input-group-append">
<%= button_tag Octicons::Octicon.new("search").to_svg.html_safe, class: "btn btn-sm btn-outline-secondary" %>
</div>
</div>
<%- current_criterias.except(:by_domain).compact.each_pair do |name, value| %>
<%= hidden_field_tag name, value%>
<% end %>
</div>
<div class="col-auto">
<%= link_to Octicons::Octicon.new("x").to_svg.html_safe, checks_path, class: "btn btn-danger btn-sm btn-outline-danger" %>
</div>
</div>
<% end %>
</div>
</div>

View File

@ -1,32 +1,39 @@
<div class="mb-4">
<div class="mb-4 table-responsive">
<table class="table table-checks">
<thead>
<tr>
<th scope="col"></th>
<th scope="col">
<%= t(".domain") %>
<%== checks_sort_links(:domain) %>
<span class="sort-links mx-sm-3 text-nowrap">
<%== checks_sort_links(:domain) %>
</span>
</th>
<th scope="col">
<%= t(".expiry_date") %>
<%== checks_sort_links(:domain_expires_at) %>
<span class="sort-links mx-sm-3 text-nowrap">
<%== checks_sort_links(:domain_expires_at) %>
</span>
</th>
<th scope="col"><%= t(".edit") %></th>
<th scope="col" class="text-center"><%= t(".edit") %></th>
</tr>
</thead>
<tbody>
<% checks.each do |check| %>
<tr class="check-row <%= check_row_class(check) %>">
<td>
<span class="badge badge-secondary"><%= check_kind_label(check) %></span>
<span class="badge badge-info"><%= t(".kind_labels.#{check.kind}") %></span>
</td>
<td>
<strong><%= check.domain %></strong>
</td>
<td>
<%= format_utc(check.domain_expires_at) if check.domain_expires_at.present? %>
<% if check.domain_expires_at.present? %>
<%= content_tag :span, format_date(check.domain_expires_at), class: "d-none d-md-inline" %>
<%= content_tag :span, format_date(check.domain_expires_at, format: :short), class: "d-inline d-md-none" %>
<% end %>
</td>
<td class="action">
<td class="action text-center">
<%= link_to edit_check_path(check) do %>
<%== Octicons::Octicon.new("pencil").to_svg %>
<% end %>

View File

@ -1,19 +1,14 @@
<div class="container">
<div class="container-fluid">
<div class="row justify-content-center">
<div class="col-12 col-lg-10">
<div class="col-12 col-lg-10 col-xl-8">
<% if @checks.empty? && current_scopes.blank? %>
<div class="alert alert-info">
<%= t(".no_check_yet_html", new_domain_path: new_check_path(kind: :domain), new_ssl_path: new_check_path(kind: :ssl)) %>
</div>
<% else %>
<h1><%= t(".title") %></h1>
<%= link_to("Domains", checks_path(current_criterias.merge(kind: :domain))) %>
<%= link_to("SSL", checks_path(current_criterias.merge(kind: :ssl))) %>
<%= link_to("In error", checks_path(current_criterias.merge(recurrent_failures: true))) %>
<%= form_tag(checks_path(current_scopes), method: :get) do %>
<%= search_field_tag :by_domain, current_scopes[:by_domain] %>
<%= button_tag t(".filter") %>
<% end %>
<h1 class="mb-3 mb-sm-5"><%= t(".title") %></h1>
<%= render "filters" %>
<% if @checks.any? %>
<%= render "table", checks: @checks %>

View File

@ -12,6 +12,11 @@ en:
check:
past: "can't be in the future"
date:
formats:
short: "%-d, %b %Y"
long: "%A, %B %d, %Y"
devise:
registrations:
new:
@ -64,6 +69,7 @@ en:
checks:
index:
title: List of your checks
no_matching_check: "No checks match your filters."
no_check_yet_html: |
You have not set up a check yet.
Please add a <a href="%{new_domain_path}">domain</a>
@ -80,6 +86,11 @@ en:
saved: "Your check has been saved."
invalid: "Please check the form."
filters:
kind_domain: Domain
kind_ssl: SSL
with_error: Error
form:
generic:
domain: Domain
@ -90,3 +101,11 @@ en:
notifications_hint: |
Receive notifications to warn you when our system detects that the
expiration date is coming. The time is set in number of days.
table:
domain: Name
expiry_date: Expiration
edit: Edit
kind_labels:
domain: Domain
ssl: SSL

View File

@ -47,6 +47,11 @@ fr:
short: "%d %b %H:%M"
pm: pm
date:
formats:
short: "%d/%m/%Y"
long: "%A %d %B %Y"
devise:
registrations:
new:
@ -99,6 +104,7 @@ fr:
checks:
index:
title: "Liste de vos vérifications"
no_matching_check: "Aucune vérification ne correspond à vos critères."
no_check_yet_html: |
Vous n'avez pas encore créé de vérification.
Vous pouvez en ajouter pour un <a href="%{new_domain_path}">domaine</a>
@ -115,6 +121,11 @@ fr:
saved: La vérification est enregistrée.
invalid: Veuillez vérifier le formulaire.
filters:
kind_domain: Domaine
kind_ssl: SSL
with_error: En erreur
form:
generic:
domain: Domaine
@ -125,3 +136,11 @@ fr:
notifications_hint: |
Recevez des notifications pour vous avertir lorsque notre système détecte
que la date d'expiration approche. Le délai est indiqué ennombre de jours.
table:
domain: Nom
expiry_date: "Expiration"
edit: Modifier
kind_labels:
domain: Domaine
ssl: SSL

View File

@ -76,7 +76,7 @@ ssl_check_chexpire_org_error = Check.create!(
user: [user1, user2].sample,
kind: Check.kinds.keys.sample,
domain: "#{word}.#{ext}",
domain_expires_at: rand(1..300).days.from_now,
domain_expires_at: rand(8..300).days.from_now,
domain_updated_at: rand(1..300).days.ago,
domain_created_at: rand(301..3000).days.ago,
)