Skip to content

Commit

Permalink
Merge branch 'master' into chromatic-setup
Browse files Browse the repository at this point in the history
  • Loading branch information
luucvanderzee committed Jan 26, 2024
2 parents dcec7b7 + 77ba13f commit 2c72b8d
Show file tree
Hide file tree
Showing 286 changed files with 3,901 additions and 3,089 deletions.
1 change: 1 addition & 0 deletions back/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ gem 'prawn-grouping', '~> 0.2.0'
# "undefined method 'mailgun_settings=' for ActionMailer::Base:Class"
# exception.
gem 'aws-sdk-s3', '~> 1'
gem 'aws-sdk-bedrockruntime', '~> 1'
gem 'bootsnap', '~> 1', require: false
gem 'dalli', '~> 3.2.4'
gem 'mailgun-ruby', '~>1.2.8'
Expand Down
7 changes: 6 additions & 1 deletion back/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ PATH
analytics
content_builder
rails (~> 7.0)
user_custom_fields

PATH
remote: engines/commercial/smart_groups
Expand Down Expand Up @@ -483,7 +484,10 @@ GEM
activerecord (>= 4.0.0, < 7.1)
aws-eventstream (1.2.0)
aws-partitions (1.786.0)
aws-sdk-core (3.178.0)
aws-sdk-bedrockruntime (1.4.0)
aws-sdk-core (~> 3, >= 3.188.0)
aws-sigv4 (~> 1.1)
aws-sdk-core (3.188.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
Expand Down Expand Up @@ -1230,6 +1234,7 @@ DEPENDENCIES
annotate
api-pagination (~> 5.0.0)
awesome_nested_set (~> 3.5.0)
aws-sdk-bedrockruntime (~> 1)
aws-sdk-s3 (~> 1)
axlsx (= 3.0.0.pre)
bcrypt (~> 3.1.7)
Expand Down
2 changes: 1 addition & 1 deletion back/app/controllers/web_api/v1/ideas_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def update
user_can_moderate_project = UserRoleService.new.can_moderate_project?(project, current_user)
update_params = idea_params(input.custom_form, user_can_moderate_project).to_h
update_params[:custom_field_values] = input.custom_field_values.merge(update_params[:custom_field_values] || {})
CustomFieldService.new.cleanup_custom_field_values! update_params[:custom_field_values]
CustomFieldService.new.compact_custom_field_values! update_params[:custom_field_values]
input.assign_attributes update_params
authorize input
if anonymous_not_allowed?(phase)
Expand Down
36 changes: 24 additions & 12 deletions back/app/controllers/web_api/v1/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,17 +150,11 @@ def create
end

def update
user_params = permitted_attributes @user
user_params[:custom_field_values] = @user.custom_field_values.merge(user_params[:custom_field_values] || {})
user_params[:onboarding] = @user.onboarding.merge(user_params[:onboarding] || {})
user_params = user_params.to_h
CustomFieldService.new.cleanup_custom_field_values! user_params[:custom_field_values]
@user.assign_attributes user_params
@user.assign_attributes(update_params)
remove_image_if_requested!(@user, update_params, :avatar)
authorize(@user)

remove_image_if_requested!(@user, user_params, :avatar)

authorize @user
save_params = user_params.key?(:custom_field_values) ? { context: :form_submission } : {}
save_params = update_params.key?(:custom_field_values) ? { context: :form_submission } : {}
if @user.save save_params
SideFxUserService.new.after_update(@user, current_user)
render json: WebApi::V1::UserSerializer.new(
Expand All @@ -178,7 +172,7 @@ def destroy
end

def block
block_end_at = Time.zone.now + AppConfiguration.instance.settings('user_blocking', 'duration').days
block_end_at = Time.zone.now + app_configuration.settings('user_blocking', 'duration').days

authorize @user, :block?
if @user.update(
Expand Down Expand Up @@ -264,7 +258,7 @@ def set_user
end

def reset_confirm_on_existing_no_password_user?
return false unless AppConfiguration.instance.feature_activated?('user_confirmation')
return false unless app_configuration.feature_activated?('user_confirmation')

original_user = @user
errors = original_user.errors.details[:email]
Expand All @@ -287,4 +281,22 @@ def reset_confirm_on_existing_no_password_user?
def view_private_attributes?
Pundit.policy!(current_user, (@user || User)).view_private_attributes?
end

def update_params
@update_params ||= permitted_attributes(@user).tap do |attrs|
attrs[:onboarding] = @user.onboarding.merge(attrs[:onboarding].to_h)
attrs[:custom_field_values] = @user.custom_field_values.merge(attrs[:custom_field_values].to_h)
CustomFieldService.new.compact_custom_field_values!(attrs[:custom_field_values])

# Even if the feature is not activated, we still want to allow the user to remove
# their avatar.
if !app_configuration.feature_activated?('user_avatars') && !attrs[:avatar].nil?
attrs.delete(:avatar)
end
end.permit!
end

def app_configuration
@app_configuration ||= AppConfiguration.instance
end
end
4 changes: 4 additions & 0 deletions back/app/policies/application_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,8 @@ def owner?
def active?
user&.active?
end

def active_admin?
admin? && active?
end
end
2 changes: 1 addition & 1 deletion back/app/policies/idea_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def index_xlsx?
end

def index_mini?
admin? && active?
active_admin?
end

def create?
Expand Down
8 changes: 5 additions & 3 deletions back/app/policies/phase_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def destroy?
end

def survey_results?
ProjectPolicy.new(user, record.project).active_moderator?
active_moderator?
end

def submission_count?
Expand All @@ -44,8 +44,10 @@ def index_xlsx?
end

def delete_inputs?
return false unless active?
active_moderator?
end

UserRoleService.new.can_moderate_project? record.project, user
def active_moderator?
ProjectPolicy.new(user, record.project).active_moderator?
end
end
16 changes: 7 additions & 9 deletions back/app/policies/user_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -104,22 +104,20 @@ def view_private_attributes?
end

def permitted_attributes_for_create
[:email] + shared_permitted_attributes
end

def permitted_attributes_for_update
shared_permitted_attributes.tap do |attrs|
attrs.push :email if !AppConfiguration.instance.feature_activated?('user_confirmation')
permitted_attributes_for_update.tap do |attributes|
attributes.delete(:avatar) unless AppConfiguration.instance.feature_activated?('user_avatar')
end
end

private

def shared_permitted_attributes
def permitted_attributes_for_update
# avatar is allowed even if the feature "user_avatars" is not activated to allow
# users to remove their avatar.
shared = [:email, :first_name, :last_name, :password, :avatar, :locale, { onboarding: [:topics_and_areas], custom_field_values: allowed_custom_field_keys, bio_multiloc: CL2_SUPPORTED_LOCALES }]
admin? ? shared + [roles: %i[type project_id project_folder_id]] : shared
end

private

def allowed_custom_field_keys
allowed_fields = allowed_custom_fields
simple_keys = allowed_fields.support_single_value.pluck(:key).map(&:to_sym)
Expand Down
16 changes: 8 additions & 8 deletions back/app/services/custom_field_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,15 @@ def generate_token(str)
str.dup.concat('_', [*('a'..'z'), *('0'..'9')].sample(3).join)
end

def cleanup_custom_field_values!(custom_field_values)
custom_field_values.each_key do |key|
value = custom_field_values[key]
is_boolean = !!value == value
next if is_boolean || value.present?

custom_field_values.delete key
# Removes all blank values from the values hash in place, except for `false` values,
# and returns self.
# @example
# compact_custom_field_values!({a: 1, b: '', c: false, d: nil})
# # => {a: 1, c: false}
def compact_custom_field_values!(cf_values)
cf_values.keep_if do |_key, value|
value.present? || value == false
end
custom_field_values
end

# @param [Hash<String, _>] custom_field_values
Expand Down
14 changes: 10 additions & 4 deletions back/app/services/survey_results_generator_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,29 +39,35 @@ def visit_multiline_text(field)
answers = inputs
.select("custom_field_values->'#{field.key}' as value")
.where("custom_field_values->'#{field.key}' IS NOT NULL")
.map(&:value)
.map do |answer|
{ answer: answer.value }
end
answer_count = answers.size
{
inputType: field.input_type,
question: field.title_multiloc,
required: field.required,
totalResponses: answer_count,
customFieldId: field.id
customFieldId: field.id,
textResponses: answers
}
end

def visit_text(field)
answers = inputs
.select("custom_field_values->'#{field.key}' as value")
.where("custom_field_values->'#{field.key}' IS NOT NULL")
.map(&:value)
.map do |answer|
{ answer: answer.value }
end
answer_count = answers.size
{
inputType: field.input_type,
question: field.title_multiloc,
required: field.required,
totalResponses: answer_count,
customFieldId: field.id
customFieldId: field.id,
textResponses: answers
}
end

Expand Down
2 changes: 1 addition & 1 deletion back/config/locales/de-DE.yml
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ de:
ISCED8: Doktortitel oder gleichwertiger Abschluss
initiatives:
default_threshold_reached_message: >
<p>Die Initiatoren sind eingeladen, ihre Vorschlag bei der nächsten Stadtratssitzung zu präsentieren. Wir werden ein offizielles Update veröffentlichen.</p>
<p>Die Initiator*innen sind eingeladen, ihren Vorschlag bei der nächsten Stadtratssitzung zu präsentieren. Wir werden ein offizielles Update veröffentlichen.</p>
default_eligibility_criteria: >
<ul> <li>Es muss in die Politikbereiche und Kompetenzen des lokalen Politiks fallen.</li> <li>Es dient eher dem öffentlichen als dem individuellen Interesse</li> <li>Es diskriminiert nicht aufgrund von Geschlecht, Rasse, Alter oder Hintergrund.</li> <li>Es schadet anderen nicht</li></ul>
default_posting_tips: >
Expand Down
24 changes: 24 additions & 0 deletions back/config/schemas/settings.schema.json.erb
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,18 @@
}
},

"user_avatars": {
"type": "object",
"title": "User avatars",
"description": "Allow users to upload a profile picture.",
"additionalProperties": false,
"required": ["allowed", "enabled"],
"properties": {
"allowed": { "type": "boolean", "default": true },
"enabled": { "type": "boolean", "default": true }
}
},

"internal_commenting": {
"type": "object",
"title": "Internal commenting",
Expand Down Expand Up @@ -1327,6 +1339,18 @@
"allowed": { "type": "boolean", "default": false },
"enabled": { "type": "boolean", "default": false }
}
},

"user_session_recording": {
"type": "object",
"title": "User session recording",
"description": "Enables the recording of a small fraction of user sessions for analysis and product research purposes. Requires active consent from the customer.",
"additionalProperties": false,
"required": ["allowed", "enabled"],
"properties": {
"allowed": { "type": "boolean", "default": true },
"enabled": { "type": "boolean", "default": false }
}
}
},
"dependencies": {
Expand Down
Loading

0 comments on commit 2c72b8d

Please sign in to comment.