decidim-homepage_proposals 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -4
- data/app/cells/decidim/homepage_proposals/content_blocks/proposals_slider_cell.rb +7 -3
- data/app/packs/src/decidim/homepage_proposals/glideBuilder.js +45 -9
- data/app/packs/src/decidim/homepage_proposals/glidejs/Manager.js +3 -11
- data/app/packs/src/decidim/homepage_proposals/main.js +7 -0
- data/app/packs/stylesheets/decidim/homepage_proposals/homepage_proposals.scss +11 -0
- data/app/views/decidim/shared/homepage_proposals/_filters.erb +42 -42
- data/config/i18n-tasks.yml +29 -1
- data/config/locales/en.yml +7 -3
- data/lib/decidim/homepage_proposals/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b2f59c3f281a8e0a637928618dcfcd6a4afc4fb613e8ddcb48d331852b38b81a
|
4
|
+
data.tar.gz: 9e536edf44c0e0c6175c911066f25e16f08cb4914f88ec7f4ebf75bc8fd3b542
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc4b98d0f56d8f4c06a898d443ab4550dc4011ff394de0e0579535c85b0bdce4afe27a83cc083e7d1494777c8f7f9a1e19b90af3faadd41a993cd014468b62c5
|
7
|
+
data.tar.gz: 6082c4cbf2fb06cc437a7d28e824cbd841d404d13d98ce09aa2bf09f0f1aae400f652c2260e3944fdd7dde4376ae172d24d818c85b4451fe86f801bdfb7d75ae
|
data/README.md
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
# Decidim::HomepageProposals
|
2
2
|
|
3
|
-
|
3
|
+
Proposals homepage content block presented as carousel.
|
4
4
|
|
5
|
-
|
5
|
+
![Demo image](./docs/images/glanced_proposals.png)
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
With this module you can have an overview of current proposals on the platform. Carousel support live reload based on selected filters and refreshing using Ajax requests.
|
8
|
+
|
9
|
+
## Requirements
|
10
|
+
|
11
|
+
* [GlideJS](https://github.com/glidejs/glide)
|
9
12
|
|
10
13
|
## Installation
|
11
14
|
|
@@ -23,6 +26,13 @@ bundle exec rake decidim_module_homepage_proposals:webpacker:install
|
|
23
26
|
bundle exec rake assets:precompile
|
24
27
|
```
|
25
28
|
|
29
|
+
## Usage in Decidim
|
30
|
+
|
31
|
+
* Go to the backoffice
|
32
|
+
* Navigate to homepage content blocks
|
33
|
+
* Configure the homepage proposals content block
|
34
|
+
* Enable content block
|
35
|
+
|
26
36
|
## Contributing
|
27
37
|
|
28
38
|
See [Decidim](https://github.com/decidim/decidim).
|
@@ -12,8 +12,13 @@ module Decidim
|
|
12
12
|
include ActionView::Helpers::FormOptionsHelper
|
13
13
|
include Decidim::FiltersHelper
|
14
14
|
include Decidim::FilterResource
|
15
|
+
include Decidim::ComponentPathHelper
|
15
16
|
|
16
|
-
|
17
|
+
def default_linked_component_path
|
18
|
+
main_component_path(Decidim::Component.find(selected_component_id))
|
19
|
+
rescue ActiveRecord::RecordNotFound
|
20
|
+
root_path
|
21
|
+
end
|
17
22
|
|
18
23
|
def content_block_settings
|
19
24
|
@content_block_settings ||= Decidim::ContentBlock.find_by(
|
@@ -23,8 +28,7 @@ module Decidim
|
|
23
28
|
end
|
24
29
|
|
25
30
|
def options_for_default_component
|
26
|
-
|
27
|
-
options = components.map do |component|
|
31
|
+
options = linked_components.map do |component|
|
28
32
|
["#{translated_attribute(component.name)} (#{translated_attribute(component.participatory_space.title)})", component.id]
|
29
33
|
end
|
30
34
|
|
@@ -1,16 +1,52 @@
|
|
1
1
|
import Glide from "@glidejs/glide";
|
2
2
|
|
3
|
+
// Create a GlideJS carousel
|
4
|
+
// See documentation: https://glidejs.com/docs/
|
3
5
|
export default class GlideBuilder {
|
4
|
-
|
6
|
+
static defaultPervView() {
|
7
|
+
return 4;
|
8
|
+
}
|
9
|
+
|
10
|
+
static defaultBreakpoints() {
|
11
|
+
return { 1024: { perView: 3 }, 768: { perView: 2 }, 480: { perView: 1 } };
|
12
|
+
}
|
13
|
+
|
14
|
+
constructor(selector = '.glide', type = 'carousel', pervView = GlideBuilder.defaultPervView()) {
|
5
15
|
this.type = type
|
16
|
+
this.pervView = this.setPervView(pervView);
|
17
|
+
this.breakpoints = this.setBreakpoints();
|
6
18
|
this.setOpts()
|
7
19
|
this.glide = new Glide(selector, this.options)
|
8
20
|
|
9
21
|
this.bindings()
|
10
22
|
}
|
11
23
|
|
12
|
-
|
13
|
-
|
24
|
+
// Set pervView, must be between 0 and 4 excluded
|
25
|
+
// Returns default pervView when :
|
26
|
+
// * pervView < 1 : Placeholder is added at ./glideItems/Manager.js:122
|
27
|
+
// * pervView > 4 : Max pervView must be 4
|
28
|
+
setPervView(pervView) {
|
29
|
+
if (pervView > 0 && pervView < 4) {
|
30
|
+
return pervView;
|
31
|
+
} else {
|
32
|
+
return GlideBuilder.defaultPervView();
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
// Glide breakpoints must be accorded to the pervView to prevent scrolling on placeholders
|
37
|
+
setBreakpoints() {
|
38
|
+
let breakpoints;
|
39
|
+
switch (this.pervView) {
|
40
|
+
case 2:
|
41
|
+
breakpoints = { 1024: {perView: 2}, 768: {perView: 2}, 480: {perView: 1} };
|
42
|
+
break;
|
43
|
+
case 1:
|
44
|
+
breakpoints = { 1024: {perView: 1}, 768: {perView: 1}, 480: {perView: 1} };
|
45
|
+
break;
|
46
|
+
default:
|
47
|
+
breakpoints = GlideBuilder.defaultBreakpoints();
|
48
|
+
}
|
49
|
+
return breakpoints;
|
14
50
|
}
|
15
51
|
|
16
52
|
destroy() {
|
@@ -28,8 +64,10 @@ export default class GlideBuilder {
|
|
28
64
|
bindings() {
|
29
65
|
this.glide.on("run", () => {
|
30
66
|
let bulletNumber = this.glide.index;
|
31
|
-
$
|
32
|
-
|
67
|
+
let $glideBullets = $(".glide__bullets");
|
68
|
+
|
69
|
+
$($glideBullets.children()).css("color", "lightgrey");
|
70
|
+
$($glideBullets.children().get(bulletNumber + 1)).css("color", "grey");
|
33
71
|
});
|
34
72
|
}
|
35
73
|
|
@@ -38,11 +76,9 @@ export default class GlideBuilder {
|
|
38
76
|
type: this.type,
|
39
77
|
startAt: 0,
|
40
78
|
autoplay: 0,
|
41
|
-
perView:
|
79
|
+
perView: this.pervView,
|
80
|
+
breakpoints: this.breakpoints,
|
42
81
|
hoverpause: true,
|
43
|
-
breakpoints: {
|
44
|
-
1024: { perView: 3 }, 768: { perView: 2 }, 480: { perView: 1 }
|
45
|
-
},
|
46
82
|
perTouch: 1
|
47
83
|
}
|
48
84
|
}
|
@@ -73,9 +73,9 @@ export default class Manager {
|
|
73
73
|
this.generateGlides([])
|
74
74
|
})
|
75
75
|
.always((res) => {
|
76
|
-
this.glide = new GlideBuilder('.glide', 'carousel');
|
76
|
+
this.glide = new GlideBuilder('.glide', 'carousel', res.length);
|
77
77
|
|
78
|
-
if (res.length <= 1 || res.status === 500) {
|
78
|
+
if (res.length === undefined || res.length <= 1 || res.status === 500) {
|
79
79
|
this.glide.disable()
|
80
80
|
}
|
81
81
|
this.endLoading();
|
@@ -104,7 +104,7 @@ export default class Manager {
|
|
104
104
|
this.$proposalsGlideItems.append(notFoundGlide.render())
|
105
105
|
$(".glide__bullets > .glide__bullet:last").before(notFoundGlide.bullet(0));
|
106
106
|
|
107
|
-
for (let i = 0; i < GlideBuilder.
|
107
|
+
for (let i = 0; i < GlideBuilder.defaultPervView() - 1; i++) {
|
108
108
|
this.$proposalsGlideItems.append(notFoundGlide.placeholder());
|
109
109
|
}
|
110
110
|
}
|
@@ -118,13 +118,5 @@ export default class Manager {
|
|
118
118
|
this.$proposalsGlideItems.append(proposalGlide.render());
|
119
119
|
$(".glide__bullets > .glide__bullet:last").before(proposalGlide.bullet(i));
|
120
120
|
}
|
121
|
-
|
122
|
-
if (proposals.length < GlideBuilder.pervView()) {
|
123
|
-
let missingCount = GlideBuilder.pervView() - proposals.length
|
124
|
-
|
125
|
-
for (let i = 0; i < missingCount; i++) {
|
126
|
-
this.$proposalsGlideItems.append(new GlideItem(null).placeholder());
|
127
|
-
}
|
128
|
-
}
|
129
121
|
}
|
130
122
|
}
|
@@ -1,5 +1,10 @@
|
|
1
1
|
import Manager from "./glidejs/Manager"
|
2
2
|
|
3
|
+
// Build GlideJS carousel in the content block
|
4
|
+
// Tree
|
5
|
+
// ./glideBuilder.js - Build a new instance of GlideJS carousel with options based on current number of proposals found
|
6
|
+
// ./glidejs/Manager.js - Start, Refresh, Stop GlideJS carousel, creates proposals cards items in carousel
|
7
|
+
// ./glidejs/glideitems/* - GlideJS items to render
|
3
8
|
$(() => {
|
4
9
|
const $proposalsSlider = $("#proposals_slider");
|
5
10
|
const $proposalsGlideItems = $("#proposals_glide_items");
|
@@ -9,10 +14,12 @@ $(() => {
|
|
9
14
|
const smallSlider = new Manager($proposalsSlider, $proposalsGlideItems, $(".glide__bullet.glide__bullet_idx"), $smallFilterForm);
|
10
15
|
slider.start()
|
11
16
|
|
17
|
+
// Refresh slider when Desktop filter form changes
|
12
18
|
$filterForm.on("change", () => {
|
13
19
|
slider.start()
|
14
20
|
});
|
15
21
|
|
22
|
+
// Refresh slider when Mobile filter form changes
|
16
23
|
$smallFilterForm.on("change", () => {
|
17
24
|
smallSlider.start()
|
18
25
|
});
|
@@ -1,47 +1,47 @@
|
|
1
|
-
<%= filter_form_for filter, decidim_participatory_processes_path
|
2
|
-
<div class="
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
<
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
%>
|
34
|
-
</label>
|
35
|
-
|
36
|
-
</fieldset>
|
37
|
-
|
1
|
+
<%= filter_form_for filter, decidim_participatory_processes_path, id: 'filters-form' do |form| %>
|
2
|
+
<div class="row">
|
3
|
+
<div class="columns flex-v-center">
|
4
|
+
<p><%= I18n.t("decidim.homepage_proposals.proposal_at_a_glance.filters.intro") %></p>
|
5
|
+
<div>
|
6
|
+
<%= cell(
|
7
|
+
"decidim/scopes_picker",
|
8
|
+
form,
|
9
|
+
attribute: :scope_id,
|
10
|
+
multiple: true,
|
11
|
+
label: false,
|
12
|
+
checkboxes_on_top: false
|
13
|
+
) %>
|
14
|
+
</div>
|
15
|
+
<p><%= I18n.t("decidim.homepage_proposals.proposal_at_a_glance.filters.about") %></p>
|
16
|
+
<div>
|
17
|
+
<%= form.categories_select :category_id,
|
18
|
+
categories_filter,
|
19
|
+
disable_parents: false,
|
20
|
+
label: false,
|
21
|
+
selected: filter.category_id,
|
22
|
+
include_blank: t("decidim.homepage_proposals.proposal_at_a_glance.filters.default_categories") %>
|
23
|
+
</div>
|
24
|
+
<p><%= I18n.t("decidim.homepage_proposals.proposal_at_a_glance.filters.in") %></p>
|
25
|
+
<div>
|
26
|
+
<%= form.select :component_id,
|
27
|
+
options_for_default_component,
|
28
|
+
label: false,
|
29
|
+
selected: filter.component_id,
|
30
|
+
data: { placeholder: t("decidim.homepage_proposals.proposal_at_a_glance.filters.components") }
|
31
|
+
%>
|
32
|
+
</div>
|
38
33
|
</div>
|
39
|
-
|
40
34
|
</div>
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
35
|
+
<div class="row">
|
36
|
+
<div class="columns medium-3">
|
37
|
+
<div class="clear-filters">
|
38
|
+
<%= link_to t("decidim.homepage_proposals.proposal_at_a_glance.filters.clear_filters"), decidim_participatory_processes_path(anchor: "proposals_slider"), class: "button button--secondary small button--sc" %>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
<div class="columns medium-3">
|
42
|
+
<div class="all-proposals flex-justify-end">
|
43
|
+
<%= link_to t("decidim.homepage_proposals.proposal_at_a_glance.filters.all_proposals"), default_linked_component_path, class: "button button--secondary small button--sc" %>
|
44
|
+
</div>
|
45
45
|
</div>
|
46
46
|
</div>
|
47
47
|
<% end %>
|
data/config/i18n-tasks.yml
CHANGED
@@ -2,9 +2,37 @@
|
|
2
2
|
|
3
3
|
base_locale: en
|
4
4
|
locales: [en]
|
5
|
-
|
5
|
+
search:
|
6
|
+
relative_roots:
|
7
|
+
- app/cells
|
8
|
+
- app/controllers
|
9
|
+
- app/helpers
|
10
|
+
- app/mailers
|
11
|
+
- app/presenters
|
12
|
+
- app/views
|
6
13
|
ignore_unused:
|
7
14
|
- "decidim.components.homepage_proposals.name"
|
15
|
+
- decidim.homepage_proposals.content_blocks.proposals_slider.filters_small_view.{close_modal,filter,filter_by,unfold}
|
16
|
+
- decidim.homepage_proposals.content_blocks.proposals_slider.{learn_more,loading,name,search}
|
17
|
+
- decidim.homepage_proposals.content_blocks.proposals_slider_settings_form.activate_filters
|
18
|
+
- decidim.homepage_proposals.content_blocks.proposals_slider_settings_form.default_linked_component
|
19
|
+
- decidim.homepage_proposals.content_blocks.proposals_slider_settings_form.linked_components_id
|
20
|
+
- decidim.homepage_proposals.proposal_at_a_glance.filters.categories
|
21
|
+
- decidim.homepage_proposals.proposal_at_a_glance.filters.default_components
|
22
|
+
- decidim.homepage_proposals.proposal_at_a_glance.filters.default_scope
|
23
|
+
- decidim.homepage_proposals.proposal_at_a_glance.filters.scope
|
24
|
+
- decidim.homepage_proposals.proposal_at_a_glance.learn_more
|
25
|
+
- decidim.homepage_proposals.proposal_at_a_glance.no_proposals.description
|
26
|
+
- decidim.homepage_proposals.proposal_at_a_glance.no_proposals.title
|
8
27
|
|
9
28
|
ignore_missing:
|
10
29
|
- decidim.participatory_processes.scopes.global
|
30
|
+
- decidim.homepage_proposals.content_blocks.proposals_slider.show.loading
|
31
|
+
- decidim.homepage_proposals.content_blocks.proposals_slider_settings_form.show.activate_filters
|
32
|
+
- decidim.homepage_proposals.content_blocks.proposals_slider_settings_form.show.linked_components_id
|
33
|
+
- decidim.homepage_proposals.content_blocks.proposals_slider_settings_form.show.default_linked_component
|
34
|
+
- decidim.shared.homepage_proposals.filters_small_view.filters_small_view.filter
|
35
|
+
- decidim.shared.homepage_proposals.filters_small_view.filters_small_view.unfold
|
36
|
+
- decidim.shared.homepage_proposals.filters_small_view.filters_small_view.filter_by
|
37
|
+
- decidim.shared.homepage_proposals.filters_small_view.filters_small_view.close_modal
|
38
|
+
|
data/config/locales/en.yml
CHANGED
@@ -10,24 +10,28 @@ en:
|
|
10
10
|
filter_by: Filter by
|
11
11
|
unfold: Unfold
|
12
12
|
learn_more: Learn more
|
13
|
-
name: Proposals slider
|
14
13
|
loading: Loading...
|
14
|
+
name: Proposals slider
|
15
15
|
search: Search
|
16
16
|
proposals_slider_settings_form:
|
17
17
|
activate_filters: Activate filters
|
18
18
|
default_linked_component: Component displayed by default
|
19
19
|
linked_components_id: Components available in filters
|
20
20
|
proposal_at_a_glance:
|
21
|
-
title: Explore proposals
|
22
21
|
filters:
|
22
|
+
about: about
|
23
|
+
all_proposals: All proposals
|
23
24
|
categories: Categories
|
24
25
|
clear_filters: Clear filters
|
25
26
|
components: Components
|
26
27
|
default_categories: All categories
|
27
28
|
default_components: All components
|
28
29
|
default_scope: All scopes
|
30
|
+
in: in
|
31
|
+
intro: I'd like to see projects from
|
29
32
|
scope: Scope
|
30
33
|
learn_more: Learn more
|
31
34
|
no_proposals:
|
32
|
-
title: No proposals
|
33
35
|
description: There are no proposals that match the selected filters.
|
36
|
+
title: No proposals
|
37
|
+
title: Explore proposals
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: decidim-homepage_proposals
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Elie Gaboriau
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-07-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: decidim-core
|