Skip to content

Commit

Permalink
Merge pull request #8543 from CitizenLabDotCo/TAN-2393-fix-contrast-o…
Browse files Browse the repository at this point in the history
…f-empty-progress-bar

Tan 2393 fix contrast of empty progress bar
  • Loading branch information
EdwinKato authored Jul 31, 2024
2 parents a47262b + 07404e5 commit 26f7a96
Show file tree
Hide file tree
Showing 39 changed files with 508 additions and 44 deletions.
2 changes: 2 additions & 0 deletions back/app/controllers/web_api/v1/phases_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ def phase_params
:document_annotation_embed_url,
:ideas_order,
:input_term,
:reacting_threshold,
:expire_days_limit,
{
title_multiloc: CL2_SUPPORTED_LOCALES,
description_multiloc: CL2_SUPPORTED_LOCALES,
Expand Down
7 changes: 7 additions & 0 deletions back/app/models/phase.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
# campaigns_settings :jsonb
# native_survey_title_multiloc :jsonb
# native_survey_button_multiloc :jsonb
# expire_days_limit :integer
# reacting_threshold :integer
#
# Indexes
#
Expand Down Expand Up @@ -137,6 +139,11 @@ class Phase < ApplicationRecord
before_validation :set_input_term
end

with_options if: ->(phase) { phase.pmethod.supports_automated_statuses? } do
validates :expire_days_limit, presence: true, numericality: { only_integer: true, greater_than: 0 }
validates :reacting_threshold, presence: true, numericality: { only_integer: true, greater_than: 1 }
end

validates :ideas_order, inclusion: { in: ->(phase) { phase.pmethod.allowed_ideas_orders } }, allow_nil: true
validates :allow_anonymous_participation, inclusion: { in: [true, false] }

Expand Down
12 changes: 12 additions & 0 deletions back/app/serializers/web_api/v1/idea_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ class WebApi::V1::IdeaSerializer < WebApi::V1::BaseSerializer
Permissions::IdeaPermissionsService.new(object, current_user(params), user_requirements_service: user_requirements_service).action_descriptors
end

attribute :expires_at, if: proc { |input|
input.published? && input.participation_method_on_creation.supports_serializing_input?(:expires_at)
} do |input|
input.published_at + input.creation_phase.expire_days_limit.days
end

attribute :reactions_needed, if: proc { |input|
input.participation_method_on_creation.supports_serializing_input?(:reactions_needed)
} do |input|
[input.creation_phase.reacting_threshold - input.likes_count, 0].max
end

has_many :topics
has_many :idea_images, serializer: WebApi::V1::ImageSerializer
has_many :phases
Expand Down
1 change: 1 addition & 0 deletions back/app/serializers/web_api/v1/phase_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class WebApi::V1::PhaseSerializer < WebApi::V1::BaseSerializer
voting_method voting_max_total voting_min_total
voting_max_votes_per_idea baskets_count
native_survey_title_multiloc native_survey_button_multiloc
expire_days_limit reacting_threshold
].each do |attribute_name|
attribute attribute_name, if: proc { |phase|
phase.pmethod.supports_serializing?(attribute_name)
Expand Down
16 changes: 13 additions & 3 deletions back/app/services/location/service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

class Location::Service
def autocomplete(input, language)
response = HTTParty.get("https://maps.googleapis.com/maps/api/place/autocomplete/json?input=#{CGI.escape(input)}&key=#{api_key}&language=#{language}")
response = http_get("https://maps.googleapis.com/maps/api/place/autocomplete/json?input=#{CGI.escape(input)}&key=#{api_key}&language=#{language}")
{ results: response['predictions'].pluck('description') }
end

Expand All @@ -13,20 +13,30 @@ def geocode(address, language)
split_coordinates = address.split(',')
location = { lat: split_coordinates[0].to_f, lng: split_coordinates[1].to_f }
else
response = HTTParty.get("https://maps.googleapis.com/maps/api/geocode/json?address=#{CGI.escape(address)}&key=#{api_key}&language=#{language}")
response = http_get("https://maps.googleapis.com/maps/api/geocode/json?address=#{CGI.escape(address)}&key=#{api_key}&language=#{language}")
location = response['results'].first['geometry']['location']
end
{ location: location }
end

def reverse_geocode(lat, lng, language)
response = HTTParty.get("https://maps.googleapis.com/maps/api/geocode/json?latlng=#{lat},#{lng}&key=#{api_key}&language=#{language}")
response = http_get("https://maps.googleapis.com/maps/api/geocode/json?latlng=#{lat},#{lng}&key=#{api_key}&language=#{language}")
{ formatted_address: response['results'].first['formatted_address'] }
end

private

def http_get(url)
HTTParty.get(url).tap do |response|
if !response.success? || response['status'] != 'OK'
ErrorReporter.report(GoogleMapsApiError.new, extra: { url: url, response: response })
end
end
end

def api_key
ENV.fetch('GOOGLE_MAPS_API_KEY', nil)
end

class GoogleMapsApiError < StandardError; end
end
12 changes: 12 additions & 0 deletions back/config/schemas/settings.schema.json.erb
Original file line number Diff line number Diff line change
Expand Up @@ -1088,6 +1088,18 @@
}
},

"form_mapping": {
"type": "object",
"title": "Mapping features used in in-platform surveys",
"description": "Alpha version - do not enable for active platform(s) unless agreed with Product. Mapping questions (pin, route & area), Esri Shapefile upload, and map page.",
"additionalProperties": false,
"required": ["allowed", "enabled"],
"properties": {
"allowed": { "type": "boolean", "default": false },
"enabled": { "type": "boolean", "default": false }
}
},

"input_form_custom_fields": {
"type": "object",
"title": "Input form builder custom fields",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class AddExpireDaysLimitAndReactingThresholdToPhases < ActiveRecord::Migration[7.0]
def change
add_column :phases, :expire_days_limit, :integer
add_column :phases, :reacting_threshold, :integer
end
end
7 changes: 5 additions & 2 deletions back/db/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1618,7 +1618,9 @@ CREATE TABLE public.phases (
votes_count integer DEFAULT 0 NOT NULL,
campaigns_settings jsonb DEFAULT '{}'::jsonb,
native_survey_title_multiloc jsonb DEFAULT '{}'::jsonb,
native_survey_button_multiloc jsonb DEFAULT '{}'::jsonb
native_survey_button_multiloc jsonb DEFAULT '{}'::jsonb,
expire_days_limit integer,
reacting_threshold integer
);


Expand Down Expand Up @@ -7511,6 +7513,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20240606112752'),
('20240612134240'),
('202407081751'),
('20240722090955');
('20240722090955'),
('20240729141927');


4 changes: 4 additions & 0 deletions back/engines/commercial/multi_tenancy/db/seeds/tenants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,10 @@ def create_localhost_tenant
enabled: true,
allowed: true
},
form_mapping: {
enabled: true,
allowed: true
},
report_builder: {
enabled: true,
allowed: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ namespace :cl2_back do
enabled: true,
allowed: true
},
form_mapping: {
enabled: false,
allowed: false
},
posthog_integration: {
enabled: false,
allowed: false
Expand Down
8 changes: 8 additions & 0 deletions back/lib/participation_method/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ def supports_reacting?
false
end

def supports_automated_statuses?
false # TODO: This is temorary, until proposal statuses are implemented
end

def supports_status?
false
end
Expand Down Expand Up @@ -138,6 +142,10 @@ def supports_serializing?(_attribute)
false
end

def supports_serializing_input?(_attribute)
false
end

# Should an admin be able to set permissions for disabled actions?
def return_disabled_actions?
false
Expand Down
18 changes: 18 additions & 0 deletions back/lib/participation_method/proposals.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ def transitive?
false
end

def assign_defaults_for_phase
super
phase.expire_days_limit ||= 90
phase.reacting_threshold ||= 300
end

# def assign_defaults(_)
# super # TODO: default status and publication status
# end
Expand All @@ -22,8 +28,20 @@ def proposed_budget_in_form?
# super # TODO: if no reviewing and no reactions + toggle
# end

def supports_automated_statuses?
true # TODO: This is temorary, until proposal statuses are implemented
end

# def supports_status?
# super # TODO: separate proposal statuses
# end

def supports_serializing?(attribute)
%i[expire_days_limit reacting_threshold].include?(attribute)
end

def supports_serializing_input?(attribute)
%i[expires_at reactions_needed].include?(attribute)
end
end
end
7 changes: 4 additions & 3 deletions back/lib/time_boundaries_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ def initialize(start_at, end_at)
end

def parse
platform_range = AppConfiguration.instance.created_at..AppConfiguration.timezone.now.end_of_day
start_range = @start_at.present? ? @start_at.to_date : platform_range.begin
end_range = @end_at.present? ? @end_at.to_date : platform_range.end
timezone = AppConfiguration.timezone
platform_range = AppConfiguration.instance.created_at..timezone.now.end_of_day
start_range = @start_at.present? ? @start_at.to_datetime.in_time_zone(timezone).beginning_of_day : platform_range.begin
end_range = @end_at.present? ? @end_at.to_datetime.in_time_zone(timezone).end_of_day : platform_range.end
requested_range = start_range...end_range
if requested_range.overlaps?(platform_range)
range = range_intersection(platform_range, requested_range)
Expand Down
24 changes: 21 additions & 3 deletions back/spec/acceptance/location_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@
let(:input) { 'New York' }

before do
allow(HTTParty).to receive(:get).and_return({ 'predictions' => [{ 'description' => 'New York, NY, USA' }] })
stub_request(:get, 'https://maps.googleapis.com/maps/api/place/autocomplete/json')
.with(query: hash_including({ input: input }))
.to_return(
status: 200,
body: { 'predictions' => [{ 'description' => 'New York, NY, USA' }] }.to_json,
headers: { content_type: 'application/json' }
)
end

example_request 'Autocomplete' do
Expand All @@ -34,7 +40,13 @@
let(:address) { 'New York' }

before do
allow(HTTParty).to receive(:get).and_return({ 'results' => [{ 'geometry' => { 'location' => { lat: 40.7127753, lng: -74.0059728 } } }] })
stub_request(:get, 'https://maps.googleapis.com/maps/api/geocode/json')
.with(query: hash_including({ address: address }))
.to_return(
status: 200,
body: { 'results' => [{ 'geometry' => { 'location' => { 'lat' => 40.7127753, 'lng' => -74.0059728 } } }] }.to_json,
headers: { content_type: 'application/json' }
)
end

example_request 'Address Geocoded' do
Expand Down Expand Up @@ -62,7 +74,13 @@
let(:lng) { -73.961452 }

before do
allow(HTTParty).to receive(:get).and_return({ 'results' => [{ 'formatted_address' => '277 Bedford Ave, Brooklyn, NY 11211, USA' }] })
stub_request(:get, 'https://maps.googleapis.com/maps/api/geocode/json')
.with(query: hash_including({ latlng: "#{lat},#{lng}" }))
.to_return(
status: 200,
body: { 'results' => [{ 'formatted_address' => '277 Bedford Ave, Brooklyn, NY 11211, USA' }] }.to_json,
headers: { content_type: 'application/json' }
)
end

example_request 'Reverse geocode' do
Expand Down
35 changes: 35 additions & 0 deletions back/spec/acceptance/phases_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,23 @@
expect(json_response.dig(:data, :relationships, :project, :data, :id)).to eq project_id
end

describe do
with_options scope: :phase do
parameter :expire_days_limit, 'Default value for how many days a proposal has to meet the voting threshold and move to the next stage. Defaults to 90.'
parameter :reacting_threshold, 'Default value for how many votes (reactions) a proposal needs to move to the next stage. Defaults to 300.'
end

let(:participation_method) { 'proposals' }
let(:expire_days_limit) { 100 }
let(:reacting_threshold) { 500 }

example_request 'Create a proposals phase' do
assert_status 201
expect(json_response.dig(:data, :attributes, :expire_days_limit)).to eq 100
expect(json_response.dig(:data, :attributes, :reacting_threshold)).to eq 500
end
end

context 'Blank phase end dates' do
let(:start_at) { @project.phases.last.end_at + 5.days }
let(:end_at) { nil }
Expand Down Expand Up @@ -449,6 +466,24 @@
expect(json_response.dig(:data, :attributes, :allow_anonymous_participation)).to eq allow_anonymous_participation
end

describe do
with_options scope: :phase do
parameter :expire_days_limit, 'Default value for how many days a proposal has to meet the voting threshold and move to the next stage.'
parameter :reacting_threshold, 'Default value for how many votes (reactions) a proposal needs to move to the next stage.'
end

let(:id) { create(:proposals_phase).id }
let(:participation_method) { 'proposals' }
let(:expire_days_limit) { 100 }
let(:reacting_threshold) { 500 }

example_request 'Update a proposals phase' do
assert_status 200
expect(json_response.dig(:data, :attributes, :expire_days_limit)).to eq 100
expect(json_response.dig(:data, :attributes, :reacting_threshold)).to eq 500
end
end

describe do
let(:id) { create(:budgeting_phase).id }
let(:participation_method) { 'voting' }
Expand Down
10 changes: 10 additions & 0 deletions back/spec/lib/participation_method/proposals_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@
participation_method.assign_defaults_for_phase
expect(phase.ideas_order).to eq 'trending'
end

it 'sets the expire_days_limit to 90' do
participation_method.assign_defaults_for_phase
expect(phase.expire_days_limit).to eq 90
end

it 'sets the reacting_threshold to 300' do
participation_method.assign_defaults_for_phase
expect(phase.reacting_threshold).to eq 300
end
end

describe '#generate_slug' do
Expand Down
1 change: 1 addition & 0 deletions back/spec/models/initiative_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
end
end

# TODO: clean-up-old-proposals-test
describe '#expires_at' do
before do
allow(Time).to receive(:now).and_return(Time.now)
Expand Down
Loading

0 comments on commit 26f7a96

Please sign in to comment.