Skip to content

Commit

Permalink
Merge pull request #1384 from alphagov/add-new-transition-form
Browse files Browse the repository at this point in the history
Add new transition form
  • Loading branch information
jkempster34 authored Sep 11, 2023
2 parents 7e6516b + 1f8f4ef commit 947d3d4
Show file tree
Hide file tree
Showing 19 changed files with 764 additions and 6 deletions.
52 changes: 49 additions & 3 deletions app/controllers/sites_controller.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
class SitesController < ApplicationController
before_action :find_site
before_action :find_site, only: %i[edit update show]
before_action :find_organisation, only: %i[new create]
before_action :check_user_is_gds_editor, only: %i[edit update]
before_action :check_user_is_site_manager, only: %i[new create]

def new
@site_form = SiteForm.new(organisation_slug: @organisation.whitehall_slug)
end

def create
@site_form = SiteForm.new(create_params)

if (site = @site_form.save)
redirect_to site_path(site), flash: { success: "Transition site created" }
else
render :new
end
end

def edit; end

def update
if @site.update(site_params)
if @site.update(update_params)
redirect_to site_path(@site), flash: { success: "Transition date updated" }
else
redirect_to edit_site_path(@site), flash: { alert: "We couldn't save your change" }
Expand All @@ -24,7 +40,30 @@ def find_site
@site = Site.find_by!(abbr: params[:id])
end

def site_params
def find_organisation
@organisation = Organisation.find_by(whitehall_slug: params[:organisation_id])
end

def create_params
params.require(:site_form).permit(
:organisation_slug,
:abbr,
:tna_timestamp,
:homepage,
:homepage_title,
:global_type,
:global_new_url,
:global_redirect_append_path,
:homepage_furl,
:hostname,
:query_params,
:special_redirect_strategy,
:aliases,
extra_organisations: [],
)
end

def update_params
params.require(:site).permit(:launch_date)
end

Expand All @@ -34,4 +73,11 @@ def check_user_is_gds_editor
redirect_to site_path(@site), alert: message
end
end

def check_user_is_site_manager
unless current_user.site_manager?
message = "Only Site Managers can access that."
redirect_to organisation_path(@organisation), alert: message
end
end
end
105 changes: 105 additions & 0 deletions app/forms/site_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
class SiteForm
include ActiveModel::Model
include ActiveModel::Attributes

attribute :organisation_slug
attribute :abbr
attribute :tna_timestamp, :datetime
attribute :homepage
attribute :homepage_title
attribute :extra_organisations
attribute :global_type
attribute :global_new_url
attribute :homepage_furl
attribute :query_params
attribute :global_redirect_append_path, :boolean, default: false
attribute :special_redirect_strategy

attribute :hostname
attribute :aliases

validate :validate_children
validate :validate_aliases
validate :aliases_are_unique

def save
return false if invalid?

ActiveRecord::Base.transaction do
site.save!
hosts.each(&:save!)
aka_hosts.each(&:save!)
end

site
end

def organisations
Organisation.where.not(whitehall_slug: organisation_slug)
end

private

def site
@site ||= Site.new(
abbr:,
tna_timestamp:,
homepage:,
organisation: Organisation.find_by(whitehall_slug: organisation_slug),
extra_organisations: Organisation.where(title: extra_organisations),
homepage_title:,
homepage_furl:,
global_type:,
global_new_url:,
global_redirect_append_path:,
query_params:,
special_redirect_strategy:,
)
end

def hosts
[default_host].concat(alias_hosts)
end

def aka_hosts
hosts.map { |host| build_aka_host(host) }
end

def default_host
@default_host ||= Host.new(hostname:, site:)
end

def alias_hosts
return [] if aliases.nil?

@alias_hosts ||= aliases.split(",").map do |host|
Host.new(hostname: host, site:)
end
end

def build_aka_host(host)
Host.new(hostname: host.aka_hostname, canonical_host: host, site:)
end

def validate_children
[site, default_host].each do |child|
errors.merge!(child.errors) if child.invalid?
end
end

def validate_aliases
alias_hosts.each do |host|
next if host.valid?

host.errors.each do |error|
errors.add(:aliases, "\"#{host.hostname}\" #{error.message}")
end
end
end

def aliases_are_unique
if alias_hosts.length != alias_hosts.map(&:hostname).uniq.length
errors.add(:aliases, "must be unique")
end
end
end
8 changes: 8 additions & 0 deletions app/models/concerns/nilify_blanks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@ module NilifyBlanks

def nilify_blanks
attributes.each do |column, value|
next if nilify_except.include?(column.to_sym)

self[column] = nil if value.blank?
end
end

private

def nilify_except
[]
end
end
9 changes: 8 additions & 1 deletion app/models/host.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class Host < ApplicationRecord
validates :hostname, presence: true
validates :hostname, hostname: true
validates :site, presence: true
validate :canonical_host_id_xor_aka_present
validate :canonical_host_id_xor_aka_present, if: -> { hostname.present? }
validate :hostname_is_downcased, if: -> { hostname.present? }

after_update :update_hits_relations, if: :saved_change_to_site_id?

Expand Down Expand Up @@ -71,4 +72,10 @@ def update_hits_relations
hits.update_all(mapping_id: nil)
Transition::Import::HitsMappingsRelations.refresh!(site)
end

def hostname_is_downcased
if hostname != hostname.downcase
errors.add(:hostname, "must be lowercase")
end
end
end
12 changes: 11 additions & 1 deletion app/models/site.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@
require "./lib/transition/path_or_url"

class Site < ApplicationRecord
include NilifyBlanks

GLOBAL_TYPES = %w[redirect archive].freeze
SPECIAL_REDIRECT_STRATEGY_TYPES = %w[via_aka supplier].freeze

belongs_to :organisation

has_many :hosts
Expand All @@ -20,8 +25,9 @@ class Site < ApplicationRecord
validates :organisation, presence: true
validates :homepage, presence: true, non_blank_url: true
validates :abbr, uniqueness: true, presence: true, format: { with: /\A[a-zA-Z0-9_-]+\z/, message: "can only contain alphanumeric characters, underscores and dashes" }
validates :special_redirect_strategy, inclusion: { in: %w[via_aka supplier], allow_nil: true }
validates :special_redirect_strategy, inclusion: { in: SPECIAL_REDIRECT_STRATEGY_TYPES, allow_blank: true }
validates :global_new_url, presence: { if: :global_redirect? }
validates :global_new_url, absence: { if: :global_archive? }
validates :global_new_url,
format: { without: /\?/,
message: "cannot contain a query when the path is appended",
Expand Down Expand Up @@ -131,4 +137,8 @@ def should_remove_unused_view?
def remove_all_hits_view
Postgres::MaterializedView.drop(precomputed_view_name)
end

def nilify_except
%i[global_redirect_append_path query_params precompute_all_hits_view]
end
end
4 changes: 4 additions & 0 deletions app/views/organisations/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
<%= render 'in_conjunction_with' %>
</header>

<% if current_user.site_manager? %>
<%= link_to "Add a transition site", new_organisation_site_path(@organisation), class: "btn btn-default" %>
<% end %>

<% unless @sites.empty? %>
<h2>Sites</h2>
<table class="sites table table-hover table-striped table-bordered" data-module="filterable-table">
Expand Down
120 changes: 120 additions & 0 deletions app/views/sites/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<% breadcrumb(:new_site, @organisation) %>

<div class="page-title-with-border">
<h1>New transition site</h1>
</div>

<%= form_for @site_form, html: { role: "form" }, url: organisation_sites_path do |form| %>
<%= render "shared/error_messages", error_messages: form.object.errors.full_messages %>

<div class="form-group row">
<div class="col-md-8">
<%= form.hidden_field :organisation_slug, value: @organisation.whitehall_slug %>

<div class="form-group">
<%= form.label :abbr %>
<%= form.text_field :abbr, class: "form-control", aria: { describedby: "abbr-help" } %>
<small id="abbr-help" class="form-text text-muted"><%= I18n.t("activemodel.hint.site_form.abbr") %></small>
</div>

<div class="form-group">
<%= form.label :tna_timestamp %>
<%= form.text_field :tna_timestamp, class: "form-control", aria: { describedby: "tna-timestamp-help" } %>
<small id="tna-timestamp-help" class="form-text text-muted"><%= I18n.t("activemodel.hint.site_form.tna_timestamp").html_safe %></small>
</div>

<div class="form-group">
<%= form.label :homepage %>
<%= form.text_field :homepage, class: "form-control", aria: { describedby: "homepage-help" } %>
<small id="homepage-help" class="form-text text-muted"><%= I18n.t("activemodel.hint.site_form.homepage") %></small>
</div>

<div class="form-group">
<%= form.label :hostname %>
<%= form.text_field :hostname, class: "form-control", aria: { describedby: "hostname-help" } %>
<small id="hostname-help" class="form-text text-muted"><%= I18n.t("activemodel.hint.site_form.hostname") %></small>
</div>

<div class="form-group">
<%= form.label :homepage_title %>
<%= form.text_field :homepage_title, class: "form-control", aria: { describedby: "homepage-title-help" } %>
<small id="homepage-title-help" class="form-text text-muted"><%= I18n.t("activemodel.hint.site_form.homepage_title") %></small>
</div>

<div class="form-group">
<%= form.label :extra_organisations %>
<%= form.collection_select :extra_organisations,
form.object.organisations,
:id,
:title,
{},
{ multiple: true, class: "form-control", aria: { describedby: "extra-organisations-help" } }
%>
<small id="extra-organisations-help" class="form-text text-muted"><%= I18n.t("activemodel.hint.site_form.extra_organisations") %></small>
</div>

<div class="form-group">
<%= form.label :homepage_furl %>
<%= form.text_field :homepage_furl, class: "form-control", aria: { describedby: "homepage-furl-help" } %>
<small id="homepage-furl-help" class="form-text text-muted"><%= I18n.t("activemodel.hint.site_form.homepage_furl") %></small>
</div>

<div class="form-group">
<%= form.label :global_type %>
<%= form.collection_radio_buttons :global_type,
Site::GLOBAL_TYPES,
:to_s,
:humanize,
aria: { describedby: "global-type-help" } do |button| %>
<div class="radio">
<%= button.label do %>
<%= button.radio_button + button.text %>
<% end %>
</div>
<% end %>
<small id="global-type-help" class="form-text text-muted"><%= I18n.t("activemodel.hint.site_form.global_type") %></small>
</div>

<div class="form-group">
<%= form.label :global_new_url %>
<%= form.text_field :global_new_url, class: "form-control" %>
</div>

<div class="form-group">
<%= form.label :query_params %>
<%= form.text_field :query_params, class: "form-control", aria: { describedby: "query-params-help" } %>
<small id="query-params-help" class="form-text text-muted row"><%= I18n.t("activemodel.hint.site_form.query_params") %></small>
</div>

<div class="form-check">
<%= form.label :global_redirect_append_path %>
<%= form.check_box :global_redirect_append_path, aria: { describedby: "global-redirect-append-path-help" } %>
<small id="global-redirect-append-path-help" class="form-text text-muted row"><%= I18n.t("activemodel.hint.site_form.global_redirect_append_path") %></small>
</div>

<div class="form-group">
<%= form.label :special_redirect_strategy %>
<%= form.collection_radio_buttons :special_redirect_strategy,
Site::SPECIAL_REDIRECT_STRATEGY_TYPES,
:to_s,
:humanize,
aria: { describedby: "special-redirect-strategy-help" } do |button| %>
<div class="radio">
<%= button.label do %>
<%= button.radio_button + button.text %>
<% end %>
</div>
<% end %>
<small id="special-redirect-strategy-help" class="form-text text-muted"><%= I18n.t("activemodel.hint.site_form.special_redirect_strategy") %></small>
</div>

<div class="form-group">
<%= form.label :aliases %>
<%= form.text_area :aliases, class: "form-control", aria: { describedby: "aliases-help" } %>
<small id="aliases-help" class="form-text text-muted"><%= I18n.t("activemodel.hint.site_form.aliases") %></small>
</div>

<%= form.submit 'Save', class: 'add-top-margin btn btn-success' %>
</div>
</div>
<% end %>
5 changes: 5 additions & 0 deletions config/breadcrumbs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
parent :root
end

crumb :new_site do |organisation|
link "New transition site"
parent :organisation, organisation
end

crumb :site do |site|
link site.default_host.hostname, site_path(site)
parent :organisation, site.organisation
Expand Down
Loading

0 comments on commit 947d3d4

Please sign in to comment.