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/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7a75ff78f..751e1d998 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" + + + 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 adf375041..f332dc2c4 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -349,6 +349,48 @@ 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 + # todo: extract to drapper. Then we can remove Domain#roles + def all_domains(page: nil, per: nil, params: {}) + # 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" + + + # 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") + 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] } + domains.each{|d| d.roles = domain_c[d.id].uniq} + + domains + end + def set_linked statuses << LINKED if statuses.detect { |s| s == LINKED }.blank? 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 0c319127b..52c7ec3c7 100644 --- a/app/views/admin/contacts/partials/_domains.haml +++ b/app/views/admin/contacts/partials/_domains.haml @@ -1,15 +1,30 @@ +- 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 %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'}=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 - - @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= x.roles.join(", ") + += paginate domains, param_name: :domain_page \ No newline at end of file