diff --git a/decidim-core/app/cells/decidim/address_cell.rb b/decidim-core/app/cells/decidim/address_cell.rb
index 0be1df3cc9fb7..04432caf3301b 100644
--- a/decidim-core/app/cells/decidim/address_cell.rb
+++ b/decidim-core/app/cells/decidim/address_cell.rb
@@ -24,11 +24,13 @@ def location_hints
end
def location
+ return pending_address_text if pending_address?
+
decidim_sanitize(translated_attribute(model.location))
end
def address
- decidim_sanitize(translated_attribute(model.address))
+ decidim_sanitize(translated_attribute(model.address)) if model.respond_to?(:address) && model.address.present?
end
private
@@ -36,5 +38,13 @@ def address
def resource_icon
icon "meetings", class: "icon--big", role: "img", "aria-hidden": true
end
+
+ def pending_address?
+ address.blank? && model.location.is_a?(Hash) ? model.location.values.none?(&:present?) : model.location.blank?
+ end
+
+ def pending_address_text
+ t("show.pending_address", scope: "decidim.meetings.meetings")
+ end
end
end
diff --git a/decidim-core/spec/cells/decidim/address_cell_spec.rb b/decidim-core/spec/cells/decidim/address_cell_spec.rb
index 1c7be4ec8f332..9a7545e0c0765 100644
--- a/decidim-core/spec/cells/decidim/address_cell_spec.rb
+++ b/decidim-core/spec/cells/decidim/address_cell_spec.rb
@@ -32,4 +32,17 @@
expect(icondata_address).to have_no_content(model.latitude)
expect(icondata_address).to have_no_content(model.longitude)
end
+
+ context "when address is pending" do
+ let(:location) { {} }
+ let(:address) { "" }
+
+ before do
+ allow(model).to receive(:location).and_return(location)
+ end
+
+ it "renders pending address text" do
+ expect(icondata_address).to have_content(I18n.t("show.pending_address", scope: "decidim.meetings.meetings"))
+ end
+ end
end
diff --git a/decidim-meetings/app/commands/decidim/meetings/admin/copy_meeting.rb b/decidim-meetings/app/commands/decidim/meetings/admin/copy_meeting.rb
index 5764e779ca32b..4a5daae0d1017 100644
--- a/decidim-meetings/app/commands/decidim/meetings/admin/copy_meeting.rb
+++ b/decidim-meetings/app/commands/decidim/meetings/admin/copy_meeting.rb
@@ -50,10 +50,10 @@ def copy_meeting!
description: parsed_description,
end_time: form.end_time,
start_time: form.start_time,
- address: form.address,
+ address: form.location_pending ? "" : form.address,
latitude: form.latitude,
longitude: form.longitude,
- location: form.location,
+ location: form.location_pending ? {} : form.location,
location_hints: form.location_hints,
component: meeting.component,
private_meeting: form.private_meeting,
diff --git a/decidim-meetings/app/commands/decidim/meetings/admin/create_meeting.rb b/decidim-meetings/app/commands/decidim/meetings/admin/create_meeting.rb
index 74f8f4d568e33..9026a48e571f7 100644
--- a/decidim-meetings/app/commands/decidim/meetings/admin/create_meeting.rb
+++ b/decidim-meetings/app/commands/decidim/meetings/admin/create_meeting.rb
@@ -43,10 +43,10 @@ def create_meeting!
registration_type: form.registration_type,
registration_url: form.registration_url,
type_of_meeting: form.clean_type_of_meeting,
- address: form.address,
+ address: form.location_pending ? "" : form.address,
latitude: form.latitude,
longitude: form.longitude,
- location: form.location,
+ location: form.location_pending ? {} : form.location,
location_hints: form.location_hints,
private_meeting: form.private_meeting,
transparent: form.transparent,
diff --git a/decidim-meetings/app/commands/decidim/meetings/admin/update_meeting.rb b/decidim-meetings/app/commands/decidim/meetings/admin/update_meeting.rb
index db4e1684521b5..653a60730a484 100644
--- a/decidim-meetings/app/commands/decidim/meetings/admin/update_meeting.rb
+++ b/decidim-meetings/app/commands/decidim/meetings/admin/update_meeting.rb
@@ -53,10 +53,10 @@ def update_meeting!
registration_url: form.registration_url,
registrations_enabled: form.registrations_enabled,
type_of_meeting: form.clean_type_of_meeting,
- address: form.address,
+ address: form.location_pending ? "" : form.address,
latitude: form.latitude,
longitude: form.longitude,
- location: form.location,
+ location: form.location_pending ? nil : form.location,
location_hints: form.location_hints,
private_meeting: form.private_meeting,
transparent: form.transparent,
diff --git a/decidim-meetings/app/forms/decidim/meetings/admin/meeting_form.rb b/decidim-meetings/app/forms/decidim/meetings/admin/meeting_form.rb
index cf005d1c4599d..42a721bbb9820 100644
--- a/decidim-meetings/app/forms/decidim/meetings/admin/meeting_form.rb
+++ b/decidim-meetings/app/forms/decidim/meetings/admin/meeting_form.rb
@@ -7,6 +7,7 @@ module Admin
class MeetingForm < ::Decidim::Meetings::BaseMeetingForm
include TranslatableAttributes
+ attribute :location_pending, Boolean, default: false
attribute :services, Array[MeetingServiceForm]
attribute :decidim_scope_id, Integer
attribute :decidim_category_id, Integer
@@ -36,7 +37,9 @@ class MeetingForm < ::Decidim::Meetings::BaseMeetingForm
validates :registration_type, presence: true
validates :registration_url, presence: true, url: true, if: ->(form) { form.on_different_platform? }
validates :type_of_meeting, presence: true
- validates :location, translatable_presence: true, if: ->(form) { form.in_person_meeting? || form.hybrid_meeting? }
+ validates :location, translatable_presence: true, if: ->(form) { !form.location_pending && (form.in_person_meeting? || form.hybrid_meeting?) }
+ validates :address, presence: true, if: ->(form) { !form.location_pending && (form.in_person_meeting? || form.hybrid_meeting?) }
+ validates :address, geocoding: true, if: ->(form) { !form.location_pending && form.has_address? && !form.geocoded? }
validates :online_meeting_url, url: true, if: ->(form) { form.online_meeting? || form.hybrid_meeting? }
validates :comments_start_time, date: { before: :comments_end_time, allow_blank: true, if: proc { |obj| obj.comments_end_time.present? } }
validates :comments_end_time, date: { after: :comments_start_time, allow_blank: true, if: proc { |obj| obj.comments_start_time.present? } }
@@ -61,6 +64,7 @@ def map_model(model)
self.decidim_category_id = model.categorization.decidim_category_id if model.categorization
self.type_of_meeting = model.type_of_meeting
+ self.location_pending = model.address.blank? && model.location.to_h.values.none?(&:present?)
end
def services_to_persist
diff --git a/decidim-meetings/app/forms/decidim/meetings/base_meeting_form.rb b/decidim-meetings/app/forms/decidim/meetings/base_meeting_form.rb
index 7555b2402c6f8..88df12fe0f03a 100644
--- a/decidim-meetings/app/forms/decidim/meetings/base_meeting_form.rb
+++ b/decidim-meetings/app/forms/decidim/meetings/base_meeting_form.rb
@@ -13,8 +13,6 @@ class BaseMeetingForm < Decidim::Form
validates :current_component, presence: true
- validates :address, presence: true, if: ->(form) { form.needs_address? }
- validates :address, geocoding: true, if: ->(form) { form.has_address? && !form.geocoded? && form.needs_address? }
validates :start_time, presence: true, date: { before: :end_time }
validates :end_time, presence: true, date: { after: :start_time }
diff --git a/decidim-meetings/app/forms/decidim/meetings/meeting_form.rb b/decidim-meetings/app/forms/decidim/meetings/meeting_form.rb
index 69403b06c8b98..c756e5c0e4d25 100644
--- a/decidim-meetings/app/forms/decidim/meetings/meeting_form.rb
+++ b/decidim-meetings/app/forms/decidim/meetings/meeting_form.rb
@@ -27,6 +27,8 @@ class MeetingForm < ::Decidim::Meetings::BaseMeetingForm
validates :title, presence: true
validates :description, presence: true
validates :type_of_meeting, presence: true
+ validates :address, presence: true, if: ->(form) { form.needs_address? }
+ validates :address, geocoding: true, if: ->(form) { form.has_address? && !form.geocoded? && form.needs_address? }
validates :location, presence: true, if: ->(form) { form.in_person_meeting? || form.hybrid_meeting? }
validates :online_meeting_url, presence: true, url: true, if: ->(form) { form.online_meeting? || form.hybrid_meeting? }
validates :registration_type, presence: true
diff --git a/decidim-meetings/app/views/decidim/meetings/admin/meetings/_form.html.erb b/decidim-meetings/app/views/decidim/meetings/admin/meetings/_form.html.erb
index 87630d4cd11ac..284d193436c43 100644
--- a/decidim-meetings/app/views/decidim/meetings/admin/meetings/_form.html.erb
+++ b/decidim-meetings/app/views/decidim/meetings/admin/meetings/_form.html.erb
@@ -19,13 +19,20 @@
- <%= form.geocoding_field :address %>
-
<%= t(".address_help") %>
+ <%= form.check_box :location_pending, label: t("location_pending", scope: "decidim.meetings.admin.meetings.form"), "data-toggle": "location_fields-div" %>
+
<%= t(".location_pending_help") %>
-
- <%= form.translated :text_area, :location %>
-
<%= t(".location_help") %>
+
diff --git a/decidim-meetings/app/views/decidim/meetings/meetings/show.html.erb b/decidim-meetings/app/views/decidim/meetings/meetings/show.html.erb
index 770a36db54c4f..ff19e0e4b4fb8 100644
--- a/decidim-meetings/app/views/decidim/meetings/meetings/show.html.erb
+++ b/decidim-meetings/app/views/decidim/meetings/meetings/show.html.erb
@@ -132,7 +132,7 @@ edit_link(
<% end %>
<%= render_meeting_body(@meeting) %>
- <% if meeting.maps_enabled? && !meeting.online_meeting? %>
+ <% if meeting.maps_enabled? && !meeting.online_meeting? && meeting.address.present? %>
<%= render partial: "decidim/shared/static_map", locals: { icon_name: "meetings", geolocalizable: meeting } %>
<% end %>
diff --git a/decidim-meetings/config/locales/en.yml b/decidim-meetings/config/locales/en.yml
index feeb8821e6632..5a06143042fbc 100644
--- a/decidim-meetings/config/locales/en.yml
+++ b/decidim-meetings/config/locales/en.yml
@@ -319,6 +319,8 @@ en:
disclaimer: 'Disclaimer: By using an external registration system, you''re aware that the organizers of %{organization} are not responsible for the data provided by the users to the external service.'
location_help: 'Location: message directed to the users implying the spot to meet at'
location_hints_help: 'Location hints: additional info. Example: the floor of the building if it is an in-person meeting, or the meeting password if it is an online meeting with restricted access.'
+ location_pending: In-person/Hybrid, venue to be decided
+ location_pending_help: Select this option if the venue has not been decided yet. The message 'Place will be communicated soon' will be shown on the public page.
online_meeting_url_help: 'Link: allow participants to connect directly to your meeting'
registration_url_help: 'Link: allow participants to go on the external service you are using for registrations'
reminder_enabled: Reminder enabled
@@ -571,6 +573,7 @@ en:
micro_camera_permissions_warning: When you click on the button below, you will be asked for microphone and/or camera permissions, and you will join the videoconference
no_slots_available: No slots available
organizations: Attending organizations
+ pending_address: Place will be communicated soon.
registration_code_help_text: Your registration code
registration_confirmation: Are you sure you want to cancel your registration for this meeting?
registration_state:
diff --git a/decidim-meetings/spec/commands/admin/copy_meeting_spec.rb b/decidim-meetings/spec/commands/admin/copy_meeting_spec.rb
index 13671a50f7c49..500cac513e5ab 100644
--- a/decidim-meetings/spec/commands/admin/copy_meeting_spec.rb
+++ b/decidim-meetings/spec/commands/admin/copy_meeting_spec.rb
@@ -16,6 +16,7 @@ module Decidim::Meetings
let(:start_time) { 1.day.from_now }
let(:private_meeting) { false }
let(:transparent) { true }
+ let(:location_pending) { false }
let(:services) do
build_list(:service, 2, meeting: meeting)
end
@@ -28,6 +29,7 @@ module Decidim::Meetings
invalid?: invalid,
title: { en: "title" },
description: { en: "description" },
+ location_pending: location_pending,
location: { en: "location" },
location_hints: { en: "location hints" },
start_time: start_time,
@@ -125,6 +127,17 @@ module Decidim::Meetings
end
end
end
+
+ context "and location_pending is true" do
+ let(:location_pending) { true }
+
+ it "sets location to nil" do
+ expect { subject.call }.to change(Meeting, :count).by(1)
+ new_meeting = Meeting.last
+ expect(new_meeting.location).to be_empty
+ expect(new_meeting.address).to be_empty
+ end
+ end
end
describe "events" do
diff --git a/decidim-meetings/spec/commands/admin/create_meeting_spec.rb b/decidim-meetings/spec/commands/admin/create_meeting_spec.rb
index 9a203a9fca71f..239cdc753c980 100644
--- a/decidim-meetings/spec/commands/admin/create_meeting_spec.rb
+++ b/decidim-meetings/spec/commands/admin/create_meeting_spec.rb
@@ -12,6 +12,7 @@ module Decidim::Meetings
let(:current_component) { create :component, participatory_space: participatory_process, manifest_name: "meetings" }
let(:scope) { create :scope, organization: organization }
let(:category) { create :category, participatory_space: participatory_process }
+ let(:location_pending) { false }
let(:address) { "address" }
let(:invalid) { false }
let(:latitude) { 40.1234 }
@@ -55,6 +56,7 @@ module Decidim::Meetings
location_hints: { en: "location_hints" },
start_time: start_time,
end_time: 1.day.from_now + 1.hour,
+ location_pending: location_pending,
address: address,
latitude: latitude,
longitude: longitude,
@@ -122,6 +124,17 @@ module Decidim::Meetings
expect(meeting.component).to eq current_component
end
+ context "and location_pending is true" do
+ let(:location_pending) { true }
+
+ it "sets location to nil" do
+ expect { subject.call }.to change(Meeting, :count).by(1)
+ new_meeting = Meeting.last
+ expect(new_meeting.location).to be_empty
+ expect(new_meeting.address).to be_empty
+ end
+ end
+
it "sets the longitude and latitude" do
subject.call
last_meeting = Meeting.last
diff --git a/decidim-meetings/spec/commands/admin/update_meeting_spec.rb b/decidim-meetings/spec/commands/admin/update_meeting_spec.rb
index 479af13847429..d77fcea99e8fd 100644
--- a/decidim-meetings/spec/commands/admin/update_meeting_spec.rb
+++ b/decidim-meetings/spec/commands/admin/update_meeting_spec.rb
@@ -12,6 +12,7 @@ module Decidim::Meetings
let(:category) { create :category, participatory_space: meeting.component.participatory_space }
let(:address) { meeting.address }
let(:invalid) { false }
+ let(:location_pending) { false }
let(:latitude) { 40.1234 }
let(:longitude) { 2.1234 }
let(:service_objects) { build_list(:service, 2) }
@@ -46,6 +47,7 @@ module Decidim::Meetings
end_time: 1.day.from_now + 1.hour,
scope: scope,
category: category,
+ location_pending: location_pending,
address: address,
latitude: latitude,
longitude: longitude,
@@ -142,6 +144,16 @@ module Decidim::Meetings
expect(action_log.version).to be_present
end
+ context "and location_pending is true" do
+ let(:location_pending) { true }
+
+ it "sets location to nil" do
+ subject.call
+ expect(translated(meeting.location)).to be_nil
+ expect(meeting.address).to be_empty
+ end
+ end
+
describe "events" do
let!(:follow) { create :follow, followable: meeting, user: user }
let(:title) { meeting.title }
@@ -159,6 +171,7 @@ module Decidim::Meetings
end_time: end_time,
scope: meeting.scope,
category: meeting.category,
+ location_pending: location_pending,
address: address,
latitude: meeting.latitude,
longitude: meeting.longitude,
diff --git a/decidim-meetings/spec/forms/admin/meeting_form_spec.rb b/decidim-meetings/spec/forms/admin/meeting_form_spec.rb
index a6d3c0e30992a..18daec309652d 100644
--- a/decidim-meetings/spec/forms/admin/meeting_form_spec.rb
+++ b/decidim-meetings/spec/forms/admin/meeting_form_spec.rb
@@ -37,6 +37,7 @@ module Decidim::Meetings
let(:services_attributes) do
services.map(&:attributes)
end
+ let(:location_pending) { false }
let(:address) { "Somewhere over the rainbow" }
let(:latitude) { 40.1234 }
let(:longitude) { 2.1234 }
@@ -66,6 +67,7 @@ module Decidim::Meetings
title_en: title[:en],
description_en: description[:en],
short_description_en: short_description[:en],
+ location_pending: location_pending,
location_en: location[:en],
location_hints_en: location_hints[:en],
address: address,
@@ -107,6 +109,36 @@ module Decidim::Meetings
it { is_expected.not_to be_valid }
end
+ describe "when location_pending enabled" do
+ let(:location_pending) { true }
+
+ it { is_expected.to be_valid }
+
+ context "and location is missing" do
+ let(:location) { { en: nil } }
+
+ it { is_expected.to be_valid }
+ end
+
+ context "and address is missing" do
+ let(:address) { nil }
+
+ it { is_expected.to be_valid }
+ end
+
+ context "and location is present" do
+ let(:location) { { en: "location" } }
+
+ it { is_expected.to be_valid }
+ end
+
+ context "and address is present" do
+ let(:address) { "Somewhere over the rainbow" }
+
+ it { is_expected.to be_valid }
+ end
+ end
+
describe "when location is missing and type of meeting is in_person" do
let(:type_of_meeting) { "in_person" }
let(:location) { { en: nil } }
diff --git a/decidim-meetings/spec/system/admin/admin_manages_meetings_spec.rb b/decidim-meetings/spec/system/admin/admin_manages_meetings_spec.rb
index 6986789c3b283..3a36b69cb2d4e 100644
--- a/decidim-meetings/spec/system/admin/admin_manages_meetings_spec.rb
+++ b/decidim-meetings/spec/system/admin/admin_manages_meetings_spec.rb
@@ -316,6 +316,51 @@
expect(page).to have_content("created the #{translated(attributes[:title])} meeting on the")
end
+ context "when the venue has not been decided yet" do
+ it "creates a new meeting without a location" do
+ find(".card-title a.button").click
+
+ fill_in_i18n(:meeting_title, "#meeting-title-tabs", **attributes[:title].except("machine_translations"))
+
+ expect(page).to have_no_field("In-person/Hybrid, venue to be decided")
+
+ select "In person", from: :meeting_type_of_meeting
+
+ expect(page).to have_field("In-person/Hybrid, venue to be decided")
+
+ check "In-person/Hybrid, venue to be decided"
+
+ expect(page).to have_no_field(:meeting_location_en)
+ expect(page).to have_no_field(:meeting_address)
+
+ fill_in_i18n_editor(:meeting_description, "#meeting-description-tabs", **attributes[:description].except("machine_translations"))
+ select "Registration disabled", from: :meeting_registration_type
+ page.execute_script("$('#meeting_start_time').focus()")
+ page.find(".datepicker-dropdown .day:not(.new)", text: "12").click
+ page.find(".datepicker-dropdown .hour", text: "10:00").click
+ page.find(".datepicker-dropdown .minute", text: "10:50").click
+
+ page.execute_script("$('#meeting_end_time').focus()")
+ page.find(".datepicker-dropdown .day:not(.new)", text: "12").click
+ page.find(".datepicker-dropdown .hour", text: "12:00").click
+ page.find(".datepicker-dropdown .minute", text: "12:50").click
+
+ scope_pick select_data_picker(:meeting_decidim_scope_id), scope
+ select translated(category.name), from: :meeting_decidim_category_id
+
+ within ".new_meeting" do
+ find("*[type=submit]").click
+ end
+
+ expect(page).to have_admin_callout("successfully")
+
+ new_meeting = Decidim::Meetings::Meeting.last
+ puts "Meeting location: #{new_meeting.location}"
+ expect(new_meeting.location).to be_empty
+ expect(new_meeting.address).to be_empty
+ end
+ end
+
context "when using the front-end geocoder", :serves_geocoding_autocomplete do
it_behaves_like(
"a record with front-end geocoding address field",
diff --git a/decidim-meetings/spec/system/meeting_spec.rb b/decidim-meetings/spec/system/meeting_spec.rb
index f3c6d6eec1612..691ee86dbf332 100644
--- a/decidim-meetings/spec/system/meeting_spec.rb
+++ b/decidim-meetings/spec/system/meeting_spec.rb
@@ -76,6 +76,16 @@ def visit_meeting
expect(page).to have_css("div.address__map")
end
+
+ context "and meeting has no address" do
+ let(:meeting) { create(:meeting, :published, :with_services, component: component, address: "", location: {}) }
+
+ it "hides the map and displays pending address text" do
+ visit_meeting
+
+ expect(page).to have_no_css("div.address__map")
+ end
+ end
end
context "and meeting is hybrid" do
@@ -119,6 +129,26 @@ def visit_meeting
expect(page).to have_no_css("div.address__map")
end
end
+
+ context "when the meeting has no address and location" do
+ let!(:meeting) { create(:meeting, :published, component: component, address: "", location: {}) }
+
+ it "displays the pending address text" do
+ visit main_component_path(component)
+ expect(page).to have_content("PLACE WILL BE COMMUNICATED SOON")
+ end
+ end
+
+ context "when meeting has an address and location" do
+ let!(:meeting) { create(:meeting, :published, component: component, address: "123 Main St", location: { "en" => "Central Park" }) }
+
+ it "displays the location and address" do
+ visit main_component_path(component)
+ expect(page).to have_content("123 Main St")
+ expect(page).to have_content("CENTRAL PARK")
+ expect(page).to have_no_content("PLACE WILL BE COMMUNICATED SOON")
+ end
+ end
end
context "when the meeting is the same as the current year" do