mirror of
https://github.com/Evolix/chexpire.git
synced 2024-05-06 18:48:38 +02:00
Manual expiray date support for unsupported domain
Validation is made when leaving the input field with an ajax call on the /checks/support.json path. JSON response include the normalized domain name (more TODO) and the supported status. UI is updated with Javascript accordingly to this response. Closes #62
This commit is contained in:
parent
ef1229d900
commit
09be8a38c2
|
@ -3,7 +3,7 @@
|
|||
|
||||
class ChecksController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :set_check, except: [:index, :new, :create]
|
||||
before_action :set_check, except: [:index, :new, :create, :supports]
|
||||
after_action :verify_authorized, except: :index
|
||||
after_action :verify_policy_scoped, only: :index
|
||||
|
||||
|
@ -65,6 +65,11 @@ class ChecksController < ApplicationController
|
|||
redirect_to checks_path
|
||||
end
|
||||
|
||||
def supports
|
||||
@check = Check.new(new_check_params)
|
||||
authorize @check
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_check
|
||||
|
@ -81,7 +86,7 @@ class ChecksController < ApplicationController
|
|||
end
|
||||
|
||||
def check_params(*others)
|
||||
params.require(:check).permit(:domain, :domain_created_at, :comment, :vendor, *others,
|
||||
params.require(:check).permit(:domain, :domain_expires_at, :comment, :vendor, *others,
|
||||
notifications_attributes: [:id, :channel, :recipient, :interval])
|
||||
end
|
||||
|
||||
|
|
57
app/frontend/components/check_validation.js
Normal file
57
app/frontend/components/check_validation.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
// Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
|
||||
// License: GNU AGPL-3+ (see full text in LICENSE file)
|
||||
|
||||
function checkValidationInitialize() {
|
||||
const element = document.getElementById("check_domain");
|
||||
|
||||
if (element && element.dataset.kind == "domain") {
|
||||
addEventSupportListener(element);
|
||||
}
|
||||
}
|
||||
|
||||
function addEventSupportListener(element) {
|
||||
element.addEventListener("blur", event => {
|
||||
const request = $.ajax("/checks/supports.json", {
|
||||
method: "post",
|
||||
dataType: "json",
|
||||
data: {
|
||||
check: {
|
||||
domain: event.target.value,
|
||||
kind: element.dataset.kind,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
request.done(response => {
|
||||
const { supported } = response.check;
|
||||
|
||||
toggleUnsupportedContainers(supported);
|
||||
setFocus(supported);
|
||||
|
||||
// set normalized domain
|
||||
element.value = response.check.domain;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function toggleUnsupportedContainers(supported) {
|
||||
const containerClass = supported ? "d-none" : "d-block";
|
||||
|
||||
document.getElementById("check_domain_expires_at_container").className = containerClass;
|
||||
|
||||
const domainHint = document.getElementById("check_domain_unsupported_container");
|
||||
domainHint.classList.remove("d-none");
|
||||
domainHint.classList.remove("d-block");
|
||||
domainHint.classList.add(containerClass);
|
||||
}
|
||||
|
||||
|
||||
function setFocus(supported) {
|
||||
if (supported) {
|
||||
return;
|
||||
}
|
||||
|
||||
document.getElementById("check_domain_expires_at").focus();
|
||||
}
|
||||
|
||||
export default checkValidationInitialize;
|
|
@ -20,9 +20,13 @@ import 'bootstrap/js/dist/tooltip';
|
|||
|
||||
import '../scss';
|
||||
|
||||
import checkValidationInitialize from '../components/check_validation';
|
||||
|
||||
Rails.start()
|
||||
Turbolinks.start()
|
||||
|
||||
document.addEventListener("turbolinks:load", () => {
|
||||
$('[data-toggle="tooltip"]').tooltip();
|
||||
|
||||
checkValidationInitialize();
|
||||
});
|
||||
|
|
|
@ -51,6 +51,7 @@ class Check < ApplicationRecord
|
|||
validates :domain, presence: true
|
||||
validate :domain_created_at_past
|
||||
validate :domain_updated_at_past
|
||||
validates :domain_expires_at, presence: true, unless: :supported?
|
||||
validates :comment, length: { maximum: 255 }
|
||||
validates :vendor, length: { maximum: 255 }
|
||||
|
||||
|
|
|
@ -20,6 +20,10 @@ class CheckPolicy < ApplicationPolicy
|
|||
owner?
|
||||
end
|
||||
|
||||
def supports?
|
||||
new?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def owner?
|
||||
|
|
|
@ -3,13 +3,34 @@
|
|||
<%= simple_form_for(check) do |f| %>
|
||||
<%= f.input :domain,
|
||||
autofocus: true,
|
||||
input_html: { autocapitalize: :none, autocorrect: :off },
|
||||
label: t(".#{check.kind || "generic" }.domain") %>
|
||||
input_html: { autocapitalize: :none, autocorrect: :off, data: { kind: check.kind } },
|
||||
label: t(".#{check.kind || "generic" }.domain"),
|
||||
hint: t(".#{check.kind || "generic" }.unsupported"),
|
||||
hint_html: {
|
||||
id: "check_domain_unsupported_container",
|
||||
class: "#{check.supported? && 'd-none'}",
|
||||
}
|
||||
%>
|
||||
|
||||
<% if check.new_record? %>
|
||||
<%= f.input :kind, as: check.kind.present? ? :hidden : :radio_buttons, collection: Check.kinds.keys %>
|
||||
<% end %>
|
||||
|
||||
<div id="check_domain_expires_at_container" class="<%= check.supported? ? "d-none" : "d-block" %>">
|
||||
<%= f.input :domain_expires_at,
|
||||
required: true,
|
||||
input_html: {
|
||||
type: :string,
|
||||
value: check.domain_expires_at&.to_date,
|
||||
# min: Date.yesterday,
|
||||
# max: 10.years.from_now.end_of_year.to_date
|
||||
},
|
||||
as: :string,
|
||||
placeholder: t(".domain_expires_at_placeholder"),
|
||||
hint: t(".domain_expires_at_hint")
|
||||
%>
|
||||
</div>
|
||||
|
||||
<%= f.input :comment %>
|
||||
<%= f.input :vendor %>
|
||||
|
||||
|
|
7
app/views/checks/supports.json.jbuilder
Normal file
7
app/views/checks/supports.json.jbuilder
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
|
||||
# License: GNU AGPL-3+ (see full text in LICENSE file)
|
||||
|
||||
json.check do
|
||||
json.supported @check.supported?
|
||||
json.domain normalize_domain(@check.domain)
|
||||
end
|
|
@ -119,6 +119,12 @@ en:
|
|||
domain: Domain
|
||||
domain:
|
||||
domain: Domain name
|
||||
unsupported: |
|
||||
This top-level domain isn't currently automatically supported.
|
||||
You'll have to fill and maintain yourself the expiry date.
|
||||
domain_expires_at_hint: |
|
||||
Fill the expiry date in YYYY-MM-DD format.
|
||||
domain_expires_at_placeholder: YYYY-MM-DD.
|
||||
ssl:
|
||||
domain: Hostname
|
||||
notifications_hint: |
|
||||
|
|
|
@ -11,6 +11,7 @@ fr:
|
|||
kind: Type
|
||||
domain_created_at: "Date de création"
|
||||
domain_updated_at: "Date de modification"
|
||||
domain_expires_at: "Date d'expiration"
|
||||
notification:
|
||||
interval: Délai
|
||||
recipient: Destinataire
|
||||
|
@ -151,6 +152,12 @@ fr:
|
|||
domain: Domaine
|
||||
domain:
|
||||
domain: Nom de domaine
|
||||
unsupported: |
|
||||
Cette extension n'est pas supportée automatiquement actuellement.
|
||||
Vous devrez saisir et maintenir vous-même sa date d'expiration.
|
||||
domain_expires_at_hint: |
|
||||
Renseignez la date d'expiration au format AAAA-MM-JJ.
|
||||
domain_expires_at_placeholder: AAAA-MM-JJ
|
||||
ssl:
|
||||
domain: Nom d'hôte
|
||||
notifications_hint: |
|
||||
|
|
|
@ -1,10 +1,29 @@
|
|||
# Copyright (C) 2018 Colin Darie <colin@darie.eu>, 2018 Evolix <info@evolix.fr>
|
||||
# License: GNU AGPL-3+ (see full text in LICENSE file)
|
||||
|
||||
# In order to update the route map below,
|
||||
# run `bundle exec annotate -r` after modifying this file
|
||||
Rails.application.routes.draw do
|
||||
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
|
||||
|
||||
resources :checks, except: [:show] do
|
||||
resources :notifications, only: [:destroy]
|
||||
collection do
|
||||
post :supports, format: :json
|
||||
end
|
||||
end
|
||||
|
||||
devise_for :users
|
||||
root to: "pages#home"
|
||||
|
||||
mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
|
||||
end
|
||||
|
||||
# == Route Map
|
||||
#
|
||||
# Prefix Verb URI Pattern Controller#Action
|
||||
# check_notification DELETE /checks/:check_id/notifications/:id(.:format) notifications#destroy
|
||||
# supports_checks POST /checks/supports(.:format) checks#supports
|
||||
# checks GET /checks(.:format) checks#index
|
||||
# POST /checks(.:format) checks#create
|
||||
# new_check GET /checks/new(.:format) checks#new
|
||||
|
@ -44,18 +63,3 @@
|
|||
# letters GET / letter_opener_web/letters#index
|
||||
# letter GET /:id(/:style)(.:format) letter_opener_web/letters#show
|
||||
# GET /:id/attachments/:file(.:format) letter_opener_web/letters#attachment
|
||||
|
||||
# In order to update the route map above,
|
||||
# run `bundle exec annotate -r` after modifying this file
|
||||
Rails.application.routes.draw do
|
||||
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
|
||||
|
||||
resources :checks, except: [:show] do
|
||||
resources :notifications, only: [:destroy]
|
||||
end
|
||||
|
||||
devise_for :users
|
||||
root to: "pages#home"
|
||||
|
||||
mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ if Rails.env.development?
|
|||
# same name.
|
||||
Annotate.set_defaults(
|
||||
'routes' => 'before',
|
||||
'position_in_routes' => 'before',
|
||||
'position_in_routes' => 'after',
|
||||
'position_in_class' => 'before',
|
||||
'position_in_test' => 'before',
|
||||
'position_in_fixture' => 'before',
|
||||
|
|
|
@ -25,6 +25,26 @@ class ChecksTest < ApplicationSystemTestCase
|
|||
fill_and_valid_new_check
|
||||
end
|
||||
|
||||
test "create a manual domain check" do
|
||||
visit new_check_path(kind: :domain)
|
||||
|
||||
domain = "unsupported.wxyz"
|
||||
fill_in("check[domain]", with: domain)
|
||||
|
||||
page.find("body").click # simulate blur
|
||||
fill_in("check[domain_expires_at]", with: "2022-04-05")
|
||||
|
||||
click_button
|
||||
|
||||
assert_equal checks_path, page.current_path
|
||||
|
||||
assert page.has_css?(".alert-success")
|
||||
assert page.has_content?(domain)
|
||||
|
||||
check = Check.last
|
||||
assert_equal Date.new(2022, 4, 5), check.domain_expires_at
|
||||
end
|
||||
|
||||
test "create a predefined ssl check" do
|
||||
visit new_check_path(kind: :ssl)
|
||||
|
||||
|
|
Loading…
Reference in a new issue