Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Publish and unpublish a conference speaker #74

Closed
2 changes: 2 additions & 0 deletions decidim-admin/spec/system/admin_manages_organization_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@

expect(page).to have_no_content("There is an error in this field.")
fill_in :organization_comments_max_length, with: ""
find_by_id("organization_rich_text_editor_in_public_views").click

expect(page).to have_content("There is an error in this field.")
end

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# frozen_string_literal: true

module Decidim
module Conferences
module Admin
# A command with all the business logic that publishes an
# existing conference speakers.
class PublishConferenceSpeaker < Decidim::Command
# Public: Initializes the command.
#
# conference_speaker - Decidim::Conferences::Admin::ConferenceSpeaker
# current_user - the user performing the action
def initialize(conference_speaker, current_user)
@conference_speaker = conference_speaker
@current_user = current_user
end

# Executes the command. Broadcasts these events:
#
# - :ok when everything is valid.
# - :invalid if the form was not valid and we could not proceed.
#
# Returns nothing.
def call
return broadcast(:invalid) if conference_speaker.published?

transaction do
publish_conference_speaker
end

broadcast(:ok, conference_speaker)
end

private

attr_reader :conference_speaker, :current_user

def publish_conference_speaker
@conference_speaker = Decidim.traceability.perform_action!(
:publish,
conference_speaker,
current_user
) do
conference_speaker.publish!
conference_speaker
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

module Decidim
module Conferences
module Admin
# A command with all the business logic that publishes an
# existing conference speakers.
class UnpublishConferenceSpeaker < Decidim::Command
# Public: Initializes the command.
#
# conference_speaker - Decidim::Conferences::Admin::ConferenceSpeaker
# current_user - the user performing the action
def initialize(conference_speaker, current_user)
@conference_speaker = conference_speaker
@current_user = current_user
end

# Executes the command. Broadcasts these events:
#
# - :ok when everything is valid.
# - :invalid if the form was not valid and we could not proceed.
#
# Returns nothing.
def call
return broadcast(:invalid) unless conference_speaker.published?

@conference_speaker = Decidim.traceability.perform_action!(
:unpublish,
conference_speaker,
current_user
) do
conference_speaker.unpublish!
conference_speaker
end
broadcast(:ok, conference_speaker)
end

private

attr_reader :conference_speaker, :current_user
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,38 @@ def destroy
end
end

def publish
enforce_permission_to(:update, :conference_speaker, speaker: conference_speaker)

Decidim::Conferences::Admin::PublishConferenceSpeaker.call(conference_speaker, current_user) do
on(:ok) do
flash[:notice] = I18n.t("conference_speakers.publish.success", scope: "decidim.admin")
redirect_to conference_speakers_path(current_conference)
end

on(:invalid) do
flash.now[:alert] = I18n.t("conference_speakers.publish.invalid", scope: "decidim.admin")
render action: "index"
end
end
end

def unpublish
enforce_permission_to(:update, :conference_speaker, speaker: conference_speaker)

Decidim::Conferences::Admin::UnpublishConferenceSpeaker.call(conference_speaker, current_user) do
on(:ok) do
flash[:notice] = I18n.t("conference_speakers.unpublish.success", scope: "decidim.admin")
redirect_to conference_speakers_path(current_conference)
end

on(:invalid) do
flash.now[:alert] = I18n.t("conference_speakers.unpublish.invalid", scope: "decidim.admin")
render action: "index"
end
end
end

private

def meetings_selected
Expand Down
2 changes: 2 additions & 0 deletions decidim-conferences/app/models/decidim/conference_speaker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class ConferenceSpeaker < ApplicationRecord
include Decidim::Loggable
include Decidim::HasUploadValidations
include Decidim::TranslatableResource
include Decidim::Publicable

translatable_fields :position, :affiliation, :short_bio

Expand All @@ -17,6 +18,7 @@ class ConferenceSpeaker < ApplicationRecord
has_many :conference_meetings, through: :conference_speaker_conference_meetings, class_name: "Decidim::ConferenceMeeting"

default_scope { order(full_name: :asc, created_at: :asc) }
scope :published, -> { where.not(published_at: nil) }

has_one_attached :avatar
validates_avatar :avatar, uploader: Decidim::AvatarUploader
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ def diff_fields_mapping
position: "Decidim::Conferences::AdminLog::ValueTypes::SpeakerPositionPresenter",
position_other: :string,
weight: :integer,
ceased_date: :date
ceased_date: :date,
published_at: :date
}
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@
<%= icon_link_to "pencil-line", edit_conference_speaker_path(current_conference, speaker), t("actions.edit", scope: "decidim.admin"), class: "action-icon--edit" %>
<% end %>

<% if allowed_to? :update, :conference_speaker, speaker: speaker %>
<% if speaker.published? %>
<%= icon_link_to "close-circle-line", unpublish_conference_speaker_path(current_conference, speaker.id), t("actions.unpublish", scope: "decidim.admin"), method: :put, class: "action-icon--unpublish", data: { confirm: t("actions.unpublish", scope: "decidim.admin") } %>
<% else %>
<%= icon_link_to "check-line", publish_conference_speaker_path(current_conference, speaker.id), t("actions.publish", scope: "decidim.admin"), method: :put, class: "action-icon--publish" %>
<% end %>
<% else %>
<span class="action-space icon"></span>
<% end %>

<% if allowed_to? :destroy, :conference_speaker, speaker: speaker %>
<%= icon_link_to "delete-bin-line", conference_speaker_path(current_conference, speaker), t("actions.destroy", scope: "decidim.admin"), class: "action-icon--remove", method: :delete, data: { confirm: t("actions.confirm_destroy", scope: "decidim.admin") } %>
<% end %>
Expand Down
6 changes: 6 additions & 0 deletions decidim-conferences/config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -127,9 +127,15 @@ en:
new:
create: Create
title: New conference speaker.
publish:
invalid: There was a problem publishing this speaker.
success: Conference speaker successfully published.
update:
error: There was a problem updating this conference speaker.
success: Conference speaker successfully updated.
unpublish:
invalid: There was a problem unpublishing this speaker.
success: Conference speaker successfully unpublished.
conference_user_roles:
create:
error: There was a problem adding an admin to this conference.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class AddPublishedAtToConferenceSpeakers < ActiveRecord::Migration[7.0]
def change
add_column :decidim_conference_speakers, :published_at, :datetime, index: true
end
end
7 changes: 6 additions & 1 deletion decidim-conferences/lib/decidim/conferences/admin_engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ class AdminEngine < ::Rails::Engine
resources :conferences, param: :slug, except: [:show, :destroy] do
resource :publish, controller: "conference_publications", only: [:create, :destroy]
resources :copies, controller: "conference_copies", only: [:new, :create]
resources :speakers, controller: "conference_speakers"
resources :speakers, controller: "conference_speakers" do
member do
put :publish
put :unpublish
end
end
resources :partners, controller: "partners", except: [:show]
resources :media_links, controller: "media_links"
resources :registration_types, controller: "registration_types" do
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

require "spec_helper"
module Decidim
module Conferences
module Admin
describe PublishConferenceSpeaker, type: :command do
let(:organization) { create :organization, available_locales: [:en] }
let(:conference_speaker) { create(:conference_speaker, published_at: nil) }
let(:current_user) { create(:user, :admin, :confirmed, organization:) }
let(:command) { described_class.new(conference_speaker, current_user) }

describe "call" do
context "when the conference speaker is not already published" do
it "publishes the conference speaker" do
expect(Decidim.traceability).to receive(:perform_action!).with(
:publish,
conference_speaker,
current_user
).and_call_original

expect(command).to broadcast(:ok, conference_speaker)
end
end

context "when the conference speaker is already published" do
before do
conference_speaker.update!(published_at: Time.current)
end

it "does not publish the conference speaker" do
expect { command.call }.not_to(change { conference_speaker.reload.published_at })

expect(command).to broadcast(:invalid)
end
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

require "spec_helper"

module Decidim
module Conferences
module Admin
describe UnpublishConferenceSpeaker, type: :command do
let(:organization) { create :organization, available_locales: [:en] }
let(:conference_speaker) { create(:conference_speaker, published_at: Time.current) }
let(:current_user) { create(:user, :admin, :confirmed, organization:) }
let(:command) { described_class.new(conference_speaker, current_user) }

describe "call" do
context "when the conference speaker is published" do
it "unpublishes the conference speaker" do
expect(Decidim.traceability).to receive(:perform_action!).with(
:unpublish,
conference_speaker,
current_user
).and_call_original

expect(command).to broadcast(:ok, conference_speaker)
end
end

context "when the conference speaker is not published" do
before do
conference_speaker.update!(published_at: nil)
end

it "does not unpublish the conference speaker" do
expect { command.call }.not_to(change { conference_speaker.reload.published_at })

expect(command).to broadcast(:invalid)
end
end
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require.context("../images", true)
import "stylesheets/decidim/proposals/admin/participatory_texts.scss"
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#participatory-text {
li {
@apply py-4 hover:cursor-move;

a {
@apply font-bold flex;

> svg {
@apply text-2xl fill-black;
}

&[aria-expanded="true"] {
& > svg {
@apply rotate-90 transition-transform;
}
}

span {
@apply ml-auto;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<% add_decidim_page_title(t(".title")) %>
<%= append_stylesheet_pack_tag "participatory_texts_admin" %>

<div class="item_show__header">
<h1 class="item_show__header-title">
Expand All @@ -15,18 +16,21 @@
<div class="row column">
<p class="mt-3"><%= t(".info_1") %></p>
<ul id="participatory-text" class="draggable-list js-connect js-list-actives mt-2.5 ml-2.5 mr-2.5"
data-component="accordion"
data-accordion
data-sort-url="#"
data-multi-expand="true"
data-allow-all-closed="true">
<%= form.fields_for(:proposals) do |prop_form| %>
<% proposal = @drafts[prop_form.index] %>

<li class="py-4 draggable-content <%= proposal.article? ? "is-active" : nil %>" data-accordion-item draggable="true">
<a href="#" class="font-bold mt-5"><%= preview_participatory_text_section_title(proposal) %>
<li class="draggable-content is-active" data-accordion-item draggable="true">
<a data-open="true" data-controls="article-<%= proposal.id %>">
<%= icon "arrow-right-s-line" %>
<%= preview_participatory_text_section_title(proposal) %>
<span><%= icon "menu-line", class: "fill-black" %></span>
</a>
<div data-tab-content>
<div data-tab-content id="article-<%= proposal.id %>">
<%= render "article-preview", { form: prop_form, proposal: } %>
</div>
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
<%= t(".title") %>
<span id="js-selected-proposals-count" class="component-counter " title="<%= t("decidim.proposals.admin.proposals.index.selected") %>"></span>
</div>
<%= render partial: "bulk-actions" %>
<%= link_to t(".statuses"), proposal_states_path, class: "button button__sm button__secondary" %>
<%= render partial: "decidim/admin/components/resource_action" %>
<div class="flex items-center gap-x-4">
<%= render partial: "bulk-actions" %>
<%= link_to t(".statuses"), proposal_states_path, class: "button button__sm button__secondary" %>
<%= render partial: "decidim/admin/components/resource_action" %>
</div>
</h1>
</div>
<%= admin_filter_selector(:proposals) %>
Expand Down
1 change: 1 addition & 0 deletions decidim-proposals/config/assets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
Decidim::Webpacker.register_path("#{base_path}/app/packs")
Decidim::Webpacker.register_entrypoints(
decidim_proposals: "#{base_path}/app/packs/entrypoints/decidim_proposals.js",
participatory_texts_admin: "#{base_path}/app/packs/entrypoints/participatory_texts_admin.js",
decidim_proposals_admin: "#{base_path}/app/packs/entrypoints/decidim_proposals_admin.js"
)
Loading