diff --git a/Gemfile b/Gemfile
index 19c12020..acfe37b7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -30,8 +30,6 @@ gem 'bcrypt', '~> 3.1.7'
# gem 'capistrano-rails', group: :development
gem 'activerecord-import'
-gem 'cells-rails' # TODO: remove
-gem 'cells-slim' # TODO: remove
gem 'chartkick'
gem 'groupdate'
gem 'hamlit'
@@ -49,7 +47,6 @@ gem 'activeadmin'
gem 'devise', '~> 4.4.0'
# Monitoring & metrics
-gem 'intercom-rails' # TODO: review
gem 'rollbar'
group :production do
gem 'rails_12factor'
@@ -63,7 +60,6 @@ group :development, :test do
gem 'capybara'
gem 'dotenv-rails'
gem 'factory_bot_rails'
- gem 'rspec-cells' # TODO: remove
gem 'rspec-rails', '3.5.2'
gem 'selenium-webdriver'
gem 'stripe-ruby-mock', require: 'stripe_mock'
diff --git a/Gemfile.lock b/Gemfile.lock
index ccefb9d3..8136cd13 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -73,17 +73,6 @@ GEM
rack (>= 1.6.0)
rack-test (>= 0.6.3)
xpath (~> 3.1)
- cells (4.1.7)
- declarative-builder (< 0.2.0)
- declarative-option (< 0.2.0)
- tilt (>= 1.4, < 3)
- uber (< 0.2.0)
- cells-rails (0.0.8)
- actionpack (>= 3.0)
- cells (>= 4.1.6, < 5.0.0)
- cells-slim (0.0.5)
- cells (>= 4.0.1, < 6.0.0)
- slim (~> 3.0)
chartkick (2.2.4)
childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11)
@@ -102,9 +91,6 @@ GEM
crass (1.0.4)
dante (0.2.0)
database_cleaner (1.6.1)
- declarative-builder (0.1.0)
- declarative-option (< 0.2.0)
- declarative-option (0.1.0)
devise (4.4.3)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
@@ -151,8 +137,6 @@ GEM
has_scope (~> 0.6)
railties (>= 4.2, <= 5.2)
responders
- intercom-rails (0.3.5)
- activesupport (> 3.0)
jbuilder (2.7.0)
activesupport (>= 4.2.0)
multi_json (>= 1.2)
@@ -274,9 +258,6 @@ GEM
netrc (~> 0.8)
rollbar (2.16.3)
multi_json
- rspec-cells (0.3.4)
- cells (>= 4.0.0, < 6.0.0)
- rspec-rails (~> 3.2)
rspec-core (3.5.4)
rspec-support (~> 3.5.0)
rspec-expectations (3.5.0)
@@ -325,9 +306,6 @@ GEM
activemodel (> 4, < 5.2)
sitemap_generator (5.3.1)
builder (~> 3.0)
- slim (3.0.8)
- temple (>= 0.7.6, < 0.9)
- tilt (>= 1.3.3, < 2.1)
slop (3.6.0)
spring (2.0.2)
activesupport (>= 4.2)
@@ -359,7 +337,6 @@ GEM
turbolinks-source (5.1.0)
tzinfo (1.2.5)
thread_safe (~> 0.1)
- uber (0.1.0)
uglifier (3.2.0)
execjs (>= 0.3.0, < 3)
unf (0.1.4)
@@ -399,8 +376,6 @@ DEPENDENCIES
bullet
byebug
capybara
- cells-rails
- cells-slim
chartkick
climate_control
database_cleaner
@@ -410,7 +385,6 @@ DEPENDENCIES
groupdate
hamlit
hashids
- intercom-rails
jbuilder (~> 2.5)
kaminari
listen (>= 3.0.5, < 3.2)
@@ -425,7 +399,6 @@ DEPENDENCIES
rails_12factor
redcarpet
rollbar
- rspec-cells
rspec-rails (= 3.5.2)
rubocop
sass-rails (~> 5.0)
diff --git a/app/admin/funder.rb b/app/admin/funder.rb
index d16e0820..38c5322e 100644
--- a/app/admin/funder.rb
+++ b/app/admin/funder.rb
@@ -1,5 +1,5 @@
ActiveAdmin.register Funder do
- permit_params :active, :microsite, :name, :primary_color, :secondary_color,
+ permit_params :active, :name, :primary_color, :secondary_color,
:slug, :website
controller do
@@ -16,7 +16,6 @@ def find_resource
link_to funder.name, [:admin, funder]
end
column :active
- column :microsite
column :funds do |funder|
funder.funds.size
end
@@ -32,7 +31,6 @@ def find_resource
row :charity_number
row :company_number
row :active
- row :microsite
row :primary_color
row :secondary_color
row :opportunities_last_updated_at
@@ -42,7 +40,6 @@ def find_resource
table_for funder.funds do
column :slug
column :active
- column :microsite
column :actions do |fund|
link_to 'View', [:admin, fund]
link_to 'Edit', [:edit_admin, fund]
@@ -56,7 +53,6 @@ def find_resource
f.input :slug
f.input :name
f.input :active
- f.input :microsite
f.input :primary_color, as: :string
f.input :secondary_color, as: :string
end
diff --git a/app/admin/recipient.rb b/app/admin/recipient.rb
index d5f947eb..09970910 100644
--- a/app/admin/recipient.rb
+++ b/app/admin/recipient.rb
@@ -1,66 +1,46 @@
ActiveAdmin.register Recipient do
- permit_params :name, :contact_number, :website, :street_address, :city,
- :region, :postal_code, :country, :charity_number,
- :company_number, :founded_on, :registered_on, :mission, :status,
- :registered, :active_on_beehive, organisation_ids: []
+ permit_params :category_name, :charity_number, :company_number, :country,
+ :description, :district, :income_band_name, :name,
+ :operating_for_name, :website
controller do
+ def scoped_collection
+ end_of_association_chain.includes(:country)
+ end
+
def find_resource
- scoped_collection.where(slug: params[:id]).first!
+ scoped_collection.find_by_hashid(params[:id])
end
end
filter :name
- filter :charity_number
- filter :company_number
- filter :country
- filter :registered
- filter :founded_on
+ filter :category_code
filter :created_at
+ filter :updated_at
index do
selectable_column
column :name
- column :website
+ column :category_name
column :country
- column :org_type
- column :street_address
- column :postal_code
- column :latitude
- column :longitude
+ column :created_at
actions
end
show do
- tabs do
- tab 'Overview' do
- attributes_table do
- row :id
- row :name
- row :mission
- row :status
- row :founded_on
- row(:registered) { status_tag(recipient.registered) }
- row :registered_on
- row :contact_number
- row :website
- row :charity_number
- row :company_number
- row('Users') do |recipient|
- recipient.users.each.map{|user| "
#{user.email} | Authorised: #{user.authorised}"}.join("").html_safe
- end
- end
- end
-
- tab 'Address' do
- attributes_table do
- row :street_address
- row :city
- row :region
- row :postal_code
- row :country
- end
- end
+ attributes_table do
+ row :id
+ row :name
+ row :category_name
+ row :description
+ row :charity_number
+ row :company_number
+ row :country
+ row :district
+ row :income_band_name
+ row :operating_for_name
+ row :website
+ row :user
end
end
end
diff --git a/app/admin/user.rb b/app/admin/user.rb
index bf7b10ae..ee8a7080 100644
--- a/app/admin/user.rb
+++ b/app/admin/user.rb
@@ -17,7 +17,7 @@
column :last_seen
actions
column 'Action' do |user|
- link_to 'Impersonate', impersonate_admin_user_path(user), target: '_blank'
+ link_to 'Impersonate', impersonate_admin_user_path(user), target: '_blank', rel: 'noopener'
end
end
diff --git a/app/assets/stylesheets/custom.sass b/app/assets/stylesheets/custom.sass
index 9dcd9648..8146cec3 100644
--- a/app/assets/stylesheets/custom.sass
+++ b/app/assets/stylesheets/custom.sass
@@ -9,6 +9,8 @@
max-width: 125px
@media screen and (max-width: 25rem)
max-width: 120px
+.crumb
+ margin: 0 5px
@media screen and (max-width: 46.875rem)
.bread, .crumb
display: none
@@ -146,6 +148,16 @@ article.featured
width: 32px
height: 30px
+nav
+ @media screen and (max-width: 30rem)
+ a
+ font-size: 15px
+ .mx20
+ margin-left: 10px
+ margin-right: 10px
+ .ml20
+ margin-left: 10px
+
#navbar-logo
width: 106px
height: 20px
diff --git a/app/cells/breadcrumb/show.slim b/app/cells/breadcrumb/show.slim
deleted file mode 100644
index e856dbd7..00000000
--- a/app/cells/breadcrumb/show.slim
+++ /dev/null
@@ -1,6 +0,0 @@
-.maxw1050.mx-auto.px15.fs14.mb30
- a.lh18.bread href= root_path class=@color Home
- - model.each_with_index do |(k, v), i|
- .crumb<> class=@color ›
- a.bread class=[disabled(v), bold(i), @color] href= v title=k
- .lh18.truncate= k
diff --git a/app/cells/breadcrumb_cell.rb b/app/cells/breadcrumb_cell.rb
deleted file mode 100644
index 963dea25..00000000
--- a/app/cells/breadcrumb_cell.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-class BreadcrumbCell < Cell::ViewModel
- def show
- return unless model.is_a?(Hash) && model.present?
-
- model.delete_if { |k, _v| k.nil? }
- @color = options[:color] || 'white'
- render
- end
-
- private
-
- def bold(i)
- i == model.size - 1 ? 'bold' : nil
- end
-
- def disabled(v)
- v.blank? ? "disabled #{@color}" : nil
- end
-end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 1432274a..ff8d8af4 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -7,8 +7,6 @@ class ApplicationController < ActionController::Base
before_action :current_user
- skip_after_action :intercom_rails_auto_include
-
rescue_from ActionController::InvalidAuthenticityToken, with: :bad_token
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorised
rescue_from ActionController::UnknownFormat do
diff --git a/app/helpers/breadcrumbs_helper.rb b/app/helpers/breadcrumbs_helper.rb
new file mode 100644
index 00000000..9bb44bb0
--- /dev/null
+++ b/app/helpers/breadcrumbs_helper.rb
@@ -0,0 +1,24 @@
+module BreadcrumbsHelper
+ def breadcrumbs(hash = {}, color: 'white')
+ items = []
+
+ hash.each_with_index do |(text, link), i|
+ items << tag.div('›', class: "crumb #{color}")
+
+ opts = link.blank? ? "disabled #{color}" : color
+
+ items << tag.a(
+ tag.div(text, class: 'truncate'),
+ class: "bread #{opts}", href: link
+ )
+ end
+
+ return if items.empty?
+
+ items.last.sub!('bread', 'bold bread')
+
+ "" \
+ "
Home" \
+ "#{items.join}
".html_safe
+ end
+end
diff --git a/app/helpers/reports_helper.rb b/app/helpers/reports_helper.rb
index a0311278..49688cd1 100644
--- a/app/helpers/reports_helper.rb
+++ b/app/helpers/reports_helper.rb
@@ -6,6 +6,10 @@ def amount_sought(proposal = @proposal)
"Between #{min} and #{max}"
end
+ def created_by(recipient = @proposal.recipient)
+ recipient.individual? ? 'an individual' : recipient.name
+ end
+
def location_description(proposal = @proposal)
"#{proposal.geographic_scale.capitalize} - " \
"#{proposal.countries.pluck(:name).to_sentence}"
diff --git a/app/models/application_record.rb b/app/models/application_record.rb
index 6c41a366..4fc0cfca 100644
--- a/app/models/application_record.rb
+++ b/app/models/application_record.rb
@@ -9,7 +9,7 @@ def markdown(str, plain: false)
options = { hard_wrap: true,
space_after_headers: true, fenced_code_blocks: true,
tables: true, footnotes: true,
- link_attributes: { target: '_blank' } }
+ link_attributes: { target: '_blank', rel: 'noopener' } }
extensions = { autolink: true, disable_indented_code_blocks: true }
diff --git a/app/models/assessment.rb b/app/models/assessment.rb
index 6a0410b8..b54dad9b 100755
--- a/app/models/assessment.rb
+++ b/app/models/assessment.rb
@@ -29,7 +29,7 @@ class Assessment < ApplicationRecord
]).freeze
belongs_to :fund
- belongs_to :proposal
+ belongs_to :proposal, counter_cache: true
belongs_to :recipient
validates :eligibility_status, inclusion: {
@@ -45,6 +45,9 @@ def self.analyse(funds, proposal)
def self.analyse_and_update!(funds, proposal)
updates = analyse(funds, proposal)
Assessment.import!(updates, on_duplicate_key_update: PERMITTED_COLUMNS)
+ Proposal.update_counters(
+ proposal.id, assessments_count: proposal.assessments.count
+ )
end
def attributes
diff --git a/app/models/fund.rb b/app/models/fund.rb
index 371c7e0c..f5b3d987 100644
--- a/app/models/fund.rb
+++ b/app/models/fund.rb
@@ -58,8 +58,11 @@ class Fund < ApplicationRecord
after_save do
funder.touch(:opportunities_last_updated_at)
themes.each { |t| t.touch(:opportunities_last_updated_at) }
+ update_counter_caches
end
+ after_destroy :update_counter_caches
+
def description_html
markdown(description)
end
@@ -93,6 +96,16 @@ def to_param
private
+ def update_counter_caches
+ funder.active_opportunities_count = funder.funds.active.size
+ funder.save
+
+ themes.each do |t|
+ t.active_opportunities_count = t.funds.active.size
+ t.save
+ end
+ end
+
def validate_integer_rules
%i[
proposal_min_amount proposal_max_amount proposal_min_duration
diff --git a/app/models/proposal.rb b/app/models/proposal.rb
index 85ef13f9..bb59f830 100755
--- a/app/models/proposal.rb
+++ b/app/models/proposal.rb
@@ -122,6 +122,10 @@ def category_name
CATEGORIES.values.reduce({}, :merge)[category_code]
end
+ def description_with_default
+ description || 'No description provided'.html_safe
+ end
+
def identifier
"##{id}"
end
@@ -155,6 +159,10 @@ def status
end
end
+ def title_with_default
+ title || 'No title provided'.html_safe
+ end
+
private
def clear_districts_if_country_wide
diff --git a/app/models/recipient.rb b/app/models/recipient.rb
index ebc88444..34958134 100644
--- a/app/models/recipient.rb
+++ b/app/models/recipient.rb
@@ -35,7 +35,6 @@ class Recipient < ApplicationRecord
belongs_to :district
belongs_to :user, optional: true
- has_one :subscription # TODO: remove after v3
has_one :proposal
has_many :assessments
@@ -69,10 +68,6 @@ class Recipient < ApplicationRecord
message: 'enter a valid website address e.g. http://www.example.com'
}, if: :website?
- def name=(s)
- self[:name] = s&.capitalize
- end
-
def charity_number=(s)
self[:charity_number] = s&.strip
end
diff --git a/app/models/subscription.rb b/app/models/subscription.rb
deleted file mode 100644
index f5ca568a..00000000
--- a/app/models/subscription.rb
+++ /dev/null
@@ -1,4 +0,0 @@
-# TODO: remove after v3
-class Subscription < ApplicationRecord
- belongs_to :recipient
-end
diff --git a/app/views/articles/index.html.haml b/app/views/articles/index.html.haml
index c5357ea7..3f8a1be8 100644
--- a/app/views/articles/index.html.haml
+++ b/app/views/articles/index.html.haml
@@ -3,7 +3,7 @@
%main.bg-ice
%header
= render partial: 'shared/nav', locals: { color: 'blue' }
- = cell(:breadcrumb, { 'Blog' => articles_path }, color: 'blue')
+ = breadcrumbs({ 'Blog' => articles_path }, color: 'blue')
%section.col2.mx-auto.mb40.px15
%h1.h2.center Blog
diff --git a/app/views/articles/show.html.haml b/app/views/articles/show.html.haml
index 53c94863..b84f8611 100644
--- a/app/views/articles/show.html.haml
+++ b/app/views/articles/show.html.haml
@@ -3,7 +3,7 @@
%main.bg-ice
%header
= render partial: 'shared/nav', locals: { color: 'blue' }
- = cell :breadcrumb, { 'Blog' => articles_path, @article.title => article_path(@article) }, color: 'blue'
+ = breadcrumbs({ 'Blog' => articles_path, @article.title => article_path(@article) }, color: 'blue')
%section.col2.mx-auto.my40.px15
.bg-white.rounded.shadow
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 5d7a44f8..7f322594 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -17,14 +17,16 @@
%iframe{:height => "0", :src => "https://www.googletagmanager.com/ns.html?id=GTM-W3BQHWD", :style => "display:none;visibility:hidden", :width => "0"}
- if !session[:read_cookies_notice]
- .fs14.lh18.white.bg-night.pt20.px20.flex.items-center.justify-between.flex-wrap{ style: 'position: fixed; bottom: 0; z-index: 9999;' }
- .mb20.md.f1
- We use cookies to give you the best experience on our website. In addition to strictly neccesary cookies, third party cookies may track your use of Beehive. If you continue without changing your settings, we'll assume that you are happy to receive all cookies.
- = link_to 'More about cookies', 'https://cookiesandyou.com/', class: 'white bold underline', target: '_blank'
-
- .mb20.md.flex.justify-center
- = link_to 'Change settings', privacy_path(anchor: 'cookies', read_cookies_notice: true), class: 'btn-sm white'
- = link_to 'Continue', update_cookies_path(functional_cookies: true, performance_cookies: true, read_cookies_notice: true), class: 'btn-sm bg-blue white shadow'
+ .bg-night.border-bottom.border-slate.fs14.lh18.white
+ .maxw1050.mx-auto.pt15.px15
+ .flex.flex-wrap
+ .mb15.md.col2
+ We use cookies to give you the best experience on our website. In addition to strictly neccesary cookies, third party cookies may track your use of Beehive. If you continue without changing your settings, we'll assume that you are happy to receive all cookies.
+ = link_to 'More about cookies', 'https://cookiesandyou.com/', class: 'white bold underline', target: '_blank', rel: 'noopener'
+
+ .mb15.md.col1.flex.justify-center.items-center
+ = link_to 'Change settings', privacy_path(anchor: 'cookies', read_cookies_notice: true), class: 'btn-sm white'
+ = link_to 'Continue', update_cookies_path(functional_cookies: true, performance_cookies: true, read_cookies_notice: true), class: 'btn-sm bg-blue white shadow'
-# TODO: spec
- if logged_in? && (@current_user&.update_version != UPDATE_VERSION)
diff --git a/app/views/opportunities/index.html.haml b/app/views/opportunities/index.html.haml
index 0d07b59d..bbbd436d 100644
--- a/app/views/opportunities/index.html.haml
+++ b/app/views/opportunities/index.html.haml
@@ -4,7 +4,7 @@
%header.bg-rich-blue
= render partial: 'shared/nav', locals: { color: 'white' }
- = cell(:breadcrumb, 'Opportunities' => opportunities_path)
+ = breadcrumbs('Opportunities' => opportunities_path)
.maxw1050.mx-auto.px15
%h1.h2.white.mb10 Pick the opportunity you’d like a suitability report for…
@@ -19,14 +19,14 @@
%h5.bold.slate Funding or support to offer?
.p20.night
.mb20 Do you provide grants or offer non- financial support to social sector organisations? Add your latest opportunities here, and we’ll get them listed on the website.
- = link_to('Add opportunity', add_opportunity_form_url('opportunities'), class: 'btn btn-wide blue bg-light-blue border-pale-blue', target: '_blank')
+ = link_to('Add opportunity', add_opportunity_form_url('opportunities'), class: 'btn btn-wide blue bg-light-blue border-pale-blue', target: '_blank', rel: 'noopener')
.border.border-mist.rounded.mb30
.p20.border-bottom.border-mist
%h5.bold.slate Don’t see the opportunities you’d like a report for?
.p20.night
.mb20 Let us know which opportunity you’d like to check and we’ll create you a custom report for a small fee.
- = link_to('Request custom report', add_opportunity_form_url('custom'), class: 'btn btn-wide blue bg-light-blue border-pale-blue', target: '_blank')
+ = link_to('Request custom report', add_opportunity_form_url('custom'), class: 'btn btn-wide blue bg-light-blue border-pale-blue', target: '_blank', rel: 'noopener')
.col2.px15.grid
- @opportunities.each do |opp|
@@ -37,8 +37,7 @@
.caps.grey.mb5= opp.class
%h3.mb10= opp.name
- -# TODO: opportunities count
- %p= pluralize(opp.funds.active.size, 'opportunity')
+ %p= pluralize(opp.active_opportunities_count, 'opportunity')
.px20.pb20.flex
= link_to 'Get report', new_recipient_path(opp), class: 'btn btn-wide white bg-blue'
diff --git a/app/views/opportunities/show.html.haml b/app/views/opportunities/show.html.haml
index 02905d5c..0e16f752 100644
--- a/app/views/opportunities/show.html.haml
+++ b/app/views/opportunities/show.html.haml
@@ -4,7 +4,7 @@
%header.bg-primary
= render partial: 'shared/nav', locals: { color: 'white' }
- = cell(:breadcrumb, 'Opportunities' => opportunities_path, @collection.name => opportunity_path(@collection))
+ = breadcrumbs('Opportunities' => opportunities_path, @collection.name => opportunity_path(@collection))
.maxw1050.mx-auto.pb20
.flex.flex-wrap.white
@@ -41,8 +41,7 @@
.f1
- unless report.private?
.night.h6.bold.mb5 Proposal
- -# TODO: default text for missing title from legacy record
- .mb15= report.title
+ .mb15= report.title_with_default
.night.h6.bold.mb5 Recipient
.mb20
diff --git a/app/views/pages/add_opportunity.html.haml b/app/views/pages/add_opportunity.html.haml
index 91c5a34e..e266619d 100644
--- a/app/views/pages/add_opportunity.html.haml
+++ b/app/views/pages/add_opportunity.html.haml
@@ -3,7 +3,7 @@
%main.bg-ice
%header
= render partial: 'shared/nav', locals: { color: 'blue' }
- = cell(:breadcrumb, { 'Add an opportunity' => add_opportunity_path }, color: 'blue')
+ = breadcrumbs({ 'Add an opportunity' => add_opportunity_path }, color: 'blue')
%section.col2.mx-auto
.center
@@ -16,7 +16,7 @@
%h1.bold.mb5 £50
.fs14.mb25.slate Per opportunity
.mb20 You submit details about an opportunity and we’ll work with you to make sure it’s added quickly and correctly.
- = link_to('Add verified opportunity', add_opportunity_form_url('verified'), class: 'btn btn-wide blue bg-light-blue border-pale-blue', target: '_blank')
+ = link_to('Add verified opportunity', add_opportunity_form_url('verified'), class: 'btn btn-wide blue bg-light-blue border-pale-blue', target: '_blank', rel: 'noopener')
.px20.py25.bg-white.shadow.rounded.flex.flex-column.justify-between
%div
@@ -24,7 +24,7 @@
%h1.bold.mb5 £199
.fs14.mb25.slate Per opportunity per year
.mb20 We gather all the details needed to add an opportunity, then add and manage it for you.
- = link_to('Add managed opportunity', add_opportunity_form_url('managed'), class: 'btn btn-wide blue bg-light-blue border-pale-blue', target: '_blank')
+ = link_to('Add managed opportunity', add_opportunity_form_url('managed'), class: 'btn btn-wide blue bg-light-blue border-pale-blue', target: '_blank', rel: 'noopener')
.bg-ice
= render partial: 'shared/footer', locals: { color: 'slate' }
\ No newline at end of file
diff --git a/app/views/pages/home.html.haml b/app/views/pages/home.html.haml
index e6a9dc07..afced767 100644
--- a/app/views/pages/home.html.haml
+++ b/app/views/pages/home.html.haml
@@ -1,9 +1,7 @@
-= content_for :title, 'My reports'
-
%header.bg-ice
= render partial: 'shared/nav', locals: { color: 'blue' }
-%main.bg-ice.flex
+%main.bg-ice.flex{ style: 'overflow-x: hidden;' }
.maxw1050.mx-auto.mt40.flex.flex-wrap.items-center
.col2.px15.mb40
%h1.bold.mb20 Save time and avoid wasted effort
@@ -20,7 +18,7 @@
The option to click on a few additional questions to rule [funders] in or out was a HUGE bonus for me – it saved me trawling through myriad websites to ascertain whether or not our project was eligible for funding.
.mt10.fs16.heading.bold.night
Karen,
- = link_to "Erb's Palsy Group", 'http://www.erbspalsygroup.co.uk/', target: '_blank'
+ = link_to "Erb's Palsy Group", 'http://www.erbspalsygroup.co.uk/', target: '_blank', rel: 'noopener'
.col2.mb40
.col1.md.px15#hex
diff --git a/app/views/pages/pricing.html.haml b/app/views/pages/pricing.html.haml
index 4db9781e..204a1ce1 100644
--- a/app/views/pages/pricing.html.haml
+++ b/app/views/pages/pricing.html.haml
@@ -3,7 +3,7 @@
%main.bg-ice
%header
= render partial: 'shared/nav', locals: { color: 'blue' }
- = cell(:breadcrumb, { 'Pricing' => pricing_path }, color: 'blue')
+ = breadcrumbs({ 'Pricing' => pricing_path }, color: 'blue')
%section.col2.mx-auto.mb40
.center.px15
diff --git a/app/views/pages/privacy.html.haml b/app/views/pages/privacy.html.haml
index 4175ba55..55340d2c 100644
--- a/app/views/pages/privacy.html.haml
+++ b/app/views/pages/privacy.html.haml
@@ -3,7 +3,7 @@
%main.bg-ice
%header
= render partial: 'shared/nav', locals: { color: 'blue' }
- = cell(:breadcrumb, { 'Privacy' => privacy_path }, color: 'blue')
+ = breadcrumbs({ 'Privacy' => privacy_path }, color: 'blue')
%section.col2.mx-auto.mb40.px15
.bg-white.rounded.shadow
@@ -65,7 +65,7 @@
%p.mb20
We use cookies to give you the best experience on our website. In addition to strictly neccesary cookies, third party cookies may track your use of Beehive. If you continue without changing your settings (below), we'll assume that you are happy to receive all cookies.
- = link_to 'More about cookies', 'https://cookiesandyou.com/', target: '_blank'
+ = link_to 'More about cookies', 'https://cookiesandyou.com/', target: '_blank', rel: 'noopener'
%h4 Strictly Necessary Cookies
.my15
diff --git a/app/views/pages/terms.html.haml b/app/views/pages/terms.html.haml
index 1b99702e..79bf1fab 100644
--- a/app/views/pages/terms.html.haml
+++ b/app/views/pages/terms.html.haml
@@ -1,10 +1,9 @@
= content_for :title, 'Terms of Service'
-
%main.bg-ice
%header
= render partial: 'shared/nav', locals: { color: 'blue' }
- = cell(:breadcrumb, { 'Terms' => terms_path }, color: 'blue')
+ = breadcrumbs({ 'Terms' => terms_path }, color: 'blue')
%section.col2.mx-auto.mb40.px15
.bg-white.rounded.shadow
@@ -76,10 +75,10 @@
Purchasing a 'Private' report is non-refundable.
%li.mb5
All payments made through Beehive are processed by Stripe. Beehive does not store any of the information you submit while making a purchase. Should you choose to purchase a 'Private' report on Beehive, you understand and acknowledge that the purchase transaction and the collection of your information is governed by the
- = link_to 'Stripe Terms of Service', 'https://stripe.com/gb/legal', target: '_blank', class: 'blue'
+ = link_to 'Stripe Terms of Service', 'https://stripe.com/gb/legal', target: '_blank', rel: 'noopener', class: 'blue'
and the
= succeed '.' do
- = link_to 'Stripe Privacy Policy', 'https://stripe.com/gb/privacy', target: '_blank', class: 'blue'
+ = link_to 'Stripe Privacy Policy', 'https://stripe.com/gb/privacy', target: '_blank', rel: 'noopener', class: 'blue'
%li.mb5
When making a payment you represent and warrant that: (i) you have the legal right to use any credit card(s) or other payment method(s) in connection with any purchase; and that (ii) the information you supply to us is true, correct and complete.
%li
diff --git a/app/views/proposals/new.html.haml b/app/views/proposals/new.html.haml
index a75abf85..3e0274e3 100644
--- a/app/views/proposals/new.html.haml
+++ b/app/views/proposals/new.html.haml
@@ -6,8 +6,7 @@
.center.mb40
.fs32.px5.white.heading= collection_title(@collection)
.fs16.py15.white Avoid wasted effort with a suitability report that helps you decide where to apply
- -# TODO: opportunities count
- .fs15.white.italic= pluralize(@collection.funds.active.size, 'opportunity')
+ .fs15.white.italic= pluralize(@collection.active_opportunities_count, 'opportunity')
.bg-white.rounded.shadow
@@ -119,7 +118,7 @@
.border-top.border-mist.pb10.pt30
.px20
.heading.fs18.bold.night.mb20 Consent
- .mb20= u.input :terms_agreed, as: :boolean, label: false, inline_label: "I accept the #{link_to('terms of service', terms_path, target: '_blank')} and #{link_to('privacy policy', privacy_path, target: '_blank')} * ".html_safe
+ .mb20= u.input :terms_agreed, as: :boolean, label: false, inline_label: "I accept the #{link_to('terms of service', terms_path, target: '_blank', rel: 'noopener')} and #{link_to('privacy policy', privacy_path, target: '_blank', rel: 'noopener')} * ".html_safe
.mb20= u.input :marketing_consent, as: :radio_buttons, required: true, label_html: { class: 'private' }
.border-top.border-mist.p20
@@ -128,7 +127,7 @@
.mt10.mb20= f.input :public_consent, as: :boolean, label: false, inline_label: 'I understand', hint: false
- = f.submit 'Get suitability report', class: 'btn-wide bg-rich-blue white shadow', data: { disable_with: 'Checking...' }
+ = f.submit 'Get suitability report', class: 'btn-wide bg-rich-blue white shadow', data: { disable_with: 'Creating report...' }
.bg-dark-blue
= render partial: 'shared/footer', locals: { color: 'white' }
diff --git a/app/views/recipients/new.html.haml b/app/views/recipients/new.html.haml
index f88e391a..d6255410 100644
--- a/app/views/recipients/new.html.haml
+++ b/app/views/recipients/new.html.haml
@@ -6,8 +6,7 @@
.center.mb40
.fs32.px5.white.heading= collection_title(@collection)
.fs16.py15.white Avoid wasted effort with a suitability report that helps you decide where to apply
- -# TODO: opportunities count
- .fs15.white.italic= pluralize(@collection.funds.active.size, 'opportunity')
+ .fs15.white.italic= pluralize(@collection.active_opportunities_count, 'opportunity')
.bg-white.rounded.shadow
diff --git a/app/views/report_mailer/notify.html.haml b/app/views/report_mailer/notify.html.haml
index bb2bd0f1..fdfd0af6 100644
--- a/app/views/report_mailer/notify.html.haml
+++ b/app/views/report_mailer/notify.html.haml
@@ -14,12 +14,12 @@
is ready.
%p
- = link_to('View full report', report_url(@proposal, t: @proposal.access_token), target: '_blank')
- = link_to('All my reports', sign_in_lookup_url(email: @user.email), target: '_blank')
+ = link_to('View full report', report_url(@proposal, t: @proposal.access_token), target: '_blank', rel: 'noopener')
+ = link_to('All my reports', sign_in_lookup_url(email: @user.email), target: '_blank', rel: 'noopener')
%p Please note
%p
Unless you opt to
= succeed ',' do
- = link_to('keep the report Private', new_charge_url(@proposal), target: '_blank')
+ = link_to('keep the report Private', new_charge_url(@proposal), target: '_blank', rel: 'noopener')
it will be added to a publically viewable directory that others can browse.
diff --git a/app/views/reports/index.html.haml b/app/views/reports/index.html.haml
index 3647bbc2..17c4ec4d 100644
--- a/app/views/reports/index.html.haml
+++ b/app/views/reports/index.html.haml
@@ -4,7 +4,7 @@
%header.bg-rich-blue
= render partial: 'shared/nav', locals: { color: 'white' }
- = cell(:breadcrumb, 'My reports' => reports_path)
+ = breadcrumbs('My reports' => reports_path)
.maxw1050.mx-auto.px15
%h1.h2.white.mb10 My reports
@@ -30,14 +30,13 @@
Created
= time_ago_in_words(report.created_at)
ago
- -# •
- -# TODO: opportunities count
+ •
+ = pluralize(report.assessments_count, 'opportunity')
.p20.flex.flex-column.f1
.f1
.night.h6.bold.mb5 Proposal
- -# TODO: default text for missing title from legacy record
- .mb15= report.title
+ .mb15= report.title_with_default
.night.h6.bold.mb5 Recipient
.mb20= recipient_name(report.recipient)
diff --git a/app/views/reports/show.html.haml b/app/views/reports/show.html.haml
index be10978d..fa45ff7c 100755
--- a/app/views/reports/show.html.haml
+++ b/app/views/reports/show.html.haml
@@ -6,9 +6,9 @@
= render partial: 'shared/nav', locals: { color: 'white' }
-# TODO: spec
- if @collection
- = cell(:breadcrumb, 'Opportunities' => opportunities_path, @collection.name => opportunity_path(@collection), @proposal.identifier => report_path(@proposal))
+ = breadcrumbs('Opportunities' => opportunities_path, @collection.name => opportunity_path(@collection), @proposal.identifier => report_path(@proposal))
- else
- = cell(:breadcrumb, 'Opportunities' => opportunities_path, "Report #{@proposal.identifier}" => report_path(@proposal))
+ = breadcrumbs('Opportunities' => opportunities_path, "Report #{@proposal.identifier}" => report_path(@proposal))
.maxw1050.mx-auto.px15.pb40
.flex.justify-between.white
@@ -20,8 +20,7 @@
-# TODO: status
-# .btn.border-white= @proposal.status.capitalize
Created for
- -# TODO: when individual?
- = @proposal.recipient.name
+ = created_by
= time_ago_in_words(@proposal.created_at)
ago
@@ -35,8 +34,7 @@
.mt40.flex.flex-wrap
.col2.px15
%h3.bold.night.mb40
- -# TODO: opportunities count
- = pluralize(@proposal.assessments.size, 'opportunity')
+ = pluralize(@proposal.assessments_count, 'opportunity')
checked
- @proposal.assessments.includes(fund: [:funder]).each do |a|
@@ -54,9 +52,9 @@
-# TODO: truncate
.mb15.markdown= raw(a.fund.description_html)
-# TODO: size
- = link_to 'Website', a.fund.website, target: '_blank', class: 'btn blue border-mist', onclick: "trackOutboundLink('#{a.fund.website}');"
+ = link_to 'Website', a.fund.website, target: '_blank', rel: 'noopener', class: 'btn blue border-mist', onclick: "trackOutboundLink('#{a.fund.website}');"
- a.fund.links.each do |text, href|
- = link_to text, href, target: '_blank', class: 'btn blue border-mist', onclick: "trackOutboundLink('#{href}');"
+ = link_to text, href, target: '_blank', rel: 'noopener', class: 'btn blue border-mist', onclick: "trackOutboundLink('#{href}');"
.p20.border-top-thick.border-bottom-thick{ class: a.banner.background }
.flex.items-center
@@ -79,12 +77,10 @@
%h6.bold.slate Proposal
.m20
.fs14.heading.bold.night.mb5 Title
- -# TODO: default text for missing title from legacy record
- .fs14.lh18.slate= @proposal.title
+ .fs14.lh18.slate= @proposal.title_with_default
.m20
.fs14.heading.bold.night.mb5 Description
- -# TODO: default text for missing description from legacy record
- .fs14.lh18.slate= @proposal.description
+ .fs14.lh18.slate= @proposal.description_with_default
.m20
.fs14.heading.bold.night.mb5 Support type
.fs14.lh18.slate= support_type
@@ -131,7 +127,7 @@
- if @proposal.recipient.website.present?
.m20
.fs14.heading.bold.night.mb5 Website
- = link_to(@proposal.recipient.website, @proposal.recipient.website, target: '_blank', class: 'fs14 slate', onclick: "trackOutboundLink('#{@proposal.recipient.website}');")
+ = link_to(@proposal.recipient.website, @proposal.recipient.website, target: '_blank', rel: 'noopener', class: 'fs14 slate', onclick: "trackOutboundLink('#{@proposal.recipient.website}');")
.bg-ice
= render partial: 'shared/footer', locals: { color: 'slate' }
diff --git a/app/views/shared/_footer.html.haml b/app/views/shared/_footer.html.haml
index 3c7d3357..fd95c2d3 100644
--- a/app/views/shared/_footer.html.haml
+++ b/app/views/shared/_footer.html.haml
@@ -18,4 +18,4 @@
= link_to('Privacy', privacy_path, class: 'mx10')
= link_to('Terms', terms_path, class: 'mx10')
- = link_to("© #{Date.today.year} CAST", 'http://www.wearecast.org.uk', class: 'ml10', target: '_blank', onclick: "trackOutboundLink('http://www.wearecast.org.uk');")
\ No newline at end of file
+ = link_to("© #{Date.today.year} CAST", 'http://www.wearecast.org.uk', class: 'ml10', target: '_blank', rel: 'noopener', onclick: "trackOutboundLink('http://www.wearecast.org.uk');")
\ No newline at end of file
diff --git a/app/views/shared/_head.html.haml b/app/views/shared/_head.html.haml
index 75952206..409cd8a7 100644
--- a/app/views/shared/_head.html.haml
+++ b/app/views/shared/_head.html.haml
@@ -6,8 +6,13 @@
= csrf_meta_tags
%meta{ content: 'width=device-width, initial-scale=1', name: 'viewport' }
+ %meta{ name: 'title', content: 'Beehive - Grant funding suitability checker' }
+ %meta{ name: 'description', content: 'A free grant funding suitability tool that uses a funders guidelines, priorities and open data to produce a report that helps you decide where to apply.' }
+
+ %meta{ property: 'og:type', content: 'website' }
+ %meta{ property: 'og:url', content: 'https://www.beehivegiving.org' }
%meta{ property: 'og:title', content: 'Beehive - Grant funding suitability checker' }
- %meta{ property: 'og:description', content: 'Save time and avoid wasted effort with a free suitability check of 120+ funds before applying' }
+ %meta{ property: 'og:description', content: 'A free grant funding suitability tool that uses a funders guidelines, priorities and open data to produce a report that helps you decide where to apply.' }
%meta{ property: 'og:image', content: asset_url('logo-social-1200x630.png') }
- if !allow_functional_cookies?
@@ -56,9 +61,6 @@
a.appendChild(r);
})(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv=');
- - if logged_in?
- = intercom_script_tag
-
-# Mixpanel
:javascript
(function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable time_event track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.set_once people.increment people.append people.union people.track_charge people.clear_charges people.delete_user".split(" ");
diff --git a/app/views/shared/_nav.html.haml b/app/views/shared/_nav.html.haml
index 50f9b29e..4754039a 100644
--- a/app/views/shared/_nav.html.haml
+++ b/app/views/shared/_nav.html.haml
@@ -1,4 +1,3 @@
--# TODO: responsive
.maxw1050.mx-auto.px15
%nav.pt20.mb7.heading.bold.flex.justify-between.items-center
= link_to 'Beehive', root_path, id: 'navbar-logo', alt: 'Beehive logo', class: color
diff --git a/app/views/sign_in/set/new.html.haml b/app/views/sign_in/set/new.html.haml
index d7fbe568..6ef63cb3 100644
--- a/app/views/sign_in/set/new.html.haml
+++ b/app/views/sign_in/set/new.html.haml
@@ -25,7 +25,7 @@
- if @user.terms_agreed != true
.mb20.field_with_errors
- = f.input :terms_agreed, as: :boolean, label: false, inline_label: "I accept the #{link_to('terms of service', terms_path, target: '_blank')} and #{link_to('privacy policy', privacy_path, target: '_blank')}".html_safe
+ = f.input :terms_agreed, as: :boolean, label: false, inline_label: "I accept the #{link_to('terms of service', terms_path, target: '_blank', rel: 'noopener')} and #{link_to('privacy policy', privacy_path, target: '_blank', rel: 'noopener')}".html_safe
.error= @user.errors[:terms_agreed][0]
= f.submit 'Continue', class: 'btn-wide bg-rich-blue white shadow', data: { disable_with: 'Setting...' }
diff --git a/config/initializers/intercom.rb b/config/initializers/intercom.rb
deleted file mode 100644
index 28e92291..00000000
--- a/config/initializers/intercom.rb
+++ /dev/null
@@ -1,92 +0,0 @@
-IntercomRails.config do |config|
- # == Intercom app_id
- #
- config.app_id = ENV['INTERCOM_APP_ID'] || 'i274pwcd'
-
- # == Intercom secret key
- # This is required to enable secure mode, you can find it on your Setup
- # guide in the "Secure Mode" step.
- #
- # config.api_secret = "..."
-
- # == Enabled Environments
- # Which environments is auto inclusion of the Javascript enabled for
- #
- config.enabled_environments = %w[production]
-
- # == Current user method/variable
- # The method/variable that contains the logged in user in your controllers.
- # If it is `current_user` or `@user`, then you can ignore this
- #
- # config.user.current = Proc.new { current_user }
-
- # == Include for logged out Users
- # If set to true, include the Intercom messenger on all pages, regardless of whether
- # The user model class (set below) is present. Only available for Apps on the Acquire plan.
- # config.include_for_logged_out_users = true
-
- # == User model class
- # The class which defines your user model
- #
- # config.user.model = Proc.new { User }
-
- # == Exclude users
- # A Proc that given a user returns true if the user should be excluded
- # from imports and Javascript inclusion, false otherwise.
- #
- # config.user.exclude_if = Proc.new { |user| user.deleted? }
-
- # == User Custom Data
- # A hash of additional data you wish to send about your users.
- # You can provide either a method name which will be sent to the current
- # user object, or a Proc which will be passed the current user.
- #
- # config.user.custom_data = {
- # :plan => Proc.new { |current_user| current_user.plan.name },
- # :favorite_color => :favorite_color
- # }
-
- # == User -> Company association
- # A Proc that given a user returns an array of companies
- # that the user belongs to.
- #
- # config.user.company_association = Proc.new { |user| user.companies.to_a }
- # config.user.company_association = Proc.new { |user| [user.company] }
-
- # == Current company method/variable
- # The method/variable that contains the current company for the current user,
- # in your controllers. 'Companies' are generic groupings of users, so this
- # could be a company, app or group.
- #
- # config.company.current = Proc.new { current_company }
-
- # == Company Custom Data
- # A hash of additional data you wish to send about a company.
- # This works the same as User custom data above.
- #
- # config.company.custom_data = {
- # :number_of_messages => Proc.new { |app| app.messages.count },
- # :is_interesting => :is_interesting?
- # }
-
- # == Company Plan name
- # This is the name of the plan a company is currently paying (or not paying) for.
- # e.g. Messaging, Free, Pro, etc.
- #
- # config.company.plan = Proc.new { |current_company| current_company.plan.name }
-
- # == Company Monthly Spend
- # This is the amount the company spends each month on your app. If your company
- # has a plan, it will set the 'total value' of that plan appropriately.
- #
- # config.company.monthly_spend = Proc.new { |current_company| current_company.plan.price }
- # config.company.monthly_spend = Proc.new { |current_company| (current_company.plan.price - current_company.subscription.discount) }
-
- # == Custom Style
- # By default, Intercom will add a button that opens the messenger to
- # the page. If you'd like to use your own link to open the messenger,
- # uncomment this line and clicks on any element with id 'Intercom' will
- # open the messenger.
- #
- # config.inbox.style = :custom
-end
diff --git a/config/routes.rb b/config/routes.rb
index 63ccd8a4..20ec9466 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -75,6 +75,7 @@
get '/fund/:slug', to: redirect('/opportunities')
get '/funds', to: redirect('/opportunities')
get '/funds/:slug', to: redirect('/opportunities')
+ get '/funds/theme/:slug', to: redirect('/opportunities')
get '/password_resets/new', to: redirect('/sign-in')
get '/welcome', to: redirect('/')
end
diff --git a/db/migrate/20181129165600_drop_status_from_recipients.rb b/db/migrate/20181129165600_drop_status_from_recipients.rb
new file mode 100644
index 00000000..6b44bbe0
--- /dev/null
+++ b/db/migrate/20181129165600_drop_status_from_recipients.rb
@@ -0,0 +1,5 @@
+class DropStatusFromRecipients < ActiveRecord::Migration[5.1]
+ def change
+ remove_column :recipients, :status, :string
+ end
+end
diff --git a/db/migrate/20181130111331_drop_subscriptions.rb b/db/migrate/20181130111331_drop_subscriptions.rb
new file mode 100644
index 00000000..05763804
--- /dev/null
+++ b/db/migrate/20181130111331_drop_subscriptions.rb
@@ -0,0 +1,5 @@
+class DropSubscriptions < ActiveRecord::Migration[5.1]
+ def change
+ drop_table :subscriptions
+ end
+end
diff --git a/db/migrate/20181130112454_remove_microsite_column_from_funders.rb b/db/migrate/20181130112454_remove_microsite_column_from_funders.rb
new file mode 100644
index 00000000..4eebc6f6
--- /dev/null
+++ b/db/migrate/20181130112454_remove_microsite_column_from_funders.rb
@@ -0,0 +1,5 @@
+class RemoveMicrositeColumnFromFunders < ActiveRecord::Migration[5.1]
+ def change
+ remove_column :funders, :microsite, :boolean
+ end
+end
diff --git a/db/migrate/20181130114527_add_assessments_count_to_proposals.rb b/db/migrate/20181130114527_add_assessments_count_to_proposals.rb
new file mode 100644
index 00000000..0c3d5225
--- /dev/null
+++ b/db/migrate/20181130114527_add_assessments_count_to_proposals.rb
@@ -0,0 +1,31 @@
+class AddAssessmentsCountToProposals < ActiveRecord::Migration[5.1]
+ def down
+ remove_column :proposals, :assessments_count
+ remove_column :funders, :active_opportunities_count
+ remove_column :themes, :active_opportunities_count
+ end
+
+ def up
+ add_column :proposals, :assessments_count, :integer, null: false, default: 0
+ add_column :funders, :active_opportunities_count, :integer, null: false, default: 0
+ add_column :themes, :active_opportunities_count, :integer, null: false, default: 0
+
+ Proposal.reset_column_information
+ Proposal.find_each do |p|
+ Proposal.reset_counters(p.id, :assessments)
+ print 'p'
+ end
+
+ Funder.reset_column_information
+ Funder.find_each do |f|
+ Funder.update_counters(f.id, active_opportunities_count: f.funds.active.size)
+ print 'f'
+ end
+
+ Theme.reset_column_information
+ Theme.find_each do |t|
+ Theme.update_counters(t.id, active_opportunities_count: t.funds.active.size)
+ print 't'
+ end
+ end
+end
diff --git a/db/migrate/20181130143755_remove_unused_fields_from_proposals.rb b/db/migrate/20181130143755_remove_unused_fields_from_proposals.rb
new file mode 100644
index 00000000..ee2d2910
--- /dev/null
+++ b/db/migrate/20181130143755_remove_unused_fields_from_proposals.rb
@@ -0,0 +1,42 @@
+class RemoveUnusedFieldsFromProposals < ActiveRecord::Migration[5.1]
+ def change
+ remove_column :proposals, :gender, :string
+ remove_column :proposals, :outcome1, :string
+ remove_column :proposals, :outcome2, :string
+ remove_column :proposals, :outcome3, :string
+ remove_column :proposals, :outcome4, :string
+ remove_column :proposals, :outcome5, :string
+ remove_column :proposals, :beneficiaries_other, :string
+ remove_column :proposals, :min_age, :integer
+ remove_column :proposals, :max_age, :integer
+ remove_column :proposals, :beneficiaries_count, :integer
+ remove_column :proposals, :activity_costs, :float
+ remove_column :proposals, :people_costs, :float
+ remove_column :proposals, :capital_costs, :float
+ remove_column :proposals, :other_costs, :float
+ remove_column :proposals, :activity_costs_estimated, :boolean
+ remove_column :proposals, :people_costs_estimated, :boolean
+ remove_column :proposals, :capital_costs_estimated, :boolean
+ remove_column :proposals, :other_costs_estimated, :boolean
+ remove_column :proposals, :all_funding_required, :boolean
+ remove_column :proposals, :beneficiaries_other_required, :boolean
+ remove_column :proposals, :type_of_support, :string
+ remove_column :proposals, :affect_people, :boolean
+ remove_column :proposals, :affect_other, :boolean
+ remove_column :proposals, :affect_geo, :integer
+ remove_column :proposals, :total_costs_estimated, :boolean
+ remove_column :proposals, :implementations_other_required, :boolean
+ remove_column :proposals, :implementations_other, :string
+ remove_column :proposals, :recommended_funds, :jsonb
+ remove_column :proposals, :eligibility, :jsonb
+ remove_column :proposals, :suitability, :jsonb
+ remove_column :proposals, :legacy, :boolean
+
+ drop_table :age_groups_proposals
+ drop_table :age_groups
+ drop_table :beneficiaries_proposals
+ drop_table :beneficiaries
+ drop_table :implementations_proposals
+ drop_table :implementations
+ end
+end
diff --git a/db/migrate/20181130152131_tidy_up_schema.rb b/db/migrate/20181130152131_tidy_up_schema.rb
new file mode 100644
index 00000000..5c011359
--- /dev/null
+++ b/db/migrate/20181130152131_tidy_up_schema.rb
@@ -0,0 +1,51 @@
+class TidyUpSchema < ActiveRecord::Migration[5.1]
+ def change
+ drop_table :attempts
+ drop_table :enquiries
+ drop_table :feedbacks
+ drop_table :requests
+
+ remove_column :recipients, :contact_number, :string
+ remove_column :recipients, :street_address, :string
+ remove_column :recipients, :city, :string
+ remove_column :recipients, :region, :string
+ remove_column :recipients, :postal_code, :string
+ remove_column :recipients, :country_alpha2, :string
+ remove_column :recipients, :mission, :text
+ remove_column :recipients, :founded_on, :date
+ remove_column :recipients, :registered_on, :date
+ remove_column :recipients, :registered, :boolean
+ remove_column :recipients, :active_on_beehive, :boolean
+ remove_column :recipients, :org_type, :boolean
+ remove_column :recipients, :latitude, :float
+ remove_column :recipients, :longitude, :float
+ remove_column :recipients, :contact_email, :string
+ remove_column :recipients, :charity_name, :string
+ remove_column :recipients, :charity_status, :string
+ remove_column :recipients, :charity_income, :float
+ remove_column :recipients, :charity_spending, :float
+ remove_column :recipients, :charity_recent_accounts_link, :string
+ remove_column :recipients, :charity_trustees, :string
+ remove_column :recipients, :charity_employees, :string
+ remove_column :recipients, :charity_volunteers, :string
+ remove_column :recipients, :charity_year_ending, :string
+ remove_column :recipients, :charity_days_overdue, :string
+ remove_column :recipients, :charity_registered_date, :string
+ remove_column :recipients, :company_name, :string
+ remove_column :recipients, :company_type, :string
+ remove_column :recipients, :company_status, :string
+ remove_column :recipients, :company_incorporated_date, :date
+ remove_column :recipients, :company_last_accounts_date, :date
+ remove_column :recipients, :company_next_accounts_date, :date
+ remove_column :recipients, :company_next_returns_date, :date
+ remove_column :recipients, :company_last_returns_date, :date
+ remove_column :recipients, :company_sic, :text
+ remove_column :recipients, :company_recent_accounts_link, :string
+ remove_column :recipients, :grants_count, :integer
+ remove_column :recipients, :multi_national, :boolean
+ remove_column :recipients, :employees, :integer
+ remove_column :recipients, :volunteers, :integer
+ remove_column :recipients, :funds_checked, :integer
+ remove_column :recipients, :income, :integer
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 73d0e10d..6a9c5b5f 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20181120150620) do
+ActiveRecord::Schema.define(version: 20181130152131) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -46,20 +46,6 @@
t.index ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true
end
- create_table "age_groups", id: :serial, force: :cascade do |t|
- t.string "label"
- t.integer "age_from"
- t.integer "age_to"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- end
-
- create_table "age_groups_proposals", id: :serial, force: :cascade do |t|
- t.integer "age_group_id"
- t.integer "proposal_id"
- t.index ["age_group_id", "proposal_id"], name: "index_age_groups_proposals_on_age_group_id_and_proposal_id"
- end
-
create_table "answers", id: :serial, force: :cascade do |t|
t.integer "category_id", null: false
t.integer "criterion_id", null: false
@@ -105,34 +91,6 @@
t.index ["recipient_id"], name: "index_assessments_on_recipient_id"
end
- create_table "attempts", force: :cascade do |t|
- t.bigint "funder_id"
- t.bigint "recipient_id"
- t.bigint "proposal_id"
- t.string "state", default: "basics", null: false
- t.string "access_token"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["funder_id"], name: "index_attempts_on_funder_id"
- t.index ["proposal_id"], name: "index_attempts_on_proposal_id"
- t.index ["recipient_id"], name: "index_attempts_on_recipient_id"
- end
-
- create_table "beneficiaries", id: :serial, force: :cascade do |t|
- t.string "label", limit: 255
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.string "category"
- t.string "sort"
- end
-
- create_table "beneficiaries_proposals", id: :serial, force: :cascade do |t|
- t.integer "beneficiary_id"
- t.integer "proposal_id"
- t.index ["beneficiary_id"], name: "index_beneficiaries_proposals_on_beneficiary_id"
- t.index ["proposal_id"], name: "index_beneficiaries_proposals_on_proposal_id"
- end
-
create_table "countries", id: :serial, force: :cascade do |t|
t.string "name", limit: 255
t.string "alpha2", limit: 255
@@ -205,33 +163,6 @@
t.index ["proposal_id"], name: "index_districts_proposals_on_proposal_id"
end
- create_table "enquiries", id: :serial, force: :cascade do |t|
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.integer "approach_funder_count", default: 0
- t.integer "fund_id"
- t.integer "proposal_id"
- t.index ["fund_id"], name: "index_enquiries_on_fund_id"
- t.index ["proposal_id"], name: "index_enquiries_on_proposal_id"
- end
-
- create_table "feedbacks", id: :serial, force: :cascade do |t|
- t.integer "user_id"
- t.integer "nps"
- t.integer "taken_away"
- t.integer "informs_decision"
- t.text "other"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.string "application_frequency"
- t.string "grant_frequency"
- t.string "marketing_frequency"
- t.integer "price"
- t.string "most_useful"
- t.integer "suitable"
- t.index ["user_id"], name: "index_feedbacks_on_user_id"
- end
-
create_table "fund_themes", force: :cascade do |t|
t.bigint "fund_id"
t.bigint "theme_id"
@@ -250,10 +181,10 @@
t.boolean "active", default: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
- t.boolean "microsite", default: false, null: false
t.string "primary_color"
t.string "secondary_color"
t.datetime "opportunities_last_updated_at", default: "2018-10-31 00:00:00", null: false
+ t.integer "active_opportunities_count", default: 0, null: false
t.index ["slug"], name: "index_funders_on_slug", unique: true
end
@@ -292,18 +223,6 @@
t.datetime "updated_at", null: false
end
- create_table "implementations", id: :serial, force: :cascade do |t|
- t.string "label", limit: 255
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- end
-
- create_table "implementations_proposals", id: :serial, force: :cascade do |t|
- t.integer "implementation_id"
- t.integer "proposal_id"
- t.index ["implementation_id", "proposal_id"], name: "index_implementations_proposals"
- end
-
create_table "proposal_themes", force: :cascade do |t|
t.bigint "proposal_id"
t.bigint "theme_id"
@@ -317,42 +236,12 @@
t.integer "recipient_id"
t.string "title"
t.string "description"
- t.string "gender"
- t.string "outcome1"
- t.string "outcome2"
- t.string "outcome3"
- t.string "outcome4"
- t.string "outcome5"
- t.string "beneficiaries_other"
- t.integer "min_age"
- t.integer "max_age"
- t.integer "beneficiaries_count"
t.integer "min_duration"
- t.float "activity_costs"
- t.float "people_costs"
- t.float "capital_costs"
- t.float "other_costs"
t.integer "min_amount"
- t.boolean "activity_costs_estimated", default: false
- t.boolean "people_costs_estimated", default: false
- t.boolean "capital_costs_estimated", default: false
- t.boolean "other_costs_estimated", default: false
- t.boolean "all_funding_required"
- t.boolean "beneficiaries_other_required"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
- t.string "type_of_support"
t.string "state", default: "complete"
- t.boolean "affect_people"
- t.boolean "affect_other"
- t.integer "affect_geo"
- t.boolean "total_costs_estimated", default: false
t.boolean "prevent_funder_verification"
- t.boolean "implementations_other_required"
- t.string "implementations_other"
- t.jsonb "recommended_funds", default: []
- t.jsonb "eligibility", default: {}, null: false
- t.jsonb "suitability", default: {}, null: false
t.integer "category_code"
t.boolean "public_consent"
t.string "support_details"
@@ -361,12 +250,12 @@
t.string "geographic_scale"
t.bigint "user_id"
t.string "access_token"
- t.boolean "legacy"
t.datetime "private"
t.bigint "collection_id"
t.string "collection_type"
t.bigint "duplicate_of"
t.datetime "migrated_on"
+ t.integer "assessments_count", default: 0, null: false
t.index ["collection_id"], name: "index_proposals_on_collection_id"
t.index ["collection_type"], name: "index_proposals_on_collection_type"
t.index ["recipient_id"], name: "index_proposals_on_recipient_id"
@@ -386,57 +275,14 @@
create_table "recipients", id: :serial, force: :cascade do |t|
t.string "name", limit: 255
- t.string "contact_number", limit: 255
t.string "website", limit: 255
- t.string "street_address", limit: 255
- t.string "city", limit: 255
- t.string "region", limit: 255
- t.string "postal_code", limit: 255
- t.string "country_alpha2", limit: 255
t.string "charity_number", limit: 255
t.string "company_number", limit: 255
t.string "slug", limit: 255
- t.text "mission"
- t.string "status", limit: 255, default: "Active - currently operational"
- t.date "founded_on"
- t.date "registered_on"
- t.boolean "registered"
- t.boolean "active_on_beehive"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
- t.integer "org_type"
- t.float "latitude"
- t.float "longitude"
- t.string "contact_email"
- t.string "charity_name"
- t.string "charity_status"
- t.float "charity_income"
- t.float "charity_spending"
- t.string "charity_recent_accounts_link"
- t.string "charity_trustees"
- t.string "charity_employees"
- t.string "charity_volunteers"
- t.string "charity_year_ending"
- t.string "charity_days_overdue"
- t.string "charity_registered_date"
- t.string "company_name"
- t.string "company_type"
- t.string "company_status"
- t.date "company_incorporated_date"
- t.date "company_last_accounts_date"
- t.date "company_next_accounts_date"
- t.date "company_next_returns_date"
- t.date "company_last_returns_date"
- t.text "company_sic", array: true
- t.string "company_recent_accounts_link"
- t.integer "grants_count", default: 0
t.integer "operating_for"
- t.boolean "multi_national"
t.integer "income_band"
- t.integer "employees"
- t.integer "volunteers"
- t.integer "funds_checked", default: 0, null: false
- t.integer "income"
t.jsonb "reveals", default: [], null: false
t.integer "category_code"
t.string "description"
@@ -451,29 +297,6 @@
t.index ["user_id"], name: "index_recipients_on_user_id"
end
- create_table "requests", force: :cascade do |t|
- t.bigint "fund_id"
- t.bigint "recipient_id"
- t.string "message"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.index ["fund_id"], name: "index_requests_on_fund_id"
- t.index ["recipient_id"], name: "index_requests_on_recipient_id"
- end
-
- create_table "subscriptions", id: :serial, force: :cascade do |t|
- t.integer "recipient_id"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
- t.string "stripe_user_id"
- t.boolean "active", default: false, null: false
- t.date "expiry_date"
- t.integer "percent_off", default: 0, null: false
- t.integer "version", default: 1, null: false
- t.index ["recipient_id"], name: "index_subscriptions_on_recipient_id"
- t.index ["stripe_user_id"], name: "index_subscriptions_on_stripe_user_id", unique: true
- end
-
create_table "themes", force: :cascade do |t|
t.string "name", null: false
t.integer "parent_id"
@@ -483,6 +306,7 @@
t.string "slug"
t.string "classes"
t.datetime "opportunities_last_updated_at", default: "2018-10-31 00:00:00", null: false
+ t.integer "active_opportunities_count", default: 0, null: false
t.index ["name"], name: "index_themes_on_name", unique: true
t.index ["parent_id"], name: "index_themes_on_parent_id"
t.index ["slug"], name: "index_themes_on_slug", unique: true
@@ -517,11 +341,6 @@
add_foreign_key "assessments", "funds"
add_foreign_key "assessments", "proposals"
add_foreign_key "assessments", "recipients"
- add_foreign_key "attempts", "funders"
- add_foreign_key "attempts", "proposals"
- add_foreign_key "attempts", "recipients"
- add_foreign_key "enquiries", "funds"
- add_foreign_key "enquiries", "proposals"
add_foreign_key "fund_themes", "funds"
add_foreign_key "fund_themes", "themes"
add_foreign_key "funds", "geo_areas"
diff --git a/lib/tasks/migrate.rake b/lib/tasks/migrate.rake
index eca5970c..29cfd232 100644
--- a/lib/tasks/migrate.rake
+++ b/lib/tasks/migrate.rake
@@ -21,11 +21,7 @@ namespace :migrate do
proposals = Proposal.where(recipient_id: recipient.id)
users = User.where(organisation_id: recipient.id)
- funds = if recipient&.subscription.try(:active)
- Fund.active
- elsif recipient.reveals.any?
- Fund.where(slug: recipient.reveals).active
- end
+ funds = Fund.where(slug: recipient.reveals).active if recipient.reveals.any?
return puts ': no Users' unless users.any?
diff --git a/spec/cells/breadcrumb_cell_spec.rb b/spec/cells/breadcrumb_cell_spec.rb
deleted file mode 100644
index d53d510c..00000000
--- a/spec/cells/breadcrumb_cell_spec.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-require 'rails_helper'
-
-describe BreadcrumbCell do
- controller ApplicationController
-
- it 'missing path option' do
- breadcrumb = cell(:breadcrumb).call(:show)
- expect(breadcrumb).not_to(have_css '.bread')
- end
-
- it 'path option empty' do
- breadcrumb = cell(:breadcrumb, {}).call(:show)
- expect(breadcrumb).not_to(have_css '.bread')
- end
-
- it '#bold' do
- breadcrumb = cell(:breadcrumb, 'a' => 'b').call(:show)
- expect(breadcrumb).to have_css('.bold', count: 1)
- end
-
- it '#disabled' do
- breadcrumb = cell(:breadcrumb, 'a' => nil).call(:show)
- expect(breadcrumb).to have_css('.disabled.white', count: 1)
- end
-
- it '#disabled with custom color' do
- breadcrumb = cell(:breadcrumb, { 'a' => nil }, color: 'blue').call(:show)
- expect(breadcrumb).to have_css('.disabled.blue', count: 1)
- end
-end
diff --git a/spec/helpers/breadcrumbs_helper_spec.rb b/spec/helpers/breadcrumbs_helper_spec.rb
new file mode 100644
index 00000000..c6c79407
--- /dev/null
+++ b/spec/helpers/breadcrumbs_helper_spec.rb
@@ -0,0 +1,35 @@
+require 'rails_helper'
+
+describe BreadcrumbsHelper do
+ class BreadcrumbsHelperClass
+ include ActionView::Helpers
+ include Rails.application.routes.url_helpers
+ include BreadcrumbsHelper
+ end
+
+ subject { BreadcrumbsHelperClass.new }
+
+ it 'hash option missing' do
+ expect(subject.breadcrumbs).to be_nil
+ end
+
+ it 'hash option empty' do
+ expect(subject.breadcrumbs({})).to be_nil
+ end
+
+ it 'bold' do
+ opts = { 'a' => 'b' }
+ expect(subject.breadcrumbs(opts)).to have_css('.bold', count: 1)
+ end
+
+ it 'disabled' do
+ opts = { 'a' => nil }
+ expect(subject.breadcrumbs(opts)).to have_css('.disabled', count: 1)
+ end
+
+ it 'custom color' do
+ opts = { 'a' => nil }
+ expect(subject.breadcrumbs(opts, color: 'blue'))
+ .to have_css('.blue', count: 3)
+ end
+end
diff --git a/spec/helpers/reports_helper_spec.rb b/spec/helpers/reports_helper_spec.rb
index df824aad..455c95bd 100644
--- a/spec/helpers/reports_helper_spec.rb
+++ b/spec/helpers/reports_helper_spec.rb
@@ -10,12 +10,24 @@ class ReportsHelperClass
subject { ReportsHelperClass.new }
let(:proposal) { create(:proposal) }
+ let(:recipient) { proposal.recipient }
it '#amount_sought' do
msg = 'Between £10,000 and £250,000'
expect(subject.amount_sought(proposal)).to eq(msg)
end
+ context '#created_by' do
+ it 'individual' do
+ recipient.category_code = 101
+ expect(subject.created_by(recipient)).to eq('an individual')
+ end
+
+ it 'organisation' do
+ expect(subject.created_by(recipient)).to eq(recipient.name)
+ end
+ end
+
it '#location_description' do
msg = "Local - #{proposal.countries.last.name}"
expect(subject.location_description(proposal)).to eq(msg)
@@ -23,22 +35,22 @@ class ReportsHelperClass
context '#recipient_type' do
it 'individual' do
- proposal.recipient.category_code = 101
- proposal.recipient.description = nil
- expect(subject.recipient_type(proposal.recipient)).to eq('An individual')
+ recipient.category_code = 101
+ recipient.description = nil
+ expect(subject.recipient_type(recipient)).to eq('An individual')
end
it 'organisation' do
msg = 'A charitable organisation - Charity registered in England & Wales'
- expect(subject.recipient_type(proposal.recipient)).to eq(msg)
+ expect(subject.recipient_type(recipient)).to eq(msg)
end
end
context '#recipient_name' do
it 'individual' do
- proposal.recipient.category_code = 101
- proposal.recipient.description = nil
- expect(subject.recipient_name(proposal.recipient)).to eq('An individual')
+ recipient.category_code = 101
+ recipient.description = nil
+ expect(subject.recipient_name(recipient)).to eq('An individual')
end
it 'organisation' do
diff --git a/spec/models/article_spec.rb b/spec/models/article_spec.rb
index 9876c35a..30721d53 100644
--- a/spec/models/article_spec.rb
+++ b/spec/models/article_spec.rb
@@ -28,7 +28,8 @@
it '#body_html returns html' do
html = '\n"
+ "target=\"_blank\" rel=\"noopener\">www.beehivegiving.org" \
+ "\n"
expect(subject.body_html).to eq(html)
end
end
diff --git a/spec/models/funder_spec.rb b/spec/models/funder_spec.rb
index c60a995e..c31a6c27 100644
--- a/spec/models/funder_spec.rb
+++ b/spec/models/funder_spec.rb
@@ -32,4 +32,29 @@
expect(create(:funder, name: 'Funder Name').slug).to eq 'funder-name-2'
end
end
+
+ context '#active_opportunities_count' do
+ it 'updated when active opportunity added' do
+ expect(subject.active_opportunities_count).to eq(0)
+ expect_opportunity_added
+ end
+
+ it 'updated when opportunity no longer active' do
+ expect_opportunity_added
+ @opportunity.update!(state: 'inactive')
+ expect(subject.active_opportunities_count).to eq(0)
+ end
+
+ it 'updated when opportunity destroyed' do
+ expect_opportunity_added
+ @opportunity.destroy
+ expect(subject.active_opportunities_count).to eq(0)
+ end
+ end
+
+ def expect_opportunity_added
+ @opportunity = build(:fund, state: 'active')
+ subject.update!(funds: [@opportunity])
+ expect(subject.active_opportunities_count).to eq(1)
+ end
end
diff --git a/spec/models/proposal_spec.rb b/spec/models/proposal_spec.rb
index b52d323b..bbe33309 100644
--- a/spec/models/proposal_spec.rb
+++ b/spec/models/proposal_spec.rb
@@ -250,6 +250,48 @@
end
end
+ context '#description_with_default' do
+ it 'missing' do
+ subject.description = nil
+ msg = 'No description provided'
+ expect(subject.description_with_default).to eq(msg)
+ end
+
+ it 'present' do
+ expect(subject.description_with_default).to eq(subject.description)
+ end
+ end
+
+ context '#title_with_default' do
+ it 'missing' do
+ subject.title = nil
+ msg = 'No title provided'
+ expect(subject.title_with_default).to eq(msg)
+ end
+
+ it 'present' do
+ expect(subject.title_with_default).to eq(subject.title)
+ end
+ end
+
+ context '#assessments_count' do
+ it 'updated when assessment added' do
+ expect(subject.assessments_count).to eq(0)
+ end
+
+ it 'updated when assessment destroyed' do
+ expect_assessment_added
+ @assessment.destroy
+ expect(subject.assessments_count).to eq(0)
+ end
+ end
+
+ def expect_assessment_added
+ @assessment = build(:assessment)
+ subject.update!(assessments: [@assessment])
+ expect(subject.assessments_count).to eq(1)
+ end
+
scenario '#country set'
scenario 'countries & districts properly cleared & last selection takes precedence'
diff --git a/spec/models/theme_spec.rb b/spec/models/theme_spec.rb
index fef976ec..0f54ce57 100644
--- a/spec/models/theme_spec.rb
+++ b/spec/models/theme_spec.rb
@@ -62,4 +62,28 @@
it('#primary_color') { expect(subject.primary_color).to eq(nil) }
it('#secondary_color') { expect(subject.primary_color).to eq(nil) }
+
+ context '#active_opportunities_count' do
+ it 'updated when active opportunity added' do
+ expect(subject.active_opportunities_count).to eq(0)
+ expect_opportunity_added
+ end
+
+ it 'updated when opportunity no longer active' do
+ expect_opportunity_added
+ @opportunity.update!(state: 'inactive')
+ expect(subject.active_opportunities_count).to eq(0)
+ end
+
+ it 'updated when opportunity destroyed' do
+ expect_opportunity_added
+ @opportunity.destroy
+ expect(subject.active_opportunities_count).to eq(0)
+ end
+ end
+
+ def expect_opportunity_added
+ @opportunity = create(:fund, state: 'active', themes: [subject])
+ expect(subject.active_opportunities_count).to eq(1)
+ end
end