From af4e609a6d618adcd063bdacb27b4db605d908b8 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Wed, 4 Nov 2015 13:45:10 +0200 Subject: [PATCH 1/5] Story#105314040 In admin contacts show all domains. Roles are missing --- app/controllers/admin/contacts_controller.rb | 2 +- app/models/contact.rb | 20 +++++++++++++++++++ .../admin/contacts/partials/_domains.haml | 13 ++++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/app/controllers/admin/contacts_controller.rb b/app/controllers/admin/contacts_controller.rb index 1388db636..a1df165d2 100644 --- a/app/controllers/admin/contacts_controller.rb +++ b/app/controllers/admin/contacts_controller.rb @@ -45,7 +45,7 @@ class Admin::ContactsController < AdminController private def set_contact - @contact = Contact.includes(domains: :registrar).find(params[:id]) + @contact = Contact.find(params[:id]) end def contact_params diff --git a/app/models/contact.rb b/app/models/contact.rb index adf375041..8416aa971 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -349,6 +349,26 @@ class Contact < ActiveRecord::Base "#{code} #{name}" end + + # what we can do load firstly by registrant + # if total is smaller than needed, the load more + # we also need to sort by valid_to + def all_domains(page: nil, per: nil) + sql = %Q{id IN ( + select domain_id from domain_contacts where contact_id=#{id} + UNION + select id from domains where registrant_id=#{id} + )} + + + # sql = Domain.joins(:domain_contacts).where(domain_contacts: {contact_id: id}).select("#{Domain.table_name}.*".freeze, "'domain_contacts' AS style"). + # union(registrant_domains.select("#{Domain.table_name}.*".freeze, "'registrant_domains' AS style")).to_sql + # merged_sql = "select #{Domain.column_names.join(',')}, array_agg (t.style) over (partition by t.id) style from (#{sql} limit #{per.to_i}) t" + domains = Domain.where(sql).order("valid_to DESC NULLS LAST").includes(:registrar).page(page).per(per) + + domains + end + def set_linked statuses << LINKED if statuses.detect { |s| s == LINKED }.blank? end diff --git a/app/views/admin/contacts/partials/_domains.haml b/app/views/admin/contacts/partials/_domains.haml index 0c319127b..744f40744 100644 --- a/app/views/admin/contacts/partials/_domains.haml +++ b/app/views/admin/contacts/partials/_domains.haml @@ -1,15 +1,20 @@ +- domains = @contact.all_domains(page: params[:domain_page], per: 20) #contacts.panel.panel-default .panel-heading= t(:domains) .table-responsive %table.table.table-hover.table-bordered.table-condensed %thead %tr - %th{class: 'col-xs-4'}= t(:domain_name) - %th{class: 'col-xs-4'}= t(:registrar) - %th{class: 'col-xs-4'}= t(:valid_to) + %th{class: 'col-xs-3'}= t(:domain_name) + %th{class: 'col-xs-3'}= t(:registrar) + %th{class: 'col-xs-3'}= t(:valid_to) + %th{class: 'col-xs-3'}= t(:roles) %tbody - - @contact.registrant_domains.each do |x| + - domains.each do |x| %tr %td= link_to(x.name, [:admin, x]) %td= link_to(x.registrar, [:admin, x.registrar]) %td= l(x.valid_to, format: :short) + %td= t(:registrar) + += paginate domains, param_name: :domain_page \ No newline at end of file From 50983cd95d406649c1c379062d1d98f50450af09 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Wed, 4 Nov 2015 15:28:46 +0200 Subject: [PATCH 2/5] add roles to domans list --- app/models/contact.rb | 4 ++++ app/models/domain.rb | 2 ++ app/views/admin/contacts/partials/_domains.haml | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/app/models/contact.rb b/app/models/contact.rb index 8416aa971..e6a741192 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -365,6 +365,10 @@ class Contact < ActiveRecord::Base # union(registrant_domains.select("#{Domain.table_name}.*".freeze, "'registrant_domains' AS style")).to_sql # merged_sql = "select #{Domain.column_names.join(',')}, array_agg (t.style) over (partition by t.id) style from (#{sql} limit #{per.to_i}) t" domains = Domain.where(sql).order("valid_to DESC NULLS LAST").includes(:registrar).page(page).per(per) + domain_c = Hash.new([]) + registrant_domains.where(id: domains.map(&:id)).each{|d| domain_c[d.id] |= ["Registrant"].freeze } + DomainContact.where(contact_id: id, domain_id: domains.map(&:id)).each{|d| domain_c[d.domain_id] |= [d.type] } + domains.each{|d| d.roles = domain_c[d.id].uniq} domains end diff --git a/app/models/domain.rb b/app/models/domain.rb index c9d669b7d..da6d63e9f 100644 --- a/app/models/domain.rb +++ b/app/models/domain.rb @@ -4,6 +4,8 @@ class Domain < ActiveRecord::Base include Statuses has_paper_trail class_name: "DomainVersion", meta: { children: :children_log } + attr_accessor :roles + # TODO: whois requests ip whitelist for full info for own domains and partial info for other domains # TODO: most inputs should be trimmed before validatation, probably some global logic? diff --git a/app/views/admin/contacts/partials/_domains.haml b/app/views/admin/contacts/partials/_domains.haml index 744f40744..f99c0926d 100644 --- a/app/views/admin/contacts/partials/_domains.haml +++ b/app/views/admin/contacts/partials/_domains.haml @@ -15,6 +15,6 @@ %td= link_to(x.name, [:admin, x]) %td= link_to(x.registrar, [:admin, x.registrar]) %td= l(x.valid_to, format: :short) - %td= t(:registrar) + %td= x.roles.join(", ") = paginate domains, param_name: :domain_page \ No newline at end of file From 5dc550172d22e0fe095d7f00cdc848f716b0fda0 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Wed, 4 Nov 2015 16:23:01 +0200 Subject: [PATCH 3/5] add sorting to contact domains --- app/helpers/application_helper.rb | 12 ++++++++++ app/models/contact.rb | 23 ++++++++++++++----- .../admin/contacts/partials/_domains.haml | 8 +++---- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7a75ff78f..dea4f9228 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -55,4 +55,16 @@ module ApplicationHelper username ||= '' username.split(':').last.to_s.strip end + + def custom_sort_link(title, param_name) + sort = params.fetch(:sort, {})[param_name] + order = {"asc"=>"desc", "desc"=>"asc"}[sort] || "asc" + + # binding.pry + if params.fetch(:sort, {}).include?(param_name) + title += (sort == "asc" ? " ▲" : " ▼") + end + + link_to(title, url_for(sort: {param_name => order}), class: "sort_link #{order}") + end end diff --git a/app/models/contact.rb b/app/models/contact.rb index e6a741192..722f7e170 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -353,18 +353,29 @@ class Contact < ActiveRecord::Base # what we can do load firstly by registrant # if total is smaller than needed, the load more # we also need to sort by valid_to - def all_domains(page: nil, per: nil) - sql = %Q{id IN ( + def all_domains(page: nil, per: nil, params: {}) + sql = %Q{domains.id IN ( select domain_id from domain_contacts where contact_id=#{id} UNION select id from domains where registrant_id=#{id} )} + sorts = params.fetch(:sort, {}).first || [] + sort = Domain.column_names.include?(sorts.first) ? sorts.first : "valid_to" + order = {"asc"=>"desc", "desc"=>"asc"}[sorts.second] || "desc" - # sql = Domain.joins(:domain_contacts).where(domain_contacts: {contact_id: id}).select("#{Domain.table_name}.*".freeze, "'domain_contacts' AS style"). - # union(registrant_domains.select("#{Domain.table_name}.*".freeze, "'registrant_domains' AS style")).to_sql - # merged_sql = "select #{Domain.column_names.join(',')}, array_agg (t.style) over (partition by t.id) style from (#{sql} limit #{per.to_i}) t" - domains = Domain.where(sql).order("valid_to DESC NULLS LAST").includes(:registrar).page(page).per(per) + + domains = Domain.where(sql).includes(:registrar).page(page).per(per) + if sorts.first == "registrar_name".freeze + # using small rails hack to generate outer join + domains = domains.includes(:registrar).where.not(registrars: {id: nil}).order("registrars.name #{order} NULLS LAST") + else + domains = domains.order("#{sort} #{order} NULLS LAST") + end + + + + # adding roles. Need here to make faster sqls domain_c = Hash.new([]) registrant_domains.where(id: domains.map(&:id)).each{|d| domain_c[d.id] |= ["Registrant"].freeze } DomainContact.where(contact_id: id, domain_id: domains.map(&:id)).each{|d| domain_c[d.domain_id] |= [d.type] } diff --git a/app/views/admin/contacts/partials/_domains.haml b/app/views/admin/contacts/partials/_domains.haml index f99c0926d..32dd163da 100644 --- a/app/views/admin/contacts/partials/_domains.haml +++ b/app/views/admin/contacts/partials/_domains.haml @@ -1,13 +1,13 @@ -- domains = @contact.all_domains(page: params[:domain_page], per: 20) +- domains = @contact.all_domains(page: params[:domain_page], per: 20, params: params) #contacts.panel.panel-default .panel-heading= t(:domains) .table-responsive %table.table.table-hover.table-bordered.table-condensed %thead %tr - %th{class: 'col-xs-3'}= t(:domain_name) - %th{class: 'col-xs-3'}= t(:registrar) - %th{class: 'col-xs-3'}= t(:valid_to) + %th{class: 'col-xs-3'}=custom_sort_link t(:domain_name), :name + %th{class: 'col-xs-3'}=custom_sort_link t(:registrar), :registrar_name + %th{class: 'col-xs-3'}=custom_sort_link t(:valid_to), :valid_to %th{class: 'col-xs-3'}= t(:roles) %tbody - domains.each do |x| From 26b0ca7cdd13ac39c149a29e636754230305ead6 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Wed, 4 Nov 2015 16:24:13 +0200 Subject: [PATCH 4/5] Story#105314040 add sorting to contact domains (remove debug) --- app/helpers/application_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index dea4f9228..751e1d998 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -60,7 +60,7 @@ module ApplicationHelper sort = params.fetch(:sort, {})[param_name] order = {"asc"=>"desc", "desc"=>"asc"}[sort] || "asc" - # binding.pry + if params.fetch(:sort, {}).include?(param_name) title += (sort == "asc" ? " ▲" : " ▼") end From ae5e5abfbcd6109be3183f3a652d5adbc2558484 Mon Sep 17 00:00:00 2001 From: Vladimir Krylov Date: Wed, 4 Nov 2015 17:00:52 +0200 Subject: [PATCH 5/5] Story#105314040 filter domains under contacts --- app/models/contact.rb | 21 ++++++++++++------- .../admin/contacts/partials/_domains.haml | 12 ++++++++++- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/app/models/contact.rb b/app/models/contact.rb index 722f7e170..f332dc2c4 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -353,19 +353,26 @@ class Contact < ActiveRecord::Base # what we can do load firstly by registrant # if total is smaller than needed, the load more # we also need to sort by valid_to + # todo: extract to drapper. Then we can remove Domain#roles def all_domains(page: nil, per: nil, params: {}) - sql = %Q{domains.id IN ( - select domain_id from domain_contacts where contact_id=#{id} - UNION - select id from domains where registrant_id=#{id} - )} + # compose filter sql + filter_sql = case params[:domain_filter] + when "Registrant".freeze + %Q{select id from domains where registrant_id=#{id}} + when AdminDomainContact.to_s, TechDomainContact.to_s + %Q{select domain_id from domain_contacts where contact_id=#{id} AND type='#{params[:domain_filter]}'} + else + %Q{select domain_id from domain_contacts where contact_id=#{id} UNION select id from domains where registrant_id=#{id}} + end + # get sorting rules sorts = params.fetch(:sort, {}).first || [] sort = Domain.column_names.include?(sorts.first) ? sorts.first : "valid_to" order = {"asc"=>"desc", "desc"=>"asc"}[sorts.second] || "desc" - domains = Domain.where(sql).includes(:registrar).page(page).per(per) + # fetch domains + domains = Domain.where("domains.id IN (#{filter_sql})").includes(:registrar).page(page).per(per) if sorts.first == "registrar_name".freeze # using small rails hack to generate outer join domains = domains.includes(:registrar).where.not(registrars: {id: nil}).order("registrars.name #{order} NULLS LAST") @@ -377,7 +384,7 @@ class Contact < ActiveRecord::Base # adding roles. Need here to make faster sqls domain_c = Hash.new([]) - registrant_domains.where(id: domains.map(&:id)).each{|d| domain_c[d.id] |= ["Registrant"].freeze } + registrant_domains.where(id: domains.map(&:id)).each{|d| domain_c[d.id] |= ["Registrant".freeze] } DomainContact.where(contact_id: id, domain_id: domains.map(&:id)).each{|d| domain_c[d.domain_id] |= [d.type] } domains.each{|d| d.roles = domain_c[d.id].uniq} diff --git a/app/views/admin/contacts/partials/_domains.haml b/app/views/admin/contacts/partials/_domains.haml index 32dd163da..52c7ec3c7 100644 --- a/app/views/admin/contacts/partials/_domains.haml +++ b/app/views/admin/contacts/partials/_domains.haml @@ -1,6 +1,16 @@ - domains = @contact.all_domains(page: params[:domain_page], per: 20, params: params) #contacts.panel.panel-default - .panel-heading= t(:domains) + .panel-heading + .pull-left + = t(:domains) + .pull-right + = form_tag request.path, method: :get do + = select_tag :domain_filter, options_for_select(%w(Registrant AdminDomainContact TechDomainContact), selected: params[:domain_filter]), + include_blank: true, class: 'form-control2 selectize2' + %button.btn.btn-primary + %span.glyphicon.glyphicon-search + .clearfix + .table-responsive %table.table.table-hover.table-bordered.table-condensed %thead