decidim-gallery 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE-AGPLv3.txt +661 -0
- data/README.md +30 -0
- data/Rakefile +9 -0
- data/app/cells/decidim/gallery/main/image.erb +51 -0
- data/app/cells/decidim/gallery/main/image_collection.erb +13 -0
- data/app/cells/decidim/gallery/main/image_list.erb +9 -0
- data/app/cells/decidim/gallery/main/video.erb +20 -0
- data/app/cells/decidim/gallery/main/video_collection.erb +3 -0
- data/app/cells/decidim/gallery/main_cell.rb +88 -0
- data/app/cells/decidim/gallery/video/show.erb +6 -0
- data/app/cells/decidim/gallery/video_cell.rb +96 -0
- data/app/commands/decidim/gallery/admin/create_gallery_item.rb +50 -0
- data/app/commands/decidim/gallery/admin/publish_gallery_item.rb +38 -0
- data/app/commands/decidim/gallery/admin/unpublish_gallery_item.rb +38 -0
- data/app/commands/decidim/gallery/admin/update_gallery_item.rb +44 -0
- data/app/controllers/decidim/gallery/admin/application_controller.rb +24 -0
- data/app/controllers/decidim/gallery/admin/gallery_item_controller.rb +104 -0
- data/app/controllers/decidim/gallery/application_controller.rb +8 -0
- data/app/controllers/decidim/gallery/gallery_controller.rb +9 -0
- data/app/forms/decidim/gallery/admin/gallery_item_form.rb +17 -0
- data/app/forms/decidim/gallery/admin/gallery_item_image_form.rb +14 -0
- data/app/forms/decidim/gallery/admin/gallery_item_video_form.rb +12 -0
- data/app/helpers/decidim/gallery/admin/application_helper.rb +18 -0
- data/app/model/decidim/gallery/application_record.rb +10 -0
- data/app/model/decidim/gallery/gallery_item.rb +38 -0
- data/app/overrides/decidim/admin/static_pages/edit/add_gallery.html.erb.deface +11 -0
- data/app/overrides/decidim/pages/_standalone/add_content_blocks.html.erb.deface +7 -0
- data/app/overrides/decidim/pages/_tabbed/add_content_blocks.html.erb.deface +5 -0
- data/app/packs/entrypoints/decidim_gallery.js +3 -0
- data/app/packs/images/decidim/gallery/icon.svg +1 -0
- data/app/packs/src/decidim/gallery/gallery.js +42 -0
- data/app/packs/src/decidim/gallery/masonry/EvEmitter.js +85 -0
- data/app/packs/src/decidim/gallery/masonry/getSize.js +181 -0
- data/app/packs/src/decidim/gallery/masonry/jQueryBridget.js +109 -0
- data/app/packs/src/decidim/gallery/masonry/masonry.js +202 -0
- data/app/packs/src/decidim/gallery/masonry/matchesSelector.js +25 -0
- data/app/packs/src/decidim/gallery/masonry/outlayer.js +885 -0
- data/app/packs/src/decidim/gallery/masonry/outlayerItem.js +522 -0
- data/app/packs/src/decidim/gallery/masonry/utils.js +203 -0
- data/app/packs/stylesheets/decidim/gallery/_gallery.scss +3 -0
- data/app/permissions/decidim/gallery/admin/permissions.rb +18 -0
- data/app/permissions/decidim/gallery/permissions.rb +17 -0
- data/app/views/decidim/gallery/admin/gallery_item/_form_image.html.erb +16 -0
- data/app/views/decidim/gallery/admin/gallery_item/_form_video.html.erb +16 -0
- data/app/views/decidim/gallery/admin/gallery_item/edit.html.erb +9 -0
- data/app/views/decidim/gallery/admin/gallery_item/index.html.erb +52 -0
- data/app/views/decidim/gallery/admin/gallery_item/new.html.erb +9 -0
- data/app/views/decidim/gallery/gallery/index.html.erb +11 -0
- data/config/assets.rb +9 -0
- data/config/i18n-tasks.yml +22 -0
- data/config/locales/en.yml +79 -0
- data/config/locales/fr.yml +79 -0
- data/config/locales/ro.yml +79 -0
- data/lib/decidim/gallery/admin/static_pages/command.rb +15 -0
- data/lib/decidim/gallery/admin/static_pages/form.rb +21 -0
- data/lib/decidim/gallery/admin.rb +14 -0
- data/lib/decidim/gallery/admin_engine.rb +27 -0
- data/lib/decidim/gallery/component.rb +47 -0
- data/lib/decidim/gallery/engine.rb +60 -0
- data/lib/decidim/gallery/test/factories.rb +58 -0
- data/lib/decidim/gallery/version.rb +14 -0
- data/lib/decidim/gallery.rb +14 -0
- data/lib/tasks/decidim_gallery.rake +16 -0
- metadata +163 -0
data/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Decidim::Gallery
|
2
|
+
|
3
|
+
Decidim Gallery Module.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
Gallery will be available as a Component for a Participatory
|
8
|
+
Space.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
Add this line to your application's Gemfile:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
gem "decidim-gallery"
|
16
|
+
```
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
```bash
|
21
|
+
bundle
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
|
26
|
+
See [Decidim](https://github.com/decidim/decidim).
|
27
|
+
|
28
|
+
## License
|
29
|
+
|
30
|
+
This engine is distributed under the GNU AFFERO GENERAL PUBLIC LICENSE.
|
data/Rakefile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "decidim/dev/common_rake"
|
4
|
+
|
5
|
+
desc "Generates a dummy app for testing"
|
6
|
+
task test_app: "decidim:generate_external_test_app"
|
7
|
+
|
8
|
+
desc "Generates a development app."
|
9
|
+
task development_app: "decidim:generate_external_development_app"
|
@@ -0,0 +1,51 @@
|
|
1
|
+
<% if gallery_component.settings.show_title? %>
|
2
|
+
<h3 class="section-heading gallery-heading"><%= title %> (<%= t( ".#{gallery_component.settings.gallery_type}", count: items.total_count) %>)</h3>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<% if gallery_component.settings.show_announcement? %>
|
6
|
+
<div class="row">
|
7
|
+
<div class="column"><%= translated_attribute(gallery_component.settings.announcement) %></div>
|
8
|
+
</div>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<div class="row small-up <%= model.css %> medium-up-3 mb-l gallery image" id="gallery_<%= model.section %>_<%=model.gallery_id %>">
|
12
|
+
<%= cell("decidim/gallery/main", model).collection %>
|
13
|
+
</div>
|
14
|
+
<% unless items.total_count.zero? || items.last_page? %>
|
15
|
+
<div class="row">
|
16
|
+
<div class="column">
|
17
|
+
<%= link_to t("decidim.gallery.main.load_more"), gallery_path(format: 'js', page: items.next_page,section: model.section, cb: model.id), class: "button small hollow", id: "link_gallery_#{model.section}_#{model.id}" , remote: true %>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
<% end %>
|
21
|
+
|
22
|
+
<div class="small gallery-pop-up reveal" id="galleryModal_<%= model.section %>_<%=model.id %>" <% unless browser.mobile? %> data-reveal<% end %> >
|
23
|
+
<button class="close-button" data-close aria-label="<%= t("decidim.gallery.main.close_modal") %>"
|
24
|
+
type="button">
|
25
|
+
<span aria-hidden="true">×</span>
|
26
|
+
</button>
|
27
|
+
|
28
|
+
<div class="orbit row" data-orbit data-auto-play="false">
|
29
|
+
<div class="orbit-wrapper">
|
30
|
+
<div class="orbit-controls">
|
31
|
+
<button class="orbit-previous"><span class="show-for-sr"><%= t("decidim.gallery.main.previous_slide") %></span>
|
32
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24.425 38.092">
|
33
|
+
<path id="Path_3921" data-name="Path 3921" d="M0,.13,18.222,22.218l8.81-10.68L36.55,0" transform="translate(23.789 0.771) rotate(90)" fill="none" stroke-width="6"/>
|
34
|
+
</svg>
|
35
|
+
</button>
|
36
|
+
<button class="orbit-next"><span class="show-for-sr"><%= t("decidim.gallery.main.next_slide") %></span>
|
37
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24.425 38.092">
|
38
|
+
<path id="Path_3922" data-name="Path 3922" d="M0,22.088,18.222,0l8.81,10.68L36.55,22.218" transform="translate(22.854 0.771) rotate(90)" fill="none" stroke-width="6"/>
|
39
|
+
</svg>
|
40
|
+
</button>
|
41
|
+
</div>
|
42
|
+
|
43
|
+
<ul class="orbit-container">
|
44
|
+
<%= cell("decidim/gallery/main", model).list_items %>
|
45
|
+
</ul>
|
46
|
+
</div>
|
47
|
+
</div>
|
48
|
+
</div>
|
49
|
+
<% content_for(:js_content) do %>
|
50
|
+
<%= javascript_pack_tag "decidim_gallery" %>
|
51
|
+
<% end %>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<% items.each do |item| %>
|
2
|
+
<% next unless item.attached_uploader(:photo).attached? %>
|
3
|
+
<div class="column gallery-item">
|
4
|
+
<% if browser.mobile? %>
|
5
|
+
<%= image_tag item.attached_uploader(:photo).path(variant: :big), alt: translated_attribute(item.title), class: "speaker-image" %>
|
6
|
+
<% else %>
|
7
|
+
<a href="#" title="<%= translated_attribute(item.title) %>" data-open="galleryModal_<%= model.section %>_<%=model.id %>" data-id="link<%= item.id %>">
|
8
|
+
<%= image_tag item.attached_uploader(:photo).path(variant: :big), alt: translated_attribute(item.title), class: "speaker-image" %>
|
9
|
+
</a>
|
10
|
+
<% end %>
|
11
|
+
<div class="gallery-caption"><%= translated_attribute(item.title) %></div>
|
12
|
+
</div>
|
13
|
+
<% end %>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<% items.each_with_index do |item, index| %>
|
2
|
+
<% next unless item.attached_uploader(:photo).attached? %>
|
3
|
+
<li class="<%= index.zero? ? 'is-active ' : '' %>orbit-slide" data-target="link<%= item.id %>">
|
4
|
+
<figure class="orbit-figure">
|
5
|
+
<%= image_tag item.attached_uploader(:photo).path(variant: :big), class: 'orbit-image' %>
|
6
|
+
<figcaption class="orbit-caption gallery-caption"><%= translated_attribute(item.title) %></figcaption>
|
7
|
+
</figure>
|
8
|
+
</li>
|
9
|
+
<% end %>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<% if gallery_component.settings.show_title? %>
|
2
|
+
<h3 class="section-heading gallery-heading"><%= title %> (<%= t( ".#{gallery_component.settings.gallery_type}", count: items.total_count) %>)</h3>
|
3
|
+
<% end %>
|
4
|
+
|
5
|
+
<% if gallery_component.settings.show_announcement? %>
|
6
|
+
<div class="row">
|
7
|
+
<div class="column"><%= translated_attribute(gallery_component.settings.announcement) %></div>
|
8
|
+
</div>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<div class="row small-up <%= model.css %> mb-l medium-up-3 gallery video" id="gallery_<%= model.section %>_<%=model.id %>">
|
12
|
+
<%= cell("decidim/gallery/main", model).collection %>
|
13
|
+
</div>
|
14
|
+
<% unless items.total_count.zero? || items.last_page? %>
|
15
|
+
<div class="row">
|
16
|
+
<div class="column">
|
17
|
+
<%= link_to t("decidim.gallery.main.load_more"), gallery_path(format: 'js', page: items.next_page, section: model.section, cb: model.id), class: "button small hollow", id: "link_gallery_#{model.section}_#{model.id}", remote: true %>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
<% end %>
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Gallery
|
5
|
+
class MainCell < Decidim::ViewModel
|
6
|
+
delegate :public_name_key, :has_settings?, to: :model
|
7
|
+
delegate :content_for, to: :view_context
|
8
|
+
|
9
|
+
def show
|
10
|
+
render gallery_type.to_sym if gallery_component.present?
|
11
|
+
end
|
12
|
+
|
13
|
+
def collection
|
14
|
+
render "#{gallery_type}_collection"
|
15
|
+
end
|
16
|
+
|
17
|
+
def list_items
|
18
|
+
return "" if gallery_type == "video"
|
19
|
+
|
20
|
+
render "#{gallery_type}_list"
|
21
|
+
end
|
22
|
+
|
23
|
+
def items
|
24
|
+
@items ||= Decidim::Gallery::GalleryItem
|
25
|
+
.published
|
26
|
+
.where(decidim_component_id: gallery_component.id)
|
27
|
+
.order(weight: :desc, published_at: :desc)
|
28
|
+
.page(options[:page])
|
29
|
+
.per(per_page)
|
30
|
+
end
|
31
|
+
|
32
|
+
def gallery_path(**options)
|
33
|
+
current_params = try(:params) || {}
|
34
|
+
EngineRouter.main_proxy(gallery_component).root_path({ locale: current_params[:locale] }.reverse_merge(options))
|
35
|
+
end
|
36
|
+
|
37
|
+
Settings = Struct.new(:video_url, :title, keyword_init: true)
|
38
|
+
Video = Struct.new(:settings, :cache_key_with_version, keyword_init: true)
|
39
|
+
|
40
|
+
def stubbed_video_object(item)
|
41
|
+
Video.new(settings: Settings.new(
|
42
|
+
video_url: translated_attribute(item.video_url),
|
43
|
+
title: translated_attribute(item.title)
|
44
|
+
),
|
45
|
+
cache_key_with_version: item.cache_key_with_version)
|
46
|
+
end
|
47
|
+
|
48
|
+
def title
|
49
|
+
translated_attribute(gallery_component.name)
|
50
|
+
end
|
51
|
+
|
52
|
+
def gallery_component
|
53
|
+
@gallery_component ||= Decidim::Component.find_by(id: model.gallery_id)
|
54
|
+
end
|
55
|
+
|
56
|
+
def browser
|
57
|
+
@browser ||= Browser.new(
|
58
|
+
request.headers["User-Agent"],
|
59
|
+
accept_language: request.headers["Accept-Language"]
|
60
|
+
)
|
61
|
+
end
|
62
|
+
|
63
|
+
def current_participatory_space
|
64
|
+
controller.try(:current_participatory_space)
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
|
69
|
+
def view_context
|
70
|
+
context.fetch(:view_context)
|
71
|
+
end
|
72
|
+
|
73
|
+
def per_page
|
74
|
+
gallery_component.settings.items_per_page
|
75
|
+
end
|
76
|
+
|
77
|
+
def show_title?
|
78
|
+
gallery_component.settings.show_title
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def gallery_type
|
84
|
+
gallery_component.settings.gallery_type
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<div class="column gallery-item">
|
2
|
+
<iframe src="<%= embeded_video_url %>" class="video-iframe class-<%= video_provider %>" title="<%= translated_title %>" style="border:0;"></iframe>
|
3
|
+
<div class="speaker-data">
|
4
|
+
<div class="data-name gallery-caption"><%= translated_title %></div>
|
5
|
+
</div>
|
6
|
+
</div>
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Gallery
|
5
|
+
class VideoCell < Decidim::ViewModel
|
6
|
+
include Decidim::SanitizeHelper
|
7
|
+
|
8
|
+
PROVIDERS = {
|
9
|
+
"youtube" => :youtube,
|
10
|
+
"youtu.be" => :youtube,
|
11
|
+
"vimeo" => :vimeo,
|
12
|
+
"dai.ly" => :dailymotion,
|
13
|
+
"dailymotion" => :dailymotion
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
def show
|
17
|
+
return if embeded_video_url.nil?
|
18
|
+
|
19
|
+
render
|
20
|
+
end
|
21
|
+
|
22
|
+
def translated_title
|
23
|
+
@translated_title ||= translated_attribute(model.settings.title)
|
24
|
+
end
|
25
|
+
|
26
|
+
def cache_hash
|
27
|
+
hash = []
|
28
|
+
hash.push(I18n.locale)
|
29
|
+
hash.push(model.cache_key_with_version)
|
30
|
+
hash.join(Decidim.cache_key_separator)
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def video_url
|
36
|
+
model.settings.video_url
|
37
|
+
end
|
38
|
+
|
39
|
+
def embeded_video_url
|
40
|
+
send("#{video_provider}_url".to_sym) if video_provider
|
41
|
+
end
|
42
|
+
|
43
|
+
def youtube_url
|
44
|
+
return if video_id_youtube.blank?
|
45
|
+
|
46
|
+
"//www.youtube.com/embed/#{video_id_youtube}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def vimeo_url
|
50
|
+
return if video_id_vimeo.blank?
|
51
|
+
|
52
|
+
"//player.vimeo.com/video/#{video_id_vimeo}"
|
53
|
+
end
|
54
|
+
|
55
|
+
def dailymotion_url
|
56
|
+
return if video_id_dailymotion.blank?
|
57
|
+
|
58
|
+
"//www.dailymotion.com/embed/video/#{video_id_dailymotion}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def video_id_youtube
|
62
|
+
@video_id_youtube ||= begin
|
63
|
+
regex_id = %r{(?:youtube(?:-nocookie)?\.com/(?:[^/\n\s]+/\S+/|(?:v|e(?:mbed)?)/|\S*?[?&]v=)|youtu\.be/)([a-zA-Z0-9_-]{7,11})}
|
64
|
+
match_value = regex_id.match(video_url)
|
65
|
+
match_value[1] if match_value && match_value[1].present?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def video_id_dailymotion
|
70
|
+
@video_id_dailymotion ||= begin
|
71
|
+
regex_id = %r{(?:dailymotion\.com|dai\.ly)/(?:embed/)?(?:video/)?([a-zA-Z0-9]*)}
|
72
|
+
match_value = regex_id.match(video_url)
|
73
|
+
match_value[1] if match_value && match_value[1].present?
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def video_id_vimeo
|
78
|
+
@video_id_vimeo ||= begin
|
79
|
+
regex_id = %r{vimeo\.com/(?:channels/(?:\w+/)?|groups/[^/]*/videos/|video/|)(\d+)(?:|/\?)}
|
80
|
+
match_value = regex_id.match(video_url)
|
81
|
+
match_value[1] if match_value && match_value[1].present?
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def video_provider
|
86
|
+
@video_provider ||= begin
|
87
|
+
regex_prov = /(youtube|youtu\.be|vimeo|dai\.ly|dailymotion)/
|
88
|
+
match_prov = regex_prov.match(video_url)
|
89
|
+
return unless match_prov && match_prov[1].present?
|
90
|
+
|
91
|
+
PROVIDERS[match_prov[1]]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Gallery
|
5
|
+
module Admin
|
6
|
+
class CreateGalleryItem < Rectify::Command
|
7
|
+
include ::Decidim::AttachmentAttributesMethods
|
8
|
+
|
9
|
+
def initialize(form, current_user)
|
10
|
+
@form = form
|
11
|
+
@current_user = current_user
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
return broadcast(:invalid) if @form.invalid?
|
16
|
+
|
17
|
+
transaction do
|
18
|
+
create_gallery_item!
|
19
|
+
end
|
20
|
+
|
21
|
+
broadcast(:ok, @gallery_item)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :form
|
27
|
+
|
28
|
+
def create_gallery_item!
|
29
|
+
@gallery_item = Decidim.traceability.create!(
|
30
|
+
GalleryItem,
|
31
|
+
@current_user,
|
32
|
+
attributes,
|
33
|
+
visibility: "all"
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def attributes
|
38
|
+
@hash = { title: form.title, component: form.current_component, author: @current_user, weight: form.weight }
|
39
|
+
|
40
|
+
if form.current_component.settings["gallery_type"] == "image"
|
41
|
+
@hash.merge!(attachment_attributes(:photo))
|
42
|
+
else
|
43
|
+
@hash.merge!(video_url: form.video_url)
|
44
|
+
end
|
45
|
+
@hash
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Gallery
|
5
|
+
module Admin
|
6
|
+
class PublishGalleryItem < Rectify::Command
|
7
|
+
def initialize(gallery_item, current_user)
|
8
|
+
@gallery_item = gallery_item
|
9
|
+
@current_user = current_user
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
return broadcast(:invalid) if @gallery_item.published?
|
14
|
+
|
15
|
+
transaction do
|
16
|
+
publish_gallery_item!
|
17
|
+
end
|
18
|
+
|
19
|
+
broadcast(:ok, @gallery_item)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def publish_gallery_item!
|
25
|
+
@gallery_item = Decidim.traceability.perform_action!(
|
26
|
+
:publish,
|
27
|
+
@gallery_item,
|
28
|
+
@current_user,
|
29
|
+
visibility: "all"
|
30
|
+
) do
|
31
|
+
@gallery_item.publish!
|
32
|
+
@gallery_item
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Gallery
|
5
|
+
module Admin
|
6
|
+
class UnpublishGalleryItem < Rectify::Command
|
7
|
+
def initialize(gallery_item, current_user)
|
8
|
+
@gallery_item = gallery_item
|
9
|
+
@current_user = current_user
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
return broadcast(:invalid) unless @gallery_item.published?
|
14
|
+
|
15
|
+
transaction do
|
16
|
+
unpublish_gallery_item!
|
17
|
+
end
|
18
|
+
|
19
|
+
broadcast(:ok, @gallery_item)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def unpublish_gallery_item!
|
25
|
+
@gallery_item = Decidim.traceability.perform_action!(
|
26
|
+
:unpublish,
|
27
|
+
@gallery_item,
|
28
|
+
@current_user,
|
29
|
+
visibility: "all"
|
30
|
+
) do
|
31
|
+
@gallery_item.unpublish!
|
32
|
+
@gallery_item
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Gallery
|
5
|
+
module Admin
|
6
|
+
class UpdateGalleryItem < Rectify::Command
|
7
|
+
include ::Decidim::AttachmentAttributesMethods
|
8
|
+
|
9
|
+
def initialize(form, gallery_item)
|
10
|
+
@form = form
|
11
|
+
@gallery_item = gallery_item
|
12
|
+
end
|
13
|
+
|
14
|
+
def call
|
15
|
+
return broadcast(:invalid) if form.invalid?
|
16
|
+
|
17
|
+
transaction do
|
18
|
+
update_gallery_item!
|
19
|
+
end
|
20
|
+
|
21
|
+
broadcast(:ok, @gallery_item)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :form
|
27
|
+
|
28
|
+
def update_gallery_item!
|
29
|
+
@gallery_item.update!(**attributes)
|
30
|
+
end
|
31
|
+
|
32
|
+
def attributes
|
33
|
+
@hash = { title: form.title, weight: form.weight }
|
34
|
+
if @form.current_component.settings["gallery_type"] == "image"
|
35
|
+
@hash.merge!(attachment_attributes(:photo))
|
36
|
+
else
|
37
|
+
@hash.merge!(video_url: form.video_url)
|
38
|
+
end
|
39
|
+
@hash
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Gallery
|
5
|
+
module Admin
|
6
|
+
# This controller is the abstract class from which all other controllers of
|
7
|
+
# this engine inherit.
|
8
|
+
#
|
9
|
+
# Note that it inherits from `Decidim::Admin::Components::BaseController`, which
|
10
|
+
# override its layout and provide all kinds of useful methods.
|
11
|
+
class ApplicationController < Decidim::Admin::Components::BaseController
|
12
|
+
helper_method :gallery_items, :gallery_item
|
13
|
+
|
14
|
+
def gallery_items
|
15
|
+
@gallery_items ||= GalleryItem.where(component: current_component).page(params[:page]).per(15)
|
16
|
+
end
|
17
|
+
|
18
|
+
def gallery_item
|
19
|
+
@gallery_item ||= gallery_items.find(params[:id])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Gallery
|
5
|
+
module Admin
|
6
|
+
class GalleryItemController < ::Decidim::Gallery::Admin::ApplicationController
|
7
|
+
def index
|
8
|
+
enforce_permission_to :list, :gallery
|
9
|
+
end
|
10
|
+
|
11
|
+
def new
|
12
|
+
enforce_permission_to :create, :gallery
|
13
|
+
@form = form(fetch_form).instance
|
14
|
+
end
|
15
|
+
|
16
|
+
def create
|
17
|
+
enforce_permission_to :create, :gallery
|
18
|
+
@form = form(fetch_form).from_params(params, current_component: current_component)
|
19
|
+
|
20
|
+
CreateGalleryItem.call(@form, current_user) do
|
21
|
+
on(:ok) do
|
22
|
+
flash[:notice] = I18n.t("gallery_item.create.success", scope: "decidim.gallery.admin")
|
23
|
+
redirect_to EngineRouter.admin_proxy(current_component).root_path
|
24
|
+
end
|
25
|
+
|
26
|
+
on(:invalid) do
|
27
|
+
flash.now[:alert] = I18n.t("gallery_item.create.invalid", scope: "decidim.gallery.admin")
|
28
|
+
render action: "new"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def edit
|
34
|
+
enforce_permission_to :update, :gallery, gallery_item: gallery_item
|
35
|
+
@form = form(fetch_form).from_model(gallery_item)
|
36
|
+
end
|
37
|
+
|
38
|
+
def update
|
39
|
+
enforce_permission_to :update, :gallery, gallery_item: gallery_item
|
40
|
+
@form = form(fetch_form).from_params(params, current_component: current_component)
|
41
|
+
|
42
|
+
UpdateGalleryItem.call(@form, gallery_item) do
|
43
|
+
on(:ok) do
|
44
|
+
flash[:notice] = I18n.t("gallery_item.update.success", scope: "decidim.gallery.admin")
|
45
|
+
redirect_to EngineRouter.admin_proxy(current_component).root_path
|
46
|
+
end
|
47
|
+
|
48
|
+
on(:invalid) do
|
49
|
+
flash.now[:alert] = I18n.t("gallery_item.update.invalid", scope: "decidim.gallery.admin")
|
50
|
+
render action: "edit"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def publish
|
56
|
+
enforce_permission_to :update, :gallery, gallery_item: gallery_item
|
57
|
+
|
58
|
+
Decidim::Gallery::Admin::PublishGalleryItem.call(gallery_item, current_user) do
|
59
|
+
on(:ok) do
|
60
|
+
flash[:notice] = I18n.t("gallery_item.publish.success", scope: "decidim.gallery.admin")
|
61
|
+
redirect_to EngineRouter.admin_proxy(current_component).root_path
|
62
|
+
end
|
63
|
+
|
64
|
+
on(:invalid) do
|
65
|
+
flash.now[:alert] = I18n.t("gallery_item.publish.invalid", scope: "decidim.gallery.admin")
|
66
|
+
render action: "index"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def unpublish
|
72
|
+
enforce_permission_to :update, :gallery, gallery_item: gallery_item
|
73
|
+
|
74
|
+
Decidim::Gallery::Admin::UnpublishGalleryItem.call(gallery_item, current_user) do
|
75
|
+
on(:ok) do
|
76
|
+
flash[:notice] = I18n.t("gallery_item.unpublish.success", scope: "decidim.gallery.admin")
|
77
|
+
redirect_to root_path
|
78
|
+
end
|
79
|
+
|
80
|
+
on(:invalid) do
|
81
|
+
flash.now[:alert] = I18n.t("gallery_item.unpublish.invalid", scope: "decidim.gallery.admin")
|
82
|
+
render action: "index"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def destroy
|
88
|
+
enforce_permission_to :destroy, :gallery, gallery_item: gallery_item
|
89
|
+
gallery_item.destroy!
|
90
|
+
|
91
|
+
flash[:notice] = I18n.t("gallery_item.destroy.success", scope: "decidim.gallery.admin")
|
92
|
+
|
93
|
+
redirect_to root_path
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def fetch_form
|
99
|
+
current_component.settings["gallery_type"] == "image" ? GalleryItemImageForm : GalleryItemVideoForm
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Gallery
|
5
|
+
module Admin
|
6
|
+
class GalleryItemForm < Decidim::Form
|
7
|
+
alias organization current_organization
|
8
|
+
|
9
|
+
include Decidim::TranslatableAttributes
|
10
|
+
translatable_attribute :title, String
|
11
|
+
attribute :weight, Integer, default: 0
|
12
|
+
|
13
|
+
validates :title, translatable_presence: true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|