decidim-core 0.26.0.rc2 → 0.26.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of decidim-core might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/app/cells/decidim/activity_cell.rb +3 -0
- data/app/cells/decidim/author_cell.rb +1 -0
- data/app/cells/decidim/card_m/show.erb +1 -1
- data/app/cells/decidim/card_m_cell.rb +1 -1
- data/app/cells/decidim/diff/diff_mode_dropdown.erb +13 -8
- data/app/cells/decidim/diff/diff_mode_html.erb +13 -8
- data/app/cells/decidim/diff/show.erb +5 -3
- data/app/cells/decidim/endorsers_list/show.erb +1 -1
- data/app/cells/decidim/fingerprint/show.erb +1 -1
- data/app/cells/decidim/followers/show.erb +1 -1
- data/app/cells/decidim/followers_cell.rb +1 -1
- data/app/cells/decidim/following/show.erb +2 -2
- data/app/cells/decidim/groups/show.erb +1 -1
- data/app/cells/decidim/members/show.erb +1 -1
- data/app/cells/decidim/notification/show.erb +1 -1
- data/app/cells/decidim/notification_cell.rb +6 -0
- data/app/cells/decidim/profile_sidebar/show.erb +1 -1
- data/app/cells/decidim/user_conversation/messages.erb +1 -1
- data/app/cells/decidim/user_conversation_cell.rb +4 -0
- data/app/cells/decidim/user_conversations/add_conversation_users.erb +1 -1
- data/app/cells/decidim/version_cell.rb +1 -1
- data/app/cells/decidim/versions_list_cell.rb +1 -1
- data/app/cells/decidim/versions_list_item/show.erb +2 -2
- data/app/commands/decidim/messaging/reply_to_conversation.rb +4 -1
- data/app/commands/decidim/unendorse_resource.rb +5 -4
- data/app/commands/decidim/update_user_interests.rb +5 -1
- data/app/controllers/concerns/decidim/skip_timeoutable.rb +17 -0
- data/app/controllers/decidim/application_controller.rb +1 -0
- data/app/controllers/decidim/components/base_controller.rb +0 -1
- data/app/controllers/decidim/timeouts_controller.rb +2 -6
- data/app/events/decidim/amendable/amendment_base_event.rb +1 -1
- data/app/forms/decidim/messaging/message_form.rb +1 -1
- data/app/forms/decidim/user_interest_scope_form.rb +1 -1
- data/app/helpers/decidim/application_helper.rb +4 -0
- data/app/helpers/decidim/endorsable_helper.rb +7 -6
- data/app/helpers/decidim/meta_tags_helper.rb +24 -1
- data/app/helpers/decidim/sanitize_helper.rb +8 -2
- data/app/helpers/decidim/twitter_search_helper.rb +14 -0
- data/app/models/decidim/action_log.rb +1 -0
- data/app/models/decidim/moderation.rb +3 -0
- data/app/models/decidim/user.rb +0 -3
- data/app/models/decidim/user_base_entity.rb +1 -0
- data/app/models/decidim/user_group.rb +0 -3
- data/app/packs/entrypoints/decidim_core.js +3 -0
- data/app/packs/src/decidim/back_to_list.js +26 -0
- data/app/packs/src/decidim/dialog_mode.js +11 -99
- data/app/packs/src/decidim/dialog_mode.test.js +17 -4
- data/app/packs/src/decidim/diff_mode_dropdown.js +3 -3
- data/app/packs/src/decidim/dropdowns_menus.js +1 -0
- data/app/packs/src/decidim/external_link.js +6 -0
- data/app/packs/src/decidim/focus_guard.js +142 -0
- data/app/packs/src/decidim/form_filter.js +17 -1
- data/app/packs/src/decidim/form_remote.js +38 -0
- data/app/packs/src/decidim/index.js +15 -0
- data/app/packs/src/decidim/input_character_counter.js +4 -1
- data/app/packs/src/decidim/input_emoji.js +28 -5
- data/app/packs/src/decidim/input_multiple_mentions.js +19 -0
- data/app/packs/src/decidim/map/controller/static.js +6 -5
- data/app/packs/src/decidim/session_timeouter.js +10 -5
- data/app/packs/src/decidim/vendor/social-share-button.js +174 -0
- data/app/packs/stylesheets/decidim/extras/_quill.scss +1 -2
- data/app/packs/stylesheets/decidim/modules/_buttons.scss +2 -1
- data/app/packs/stylesheets/decidim/modules/_comments.scss +1 -0
- data/app/packs/stylesheets/decidim/modules/_forms.scss +6 -1
- data/app/packs/stylesheets/decidim/modules/_typography.scss +2 -0
- data/app/packs/stylesheets/decidim/utils/_settings.scss +1 -0
- data/app/packs/stylesheets/decidim/vendor/_social_share_button.scss +7 -1
- data/app/permissions/decidim/permissions.rb +9 -0
- data/app/presenters/decidim/menu_item_presenter.rb +9 -1
- data/app/validators/password_validator.rb +12 -3
- data/app/views/decidim/account/show.html.erb +1 -1
- data/app/views/decidim/application/_collection.html.erb +2 -2
- data/app/views/decidim/devise/invitations/edit.html.erb +2 -2
- data/app/views/decidim/endorsements/identities.html.erb +1 -1
- data/app/views/decidim/groups/new.html.erb +2 -0
- data/app/views/decidim/messaging/conversations/_add_conversation_users.html.erb +1 -1
- data/app/views/decidim/messaging/conversations/_reply.html.erb +1 -1
- data/app/views/decidim/messaging/conversations/_start.html.erb +1 -1
- data/app/views/decidim/messaging/conversations/create.js.erb +1 -0
- data/app/views/layouts/decidim/_language_chooser.html.erb +9 -2
- data/app/views/layouts/decidim/_logo.html.erb +1 -1
- data/app/views/layouts/decidim/_timeout_modal.html.erb +2 -0
- data/config/initializers/devise.rb +9 -20
- data/config/locales/ar.yml +72 -0
- data/config/locales/ca.yml +21 -2
- data/config/locales/cs.yml +15 -0
- data/config/locales/de.yml +20 -3
- data/config/locales/en.yml +15 -0
- data/config/locales/es-MX.yml +24 -4
- data/config/locales/es-PY.yml +20 -0
- data/config/locales/es.yml +20 -0
- data/config/locales/fi-plain.yml +20 -0
- data/config/locales/fi.yml +21 -1
- data/config/locales/fr-CA.yml +19 -0
- data/config/locales/fr.yml +42 -27
- data/config/locales/gl.yml +51 -0
- data/config/locales/hu.yml +112 -0
- data/config/locales/it.yml +9 -0
- data/config/locales/ja.yml +25 -6
- data/config/locales/no.yml +225 -0
- data/config/locales/pt.yml +2 -2
- data/config/locales/ro-RO.yml +5 -0
- data/config/locales/sv.yml +38 -1
- data/db/seeds.rb +2 -2
- data/lib/decidim/content_parsers/hashtag_parser.rb +1 -1
- data/lib/decidim/content_parsers/resource_parser.rb +97 -0
- data/lib/decidim/content_parsers.rb +1 -0
- data/lib/decidim/content_processor.rb +2 -1
- data/lib/decidim/content_renderers/link_renderer.rb +1 -1
- data/lib/decidim/content_renderers/resource_renderer.rb +30 -0
- data/lib/decidim/content_renderers.rb +1 -0
- data/lib/decidim/core/engine.rb +43 -0
- data/lib/decidim/core/test/factories.rb +2 -1
- data/lib/decidim/core/test/shared_examples/amendable/amendment_accepted_event_examples.rb +0 -1
- data/lib/decidim/core/test/shared_examples/amendable/amendment_created_event_examples.rb +0 -1
- data/lib/decidim/core/test/shared_examples/amendable/amendment_promoted_event_examples.rb +0 -1
- data/lib/decidim/core/test/shared_examples/amendable/amendment_rejected_event_examples.rb +0 -1
- data/lib/decidim/core/test/shared_examples/comments_examples.rb +27 -0
- data/lib/decidim/core/test/shared_examples/conversations_examples.rb +19 -0
- data/lib/decidim/core/test/shared_examples/endorsable.rb +69 -0
- data/lib/decidim/core/test/shared_examples/searchable_results_examples.rb +34 -0
- data/lib/decidim/core/test.rb +2 -0
- data/lib/decidim/core/version.rb +1 -1
- data/lib/decidim/endorsable.rb +5 -1
- data/lib/decidim/map/autocomplete.rb +12 -5
- data/lib/decidim/middleware/rails_cookies.rb +23 -0
- data/lib/decidim/resourceable.rb +1 -0
- data/lib/decidim/searchable.rb +10 -4
- data/lib/decidim/view_model.rb +0 -1
- data/lib/devise/models/decidim_validatable.rb +3 -3
- data/lib/tasks/upgrade/decidim_moderation_tasks.rake +32 -0
- metadata +22 -12
- data/app/helpers/decidim/filter_params_helper.rb +0 -30
- data/config/initializers/mail_previews.rb +0 -5
@@ -1,5 +1,4 @@
|
|
1
1
|
import moment from "moment"
|
2
|
-
import Foundation from "foundation-sites"
|
3
2
|
|
4
3
|
$(() => {
|
5
4
|
let sessionTimeOutEnabled = true;
|
@@ -8,17 +7,18 @@ $(() => {
|
|
8
7
|
const secondsUntilTimeoutPath = $timeoutModal.data("seconds-until-timeout-path");
|
9
8
|
const heartbeatPath = $timeoutModal.data("heartbeat-path");
|
10
9
|
const interval = parseInt($timeoutModal.data("session-timeout-interval"), 10);
|
10
|
+
const preventTimeOutSeconds = $timeoutModal.data("prevent-timeout-seconds");
|
11
11
|
let endsAt = moment().add(timeoutInSeconds, "seconds");
|
12
12
|
let lastAction = moment();
|
13
|
-
const popup = new Foundation.Reveal($timeoutModal);
|
14
13
|
const $continueSessionButton = $("#continueSession");
|
15
14
|
let lastActivityCheck = moment();
|
16
15
|
// 5 * 60 seconds = 5 Minutes
|
17
16
|
const activityCheckInterval = 5 * 60;
|
17
|
+
const preventTimeOutUntil = moment().add(preventTimeOutSeconds, "seconds");
|
18
18
|
|
19
19
|
// Ajax request is made at timeout_modal.html.erb
|
20
20
|
$continueSessionButton.on("click", () => {
|
21
|
-
$
|
21
|
+
$timeoutModal.foundation("close");
|
22
22
|
// In admin panel we have to hide all overlays
|
23
23
|
$(".reveal-overlay").css("display", "none");
|
24
24
|
lastActivityCheck = moment();
|
@@ -82,7 +82,12 @@ $(() => {
|
|
82
82
|
}
|
83
83
|
|
84
84
|
const timeRemaining = Math.round((endsAt - moment()) / 1000);
|
85
|
-
if (timeRemaining >
|
85
|
+
if (timeRemaining > 170) {
|
86
|
+
return;
|
87
|
+
}
|
88
|
+
|
89
|
+
if (moment() < preventTimeOutUntil) {
|
90
|
+
heartbeat();
|
86
91
|
return;
|
87
92
|
}
|
88
93
|
|
@@ -95,7 +100,7 @@ $(() => {
|
|
95
100
|
} else if (secondsUntilSessionExpires <= 90) {
|
96
101
|
$timeoutModal.find("#reveal-hidden-sign-out")[0].click();
|
97
102
|
} else if (secondsUntilSessionExpires <= 150) {
|
98
|
-
|
103
|
+
$timeoutModal.foundation("open");
|
99
104
|
}
|
100
105
|
});
|
101
106
|
}, interval);
|
@@ -0,0 +1,174 @@
|
|
1
|
+
/* eslint-disable complexity, default-case, no-param-reassign, consistent-return */
|
2
|
+
|
3
|
+
/*
|
4
|
+
*
|
5
|
+
* Social Share Button
|
6
|
+
*
|
7
|
+
* Copyright (c) <2012> <Jason Lee> - The MIT license
|
8
|
+
* Originally copied fom https://github.com/huacnlee/social-share-button
|
9
|
+
* Transformed from Coffescript to Javascipt with decaffeintate
|
10
|
+
*
|
11
|
+
* We've copied itlocally so it works with webpacker
|
12
|
+
*
|
13
|
+
* decaffeinate suggestions:
|
14
|
+
* DS102: Remove unnecessary code created because of implicit returns
|
15
|
+
* DS205: Consider reworking code to avoid use of IIFEs
|
16
|
+
* DS207: Consider shorter variations of null checks
|
17
|
+
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
18
|
+
*/
|
19
|
+
window.SocialShareButton = {
|
20
|
+
openUrl(url, width, height) {
|
21
|
+
if (width === null) {
|
22
|
+
width = 640;
|
23
|
+
}
|
24
|
+
if (height === null) {
|
25
|
+
height = 480;
|
26
|
+
}
|
27
|
+
const left = (screen.width / 2) - (width / 2);
|
28
|
+
const top = (screen.height * 0.3) - (height / 2);
|
29
|
+
const opt = `width=${width},height=${height},left=${left},top=${top},menubar=no,status=no,location=no`;
|
30
|
+
window.open(url, "popup", opt);
|
31
|
+
return false;
|
32
|
+
},
|
33
|
+
|
34
|
+
share(el) {
|
35
|
+
if (el.getAttribute === null) {
|
36
|
+
el = document.querySelector(el);
|
37
|
+
}
|
38
|
+
|
39
|
+
const site = el.getAttribute("data-site");
|
40
|
+
const appkey = el.getAttribute("data-appkey") || "";
|
41
|
+
const $parent = el.parentNode;
|
42
|
+
let title = encodeURIComponent(el.getAttribute(`data-${site}-title`) || $parent.getAttribute("data-title") || "");
|
43
|
+
const img = encodeURIComponent($parent.getAttribute("data-img") || "");
|
44
|
+
let url = encodeURIComponent($parent.getAttribute("data-url") || "");
|
45
|
+
const via = encodeURIComponent($parent.getAttribute("data-via") || "");
|
46
|
+
const desc = encodeURIComponent($parent.getAttribute("data-desc") || " ");
|
47
|
+
|
48
|
+
// tracking click events if google analytics enabled
|
49
|
+
const ga = window[window.GoogleAnalyticsObject || "ga"];
|
50
|
+
if (typeof ga === "function") {
|
51
|
+
ga("send", "event", "Social Share Button", "click", site);
|
52
|
+
}
|
53
|
+
|
54
|
+
if (url.length === 0) {
|
55
|
+
url = encodeURIComponent(location.href);
|
56
|
+
}
|
57
|
+
switch (site) {
|
58
|
+
case "email":
|
59
|
+
location.href = `mailto:?subject=${title}&body=${url}`;
|
60
|
+
break;
|
61
|
+
case "weibo":
|
62
|
+
this.openUrl(`http://service.weibo.com/share/share.php?url=${url}&type=3&pic=${img}&title=${title}&appkey=${appkey}`, 620, 370);
|
63
|
+
break;
|
64
|
+
case "twitter": {
|
65
|
+
let hashtags = encodeURIComponent(el.getAttribute(`data-${site}-hashtags`) || $parent.getAttribute("data-hashtags") || "");
|
66
|
+
let viaStr = "";
|
67
|
+
if (via.length > 0) {
|
68
|
+
viaStr = `&via=${via}`;
|
69
|
+
}
|
70
|
+
this.openUrl(`https://twitter.com/intent/tweet?url=${url}&text=${title}&hashtags=${hashtags}${viaStr}`, 650, 300);
|
71
|
+
break;
|
72
|
+
}
|
73
|
+
case "douban":
|
74
|
+
this.openUrl(`http://shuo.douban.com/!service/share?href=${url}&name=${title}&image=${img}&sel=${desc}`, 770, 470);
|
75
|
+
break;
|
76
|
+
case "facebook":
|
77
|
+
this.openUrl(`http://www.facebook.com/sharer/sharer.php?u=${url}`, 555, 400);
|
78
|
+
break;
|
79
|
+
case "qq":
|
80
|
+
this.openUrl(`http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=${url}&title=${title}&pics=${img}&summary=${desc}&site=${appkey}`);
|
81
|
+
break;
|
82
|
+
case "google_bookmark":
|
83
|
+
this.openUrl(`https://www.google.com/bookmarks/mark?op=edit&output=popup&bkmk=${url}&title=${title}`);
|
84
|
+
break;
|
85
|
+
case "delicious":
|
86
|
+
this.openUrl(`https://del.icio.us/save?url=${url}&title=${title}&jump=yes&pic=${img}`);
|
87
|
+
break;
|
88
|
+
case "pinterest":
|
89
|
+
this.openUrl(`http://www.pinterest.com/pin/create/button/?url=${url}&media=${img}&description=${title}`);
|
90
|
+
break;
|
91
|
+
case "linkedin":
|
92
|
+
this.openUrl(`https://www.linkedin.com/shareArticle?mini=true&url=${url}&title=${title}&summary=${desc}`);
|
93
|
+
break;
|
94
|
+
case "xing":
|
95
|
+
this.openUrl(`https://www.xing.com/spi/shares/new?url=${url}`);
|
96
|
+
break;
|
97
|
+
case "vkontakte":
|
98
|
+
this.openUrl(`http://vk.com/share.php?url=${url}&title=${title}&image=${img}`);
|
99
|
+
break;
|
100
|
+
case "odnoklassniki":
|
101
|
+
this.openUrl(`https://connect.ok.ru/offer?url=${url}&title=${title}&description=${desc}&imageUrl=${img}`);
|
102
|
+
break;
|
103
|
+
case "wechat":
|
104
|
+
if (!window.SocialShareWeChatButton) {
|
105
|
+
throw new Error("You should require social-share-button/wechat to your application.js");
|
106
|
+
}
|
107
|
+
window.SocialShareWeChatButton.qrcode({
|
108
|
+
url: decodeURIComponent(url),
|
109
|
+
header: el.getAttribute("title"),
|
110
|
+
footer: el.getAttribute("data-wechat-footer")
|
111
|
+
});
|
112
|
+
break;
|
113
|
+
|
114
|
+
case "tumblr": {
|
115
|
+
let getTumblrExtra = (param) => {
|
116
|
+
const cutomData = el.getAttribute(`data-${param}`);
|
117
|
+
if (cutomData) {
|
118
|
+
return encodeURIComponent(cutomData);
|
119
|
+
}
|
120
|
+
};
|
121
|
+
|
122
|
+
let tumblrParams = () => {
|
123
|
+
const path = getTumblrExtra("type") || "link";
|
124
|
+
|
125
|
+
const params = (() => {
|
126
|
+
switch (path) {
|
127
|
+
case "text": {
|
128
|
+
title = getTumblrExtra("title") || title;
|
129
|
+
return `title=${title}`;
|
130
|
+
}
|
131
|
+
case "photo": {
|
132
|
+
title = getTumblrExtra("caption") || title;
|
133
|
+
let source = getTumblrExtra("source") || img;
|
134
|
+
return `caption=${title}&source=${source}`;
|
135
|
+
}
|
136
|
+
case "quote": {
|
137
|
+
let quote = getTumblrExtra("quote") || title;
|
138
|
+
let source = getTumblrExtra("source") || "";
|
139
|
+
return `quote=${quote}&source=${source}`;
|
140
|
+
}
|
141
|
+
// actually, it's a link clause
|
142
|
+
default: {
|
143
|
+
title = getTumblrExtra("title") || title;
|
144
|
+
url = getTumblrExtra("url") || url;
|
145
|
+
return `name=${title}&url=${url}`;
|
146
|
+
}} })();
|
147
|
+
|
148
|
+
return `/${path}?${params}`;
|
149
|
+
};
|
150
|
+
|
151
|
+
this.openUrl(`http://www.tumblr.com/share${tumblrParams()}`);
|
152
|
+
break;
|
153
|
+
}
|
154
|
+
case "reddit":
|
155
|
+
this.openUrl(`http://www.reddit.com/submit?url=${url}&newwindow=1`, 555, 400);
|
156
|
+
break;
|
157
|
+
case "hacker_news":
|
158
|
+
this.openUrl(`http://news.ycombinator.com/submitlink?u=${url}&t=${title}`, 770, 500);
|
159
|
+
break;
|
160
|
+
case "telegram":
|
161
|
+
this.openUrl(`https://telegram.me/share/url?text=${title}&url=${url}`);
|
162
|
+
break;
|
163
|
+
case "whatsapp_app": {
|
164
|
+
let whatsappAppUrl = `whatsapp://send?text=${title}%0A${url}`;
|
165
|
+
window.open(whatsappAppUrl, "_top");
|
166
|
+
break;
|
167
|
+
}
|
168
|
+
case "whatsapp_web":
|
169
|
+
this.openUrl(`https://web.whatsapp.com/send?text=${title}%0A${url}`);
|
170
|
+
break;
|
171
|
+
}
|
172
|
+
return false;
|
173
|
+
}
|
174
|
+
};
|
@@ -372,7 +372,7 @@
|
|
372
372
|
.link{
|
373
373
|
cursor: pointer;
|
374
374
|
color: var(--secondary);
|
375
|
-
font-weight:
|
375
|
+
font-weight: $anchor-font-weight;
|
376
376
|
|
377
377
|
&:hover{
|
378
378
|
color: $anchor-color-hover;
|
@@ -384,6 +384,7 @@
|
|
384
384
|
.link-alt{
|
385
385
|
cursor: pointer;
|
386
386
|
color: $anchor-color;
|
387
|
+
font-weight: $anchor-font-weight;
|
387
388
|
|
388
389
|
&:hover{
|
389
390
|
color: $anchor-color-hover;
|
@@ -135,13 +135,18 @@ input[type="radio"]{
|
|
135
135
|
}
|
136
136
|
|
137
137
|
&__trigger{
|
138
|
+
position: relative;
|
139
|
+
top: -$form-spacing;
|
140
|
+
}
|
141
|
+
|
142
|
+
&__button{
|
138
143
|
position: absolute;
|
139
144
|
bottom: $global-margin * .5;
|
140
145
|
right: $global-margin;
|
141
146
|
cursor: pointer;
|
142
147
|
}
|
143
148
|
|
144
|
-
&
|
149
|
+
&__button svg{
|
145
150
|
width: 1em;
|
146
151
|
}
|
147
152
|
}
|
@@ -206,6 +206,7 @@ $anchor-outline-focus: 1px dotted rgba(black, .5);
|
|
206
206
|
$anchor-outline-offset: 2px;
|
207
207
|
$anchor-text-decoration: none;
|
208
208
|
$anchor-text-decoration-hover: none;
|
209
|
+
$anchor-font-weight: $global-weight-normal;
|
209
210
|
$hr-width: $global-width;
|
210
211
|
$hr-border: 1px solid $medium-gray;
|
211
212
|
$hr-margin: 6rem auto 5rem;
|
@@ -1,4 +1,10 @@
|
|
1
|
-
//
|
1
|
+
//
|
2
|
+
// Social Share Button
|
3
|
+
//
|
4
|
+
// Copyright (c) <2012> <Jason Lee> - The MIT license
|
5
|
+
// Originally copied fom https://github.com/huacnlee/social-share-button
|
6
|
+
// Adapted to Decidim assets pipeline
|
7
|
+
//
|
2
8
|
|
3
9
|
.social-share-button .ssb-icon{
|
4
10
|
background-position: center center;
|
@@ -10,6 +10,8 @@ module Decidim
|
|
10
10
|
component_public_action?
|
11
11
|
search_scope_action?
|
12
12
|
|
13
|
+
public_report_content_action?
|
14
|
+
|
13
15
|
return permission_action unless user
|
14
16
|
|
15
17
|
user_manager_permissions
|
@@ -28,6 +30,13 @@ module Decidim
|
|
28
30
|
|
29
31
|
private
|
30
32
|
|
33
|
+
def public_report_content_action?
|
34
|
+
return unless permission_action.action == :create &&
|
35
|
+
permission_action.subject == :moderation
|
36
|
+
|
37
|
+
allow!
|
38
|
+
end
|
39
|
+
|
31
40
|
def read_public_pages_action?
|
32
41
|
return unless permission_action.subject == :public_page &&
|
33
42
|
permission_action.action == :read
|
@@ -27,7 +27,7 @@ module Decidim
|
|
27
27
|
|
28
28
|
def render
|
29
29
|
content_tag :li, class: link_wrapper_classes do
|
30
|
-
output = [link_to(composed_label, url)]
|
30
|
+
output = [link_to(composed_label, url, link_options)]
|
31
31
|
output.push(@view.send(:simple_menu, @menu_item.submenu).render) if @menu_item.submenu
|
32
32
|
|
33
33
|
safe_join(output)
|
@@ -36,6 +36,14 @@ module Decidim
|
|
36
36
|
|
37
37
|
private
|
38
38
|
|
39
|
+
def link_options
|
40
|
+
if is_active_link?(url, active)
|
41
|
+
{ aria: { current: "page" } }
|
42
|
+
else
|
43
|
+
{}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
39
47
|
def composed_label
|
40
48
|
icon_name.present? ? icon(icon_name) + label : label
|
41
49
|
end
|
@@ -49,6 +49,15 @@ class PasswordValidator < ActiveModel::EachValidator
|
|
49
49
|
I18n.t "password_validator.#{reason}"
|
50
50
|
end
|
51
51
|
|
52
|
+
def organization
|
53
|
+
@organization ||= organization_from_record
|
54
|
+
end
|
55
|
+
|
56
|
+
def organization_from_record
|
57
|
+
return record.current_organization if record.respond_to?(:current_organization)
|
58
|
+
return record.organization if record.respond_to?(:organization)
|
59
|
+
end
|
60
|
+
|
52
61
|
def strong?
|
53
62
|
VALIDATION_METHODS.each do |method|
|
54
63
|
@weak_password_reasons << method.to_s.sub(/\?$/, "").to_sym if send(method.to_s)
|
@@ -96,10 +105,10 @@ class PasswordValidator < ActiveModel::EachValidator
|
|
96
105
|
end
|
97
106
|
|
98
107
|
def domain_included_in_password?
|
99
|
-
return false unless
|
100
|
-
return true if value.include?(
|
108
|
+
return false unless organization && organization.host
|
109
|
+
return true if value.include?(organization.host)
|
101
110
|
|
102
|
-
|
111
|
+
organization.host.split(".").each do |part|
|
103
112
|
next if part.length < IGNORE_SIMILARITY_SHORTER_THAN
|
104
113
|
|
105
114
|
return true if value.include?(part)
|
@@ -30,7 +30,7 @@
|
|
30
30
|
<% else %>
|
31
31
|
<% if current_organization.sign_in_enabled? %>
|
32
32
|
<p>
|
33
|
-
<
|
33
|
+
<button type="button" data-toggle="passwordChange" class="link change-password"><%= t ".change_password" %></button>
|
34
34
|
</p>
|
35
35
|
<div id="passwordChange" class="toggle-show" data-toggler=".is-expanded">
|
36
36
|
<%= render partial: "password_fields", locals: { form: f } %>
|
@@ -1,11 +1,11 @@
|
|
1
1
|
<% unless attachment_collection.unused? %>
|
2
2
|
<div class="docs__container">
|
3
|
-
<
|
3
|
+
<button type="button" data-toggle="docs-collection-<%= attachment_collection.id %>"><%= icon "caret-right", class: "icon--small", role: "img", "aria-hidden": true %>
|
4
4
|
<strong><%= translated_attribute(attachment_collection.name) %></strong>
|
5
5
|
|
6
6
|
<% attachment_collection_documents_count = attachment_collection.attachments.select(&:document?).count %>
|
7
7
|
<small>(<%= attachment_collection_documents_count %> <%= t("decidim.application.collection.documents", count: attachment_collection_documents_count) %>)</small>
|
8
|
-
</
|
8
|
+
</button>
|
9
9
|
|
10
10
|
<div id="docs-collection-<%= attachment_collection.id %>" class="docs__content hide" data-toggler=".hide">
|
11
11
|
<p><%= translated_attribute(attachment_collection.description) %></p>
|
@@ -27,11 +27,11 @@
|
|
27
27
|
|
28
28
|
<% if f.object.class.require_password_on_accepting %>
|
29
29
|
<div class="field">
|
30
|
-
<p><%= f.password_field :password, required: "required", minlength: ::
|
30
|
+
<p><%= f.password_field :password, required: "required", minlength: ::PasswordValidator::MINIMUM_LENGTH, maxlength: ::PasswordValidator::MAX_LENGTH %></p>
|
31
31
|
</div>
|
32
32
|
|
33
33
|
<div class="field">
|
34
|
-
<p><%= f.password_field :password_confirmation, required: "required", minlength: ::
|
34
|
+
<p><%= f.password_field :password_confirmation, required: "required", minlength: ::PasswordValidator::MINIMUM_LENGTH, maxlength: ::PasswordValidator::MAX_LENGTH %></p>
|
35
35
|
</div>
|
36
36
|
<% end %>
|
37
37
|
</div>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div class="reveal__header reveal__header--nomargin reveal__bg p-s">
|
2
|
-
<h6 class="heading6 m-none"><%= t ".select_identity" %></h6>
|
2
|
+
<h6 class="heading6 m-none reveal__title"><%= t ".select_identity" %></h6>
|
3
3
|
</div>
|
4
4
|
<ul class="reveal__list">
|
5
5
|
<%= render_endorsement_identity(resource, current_user) %>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
<%= t(".title") %>
|
4
4
|
</h2>
|
5
5
|
|
6
|
-
<%=
|
6
|
+
<%= decidim_form_for form, url: decidim.conversation_path(conversation.id), method: :put, remote: true do |f| %>
|
7
7
|
<%= f.label :body, nil, class: "show-for-sr" %>
|
8
8
|
<%= f.text_area :body, label: false, rows: 4, required: true, placeholder: t(".placeholder") %>
|
9
9
|
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<%= t(".title") %>
|
6
6
|
</h2>
|
7
7
|
|
8
|
-
<%=
|
8
|
+
<%= decidim_form_for form, url: decidim.conversations_path, remote: true do |f| %>
|
9
9
|
<%= form_required_explanation %>
|
10
10
|
|
11
11
|
<% @form.recipient.each do |recipient| %>
|
@@ -1,2 +1,3 @@
|
|
1
1
|
$("#messages").append("<%= j(render "messages", sender: conversation.messages.first.sender, messages: [conversation.messages.first]).html_safe %>");
|
2
2
|
$(".add-message").replaceWith("<%= j(render "reply", form: form, conversation: conversation).html_safe %>");
|
3
|
+
$("#new_message_").foundation();
|
@@ -7,10 +7,17 @@
|
|
7
7
|
data-close-on-click="true"
|
8
8
|
role="menubar">
|
9
9
|
<li class="is-dropdown-submenu-parent" role="presentation">
|
10
|
-
<%= link_to
|
10
|
+
<%= link_to "#language-chooser-menu", id: "language-chooser-control", "aria-controls": "language-chooser-menu", "aria-haspopup": "menu", role: "menuitem" do %>
|
11
|
+
<span aria-hidden="true"><%= t("name", scope: "locale") %></span>
|
12
|
+
<span class="show-for-sr">
|
13
|
+
<% available_locales.each do |locale| %>
|
14
|
+
<span lang="<%= locale %>"><%= I18n.with_locale(locale) { t("layouts.decidim.language_chooser.choose_language") } %></span>
|
15
|
+
<% end %>
|
16
|
+
</span>
|
17
|
+
<% end %>
|
11
18
|
<ul class="menu is-dropdown-submenu" id="language-chooser-menu" role="menu" aria-labelledby="language-chooser-control">
|
12
19
|
<% (available_locales - [I18n.locale.to_s]).each do |locale| %>
|
13
|
-
<li
|
20
|
+
<li role="presentation"><%= link_to locale_name(locale), decidim.locale_path(locale: locale), method: :post, role: "menuitem", lang: locale %></li>
|
14
21
|
<% end %>
|
15
22
|
</ul>
|
16
23
|
</li>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<% if organization %>
|
2
|
-
<%= link_to decidim.root_url(host: organization.host),
|
2
|
+
<%= link_to decidim.root_url(host: organization.host), "aria-label": t("front_page_link", scope: "decidim.accessibility") do %>
|
3
3
|
<% if organization.logo.attached? %>
|
4
4
|
<%= image_tag organization.attached_uploader(:logo).variant_path(:medium), alt: t("logo", scope: "decidim.accessibility", organization: organization.name) %>
|
5
5
|
<% else %>
|
@@ -1,9 +1,11 @@
|
|
1
1
|
<% if current_user && !current_user.remember_created_at %>
|
2
2
|
<% timeout_time_seconds = Decidim.config.expire_session_after.to_i %>
|
3
|
+
<% prevent_timeout_for = try(:prevent_timeout_seconds) || 0 %>
|
3
4
|
<div class="reveal" id="timeoutModal" data-close-on-click="false" data-close-on-esc="false"
|
4
5
|
data-seconds-until-timeout-path="<%= decidim.seconds_until_timeout_path %>"
|
5
6
|
data-heartbeat-path="<%= decidim.heartbeat_path %>"
|
6
7
|
data-session-timeout="<%= timeout_time_seconds %>"
|
8
|
+
data-prevent-timeout-seconds="<%= prevent_timeout_for %>"
|
7
9
|
data-session-timeout-interval="<%= Decidim.config.session_timeout_interval.to_i * 1000 %>" data-reveal>
|
8
10
|
<h2><%= t(".title") %></h2>
|
9
11
|
<p><%= t(".body", minutes: (timeout_time_seconds / 60) - 2) %></p>
|
@@ -9,6 +9,13 @@ class RandomStalling < Devise::FailureApp
|
|
9
9
|
sleep rand * 5
|
10
10
|
super
|
11
11
|
end
|
12
|
+
|
13
|
+
protected
|
14
|
+
|
15
|
+
def i18n_options(options)
|
16
|
+
options[:locale] = session[:user_locale]
|
17
|
+
super
|
18
|
+
end
|
12
19
|
end
|
13
20
|
|
14
21
|
Devise.setup do |config|
|
@@ -19,12 +26,6 @@ Devise.setup do |config|
|
|
19
26
|
# by default. You can change it below and use your own secret key.
|
20
27
|
# config.secret_key = 'e1f4e9899fb5e8b3123950b19cd0f6d22ecaa8c7fb792b6db5a939edc2b3bab722d06a6a46345ee9bf12caa0178408d6134ea92ed778977b8a7ed1007a0c6dbe'
|
21
28
|
|
22
|
-
# ==> Mailer Configuration
|
23
|
-
# Configure the e-mail address which will be shown in Devise::Mailer,
|
24
|
-
# note that it will be overwritten if you use your own mailer class
|
25
|
-
# with default "from" parameter.
|
26
|
-
config.mailer_sender = Decidim.config.mailer_sender
|
27
|
-
|
28
29
|
# Configure the class responsible to send e-mails.
|
29
30
|
config.mailer = "Decidim::DecidimDeviseMailer"
|
30
31
|
|
@@ -174,14 +175,6 @@ Devise.setup do |config|
|
|
174
175
|
# Default: true
|
175
176
|
config.allow_insecure_sign_in_after_accept = true
|
176
177
|
|
177
|
-
# ==> Configuration for :confirmable
|
178
|
-
# A period that the user is allowed to access the website even without
|
179
|
-
# confirming their account. For instance, if set to 2.days, the user will be
|
180
|
-
# able to access the website for two days without confirming their account,
|
181
|
-
# access will be blocked just in the third day. Default is 0.days, meaning
|
182
|
-
# the user cannot access the website without confirming their account.
|
183
|
-
config.allow_unconfirmed_access_for = Decidim.unconfirmed_access_for
|
184
|
-
|
185
178
|
# A period that the user is allowed to confirm their account before their
|
186
179
|
# token becomes invalid. For example, if set to 3.days, the user can confirm
|
187
180
|
# their account within 3 days after the mail was sent, but on the fourth day
|
@@ -215,18 +208,14 @@ Devise.setup do |config|
|
|
215
208
|
|
216
209
|
# ==> Configuration for :validatable
|
217
210
|
# Range for password length.
|
218
|
-
|
211
|
+
# NOTE: this will not be used as we're using our own PasswordValidator
|
212
|
+
# config.password_length = 6..128
|
219
213
|
|
220
214
|
# Email regex used to validate email formats. It simply asserts that
|
221
215
|
# one (and only one) @ exists in the given string. This is mainly
|
222
216
|
# to give user feedback and not to assert the e-mail validity.
|
223
217
|
config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
|
224
218
|
|
225
|
-
# ==> Configuration for :timeoutable
|
226
|
-
# The time you want to timeout the user session without activity. After this
|
227
|
-
# time the user will be asked for credentials again. Default is 30 minutes.
|
228
|
-
config.timeout_in = Decidim.config.expire_session_after
|
229
|
-
|
230
219
|
# ==> Configuration for :lockable
|
231
220
|
# Defines which strategy will be used to lock an account.
|
232
221
|
# :failed_attempts = Locks an account after a number of failed attempts to sign in.
|