Skip to content

Commit

Permalink
An assembly member can be an existing user
Browse files Browse the repository at this point in the history
  • Loading branch information
rbngzlv committed May 11, 2018
1 parent 19a1f0b commit 31d1f22
Show file tree
Hide file tree
Showing 22 changed files with 331 additions and 36 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -26,6 +26,7 @@ end
**Added**:

- **decidim-assemblies**: Add members to assemblies. [\#3008](https://github.com/decidim/decidim/pull/3008)
- **decidim-assemblies**: An assembly member can be related to an existing user. [\#3302](https://github.com/decidim/decidim/pull/3302)
- **decidim-meetings**: Add organizer to meeting and meeting types [\#3136](https://github.com/decidim/decidim/pull/3136)
- **decidim-meetings**: Add Minutes entity to manage Minutes. [\#3213](https://github.com/decidim/decidim/pull/3213)
- **decidim-admin**: Links to participatory space index & show pages from the admin dashboard. [\#3325](https://github.com/decidim/decidim/pull/3325)
Expand Down
2 changes: 1 addition & 1 deletion decidim-admin/lib/decidim/admin/form_builder.rb
Expand Up @@ -19,7 +19,7 @@ class FormBuilder < Decidim::FormBuilder
# @param [Hash] prompt_options
# Prompt configuration. A hash with options:
# - :url (String) The url where the ajax endpoint to fill the select
# - :text (String) Text to use as placeholder
# - :placeholder (String) Text to use as placeholder
# - :no_results (String) (optional) Text to use when there are no matching results (default: No results found)
# - :search_prompt (String) (optional) Text to prompt for search input (default: Type at least three characters to search)
#
Expand Down
@@ -1,6 +1,28 @@
((exports) => {
const { createFieldDependentInputs } = exports.DecidimAdmin;

const $assemblyMemberType = $("#assembly_member_existing_user");

createFieldDependentInputs({
controllerField: $assemblyMemberType,
wrapperSelector: ".user-fields",
dependentFieldsSelector: ".user-fields--full-name",
dependentInputSelector: "input",
enablingCondition: ($field) => {
return $field.val() === "false"
}
});

createFieldDependentInputs({
controllerField: $assemblyMemberType,
wrapperSelector: ".user-fields",
dependentFieldsSelector: ".user-fields--user-picker",
dependentInputSelector: "input",
enablingCondition: ($field) => {
return $field.val() === "true"
}
});

const $assemblyMemberPosition = $("#assembly_member_position");

createFieldDependentInputs({
Expand Down
Expand Up @@ -61,7 +61,8 @@ def create_assembly_member!
:position_other,
:weight
).merge(
assembly: assembly
assembly: assembly,
user: form.user
),
log_info
)
Expand Down
Expand Up @@ -57,6 +57,8 @@ def update_assembly_member!
:position,
:position_other,
:weight
).merge(
user: form.user
),
log_info
)
Expand Down
Expand Up @@ -18,11 +18,24 @@ class AssemblyMemberForm < Form
attribute :designation_mode, String
attribute :position, String
attribute :position_other, String
attribute :user_id, Integer
attribute :existing_user, Boolean, default: false

validates :full_name, :designation_date, presence: true
validates :designation_date, presence: true
validates :full_name, presence: true, unless: proc { |object| object.existing_user }
validates :position, inclusion: { in: Decidim::AssemblyMember::POSITIONS }
validates :position_other, presence: true, if: ->(form) { form.position == "other" }
validates :ceased_date, date: { after: :designation_date, allow_blank: true }
validates :user, presence: true, if: proc { |object| object.existing_user }

def map_model(model)
self.user_id = model.decidim_user_id
self.existing_user = user_id.present?
end

def user
@user ||= current_organization.users.find_by(id: user_id)
end

def positions_for_select
Decidim::AssemblyMember::POSITIONS.map do |position|
Expand Down
1 change: 1 addition & 0 deletions decidim-assemblies/app/models/decidim/assembly_member.rb
Expand Up @@ -9,6 +9,7 @@ class AssemblyMember < ApplicationRecord

POSITIONS = %w(president vice_president secretary other).freeze

belongs_to :user, foreign_key: "decidim_user_id", class_name: "Decidim::User", optional: true
belongs_to :assembly, foreign_key: "decidim_assembly_id", class_name: "Decidim::Assembly"
alias participatory_space assembly

Expand Down
@@ -0,0 +1,24 @@
# frozen_string_literal: true

module Decidim
module Admin
#
# Decorator for assembly members
#
class AssemblyMemberPresenter < SimpleDelegator
def name
if user
"#{user.name} (#{Decidim::UserPresenter.new(user).nickname})"
else
full_name
end
end

def position
return position_other if __getobj__.position == "other"

I18n.t(__getobj__.position, scope: "decidim.admin.models.assembly_member.positions", default: "")
end
end
end
end
Expand Up @@ -11,6 +11,14 @@ def age

delegate :profile_url, :avatar_url, to: :user, allow_nil: true

def name
user ? user.name : full_name
end

def nickname
user.nickname if user
end

def personal_information
[
gender.presence,
Expand All @@ -24,5 +32,15 @@ def position

I18n.t(__getobj__.position, scope: "decidim.admin.models.assembly_member.positions", default: "")
end

private

def user
@user ||= begin
if (user = __getobj__.user.presence)
Decidim::UserPresenter.new(user)
end
end
end
end
end
Expand Up @@ -6,8 +6,21 @@
</div>

<div class="card-section">
<div class="row column">
<%= form.text_field :full_name, autofocus: true %>
<div class="user-fields">
<div class="row column">
<%= form.select :existing_user, [[t(".non_user"), false], [t(".existing_user"), true]], label: t(".user_type") %>
</div>

<div class="row column user-fields--full-name">
<%= form.text_field :full_name, autofocus: true %>
</div>

<div class="row column user-fields--user-picker">
<% prompt_options = { url: decidim_admin.users_organization_url, placeholder: t(".select_user") } %>
<%= form.autocomplete_select(:user_id, form.object.user.presence, { multiple: false }, prompt_options) do |user|
{ value: user.id, label: "#{user.name} (@#{user.nickname})" }
end %>
</div>
</div>

<div class="position-fields">
Expand Down
Expand Up @@ -59,12 +59,13 @@
</thead>
<tbody>
<% @assembly_members.each do |member| %>
<% member_presenter = Decidim::Admin::AssemblyMemberPresenter.new(member) %>
<tr>
<td>
<%= member.full_name %>
<%= member_presenter.name %>
</td>
<td>
<%= Decidim::AssemblyMemberPresenter.new(member).position %>
<%= member_presenter.position %>
</td>
<td>
<%= l member.designation_date, format: :datepicker %>
Expand Down
Expand Up @@ -7,21 +7,41 @@
<div class="author-data author-data--big">
<div class="author-data__main">
<div class="author author--flex">
<span class="author__avatar">
<%= image_tag asset_path("decidim/default-avatar.svg") %>
</span>
<div>
<div class="author__name--container">
<%= member_presenter.full_name %>
<% if (profile_url = member_presenter.profile_url) %>
<a href="<%= profile_url %>" class="author__avatar">
<%= image_tag member_presenter.avatar_url(:big) %>
</a>
<div>
<div class="author__name--container">
<a href="<%= profile_url %>" class="author__name">
<%= member_presenter.name %>
</a>
</div>
<% if (nickname = member_presenter.nickname) %>
<a href="<%= profile_url %>" class="author__nickname">
<%= nickname %>
</a>
<% end %>
</div>
</div>
<% else %>
<span class="author__avatar"><%= image_tag asset_path("decidim/default-avatar.svg") %></span>
<div>
<div class="author__name--container"><%= member_presenter.name %></div>
<% if (nickname = member_presenter.nickname) %>
<span class="author__nickname"><%= nickname %></span>
<% end %>
</div>
<% end %>
</div>
</div>
</div>
</div>
<div class="card__text card--picture-offset">
<div><small><strong><%= member_presenter.position %></strong></small></div>
<div class="text-small"><%= t(".desiganted_on") %> <strong> <%= l assembly_member.designation_date, format: :datepicker %></strong></div>
<div>
<small><strong><%= member_presenter.position %></strong></small>
</div>
<div class="text-small"><%= t(".desiganted_on") %>
<strong> <%= l assembly_member.designation_date, format: :datepicker %></strong></div>
<div class="text-small mt-s"><%= member_presenter.personal_information %></div>
</div>
</div>
Expand Down
4 changes: 4 additions & 0 deletions decidim-assemblies/config/locales/en.yml
Expand Up @@ -208,7 +208,11 @@ en:
slug_help: 'URL slugs are used to generate the URLs that point to this assembly. Only accepts letters, numbers and dashes, and must start with a letter. Example: %{url}'
assembly_members:
form:
existing_user: Existing user
non_user: Non user
select_a_position: Select a position
select_user: Select an user
user_type: User type
index:
filter:
all: All
Expand Down
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class AssemblyMemberBelongsToUser < ActiveRecord::Migration[5.1]
def change
add_reference :decidim_assembly_members, :decidim_user, index: { name: "index_decidim_assembly_members_on_decidim_user_id" }
end
end
4 changes: 4 additions & 0 deletions decidim-assemblies/lib/decidim/assemblies/test/factories.rb
Expand Up @@ -128,5 +128,9 @@
trait :ceased do
ceased_date { Faker::Date.between(1.day.ago, 5.days.ago) }
end

trait :with_user do
user { create(:user, organization: assembly.organization) }
end
end
end
11 changes: 11 additions & 0 deletions decidim-assemblies/spec/commands/create_assembly_member_spec.rb
Expand Up @@ -7,12 +7,14 @@ module Decidim::Assemblies
subject { described_class.new(form, current_user, assembly) }

let(:assembly) { create(:assembly) }
let(:user) { nil }
let!(:current_user) { create :user, :confirmed, organization: assembly.organization }
let(:form) do
instance_double(
Admin::AssemblyMemberForm,
invalid?: invalid,
full_name: "Full name",
user: user,
attributes: {
weight: 0,
full_name: "Full name",
Expand Down Expand Up @@ -63,6 +65,15 @@ module Decidim::Assemblies
action_log = Decidim::ActionLog.last
expect(action_log.version).to be_present
end

context "with an existing user in the platform" do
let!(:user) { create(:user, organization: assembly.organization) }

it "sets the user" do
subject.call
expect(assembly_member.user).to eq user
end
end
end
end
end
14 changes: 13 additions & 1 deletion decidim-assemblies/spec/commands/update_assembly_member_spec.rb
Expand Up @@ -7,14 +7,16 @@ module Decidim::Assemblies
subject { described_class.new(form, assembly_member) }

let!(:assembly) { create(:assembly) }
let(:assembly_member) { create :assembly_member, assembly: assembly }
let(:assembly_member) { create :assembly_member, :with_user, assembly: assembly }
let!(:current_user) { create :user, :confirmed, organization: assembly.organization }
let(:user) { nil }
let(:form) do
instance_double(
Admin::AssemblyMemberForm,
invalid?: invalid,
current_user: current_user,
full_name: "New name",
user: user,
attributes: {
weight: 0,
full_name: "New name",
Expand Down Expand Up @@ -60,6 +62,16 @@ module Decidim::Assemblies
action_log = Decidim::ActionLog.last
expect(action_log.version).to be_present
end

context "when is an existing user in the platform" do
let!(:user) { create :user, organization: assembly.organization }

it "sets the user" do
expect do
subject.call
end.to change { assembly_member.reload && assembly_member.user }.from(assembly_member.user).to(user)
end
end
end
end
end

0 comments on commit 31d1f22

Please sign in to comment.