BIN
app/assets/images/icon_home_debates.png
Normal file
BIN
app/assets/images/icon_home_debates.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
app/assets/images/icon_home_decides.png
Normal file
BIN
app/assets/images/icon_home_decides.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.3 KiB |
BIN
app/assets/images/icon_home_propones.png
Normal file
BIN
app/assets/images/icon_home_propones.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
BIN
app/assets/images/icon_home_sehace.png
Normal file
BIN
app/assets/images/icon_home_sehace.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 7.7 KiB |
8
app/assets/javascripts/moderator_proposals.js.coffee
Normal file
8
app/assets/javascripts/moderator_proposals.js.coffee
Normal file
@@ -0,0 +1,8 @@
|
||||
App.ModeratorProposals =
|
||||
|
||||
add_class_faded: (id) ->
|
||||
$("##{id}").addClass("faded")
|
||||
$("#comments").addClass("faded")
|
||||
|
||||
hide_moderator_actions: (id) ->
|
||||
$("##{id} .js-moderator-proposals-actions:first").hide()
|
||||
@@ -1,26 +1,32 @@
|
||||
App.PreventDoubleSubmission =
|
||||
disable_button: (button) ->
|
||||
unless button.hasClass('disabled')
|
||||
loading = button.data('loading') ? '...'
|
||||
button.addClass('disabled').attr('disabled', 'disabled')
|
||||
button.data('text', button.val())
|
||||
button.val(loading)
|
||||
disable_buttons: (buttons) ->
|
||||
setTimeout ->
|
||||
buttons.each ->
|
||||
button = $(this)
|
||||
unless button.hasClass('disabled')
|
||||
loading = button.data('loading') ? '...'
|
||||
button.addClass('disabled').attr('disabled', 'disabled')
|
||||
button.data('text', button.val())
|
||||
button.val(loading)
|
||||
, 1
|
||||
|
||||
reset_button: (button) ->
|
||||
if button.hasClass('disabled')
|
||||
button_text = button.data('text')
|
||||
button.removeClass('disabled').attr('disabled', null)
|
||||
if button_text
|
||||
button.val(button_text)
|
||||
button.data('text', null)
|
||||
reset_buttons: (buttons) ->
|
||||
buttons.each ->
|
||||
button = $(this)
|
||||
if button.hasClass('disabled')
|
||||
button_text = button.data('text')
|
||||
button.removeClass('disabled').attr('disabled', null)
|
||||
if button_text
|
||||
button.val(button_text)
|
||||
button.data('text', null)
|
||||
|
||||
initialize: ->
|
||||
$('form').on('submit', event, ->
|
||||
button = $(this).find(':button, :submit')
|
||||
App.PreventDoubleSubmission.disable_button(button)
|
||||
buttons = $(this).find(':button, :submit')
|
||||
App.PreventDoubleSubmission.disable_buttons(buttons)
|
||||
).on('ajax:success', ->
|
||||
button = $(this).find(':button, :submit')
|
||||
App.PreventDoubleSubmission.reset_button(button)
|
||||
buttons = $(this).find(':button, :submit')
|
||||
App.PreventDoubleSubmission.reset_buttons(buttons)
|
||||
)
|
||||
|
||||
false
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
App.Tags =
|
||||
|
||||
initialize: ->
|
||||
$tag_input = $('input#debate_tag_list')
|
||||
$tag_input = $('input.js-tag-list')
|
||||
|
||||
$('body .js-add-tag-link').each ->
|
||||
$this = $(this)
|
||||
|
||||
@@ -12,8 +12,5 @@ App.Votes =
|
||||
|
||||
initialize: ->
|
||||
App.Votes.hoverize votes for votes in $("div.votes")
|
||||
App.Votes.hoverize votes for votes in $("div.supports")
|
||||
false
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -10,4 +10,5 @@
|
||||
@import "admin";
|
||||
@import "participacion";
|
||||
@import "debates";
|
||||
@import "proposals";
|
||||
@import "c3";
|
||||
|
||||
@@ -352,7 +352,7 @@
|
||||
@media (min-width: $small-breakpoint) {
|
||||
border-top-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
margin: 0 rem-calc(-24) 0 rem-calc(12);
|
||||
margin: 0 rem-calc(-25) 0 rem-calc(12);
|
||||
}
|
||||
|
||||
&:after {
|
||||
@@ -487,13 +487,16 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h3 {
|
||||
border-top: 2px solid $brand;
|
||||
display: inline-block;
|
||||
font-size: rem-calc(16);
|
||||
margin: -1px 0 rem-calc(12);
|
||||
padding-top: rem-calc(6);
|
||||
text-transform: uppercase;
|
||||
aside {
|
||||
|
||||
h3 {
|
||||
border-top: 2px solid $brand;
|
||||
display: inline-block;
|
||||
font-size: rem-calc(16);
|
||||
margin: -1px 0 rem-calc(12);
|
||||
padding-top: rem-calc(6);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
.votes {
|
||||
@@ -636,7 +639,7 @@
|
||||
.comment-votes {
|
||||
color: $text-medium;
|
||||
font-weight: lighter;
|
||||
margin: rem-calc(15) rem-calc(6) 0;
|
||||
margin: rem-calc(8) rem-calc(12) rem-calc(6) 0;
|
||||
|
||||
a {
|
||||
color: $text-light;
|
||||
@@ -650,7 +653,7 @@
|
||||
|
||||
[class^="icon-"] {
|
||||
font-size: rem-calc(20);
|
||||
vertical-align: top;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -676,6 +679,7 @@
|
||||
.comment-user {
|
||||
margin-top: rem-calc(6);
|
||||
padding: rem-calc(6) 0;
|
||||
overflow: hidden;
|
||||
|
||||
@each $n in ("1", "2", "3","4", "5") {
|
||||
&.level-#{$n} {
|
||||
@@ -757,6 +761,7 @@
|
||||
|
||||
.button {
|
||||
background: none;
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
.icon-stats:before {
|
||||
content: "r";
|
||||
}
|
||||
.icon-initiatives:before {
|
||||
.icon-proposals:before {
|
||||
content: "h";
|
||||
}
|
||||
.icon-organizations:before {
|
||||
|
||||
@@ -329,7 +329,7 @@ header {
|
||||
@media (min-width: $small-breakpoint) {
|
||||
display: inline-block;
|
||||
margin-bottom: 0;
|
||||
margin-left: rem-calc(24);
|
||||
margin-left: rem-calc(12);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@@ -656,7 +656,7 @@ header {
|
||||
@media (min-width: $small-breakpoint) {
|
||||
line-height: $line-height*3;
|
||||
margin-left: rem-calc(12);
|
||||
margin-right: rem-calc(72);
|
||||
margin-right: rem-calc(36);
|
||||
}
|
||||
|
||||
&:after {
|
||||
@@ -772,7 +772,7 @@ footer {
|
||||
@extend .tags;
|
||||
|
||||
h3 {
|
||||
border-top: 1px solid $votes-border;
|
||||
border-top: 2px solid $brand;
|
||||
display: inline-block;
|
||||
font-family: $font-family-sans-serif;
|
||||
font-size: rem-calc(16);
|
||||
@@ -925,6 +925,18 @@ form {
|
||||
margin-bottom: rem-calc(12);
|
||||
}
|
||||
|
||||
.note-marked {
|
||||
@extend .note;
|
||||
background: yellow;
|
||||
display: inline-block;
|
||||
|
||||
em {
|
||||
background: white;
|
||||
display: inline-block;
|
||||
padding-left: rem-calc(6);
|
||||
}
|
||||
}
|
||||
|
||||
.ckeditor {
|
||||
min-height: rem-calc(312);
|
||||
}
|
||||
@@ -1403,6 +1415,7 @@ table {
|
||||
|
||||
li {
|
||||
font-size: rem-calc(15);
|
||||
line-height: rem-calc(30);
|
||||
margin-bottom: rem-calc(12);
|
||||
}
|
||||
}
|
||||
|
||||
733
app/assets/stylesheets/proposals.scss
Normal file
733
app/assets/stylesheets/proposals.scss
Normal file
@@ -0,0 +1,733 @@
|
||||
// Table of Contents
|
||||
//
|
||||
// 01. Debates
|
||||
// 02. Index
|
||||
// 02.1. Featured
|
||||
// 02.2. List
|
||||
// 03. Show
|
||||
// 04. New
|
||||
// 05. Comments
|
||||
// 06. Flags
|
||||
//
|
||||
|
||||
// 01. Proposals
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
.button-proposal {
|
||||
background: $proposals;
|
||||
|
||||
&:hover {
|
||||
background: $proposals-border;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin supports {
|
||||
background: $proposals;
|
||||
border-top: 1px solid $proposals-border;
|
||||
margin: 0 rem-calc(-12);
|
||||
padding: rem-calc(14) rem-calc(12);
|
||||
position: relative;
|
||||
|
||||
.progress {
|
||||
background-color: rgba(255,255,255,.8);
|
||||
height: rem-calc(12);
|
||||
margin-bottom: rem-calc(6);
|
||||
margin-top: rem-calc(4);
|
||||
|
||||
.meter {
|
||||
background: $votes-like;
|
||||
}
|
||||
}
|
||||
|
||||
abbr {
|
||||
color: white;
|
||||
|
||||
&[title] {
|
||||
border-bottom: 1px dotted white;
|
||||
}
|
||||
}
|
||||
|
||||
.button-support {
|
||||
background: white;
|
||||
color: $proposals;
|
||||
display: inline-block;
|
||||
font-size: rem-calc(14);
|
||||
margin-top: rem-calc(12);
|
||||
|
||||
&:hover {
|
||||
background: $proposals-border;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:active {
|
||||
opacity: .75;
|
||||
}
|
||||
}
|
||||
|
||||
.total-supports {
|
||||
color: white;
|
||||
text-align: center;
|
||||
font-size: rem-calc(14);
|
||||
|
||||
span {
|
||||
display: block;
|
||||
font-size: rem-calc(11);
|
||||
opacity: .75;
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
margin: 0 rem-calc(6);
|
||||
}
|
||||
|
||||
.not-logged {
|
||||
background: rgba(255,164,45,.9);
|
||||
color: white;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
line-height: $line-height*2;
|
||||
padding-top: rem-calc(12);
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#222222', endColorstr='#222222'); /* IE */
|
||||
|
||||
a {
|
||||
color: white;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.anonymous-votes, .organizations-votes {
|
||||
background: $warning-bg;
|
||||
color: $warning-color;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
line-height: $line-height;
|
||||
padding-top: rem-calc(12);
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
|
||||
p {
|
||||
color: $warning-color;
|
||||
margin: 0 rem-calc(12);
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $warning-color;
|
||||
font-weight: bold;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.supported {
|
||||
color: white;
|
||||
margin-top: rem-calc(12);
|
||||
}
|
||||
}
|
||||
|
||||
// 02. Index
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
// 02.1. Featured
|
||||
// - - - - - - - - - - - - -
|
||||
|
||||
.proposal-featured {
|
||||
|
||||
.panel {
|
||||
background: white;
|
||||
border: 1px solid;
|
||||
border-color: #e5e6e9 #dfe0e4 #d0d1d5;
|
||||
border-radius: rem-calc(3);
|
||||
margin-bottom: rem-calc(24);
|
||||
padding: rem-calc(24) rem-calc(12) 0 rem-calc(12);
|
||||
|
||||
.proposal-content {
|
||||
min-height: rem-calc(353);
|
||||
}
|
||||
|
||||
.label {
|
||||
background: none;
|
||||
clear: both;
|
||||
color: $proposals;
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
padding-left: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.icon-proposals {
|
||||
color: $proposals;
|
||||
font-size: rem-calc(36);
|
||||
line-height: $line-height;
|
||||
position: absolute;
|
||||
right: rem-calc(18);
|
||||
top: rem-calc(12);
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-weight: bold;
|
||||
margin: rem-calc(8) 0 0 0;
|
||||
min-height: rem-calc(65);
|
||||
|
||||
a {
|
||||
clear: both;
|
||||
color: $text;
|
||||
display: block;
|
||||
font-size: rem-calc(16);
|
||||
line-height: $line-height;
|
||||
text-transform: lowercase;
|
||||
|
||||
&:first-letter {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.proposal-info {
|
||||
color: $text-medium;
|
||||
font-weight: lighter;
|
||||
margin-bottom: 0;
|
||||
|
||||
.icon-comments {
|
||||
font-size: rem-calc(16);
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $text-medium;
|
||||
}
|
||||
}
|
||||
|
||||
.proposal-description {
|
||||
color: $text;
|
||||
font-size: rem-calc(13);
|
||||
height: rem-calc(156);
|
||||
line-height: $line-height;
|
||||
margin-bottom: rem-calc(12);
|
||||
margin-top: rem-calc(24);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
a {
|
||||
color: $text;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
|
||||
li {
|
||||
font-size: rem-calc(13);
|
||||
margin-bottom: rem-calc(12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.truncate {
|
||||
background: image-url('truncate.png');
|
||||
background-repeat: repeat-x;
|
||||
bottom: 0;
|
||||
height: 24px;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
p {
|
||||
color: $text;
|
||||
font-size: rem-calc(14);
|
||||
line-height: $line-height;
|
||||
margin-bottom: rem-calc(12);
|
||||
|
||||
&.debate-info {
|
||||
font-size: rem-calc(13);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.supports {
|
||||
@include supports;
|
||||
}
|
||||
}
|
||||
|
||||
// 02.2. List
|
||||
// - - - - - - - - - - - - -
|
||||
|
||||
.proposals-list {
|
||||
|
||||
@media (min-width: $small-breakpoint) {
|
||||
margin-bottom: rem-calc(48);
|
||||
}
|
||||
}
|
||||
|
||||
.proposal {
|
||||
@extend .proposal-featured;
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
|
||||
.panel {
|
||||
border-radius: 0;
|
||||
box-shadow: 0px 1px 3px 0 $border;
|
||||
margin-bottom: rem-calc(12);
|
||||
min-height: rem-calc(192);
|
||||
padding-top: rem-calc(12);
|
||||
|
||||
@media (min-width: $small-breakpoint) {
|
||||
margin-bottom: rem-calc(-1);
|
||||
padding-bottom: rem-calc(12);
|
||||
}
|
||||
|
||||
.label {
|
||||
line-height: $line-height;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 0;
|
||||
min-height: rem-calc(48);
|
||||
}
|
||||
|
||||
.proposal-content {
|
||||
margin: 0;
|
||||
min-height: rem-calc(180);
|
||||
|
||||
.tags {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-proposals {
|
||||
font-size: rem-calc(18);
|
||||
left: rem-calc(88);
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.proposal-description {
|
||||
height: rem-calc(72);
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.supports {
|
||||
border: 1px solid $proposals-border;
|
||||
margin: 0 rem-calc(-12);
|
||||
|
||||
@media (min-width: $small-breakpoint) {
|
||||
border-top-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
margin: 0 rem-calc(-25) 0 rem-calc(12);
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: none;
|
||||
position: absolute;
|
||||
display: block;
|
||||
border-style: solid;
|
||||
border-color: #664212 transparent transparent transparent;
|
||||
bottom: rem-calc(-14);
|
||||
border-left-width: 0;
|
||||
border-right-color: transparent;
|
||||
right: rem-calc(-1);
|
||||
border-width: 1em 1em 0 0;
|
||||
|
||||
@media (min-width: $small-breakpoint) {
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
|
||||
.total-supports {
|
||||
display: inline-block;
|
||||
line-height: $line-height;
|
||||
padding-top: rem-calc(12);
|
||||
vertical-align: top;
|
||||
|
||||
@media (min-width: $small-breakpoint) {
|
||||
display: block;
|
||||
float: none;
|
||||
margin-left: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.not-logged {
|
||||
line-height: $line-height;
|
||||
padding-top: rem-calc(24);
|
||||
}
|
||||
|
||||
.anonymous-votes, .organizations-votes {
|
||||
padding-top: rem-calc(24);
|
||||
}
|
||||
|
||||
.divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: $medium-breakpoint) {
|
||||
.divider {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 03. Show
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
.proposal-show {
|
||||
padding-top: rem-calc(12);
|
||||
|
||||
.back {
|
||||
@include back;
|
||||
}
|
||||
|
||||
.icon-angle-left {
|
||||
@extend .back;
|
||||
}
|
||||
|
||||
h1 {
|
||||
clear: both;
|
||||
font-size: rem-calc(30);
|
||||
font-weight: bold;
|
||||
margin: 0;
|
||||
text-transform: lowercase;
|
||||
|
||||
&:first-letter {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
.edit-proposal {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.proposal-info {
|
||||
clear: both;
|
||||
color: $text-medium;
|
||||
font-weight: lighter;
|
||||
line-height: $line-height*2;
|
||||
text-align: justify;
|
||||
|
||||
a {
|
||||
color: $text-medium;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: rem-calc(15);
|
||||
line-height: $line-height;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
|
||||
li {
|
||||
font-size: rem-calc(13);
|
||||
margin-bottom: rem-calc(12);
|
||||
}
|
||||
}
|
||||
|
||||
.author-photo {
|
||||
line-height: $line-height*2;
|
||||
margin-right: rem-calc(6);
|
||||
vertical-align: middle;
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.author {
|
||||
color: $text;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
aside {
|
||||
|
||||
h3 {
|
||||
border-top: 2px solid $brand;
|
||||
display: inline-block;
|
||||
font-size: rem-calc(16);
|
||||
margin: -1px 0 rem-calc(12);
|
||||
padding-top: rem-calc(6);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
.supports {
|
||||
@include supports;
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
margin: 0;
|
||||
|
||||
.total-supports {
|
||||
display: block;
|
||||
float: none;
|
||||
line-height: $line-height;
|
||||
}
|
||||
|
||||
.not-logged {
|
||||
line-height: $line-height;
|
||||
padding: rem-calc(24);
|
||||
}
|
||||
|
||||
@media (min-width: $small-breakpoint + em-calc(1)) and (max-width:$medium-breakpoint) {
|
||||
.in-favor, .against {
|
||||
text-align: left;
|
||||
width: rem-calc(100);
|
||||
}
|
||||
}
|
||||
|
||||
.divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (min-width: $medium-breakpoint) {
|
||||
.divider {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.leave-comment {
|
||||
display: inline-block;
|
||||
margin-top: rem-calc(24);
|
||||
}
|
||||
|
||||
.tags {
|
||||
display: block;
|
||||
margin: rem-calc(24) 0;
|
||||
|
||||
a {
|
||||
margin-right: rem-calc(6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bullet {
|
||||
color: $border;
|
||||
}
|
||||
|
||||
// 04. New
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
.proposal-new {
|
||||
background: white;
|
||||
padding-top: rem-calc(24);
|
||||
|
||||
.back {
|
||||
@include back;
|
||||
}
|
||||
|
||||
h1 {
|
||||
clear: both;
|
||||
font-size: rem-calc(36);
|
||||
font-weight: bold;
|
||||
line-height: $line-height*2;
|
||||
margin-bottom: rem-calc(24);
|
||||
}
|
||||
|
||||
.icon-proposals {
|
||||
color: $proposals;
|
||||
font-size: rem-calc(50);
|
||||
line-height: $line-height;
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
h2 {
|
||||
clear: both;
|
||||
font-size: rem-calc(20);
|
||||
font-weight: bold;
|
||||
line-height: $line-height;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.recommendations {
|
||||
list-style-type: none;
|
||||
margin-left: 0;
|
||||
margin-top: rem-calc(24);
|
||||
|
||||
li {
|
||||
font-size: rem-calc(12);
|
||||
margin: rem-calc(12) 0;
|
||||
|
||||
&:before {
|
||||
color: $proposals;
|
||||
content: "l ";
|
||||
font-family: "icons" !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.proposal-edit {
|
||||
@extend .proposal-new;
|
||||
}
|
||||
|
||||
// 05. Comments
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
.comments {
|
||||
background: $white;
|
||||
background-repeat: repeat-x;
|
||||
padding-top: rem-calc(24);
|
||||
padding-bottom: rem-calc(96);
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
font-weight: bold;
|
||||
|
||||
span {
|
||||
font-size: rem-calc(18);
|
||||
font-weight: normal;
|
||||
opacity: .8;
|
||||
}
|
||||
}
|
||||
|
||||
.comment {
|
||||
margin: rem-calc(6) 0;
|
||||
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.comment-votes {
|
||||
color: $text-medium;
|
||||
font-weight: lighter;
|
||||
margin: rem-calc(8) rem-calc(12) rem-calc(6) 0;
|
||||
|
||||
a {
|
||||
color: $text-light;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
|
||||
&:hover {
|
||||
color: $text-medium;
|
||||
}
|
||||
}
|
||||
|
||||
[class^="icon-"] {
|
||||
font-size: rem-calc(20);
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.comment-body {
|
||||
margin-left: rem-calc(42);
|
||||
|
||||
p {
|
||||
font-size: rem-calc(14);
|
||||
}
|
||||
|
||||
.reply {
|
||||
background: white;
|
||||
border: 1px solid $border;
|
||||
font-size: rem-calc(12);
|
||||
margin: rem-calc(6) 0;
|
||||
padding: rem-calc(6);
|
||||
|
||||
.divider {
|
||||
color: $text-light;
|
||||
}
|
||||
}
|
||||
|
||||
.comment-user {
|
||||
margin-top: rem-calc(6);
|
||||
padding: rem-calc(6) 0;
|
||||
overflow: hidden;
|
||||
|
||||
@each $n in ("1", "2", "3","4", "5") {
|
||||
&.level-#{$n} {
|
||||
@if $n == "5" {
|
||||
background: $comment-level-5;
|
||||
padding: rem-calc(6) rem-calc(12);
|
||||
}
|
||||
@elseif $n == "1" {
|
||||
background: none;
|
||||
padding: rem-calc(6) rem-calc(12);
|
||||
}
|
||||
@else {
|
||||
background: $comment-official;
|
||||
padding: rem-calc(6) rem-calc(12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.is-author {
|
||||
background: $comment-author;
|
||||
padding: rem-calc(6) rem-calc(12);
|
||||
}
|
||||
|
||||
&.is-admin {
|
||||
background: $comment-admin;
|
||||
padding: rem-calc(6) rem-calc(12);
|
||||
}
|
||||
|
||||
&.is-moderator {
|
||||
@extend .is-admin;
|
||||
}
|
||||
|
||||
&.level-5 {
|
||||
background: $comment-level-5;
|
||||
padding: rem-calc(6) rem-calc(12);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.is-deleted {
|
||||
background: $deleted;
|
||||
margin-left: rem-calc(42);
|
||||
padding: rem-calc(6) rem-calc(12);
|
||||
}
|
||||
|
||||
.comment-children {
|
||||
border-left: 1px dashed $border;
|
||||
margin-left: rem-calc(42);
|
||||
padding-left: rem-calc(6);
|
||||
|
||||
@media only screen and (max-width: 40em) {
|
||||
margin-left: rem-calc(16);
|
||||
}
|
||||
}
|
||||
|
||||
.comment-info {
|
||||
color: $text-light;
|
||||
font-size: rem-calc(13);
|
||||
font-weight: lighter;
|
||||
margin-top: rem-calc(6);
|
||||
vertical-align: middle;
|
||||
|
||||
span.user-name {
|
||||
color: $text;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.faded {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
// 06. Flags
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
.flag-content {
|
||||
|
||||
.button {
|
||||
background: none;
|
||||
margin-bottom: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.flag-disable {
|
||||
color: $text-medium;
|
||||
line-height: rem-calc(24);
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.flag-active {
|
||||
@extend .flag-disable;
|
||||
color: $delete;
|
||||
}
|
||||
@@ -41,6 +41,9 @@ $votes-unlike-act: #BD6A6A;
|
||||
$delete: #F04124;
|
||||
$check: #46DB91;
|
||||
|
||||
$proposals: #FFA42D;
|
||||
$proposals-border: #CC8425;
|
||||
|
||||
// 03. Forms
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ class AccountController < ApplicationController
|
||||
|
||||
def account_params
|
||||
if @account.organization?
|
||||
params.require(:account).permit(:phone_number, :email_on_debate_comment, :email_on_comment_reply, organization_attributes: [:name, :responsible_name])
|
||||
params.require(:account).permit(:phone_number, :email_on_comment, :email_on_comment_reply, organization_attributes: [:name, :responsible_name])
|
||||
else
|
||||
params.require(:account).permit(:username, :email_on_debate_comment, :email_on_comment_reply)
|
||||
params.require(:account).permit(:username, :email_on_comment, :email_on_comment_reply)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
26
app/controllers/admin/proposals_controller.rb
Normal file
26
app/controllers/admin/proposals_controller.rb
Normal file
@@ -0,0 +1,26 @@
|
||||
class Admin::ProposalsController < Admin::BaseController
|
||||
has_filters %w{without_confirmed_hide all with_confirmed_hide}, only: :index
|
||||
|
||||
before_action :load_proposal, only: [:confirm_hide, :restore]
|
||||
|
||||
def index
|
||||
@proposals = Proposal.only_hidden.send(@current_filter).order(hidden_at: :desc).page(params[:page])
|
||||
end
|
||||
|
||||
def confirm_hide
|
||||
@proposal.confirm_hide
|
||||
redirect_to request.query_parameters.merge(action: :index)
|
||||
end
|
||||
|
||||
def restore
|
||||
@proposal.restore
|
||||
redirect_to request.query_parameters.merge(action: :index)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_proposal
|
||||
@proposal = Proposal.with_hidden.find(params[:id])
|
||||
end
|
||||
|
||||
end
|
||||
@@ -3,6 +3,7 @@ require "application_responder"
|
||||
class ApplicationController < ActionController::Base
|
||||
include SimpleCaptcha::ControllerHelpers
|
||||
include HasFilters
|
||||
include HasOrders
|
||||
|
||||
before_action :authenticate_http_basic, if: :http_basic_auth_site?
|
||||
before_action :authenticate_user!, unless: :devise_controller?, if: :beta_site?
|
||||
@@ -78,6 +79,10 @@ class ApplicationController < ActionController::Base
|
||||
@debate_votes = current_user ? current_user.debate_votes(debates) : {}
|
||||
end
|
||||
|
||||
def set_proposal_votes(proposals)
|
||||
@proposal_votes = current_user ? current_user.proposal_votes(proposals) : {}
|
||||
end
|
||||
|
||||
def set_comment_flags(comments)
|
||||
@comment_flags = current_user ? current_user.comment_flags(comments) : {}
|
||||
end
|
||||
|
||||
@@ -55,11 +55,11 @@ class CommentsController < ApplicationController
|
||||
end
|
||||
|
||||
def administrator_comment?
|
||||
["1", true].include?(comment_params[:as_administrator]) && can?(:comment_as_administrator, Debate)
|
||||
["1", true].include?(comment_params[:as_administrator]) && can?(:comment_as_administrator, @commentable)
|
||||
end
|
||||
|
||||
def moderator_comment?
|
||||
["1", true].include?(comment_params[:as_moderator]) && can?(:comment_as_moderator, Debate)
|
||||
["1", true].include?(comment_params[:as_moderator]) && can?(:comment_as_moderator, @commentable)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
12
app/controllers/concerns/has_orders.rb
Normal file
12
app/controllers/concerns/has_orders.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
module HasOrders
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
class_methods do
|
||||
def has_orders(valid_orders, *args)
|
||||
before_action(*args) do
|
||||
@valid_orders = valid_orders
|
||||
@current_order = @valid_orders.include?(params[:order]) ? params[:order] : @valid_orders.first
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -1,16 +1,17 @@
|
||||
class DebatesController < ApplicationController
|
||||
before_action :parse_order, only: :index
|
||||
before_action :parse_tag_filter, only: :index
|
||||
before_action :parse_search_terms, only: :index
|
||||
before_action :authenticate_user!, except: [:index, :show]
|
||||
has_orders %w{confidence_score hot_score created_at most_commented random}, only: :index
|
||||
|
||||
load_and_authorize_resource
|
||||
|
||||
respond_to :html, :js
|
||||
|
||||
def index
|
||||
@debates = @search_terms.present? ? Debate.search(@search_terms) : Debate.all
|
||||
@debates = @debates.tagged_with(@tag_filter) if @tag_filter
|
||||
@debates = @debates.page(params[:page]).for_render.send("sort_by_#{@order}")
|
||||
@debates = @debates.page(params[:page]).for_render.send("sort_by_#{@current_order}")
|
||||
@tag_cloud = Debate.tag_counts.order(taggings_count: :desc, name: :asc).limit(20)
|
||||
set_debate_votes(@debates)
|
||||
end
|
||||
@@ -82,11 +83,6 @@ class DebatesController < ApplicationController
|
||||
@featured_tags = ActsAsTaggableOn::Tag.where(featured: true)
|
||||
end
|
||||
|
||||
def parse_order
|
||||
@valid_orders = ['confidence_score', 'hot_score', 'created_at', 'most_commented', 'random']
|
||||
@order = @valid_orders.include?(params[:order]) ? params[:order] : @valid_orders.first
|
||||
end
|
||||
|
||||
def parse_tag_filter
|
||||
if params[:tag].present?
|
||||
@tag_filter = params[:tag] if ActsAsTaggableOn::Tag.where(name: params[:tag]).exists?
|
||||
|
||||
44
app/controllers/moderation/proposals_controller.rb
Normal file
44
app/controllers/moderation/proposals_controller.rb
Normal file
@@ -0,0 +1,44 @@
|
||||
class Moderation::ProposalsController < Moderation::BaseController
|
||||
|
||||
has_filters %w{pending_flag_review all with_ignored_flag}, only: :index
|
||||
has_orders %w{created_at flags}, only: :index
|
||||
|
||||
before_filter :load_proposals, only: [:index, :moderate]
|
||||
|
||||
load_and_authorize_resource
|
||||
|
||||
def index
|
||||
@proposals = @proposals.send(@current_filter)
|
||||
.send("sort_by_#{@current_order}")
|
||||
.page(params[:page])
|
||||
.per(50)
|
||||
end
|
||||
|
||||
def hide
|
||||
@proposal.hide
|
||||
end
|
||||
|
||||
def moderate
|
||||
@proposals = @proposals.where(id: params[:proposal_ids])
|
||||
|
||||
if params[:hide_proposals].present?
|
||||
@proposals.accessible_by(current_ability, :hide).each(&:hide)
|
||||
|
||||
elsif params[:ignore_flags].present?
|
||||
@proposals.accessible_by(current_ability, :ignore_flag).each(&:ignore_flag)
|
||||
|
||||
elsif params[:block_authors].present?
|
||||
author_ids = @proposals.pluck(:author_id).uniq
|
||||
User.where(id: author_ids).accessible_by(current_ability, :block).each(&:block)
|
||||
end
|
||||
|
||||
redirect_to request.query_parameters.merge(action: :index)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_proposals
|
||||
@proposals = Proposal.accessible_by(current_ability, :moderate)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -34,6 +34,15 @@ class PagesController < ApplicationController
|
||||
def transparency
|
||||
end
|
||||
|
||||
def proposals_info
|
||||
end
|
||||
|
||||
def participation_facts
|
||||
end
|
||||
|
||||
def participation_world
|
||||
end
|
||||
|
||||
def blog
|
||||
redirect_to "http://diario.madrid.es/blog/category/gobiernoabierto/"
|
||||
end
|
||||
|
||||
94
app/controllers/proposals_controller.rb
Normal file
94
app/controllers/proposals_controller.rb
Normal file
@@ -0,0 +1,94 @@
|
||||
class ProposalsController < ApplicationController
|
||||
before_action :parse_tag_filter, only: :index
|
||||
before_action :parse_search_terms, only: :index
|
||||
before_action :authenticate_user!, except: [:index, :show]
|
||||
has_orders %w{confidence_score hot_score created_at most_commented random}, only: :index
|
||||
|
||||
load_and_authorize_resource
|
||||
respond_to :html, :js
|
||||
|
||||
def index
|
||||
@proposals = @search_terms.present? ? Proposal.search(@search_terms) : Proposal.all
|
||||
@proposals = @proposals.tagged_with(@tag_filter) if @tag_filter
|
||||
@proposals = @proposals.page(params[:page]).for_render.send("sort_by_#{@current_order}")
|
||||
@tag_cloud = Proposal.tag_counts.order(taggings_count: :desc, name: :asc).limit(20)
|
||||
set_proposal_votes(@proposals)
|
||||
end
|
||||
|
||||
def show
|
||||
set_proposal_votes(@proposal)
|
||||
@commentable = @proposal
|
||||
@root_comments = @proposal.comments.roots.recent.page(params[:page]).per(10).for_render
|
||||
@comments = @root_comments.inject([]){|all, root| all + Comment.descendants_of(root).for_render}
|
||||
|
||||
@all_visible_comments = @root_comments + @comments
|
||||
set_comment_flags(@all_visible_comments)
|
||||
end
|
||||
|
||||
def new
|
||||
@proposal = Proposal.new
|
||||
load_featured_tags
|
||||
end
|
||||
|
||||
def create
|
||||
@proposal = Proposal.new(proposal_params)
|
||||
@proposal.author = current_user
|
||||
|
||||
if @proposal.save_with_captcha
|
||||
ahoy.track :proposal_created, proposal_id: @proposal.id
|
||||
redirect_to @proposal, notice: t('flash.actions.create.notice', resource_name: 'Proposal')
|
||||
else
|
||||
load_featured_tags
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
load_featured_tags
|
||||
end
|
||||
|
||||
def update
|
||||
@proposal.assign_attributes(proposal_params)
|
||||
if @proposal.save_with_captcha
|
||||
redirect_to @proposal, notice: t('flash.actions.update.notice', resource_name: 'Proposal')
|
||||
else
|
||||
load_featured_tags
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def flag
|
||||
Flag.flag(current_user, @proposal)
|
||||
respond_with @proposal, template: 'proposals/_refresh_flag_actions'
|
||||
end
|
||||
|
||||
def unflag
|
||||
Flag.unflag(current_user, @proposal)
|
||||
respond_with @proposal, template: 'proposals/_refresh_flag_actions'
|
||||
end
|
||||
|
||||
def vote
|
||||
@proposal.register_vote(current_user, 'yes')
|
||||
set_proposal_votes(@proposal)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def proposal_params
|
||||
params.require(:proposal).permit(:title, :question, :summary, :description, :external_url, :video_url, :responsible_name, :tag_list, :terms_of_service, :captcha, :captcha_key)
|
||||
end
|
||||
|
||||
def load_featured_tags
|
||||
@featured_tags = ActsAsTaggableOn::Tag.where(featured: true)
|
||||
end
|
||||
|
||||
def parse_tag_filter
|
||||
if params[:tag].present?
|
||||
@tag_filter = params[:tag] if ActsAsTaggableOn::Tag.where(name: params[:tag]).exists?
|
||||
end
|
||||
end
|
||||
|
||||
def parse_search_terms
|
||||
@search_terms = params[:search] if params[:search].present?
|
||||
end
|
||||
end
|
||||
@@ -13,7 +13,7 @@ class Verification::LetterController < ApplicationController
|
||||
def create
|
||||
@letter = Verification::Letter.new(user: current_user)
|
||||
if @letter.save
|
||||
redirect_to edit_letter_path, notice: t('verification.letter.create.flash.success')
|
||||
redirect_to edit_letter_path
|
||||
else
|
||||
flash.now.alert = t('verification.letter.create.alert.failure')
|
||||
render :new
|
||||
|
||||
@@ -4,11 +4,26 @@ class WelcomeController < ApplicationController
|
||||
layout "devise", only: :welcome
|
||||
|
||||
def index
|
||||
@featured_debates = Debate.sort_by_confidence_score.limit(3).for_render
|
||||
set_debate_votes(@featured_debates)
|
||||
if current_user
|
||||
redirect_to :proposals
|
||||
end
|
||||
end
|
||||
|
||||
def welcome
|
||||
end
|
||||
|
||||
def highlights
|
||||
debates = Debate.sort_by_hot_score.page(params[:page]).per(10).for_render
|
||||
set_debate_votes(debates)
|
||||
|
||||
proposals = Proposal.sort_by_hot_score.page(params[:page]).per(10).for_render
|
||||
set_proposal_votes(proposals)
|
||||
|
||||
@list = (debates.to_a + proposals.to_a).sort{|a, b| b.hot_score <=> a.hot_score}
|
||||
@paginator = debates.total_pages > proposals.total_pages ? debates : proposals
|
||||
|
||||
render 'highlights'
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -6,6 +6,7 @@ module ApplicationHelper
|
||||
end
|
||||
|
||||
def home_page?
|
||||
return false if user_signed_in?
|
||||
# Using path because fullpath yields false negatives since it contains
|
||||
# parameters too
|
||||
request.path == '/'
|
||||
|
||||
@@ -10,7 +10,7 @@ module CacheKeysHelper
|
||||
|
||||
if user_signed_in?
|
||||
user_status += ":signed"
|
||||
user_status += ":verified" if current_user.verified_at.present?
|
||||
user_status += ":verified" if current_user.level_two_or_three_verified?
|
||||
user_status += ":org" if current_user.organization?
|
||||
user_status += ":admin" if current_user.administrator?
|
||||
user_status += ":moderator" if current_user.moderator?
|
||||
|
||||
21
app/helpers/proposals_helper.rb
Normal file
21
app/helpers/proposals_helper.rb
Normal file
@@ -0,0 +1,21 @@
|
||||
module ProposalsHelper
|
||||
|
||||
def progress_bar_percentage(proposal)
|
||||
case proposal.cached_votes_up
|
||||
when 0 then 0
|
||||
when 1..Proposal.votes_needed_for_success then (proposal.cached_votes_up.to_f * 100 / Proposal.votes_needed_for_success).floor
|
||||
else 100
|
||||
end
|
||||
end
|
||||
|
||||
def supports_percentage(proposal)
|
||||
percentage = (proposal.cached_votes_up.to_f * 100 / Proposal.votes_needed_for_success)
|
||||
case percentage
|
||||
when 0 then "0%"
|
||||
when 0..(0.1) then "0.1%"
|
||||
when (0.1)..100 then number_to_percentage(percentage, strip_insignificant_zeros: true, precision: 1)
|
||||
else "100%"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
14
app/helpers/tags_helper.rb
Normal file
14
app/helpers/tags_helper.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
module TagsHelper
|
||||
|
||||
def taggable_path(taggable, tag_name)
|
||||
case taggable
|
||||
when 'debate'
|
||||
debates_path(tag: tag_name)
|
||||
when 'proposal'
|
||||
proposals_path(tag: tag_name)
|
||||
else
|
||||
'#'
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -6,4 +6,9 @@ module TextWithLinksHelper
|
||||
Rinku.auto_link(sanitized, :all, 'target="_blank" rel="nofollow"').html_safe
|
||||
end
|
||||
|
||||
def safe_html_with_links(html)
|
||||
return html unless html.html_safe?
|
||||
Rinku.auto_link(html, :all, 'target="_blank" rel="nofollow"').html_safe
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
module VotesHelper
|
||||
|
||||
def css_classes_for_debate_vote(debate_votes, debate)
|
||||
case debate_votes[debate.id]
|
||||
def css_classes_for_vote(votes, votable)
|
||||
case votes[votable.id]
|
||||
when true
|
||||
{in_favor: "voted", against: "no-voted"}
|
||||
when false
|
||||
@@ -11,4 +11,8 @@ module VotesHelper
|
||||
end
|
||||
end
|
||||
|
||||
def voted_for?(votes, votable)
|
||||
votes[votable.id]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -9,7 +9,7 @@ class Ability
|
||||
|
||||
# Not logged in users
|
||||
can :read, Debate
|
||||
|
||||
can :read, Proposal
|
||||
|
||||
if user # logged-in users
|
||||
can [:read, :update], User, id: user.id
|
||||
@@ -19,8 +19,14 @@ class Ability
|
||||
debate.editable_by?(user)
|
||||
end
|
||||
|
||||
can :read, Proposal
|
||||
can :update, Proposal do |proposal|
|
||||
proposal.editable_by?(user)
|
||||
end
|
||||
|
||||
can :create, Comment
|
||||
can :create, Debate
|
||||
can :create, Proposal
|
||||
|
||||
can [:flag, :unflag], Comment
|
||||
cannot [:flag, :unflag], Comment, user_id: user.id
|
||||
@@ -28,11 +34,18 @@ class Ability
|
||||
can [:flag, :unflag], Debate
|
||||
cannot [:flag, :unflag], Debate, author_id: user.id
|
||||
|
||||
can [:flag, :unflag], Proposal
|
||||
cannot [:flag, :unflag], Proposal, author_id: user.id
|
||||
|
||||
unless user.organization?
|
||||
can :vote, Debate
|
||||
can :vote, Comment
|
||||
end
|
||||
|
||||
if user.level_two_or_three_verified?
|
||||
can :vote, Proposal
|
||||
end
|
||||
|
||||
if user.moderator? || user.administrator?
|
||||
can :read, Organization
|
||||
can(:verify, Organization){ |o| !o.verified? }
|
||||
@@ -52,12 +65,24 @@ class Ability
|
||||
can :ignore_flag, Debate, ignored_flag_at: nil, hidden_at: nil
|
||||
cannot :ignore_flag, Debate, author_id: user.id
|
||||
|
||||
can :hide, Proposal, hidden_at: nil
|
||||
cannot :hide, Proposal, author_id: user.id
|
||||
|
||||
can :ignore_flag, Proposal, ignored_flag_at: nil, hidden_at: nil
|
||||
cannot :ignore_flag, Proposal, author_id: user.id
|
||||
|
||||
can :moderate, Proposal
|
||||
cannot :moderate, Proposal, author_id: user.id
|
||||
|
||||
can :hide, User
|
||||
cannot :hide, User, id: user.id
|
||||
|
||||
can :block, User
|
||||
cannot :block, User, id: user.id
|
||||
end
|
||||
|
||||
if user.moderator?
|
||||
can :comment_as_moderator, [Debate, Comment]
|
||||
can :comment_as_moderator, [Debate, Comment, Proposal]
|
||||
end
|
||||
|
||||
if user.administrator?
|
||||
@@ -67,6 +92,9 @@ class Ability
|
||||
can :restore, Debate
|
||||
cannot :restore, Debate, hidden_at: nil
|
||||
|
||||
can :restore, Proposal
|
||||
cannot :restore, Proposal, hidden_at: nil
|
||||
|
||||
can :restore, User
|
||||
cannot :restore, User, hidden_at: nil
|
||||
|
||||
@@ -76,10 +104,13 @@ class Ability
|
||||
can :confirm_hide, Debate
|
||||
cannot :confirm_hide, Debate, hidden_at: nil
|
||||
|
||||
can :confirm_hide, Proposal
|
||||
cannot :confirm_hide, Proposal, hidden_at: nil
|
||||
|
||||
can :confirm_hide, User
|
||||
cannot :confirm_hide, User, hidden_at: nil
|
||||
|
||||
can :comment_as_administrator, [Debate, Comment]
|
||||
can :comment_as_administrator, [Debate, Comment, Proposal]
|
||||
|
||||
can :manage, Moderator
|
||||
end
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
class Comment < ActiveRecord::Base
|
||||
include Flaggable
|
||||
|
||||
acts_as_paranoid column: :hidden_at
|
||||
include ActsAsParanoidAliases
|
||||
@@ -9,21 +10,16 @@ class Comment < ActiveRecord::Base
|
||||
|
||||
validates :body, presence: true
|
||||
validates :user, presence: true
|
||||
validates_inclusion_of :commentable_type, in: ["Debate"]
|
||||
validates_inclusion_of :commentable_type, in: ["Debate", "Proposal"]
|
||||
|
||||
validate :validate_body_length
|
||||
|
||||
belongs_to :commentable, -> { with_hidden }, polymorphic: true, counter_cache: true
|
||||
belongs_to :user, -> { with_hidden }
|
||||
|
||||
has_many :flags, as: :flaggable
|
||||
|
||||
scope :recent, -> { order(id: :desc) }
|
||||
|
||||
scope :sort_for_moderation, -> { order(flags_count: :desc, updated_at: :desc) }
|
||||
scope :pending_flag_review, -> { where(ignored_flag_at: nil, hidden_at: nil) }
|
||||
scope :with_ignored_flag, -> { where(hidden_at: nil).where.not(ignored_flag_at: nil) }
|
||||
scope :flagged, -> { where("flags_count > 0") }
|
||||
|
||||
scope :for_render, -> { with_hidden.includes(user: :organization) }
|
||||
|
||||
@@ -68,14 +64,6 @@ class Comment < ActiveRecord::Base
|
||||
cached_votes_down
|
||||
end
|
||||
|
||||
def ignored_flag?
|
||||
ignored_flag_at.present?
|
||||
end
|
||||
|
||||
def ignore_flag
|
||||
update(ignored_flag_at: Time.now)
|
||||
end
|
||||
|
||||
def as_administrator?
|
||||
administrator_id.present?
|
||||
end
|
||||
|
||||
@@ -12,16 +12,16 @@ class CommentNotifier
|
||||
private
|
||||
|
||||
def send_comment_email
|
||||
Mailer.comment(@comment).deliver_later if email_on_debate_comment?
|
||||
Mailer.comment(@comment).deliver_later if email_on_comment?
|
||||
end
|
||||
|
||||
def send_reply_email
|
||||
Mailer.reply(@comment).deliver_later if email_on_comment_reply?
|
||||
end
|
||||
|
||||
def email_on_debate_comment?
|
||||
def email_on_comment?
|
||||
commentable_author = @comment.commentable.author
|
||||
commentable_author != @author && commentable_author.email_on_debate_comment?
|
||||
commentable_author != @author && commentable_author.email_on_comment?
|
||||
end
|
||||
|
||||
def email_on_comment_reply?
|
||||
|
||||
19
app/models/concerns/flaggable.rb
Normal file
19
app/models/concerns/flaggable.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
module Flaggable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
has_many :flags, as: :flaggable
|
||||
scope :flagged, -> { where("flags_count > 0") }
|
||||
scope :pending_flag_review, -> { where(ignored_flag_at: nil, hidden_at: nil) }
|
||||
scope :with_ignored_flag, -> { where.not(ignored_flag_at: nil).where(hidden_at: nil) }
|
||||
end
|
||||
|
||||
def ignored_flag?
|
||||
ignored_flag_at.present?
|
||||
end
|
||||
|
||||
def ignore_flag
|
||||
update(ignored_flag_at: Time.now)
|
||||
end
|
||||
|
||||
end
|
||||
47
app/models/concerns/verification.rb
Normal file
47
app/models/concerns/verification.rb
Normal file
@@ -0,0 +1,47 @@
|
||||
module Verification
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
scope :level_three_verified, -> { where.not(verified_at: nil) }
|
||||
scope :level_two_verified, -> { where("users.confirmed_phone IS NOT NULL AND users.residence_verified_at IS NOT NULL") }
|
||||
scope :level_two_or_three_verified, -> { where("users.verified_at IS NOT NULL OR (users.confirmed_phone IS NOT NULL AND users.residence_verified_at IS NOT NULL)") }
|
||||
scope :unverified, -> { where("users.verified_at IS NULL AND (users.confirmed_phone IS NULL OR users.residence_verified_at IS NOT NULL)") }
|
||||
end
|
||||
|
||||
def verification_email_sent?
|
||||
email_verification_token.present?
|
||||
end
|
||||
|
||||
def verification_sms_sent?
|
||||
unconfirmed_phone.present? && sms_confirmation_code.present?
|
||||
end
|
||||
|
||||
def verification_letter_sent?
|
||||
letter_requested_at.present? && letter_verification_code.present?
|
||||
end
|
||||
|
||||
def residence_verified?
|
||||
residence_verified_at.present?
|
||||
end
|
||||
|
||||
def sms_verified?
|
||||
confirmed_phone.present?
|
||||
end
|
||||
|
||||
def level_two_verified?
|
||||
residence_verified? && sms_verified?
|
||||
end
|
||||
|
||||
def level_three_verified?
|
||||
verified_at.present?
|
||||
end
|
||||
|
||||
def level_two_or_three_verified?
|
||||
level_two_verified? || level_three_verified?
|
||||
end
|
||||
|
||||
def unverified?
|
||||
!level_two_or_three_verified?
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,5 +1,6 @@
|
||||
require 'numeric'
|
||||
class Debate < ActiveRecord::Base
|
||||
include Flaggable
|
||||
apply_simple_captcha
|
||||
|
||||
acts_as_votable
|
||||
@@ -9,7 +10,6 @@ class Debate < ActiveRecord::Base
|
||||
|
||||
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||
has_many :comments, as: :commentable
|
||||
has_many :flags, as: :flaggable
|
||||
|
||||
validates :title, presence: true
|
||||
validates :description, presence: true
|
||||
@@ -26,9 +26,6 @@ class Debate < ActiveRecord::Base
|
||||
before_save :calculate_hot_score, :calculate_confidence_score
|
||||
|
||||
scope :sort_for_moderation, -> { order(flags_count: :desc, updated_at: :desc) }
|
||||
scope :pending_flag_review, -> { where(ignored_flag_at: nil, hidden_at: nil) }
|
||||
scope :with_ignored_flag, -> { where.not(ignored_flag_at: nil).where(hidden_at: nil) }
|
||||
scope :flagged, -> { where("flags_count > 0") }
|
||||
scope :for_render, -> { includes(:tags) }
|
||||
scope :sort_by_hot_score , -> { order(hot_score: :desc) }
|
||||
scope :sort_by_confidence_score , -> { order(confidence_score: :desc) }
|
||||
@@ -100,37 +97,20 @@ class Debate < ActiveRecord::Base
|
||||
count < 0 ? 0 : count
|
||||
end
|
||||
|
||||
def ignored_flag?
|
||||
ignored_flag_at.present?
|
||||
end
|
||||
|
||||
def ignore_flag
|
||||
update(ignored_flag_at: Time.now)
|
||||
end
|
||||
|
||||
def after_commented
|
||||
save # updates the hot_score because there is a before_save
|
||||
end
|
||||
|
||||
def calculate_hot_score
|
||||
start = Time.new(2015, 6, 15)
|
||||
comments_weight = 1.0/20 # 1 positive vote / x comments
|
||||
time_unit = 12.hours.to_f
|
||||
|
||||
total = cached_votes_total + comments_weight * comments_count
|
||||
ups = cached_votes_up + comments_weight * comments_count
|
||||
downs = total - ups
|
||||
score = ups - downs
|
||||
order = Math.log([score.abs, 1].max, 10)
|
||||
sign = (score <=> 0).to_f
|
||||
seconds = ((created_at || Time.now) - start).to_f
|
||||
|
||||
self.hot_score = (((order * sign) + (seconds/time_unit)) * 1000000).round
|
||||
self.hot_score = ScoreCalculator.hot_score(created_at,
|
||||
cached_votes_total,
|
||||
cached_votes_up,
|
||||
comments_count)
|
||||
end
|
||||
|
||||
def calculate_confidence_score
|
||||
return unless cached_votes_total > 0
|
||||
self.confidence_score = cached_votes_score * (cached_votes_up / cached_votes_total.to_f) * 100
|
||||
self.confidence_score = ScoreCalculator.confidence_score(cached_votes_total,
|
||||
cached_votes_up)
|
||||
end
|
||||
|
||||
def self.search(terms)
|
||||
|
||||
181
app/models/proposal.rb
Normal file
181
app/models/proposal.rb
Normal file
@@ -0,0 +1,181 @@
|
||||
class Proposal < ActiveRecord::Base
|
||||
include Flaggable
|
||||
|
||||
apply_simple_captcha
|
||||
acts_as_votable
|
||||
acts_as_taggable
|
||||
acts_as_paranoid column: :hidden_at
|
||||
include ActsAsParanoidAliases
|
||||
|
||||
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||
has_many :comments, as: :commentable
|
||||
|
||||
validates :title, presence: true
|
||||
validates :question, presence: true
|
||||
validates :summary, presence: true
|
||||
validates :author, presence: true
|
||||
validates :responsible_name, presence: true
|
||||
|
||||
validate :validate_title_length
|
||||
validate :validate_question_length
|
||||
validate :validate_description_length
|
||||
validate :validate_responsible_length
|
||||
|
||||
validates :terms_of_service, acceptance: { allow_nil: false }, on: :create
|
||||
|
||||
before_validation :sanitize_description
|
||||
before_validation :sanitize_tag_list
|
||||
before_validation :set_responsible_name
|
||||
|
||||
before_save :calculate_hot_score, :calculate_confidence_score
|
||||
|
||||
scope :for_render, -> { includes(:tags) }
|
||||
scope :sort_by_hot_score , -> { order(hot_score: :desc) }
|
||||
scope :sort_by_confidence_score , -> { order(confidence_score: :desc) }
|
||||
scope :sort_by_created_at, -> { order(created_at: :desc) }
|
||||
scope :sort_by_most_commented, -> { order(comments_count: :desc) }
|
||||
scope :sort_by_random, -> { order("RANDOM()") }
|
||||
scope :sort_by_flags, -> { order(flags_count: :desc, updated_at: :desc) }
|
||||
|
||||
def total_votes
|
||||
cached_votes_up
|
||||
end
|
||||
|
||||
def conflictive?
|
||||
return false unless flags_count > 0 && cached_votes_up > 0
|
||||
cached_votes_up/flags_count.to_f < 5
|
||||
end
|
||||
|
||||
def description
|
||||
super.try :html_safe
|
||||
end
|
||||
|
||||
def tag_list_with_limit(limit = nil)
|
||||
return tags if limit.blank?
|
||||
|
||||
tags.sort{|a,b| b.taggings_count <=> a.taggings_count}[0, limit]
|
||||
end
|
||||
|
||||
def tags_count_out_of_limit(limit = nil)
|
||||
return 0 unless limit
|
||||
|
||||
count = tags.size - limit
|
||||
count < 0 ? 0 : count
|
||||
end
|
||||
|
||||
def description
|
||||
super.try :html_safe
|
||||
end
|
||||
|
||||
def editable?
|
||||
total_votes <= Setting.value_for("max_votes_for_proposal_edit").to_i
|
||||
end
|
||||
|
||||
def editable_by?(user)
|
||||
author_id == user.id && editable?
|
||||
end
|
||||
|
||||
def votable_by?(user)
|
||||
user.level_two_or_three_verified?
|
||||
end
|
||||
|
||||
def register_vote(user, vote_value)
|
||||
if votable_by?(user)
|
||||
vote_by(voter: user, vote: vote_value)
|
||||
end
|
||||
end
|
||||
|
||||
def code
|
||||
"#{Setting.value_for("proposal_code_prefix")}-#{created_at.strftime('%Y-%M')}-#{id}"
|
||||
end
|
||||
|
||||
def after_commented
|
||||
save # updates the hot_score because there is a before_save
|
||||
end
|
||||
|
||||
def calculate_hot_score
|
||||
self.hot_score = ScoreCalculator.hot_score(created_at,
|
||||
cached_votes_up,
|
||||
cached_votes_up,
|
||||
comments_count)
|
||||
end
|
||||
|
||||
def calculate_confidence_score
|
||||
self.confidence_score = ScoreCalculator.confidence_score(cached_votes_up,
|
||||
cached_votes_up)
|
||||
end
|
||||
|
||||
def self.title_max_length
|
||||
@@title_max_length ||= self.columns.find { |c| c.name == 'title' }.limit || 80
|
||||
end
|
||||
|
||||
def self.question_max_length
|
||||
140
|
||||
end
|
||||
|
||||
def self.description_max_length
|
||||
6000
|
||||
end
|
||||
|
||||
def self.responsible_name_max_length
|
||||
60
|
||||
end
|
||||
|
||||
def self.search(terms)
|
||||
terms.present? ? where("title ILIKE ? OR description ILIKE ? OR question ILIKE ?", "%#{terms}%", "%#{terms}%", "%#{terms}%") : none
|
||||
end
|
||||
|
||||
def self.votes_needed_for_success
|
||||
Setting.value_for('votes_for_proposal_success').to_i
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def sanitize_description
|
||||
self.description = WYSIWYGSanitizer.new.sanitize(description)
|
||||
end
|
||||
|
||||
def sanitize_tag_list
|
||||
self.tag_list = TagSanitizer.new.sanitize_tag_list(self.tag_list)
|
||||
end
|
||||
|
||||
def set_responsible_name
|
||||
if author && author.level_two_or_three_verified?
|
||||
self.responsible_name = author.document_number
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def validate_description_length
|
||||
validator = ActiveModel::Validations::LengthValidator.new(
|
||||
attributes: :description,
|
||||
maximum: Proposal.description_max_length)
|
||||
validator.validate(self)
|
||||
end
|
||||
|
||||
def validate_title_length
|
||||
validator = ActiveModel::Validations::LengthValidator.new(
|
||||
attributes: :title,
|
||||
minimum: 4,
|
||||
maximum: Proposal.title_max_length)
|
||||
validator.validate(self)
|
||||
end
|
||||
|
||||
def validate_question_length
|
||||
validator = ActiveModel::Validations::LengthValidator.new(
|
||||
attributes: :title,
|
||||
minimum: 10,
|
||||
maximum: Proposal.question_max_length)
|
||||
validator.validate(self)
|
||||
end
|
||||
|
||||
def validate_responsible_length
|
||||
validator = ActiveModel::Validations::LengthValidator.new(
|
||||
attributes: :title,
|
||||
minimum: 6,
|
||||
maximum: Proposal.responsible_name_max_length)
|
||||
validator.validate(self)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
class Setting < ActiveRecord::Base
|
||||
validates :key, presence: true, uniqueness: true
|
||||
|
||||
default_scope { order(key: :desc) }
|
||||
default_scope { order(id: :asc) }
|
||||
|
||||
def self.value_for(key)
|
||||
where(key: key).pluck(:value).first
|
||||
|
||||
@@ -86,6 +86,11 @@ class User < ActiveRecord::Base
|
||||
voted.each_with_object({}) { |v, h| h[v.votable_id] = v.value }
|
||||
end
|
||||
|
||||
def proposal_votes(proposals)
|
||||
voted = votes.for_proposals(proposals)
|
||||
voted.each_with_object({}) { |v, h| h[v.votable_id] = v.value }
|
||||
end
|
||||
|
||||
def comment_flags(comments)
|
||||
comment_flags = flags.for_comments(comments)
|
||||
comment_flags.each_with_object({}){ |f, h| h[f.flaggable_id] = true }
|
||||
@@ -123,10 +128,13 @@ class User < ActiveRecord::Base
|
||||
def block
|
||||
debates_ids = Debate.where(author_id: id).pluck(:id)
|
||||
comments_ids = Comment.where(user_id: id).pluck(:id)
|
||||
proposal_ids = Proposal.where(author_id: id).pluck(:id)
|
||||
|
||||
self.hide
|
||||
|
||||
Debate.hide_all debates_ids
|
||||
Comment.hide_all comments_ids
|
||||
Proposal.hide_all proposal_ids
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -29,25 +29,25 @@
|
||||
|
||||
<h2><%= t("account.show.personal")%></h2>
|
||||
|
||||
<div class="small-12 medium-4">
|
||||
<% if @account.organization? %>
|
||||
<%= f.fields_for :organization do |fo| %>
|
||||
<%= fo.text_field :name, autofocus: true, maxlength: Organization.name_max_length, placeholder: t("account.show.organization_name_label") %>
|
||||
<%= fo.text_field :responsible_name, autofocus: true, maxlength: Organization.responsible_name_max_length, placeholder: t("account.show.organization_responsible_name_placeholder") %>
|
||||
<% end %>
|
||||
<%= f.text_field :phone_number, placeholder: t("account.show.phone_number_label") %>
|
||||
<div class="small-12 medium-4">
|
||||
<% if @account.organization? %>
|
||||
<%= f.fields_for :organization do |fo| %>
|
||||
<%= fo.text_field :name, autofocus: true, maxlength: Organization.name_max_length, placeholder: t("account.show.organization_name_label") %>
|
||||
<%= fo.text_field :responsible_name, autofocus: true, maxlength: Organization.responsible_name_max_length, placeholder: t("account.show.organization_responsible_name_placeholder") %>
|
||||
<% end %>
|
||||
<%= f.text_field :phone_number, placeholder: t("account.show.phone_number_label") %>
|
||||
|
||||
<% else %>
|
||||
<%= f.text_field :username, maxlength: User.username_max_length, placeholder: t("account.show.username_label") %>
|
||||
<% end %>
|
||||
<%= f.text_field :username, maxlength: User.username_max_length, placeholder: t("account.show.username_label") %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<h2><%= t("account.show.notifications")%></h2>
|
||||
|
||||
<div>
|
||||
<%= f.label :email_on_debate_comment do %>
|
||||
<%= f.check_box :email_on_debate_comment, label: false %>
|
||||
<span class="checkbox"><%= t("account.show.email_on_debate_comment_label") %></span>
|
||||
<%= f.label :email_on_comment do %>
|
||||
<%= f.check_box :email_on_comment, label: false %>
|
||||
<span class="checkbox"><%= t("account.show.email_on_comment_label") %></span>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -11,6 +11,13 @@
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li <%= "class=active" if controller_name == "proposals" %>>
|
||||
<%= link_to admin_proposals_path do %>
|
||||
<i class="icon-proposals"></i>
|
||||
<%= t("admin.menu.hidden_proposals") %>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li <%= "class=active" if controller_name == "debates" %>>
|
||||
<%= link_to admin_debates_path do %>
|
||||
<i class="icon-debates"></i>
|
||||
|
||||
28
app/views/admin/proposals/index.html.erb
Normal file
28
app/views/admin/proposals/index.html.erb
Normal file
@@ -0,0 +1,28 @@
|
||||
<h2><%= t("admin.proposals.index.title") %></h2>
|
||||
|
||||
<%= render 'shared/filter_subnav', i18n_namespace: "admin.proposals.index" %>
|
||||
|
||||
<h3><%= page_entries_info @proposals %></h3>
|
||||
|
||||
<ul class="admin-list">
|
||||
<% @proposals.each do |proposal| %>
|
||||
<li id="<%= dom_id(proposal) %>">
|
||||
<%= link_to proposal.title, proposal_path(proposal) %>
|
||||
|
||||
<%= link_to t("admin.actions.restore"),
|
||||
restore_admin_proposal_path(proposal, request.query_parameters),
|
||||
method: :put,
|
||||
data: { confirm: t("admin.actions.confirm") },
|
||||
class: "button radius tiny success right" %>
|
||||
|
||||
<% unless proposal.confirmed_hide? %>
|
||||
<%= link_to t("admin.actions.confirm_hide"),
|
||||
confirm_hide_admin_proposal_path(proposal, request.query_parameters),
|
||||
method: :put,
|
||||
class: "button radius tiny warning right" %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
|
||||
<%= paginate @proposals %>
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<% if can? :hide, comment.user %>
|
||||
<span class="divider"> • </span>
|
||||
<%= link_to t("admin.actions.hide_author").capitalize, hide_moderation_user_path(comment.user_id, debate_id: @debate.id),
|
||||
<%= link_to t("admin.actions.hide_author").capitalize, hide_moderation_user_path(comment.user_id),
|
||||
method: :put, data: { confirm: t('admin.actions.confirm') } %>
|
||||
<% end %>
|
||||
</span>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<% if comment.hidden? || comment.user.hidden? %>
|
||||
<% if select_children(@comments, comment).size > 0 %>
|
||||
<div class="is-deleted">
|
||||
<p><%= t("debates.comment.deleted") %></p>
|
||||
<p><%= t("comments.comment.deleted") %></p>
|
||||
</div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
@@ -28,13 +28,13 @@
|
||||
<div class="comment-info">
|
||||
|
||||
<% if comment.as_administrator? %>
|
||||
<span class="user-name"><%= t("debates.comment.admin") %> #<%= comment.administrator_id%></span>
|
||||
<span class="user-name"><%= t("comments.comment.admin") %> #<%= comment.administrator_id%></span>
|
||||
<% elsif comment.as_moderator? %>
|
||||
<span class="user-name"><%= t("debates.comment.moderator") %> #<%= comment.moderator_id%></span>
|
||||
<span class="user-name"><%= t("comments.comment.moderator") %> #<%= comment.moderator_id%></span>
|
||||
<% else %>
|
||||
|
||||
<% if comment.user.hidden? %>
|
||||
<span class="user-name"><%= t("debates.comment.user_deleted") %></span>
|
||||
<span class="user-name"><%= t("comments.comment.user_deleted") %></span>
|
||||
<% else %>
|
||||
<span class="user-name"><%= comment.user.name %></span>
|
||||
<% if comment.user.official? %>
|
||||
@@ -53,7 +53,7 @@
|
||||
<% if comment.user_id == @commentable.author_id %>
|
||||
•
|
||||
<span class="label round is-author">
|
||||
<%= t("debates.comment.author") %>
|
||||
<%= t("comments.comment.author") %>
|
||||
</span>
|
||||
<% end %>
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
</span>
|
||||
|
||||
<div class="reply">
|
||||
<%= t("debates.comment.responses", count: select_children(@comments, comment).size) %>
|
||||
<%= t("comments.comment.responses", count: select_children(@comments, comment).size) %>
|
||||
|
||||
<% if user_signed_in? %>
|
||||
<span class="divider"> | </span>
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
<div><%= t("errors.messages.blank").capitalize %></div>
|
||||
|
||||
<div class="alert-box alert radius">
|
||||
<%= t("errors.messages.blank").capitalize %>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<% cache [locale_and_user_status, parent_id, commentable_cache_key(commentable)] do %>
|
||||
<% css_id = parent_or_commentable_dom_id(parent_id, commentable) %>
|
||||
<div id="js-comment-form-<%= css_id %>" <%= "style='display:none'".html_safe if toggeable %>>
|
||||
<%= form_for [commentable, Comment.new], remote: true do |f| %>
|
||||
<%= form_for Comment.new, remote: true do |f| %>
|
||||
<%= label_tag "comment-body-#{css_id}", t("comments.form.leave_comment") %>
|
||||
<%= f.text_area :body, id: "comment-body-#{css_id}", maxlength: Comment.body_max_length, label: false %>
|
||||
<%= f.hidden_field :commentable_type, value: commentable.class.name %>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<span>
|
||||
<%= t('debates.comment.votes', count: comment.total_votes) %>
|
||||
<%= t('comments.comment.votes', count: comment.total_votes) %>
|
||||
</span>
|
||||
|
|
||||
<span class="in_favor">
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<a class="js-add-tag-link"><%= tag.name %></a>
|
||||
<% end %>
|
||||
</span>
|
||||
<%= f.text_field :tag_list, value: @debate.tag_list.to_s, label: false, placeholder: t("debates.form.tags_placeholder") %>
|
||||
<%= f.text_field :tag_list, value: @debate.tag_list.to_s, label: false, placeholder: t("debates.form.tags_placeholder"), class: 'js-tag-list' %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<% voted_classes = css_classes_for_debate_vote(@debate_votes, debate) %>
|
||||
<% voted_classes = css_classes_for_vote(@debate_votes, debate) %>
|
||||
<div class="votes">
|
||||
<div class="in-favor inline-block">
|
||||
<%= link_to vote_debate_path(debate, value: 'yes'),
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
<section role="main">
|
||||
<% content_for :header_addon do %>
|
||||
<%= render "shared/search_form_header",
|
||||
search_path: debates_path(page: 1),
|
||||
i18n_namespace: "debates.index.search_form" %>
|
||||
<% end %>
|
||||
|
||||
<section role="main">
|
||||
<div class="wrap row">
|
||||
<div id="debates" class="debates-list small-12 medium-9 column js-order-<%= @order.dasherize %>">
|
||||
<div id="debates" class="debates-list small-12 medium-9 column">
|
||||
|
||||
<div class="filters">
|
||||
<div class="small-12 medium-7 left">
|
||||
<% if @search_terms %>
|
||||
@@ -16,39 +22,36 @@
|
||||
</h2>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if @tag_filter || @search_terms %>
|
||||
<div class="small-12 medium-5 margin-top inline-block debates-order">
|
||||
<h6 class="inline-block">
|
||||
<%= t("debates.index.select_order") %>
|
||||
</h6>
|
||||
<%= render 'shared/order_selector', i18n_namespace: "debates.index" %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="small-12 inline-block">
|
||||
<h2 class="inline-block">
|
||||
<%= t("debates.index.select_order_long") %>
|
||||
</h2>
|
||||
<%= render 'shared/order_selector', i18n_namespace: "debates.index" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<form class="inline-block">
|
||||
<select class="js-location-changer" name="order-selector">
|
||||
<% @valid_orders.each do |order| %>
|
||||
<option <%= 'selected' if order == @order %>
|
||||
value='<%= current_path_with_query_params(order: order, page: 1) %>'>
|
||||
<%= t("debates.index.orders.#{order}") %>
|
||||
</option>
|
||||
<% end %>
|
||||
</select>
|
||||
</form>
|
||||
|
||||
<div class="show-for-small-only">
|
||||
<%= link_to t("debates.index.start_debate"), new_debate_path, class: 'button radius expand' %>
|
||||
</div>
|
||||
|
||||
<%= render @debates %>
|
||||
<%= paginate @debates %>
|
||||
</div>
|
||||
<div class="show-for-small-only">
|
||||
<%= link_to t("debates.index.start_debate"), new_debate_path, class: 'button radius expand' %>
|
||||
</div>
|
||||
<%= render @debates %>
|
||||
<%= paginate @debates %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
<aside class="sidebar" role="complementary">
|
||||
<%= link_to t("debates.index.start_debate"), new_debate_path, class: 'button radius expand' %>
|
||||
<%= render "shared/tag_cloud" %>
|
||||
<%= render "shared/tag_cloud", taggable: 'debate' %>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<%= @debate.description %>
|
||||
<%= safe_html_with_links @debate.description %>
|
||||
|
||||
<%= render 'shared/tags', debate: @debate %>
|
||||
|
||||
@@ -81,4 +81,5 @@
|
||||
</div>
|
||||
</section>
|
||||
<% end %>
|
||||
|
||||
<%= render "comments" %>
|
||||
|
||||
@@ -31,10 +31,10 @@
|
||||
|
||||
<div class="row-full subnavigation-container">
|
||||
<section class="subnavigation row">
|
||||
<%#= link_to t("layouts.header.welcome"), root_path %>
|
||||
<%#= link_to t("layouts.header.initiatives"), "#" %>
|
||||
<div class="small-12 medium-8 column">
|
||||
<%= link_to t("layouts.header.highlights"), highlights_path, class: ("active" if current_page? highlights_path) %>
|
||||
<%= link_to t("layouts.header.debates"), debates_path, class: ("active" if current_page?(controller: "/debates")) %>
|
||||
<%= link_to t("layouts.header.proposals"), proposals_path, class: ("active" if current_page?(controller: "/proposals")) %>
|
||||
<%= link_to t("layouts.header.more_information"), "/more_information", class: ("active" if current_page?("/more_information")) %>
|
||||
<%= link_to t("layouts.header.external_link_blog_url"), target: "_blank" do %>
|
||||
<%= t("layouts.header.external_link_blog") %>
|
||||
@@ -42,7 +42,7 @@
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="small-12 medium-4 column right">
|
||||
<%= render "shared/search_form_header" %>
|
||||
<%= yield :header_addon %>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
@@ -51,8 +51,8 @@
|
||||
<div class="row home-page">
|
||||
<div class="small-12 medium-7 column">
|
||||
<h1><%= t("layouts.header.open_city_title") %></h1>
|
||||
<p><%= t("layouts.header.open_city_slogan") %></p>
|
||||
<%= link_to t("layouts.header.see_all_debates"), debates_path, class: "button radius see-more" %>
|
||||
<p><%= t("layouts.header.open_city_slogan_html") %></p>
|
||||
<%= link_to t("layouts.header.see_all"), highlights_path, class: "button radius see-more warning" %>
|
||||
<%= link_to t("layouts.header.more_information"), "/more_information", class: "more-info" %>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<tr>
|
||||
<td style="border-bottom: 1px solid #dadfe1; padding: 20px 0;">
|
||||
<a href="#" target="_blank">
|
||||
<%= image_tag('logo_email_gobierno_abierto.png', style: "border: 0; display: block; width: 100%;max-width: 370px") %>
|
||||
<%= image_tag('logo_email_gobierno_abierto.png', style: "border: 0; display: block; width: 100%;max-width: 370px", alt: "Ayuntamiento de Madrid - Participación ciudadana, transparencia y gobierno abierto") %>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
<%= link_to t("moderation.dashboard.index.title"), moderation_root_path %>
|
||||
</li>
|
||||
|
||||
<li <%= "class=active" if controller_name == "proposals" %>>
|
||||
<%= link_to moderation_proposals_path do %>
|
||||
<i class="icon-proposals"></i>
|
||||
<%= t("moderation.menu.proposals") %>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li <%= "class=active" if controller_name == "debates" %>>
|
||||
<%= link_to moderation_debates_path do %>
|
||||
<i class="icon-debates"></i>
|
||||
|
||||
3
app/views/moderation/proposals/hide.js.erb
Normal file
3
app/views/moderation/proposals/hide.js.erb
Normal file
@@ -0,0 +1,3 @@
|
||||
var proposal_id = '<%= dom_id(@proposal) %>';
|
||||
App.ModeratorProposals.add_class_faded(proposal_id);
|
||||
App.ModeratorProposals.hide_moderator_actions(proposal_id);
|
||||
77
app/views/moderation/proposals/index.html.erb
Normal file
77
app/views/moderation/proposals/index.html.erb
Normal file
@@ -0,0 +1,77 @@
|
||||
<h2><%= t("moderation.proposals.index.title") %></h2>
|
||||
|
||||
<%= render 'shared/filter_subnav', i18n_namespace: "moderation.proposals.index" %>
|
||||
|
||||
<div class="row">
|
||||
<h3 class="small-8 large-8 columns"><%= page_entries_info @proposals %></h3>
|
||||
<div class="small-4 large-4 columns">
|
||||
<div class="right">
|
||||
<%= t("moderation.proposals.index.order") %>
|
||||
<%= render 'shared/order_selector', i18n_namespace: "moderation.proposals.index" %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= form_tag moderate_moderation_proposals_path(request.query_parameters), method: :put do %>
|
||||
<p class="right js-check">
|
||||
<%= t('shared.check') %>:
|
||||
<%= link_to t('shared.check_all'), '#', data: {check_all: "proposal_ids[]"} %>
|
||||
|
|
||||
<%= link_to t('shared.check_none'), '#', data: {check_none: "proposal_ids[]"} %>
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>
|
||||
<%= t("moderation.proposals.index.headers.proposal") %>
|
||||
</th>
|
||||
<th>
|
||||
<%= t("moderation.proposals.index.headers.moderate") %>
|
||||
</th>
|
||||
</tr>
|
||||
<% @proposals.each do |proposal| %>
|
||||
<tr id="proposal_<%= proposal.id %>">
|
||||
<td>
|
||||
<%= link_to proposal.title, proposal, target: "_blank" %>
|
||||
<br>
|
||||
<span class="date"><%= l proposal.updated_at.to_date %></span>
|
||||
<span class="bullet"> • </span>
|
||||
<%= proposal.flags_count %><i class="icon-flag flag-disable"></i>
|
||||
<span class="bullet"> • </span>
|
||||
<%= proposal.author.username %>
|
||||
<br>
|
||||
<div style="height: 4rem; overflow: hidden;">
|
||||
<%= proposal.description %>
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<%= check_box_tag "proposal_ids[]", proposal.id, nil, id: "#{dom_id(proposal)}_check" %>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
|
||||
<%= submit_tag t('moderation.proposals.index.block_authors'),
|
||||
name: "block_authors",
|
||||
class: "button radius alert",
|
||||
data: {confirm: t('moderation.proposals.index.confirm')}
|
||||
%>
|
||||
|
||||
<div class="right">
|
||||
<%= submit_tag t('moderation.proposals.index.hide_proposals'),
|
||||
name: "hide_proposals",
|
||||
class: "button radius alert",
|
||||
data: {confirm: t('moderation.proposals.index.confirm')}
|
||||
%>
|
||||
<%= submit_tag t('moderation.proposals.index.ignore_flags'),
|
||||
name: "ignore_flags",
|
||||
class: "button radius success",
|
||||
data: {confirm: t('moderation.proposals.index.confirm')}
|
||||
%>
|
||||
</div>
|
||||
|
||||
<%= paginate @proposals %>
|
||||
|
||||
<% end %>
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
<div class="page row-full">
|
||||
<div class="row">
|
||||
<div class="menu small-12 medium-3 column">
|
||||
<p><strong>¿Cómo funciona este Portal de Gobierno Abierto?</strong></p>
|
||||
<ul>
|
||||
<i class="icon-angle-left left"></i>
|
||||
<%= link_to t("debates.show.back_link"), "/more_information", class: 'left back' %>
|
||||
<ul class="clear">
|
||||
<li>
|
||||
<a href="#i">I. Participación</a>
|
||||
<ul>
|
||||
<li><a href="#i1">I.1. Espacio de debate</a></li>
|
||||
<li><a href="#i2">I.2. Espacio de propuestas</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -39,6 +41,14 @@
|
||||
<p>Tanto los hilos, como los comentarios podrán ser valorados por cualquiera, de tal manera que será la propia ciudadanía, y nadie en su nombre, la que decida cuáles son los temas más importantes en cada momento. Estos serán presentados en la portada del espacio, pudiendo por supuesto accederse a todos los demás temas en páginas posteriores, o usando otros criterios de ordenación (los temas con más comentarios, los más nuevos, los más controvertidos, etc.).</p>
|
||||
|
||||
<p>Cada uno de los trabajadores del Ayuntamiento tiene un usuario propio, que será resaltado como tal, permitiendo que participen en los debates al mismo nivel que todos los demás ciudadanos. Esto permitirá crear espacios de comunicación directos entre unos y otros, evitando los inconvenientes que implica la comunicación medidada, y respondiendo a un planteamiento claro por parte del nuevo gobierno de Madrid por el cual el Ayuntamiento trabaja para la ciudadanía, y ante ella debe responder.</p>
|
||||
|
||||
<h3 id="i2">I.I. Espacio de propuestas</h3>
|
||||
|
||||
<p>En este espacio, cualquier persona puede proponer una iniciativa con la intención de recabar los suficientes apoyos como para que la idea pase a ser consultada a toda la ciudadanía con caracter vinculante.</p>
|
||||
|
||||
<p>Las propuestas pueden ser apoyadas por ciudadanos empadronados en Madrid que hayan verificado su cuenta en la plataforma de participación, de tal manera que será la propia ciudadanía, y nadie en su nombre, la que decida cuáles son las propuestas que merecen la pena ser llevadas a cabo.</p>
|
||||
|
||||
<p>Una vez que una propuesta alcance una cantidad de apoyos equivalente al 2% del censo de Madrid (unos 53000), automaticamente pasa a ser estudiada por un grupo de trabajo del ayuntamiento y pasará a la siguiente fase de consulta popular, en la que la ciudadanía de Madrid votará si se lleva a cabo o no. El plazo máximo para recabar los apoyos necesarios será de 12 meses.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
<div class="page row-full">
|
||||
<div class="row">
|
||||
<div class="text small-12 column">
|
||||
<h1>Utilízalo en tu municipio</h1>
|
||||
<i class="icon-angle-left left"></i>
|
||||
<%= link_to t("debates.show.back_link"), "/more_information", class: 'left back' %>
|
||||
|
||||
<h1 class="clear">Utilízalo en tu municipio</h1>
|
||||
<p>Utilízalo en tu municipio libremente o ayúdanos a mejorarlo, es software libre.</p>
|
||||
|
||||
<p>Este Portal de Gobierno Abierto usa la <a href="https://github.com/ayuntamientomadrid" target="_blank">aplicación Consul</a> que es software libre, con <a href="http://www.gnu.org/licenses/agpl-3.0.html" target="_blank">licencia AGPLv3</a>, esto significa en palabras sencillas, que cualquiera puede libremente usar el código, copiarlo, verlo en detalle, modificarlo, y redistribuirlo al mundo con las modificaciones que quiera (manteniendo el que otros puedan a su vez hacer lo mismo). Porque creemos que la cultura es mejor y más rica cuando se libera.</p>
|
||||
|
||||
@@ -21,7 +21,27 @@
|
||||
<span>Participación Ciudadana, Transparencia y Gobierno Abierto</span>
|
||||
</li>
|
||||
</a>
|
||||
<a href="/proposals_info">
|
||||
<li>
|
||||
¿Cómo funcionan las propuestas ciudadanas?
|
||||
<span>Crea tus propias propuestas</span>
|
||||
</li>
|
||||
</a>
|
||||
<a href="/participation_world">
|
||||
<li>
|
||||
Participación ciudadana directa en el mundo
|
||||
<span>Sistemas de participación ciudadana que ya existen en el mundo</span>
|
||||
</li>
|
||||
</a>
|
||||
<a href="/participation_facts">
|
||||
<li>
|
||||
Hechos sobre participación ciudadana y democracia directa
|
||||
<span>Para perderle el miedo</span>
|
||||
</li>
|
||||
</a>
|
||||
</ul>
|
||||
|
||||
<p>Si tienes problemas con la web <a href="mailto:web.gobiernoabierto@madrid.es">contacta con el servicio técnico</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,30 +1,32 @@
|
||||
<div class="page row-full">
|
||||
<div class="row">
|
||||
<div class="menu small-12 medium-3 column">
|
||||
<ul>
|
||||
<li>
|
||||
<a href="#i">I. Participación</a>
|
||||
<ul>
|
||||
<li><a href="#i1">I.1. Propuestas ciudadanas</a></li>
|
||||
<li><a href="#i2">I.2. Presupuestos participativos</a></li>
|
||||
<li><a href="#i3">I.3. Legislacion colaborativa</a></li>
|
||||
<li><a href="#i4">I.4. Co-gobierno ciudadano</a></li>
|
||||
<li><a href="#i5">I.5. Participación sectorial</a></li>
|
||||
<li><a href="#i6">I.6. Inclusión, neutralidad y privacidad</a></li>
|
||||
<li><a href="#i7">I.7. Innovación social</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#ii">II. Transparencia</a>
|
||||
<ul>
|
||||
<li><a href="#ii1">II.1. Ordenanza de transparencia</a></li>
|
||||
<li><a href="#ii2">II.2. Portal de transparencia</a></li>
|
||||
<li><a href="#ii3">II.3. Datos abiertos</a></li>
|
||||
<li><a href="#ii4">II.4. Agendas públicas</a></li>
|
||||
<li><a href="#ii5">II.5. Transparencia del Lobby</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<i class="icon-angle-left left"></i>
|
||||
<%= link_to t("debates.show.back_link"), "/more_information", class: 'left back' %>
|
||||
<ul class="clear">
|
||||
<li>
|
||||
<a href="#i">I. Participación</a>
|
||||
<ul>
|
||||
<li><a href="#i1">I.1. Propuestas ciudadanas</a></li>
|
||||
<li><a href="#i2">I.2. Presupuestos participativos</a></li>
|
||||
<li><a href="#i3">I.3. Legislacion colaborativa</a></li>
|
||||
<li><a href="#i4">I.4. Co-gobierno ciudadano</a></li>
|
||||
<li><a href="#i5">I.5. Participación sectorial</a></li>
|
||||
<li><a href="#i6">I.6. Inclusión, neutralidad y privacidad</a></li>
|
||||
<li><a href="#i7">I.7. Innovación social</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#ii">II. Transparencia</a>
|
||||
<ul>
|
||||
<li><a href="#ii1">II.1. Ordenanza de transparencia</a></li>
|
||||
<li><a href="#ii2">II.2. Portal de transparencia</a></li>
|
||||
<li><a href="#ii3">II.3. Datos abiertos</a></li>
|
||||
<li><a href="#ii4">II.4. Agendas públicas</a></li>
|
||||
<li><a href="#ii5">II.5. Transparencia del Lobby</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="text small-12 medium-9 column">
|
||||
<h1>Participación y Transparencia en Madrid - Próximas novedades</h1>
|
||||
|
||||
33
app/views/pages/participation_facts.html.erb
Normal file
33
app/views/pages/participation_facts.html.erb
Normal file
@@ -0,0 +1,33 @@
|
||||
<div class="page row-full">
|
||||
<div class="row">
|
||||
<div class="text small-12 medium-10 column small-centered">
|
||||
<i class="icon-angle-left left"></i>
|
||||
<%= link_to t("debates.show.back_link"), "/more_information", class: 'left back' %>
|
||||
|
||||
<h1 class="clear">Hechos sobre participación ciudadana y democracia directa</h1>
|
||||
<br>
|
||||
<h2>La democracia directa produce gente más informada y con más cultura política.</h2>
|
||||
<p>El poner en marcha mecanismos de participación reales hace que la gente se preocupe por las decisiones que tiene que tomar, y que por lo tanto se informe sobre ellas. Esto se observa sistemáticamente al comparar diferentes regiones de un mismo país con diferentes grados de democracia directa, o en procesos particulares como por ejemplo la votación del Tratado por una Constitución para Europa, comparando los países que lo votaron en referéndum y los que no.</p>
|
||||
<p>En ocasiones se argumenta que no se deben crear mecanismos de decisión ciudadana, porque un posible bajo nivel cultural o de conocimiento político haría que se tomaran malas decisiones. Esto se ha argumentado tradicionalmente en contra del voto femenino, del voto inmigrante, del voto de la gente sin renta, etc. pero lo que se ha demostrado es que permitir a toda esa gente decidir ha sido precisamente lo que ha permitido que escaparan de su situación de desigualdad cultural y de derechos, o al menos que la mejoraran considerablemente.</p>
|
||||
<p><em>M. Benz / A. Stutzer (2004), «Are voters better informed when they have a larger say in politics?», Public Choice 119, p. 31-59</em></p>
|
||||
|
||||
<h2>La democracia directa es más efectiva para tomar decisiones que la representativa. Por ejemplo genera menos deuda.</h2>
|
||||
<p>Los proyectos disparatados y los gastos desmesurados suelen venir por parte de políticos electos en lugar de por procesos de participación ciudadana. Los estados de Estados Unidos con sistemas de iniciativas populares efectivos generan un 7% menos de deuda que los que no los tienen, y las regiones en Suiza con referéndum obligatorios para gastos públicos importantes gastan un 19% menos que los demás.</p>
|
||||
<p><em>R.K. von Weizsäcker (1992), «Staatsverschuldung und Demokratie», Kyklos 45, p. 51-67</em></p>
|
||||
<p><em>L.P. Feld / J.G. Matsusaka (2003), »Budget referendums and government spending: evidence from Swiss cantons», Journal of Public Economics 87, p. 2703-2724</em></p>
|
||||
<p><em>J. G. Matsusaka (2004), «For the Many or the Few. The Initiative, Public Policy, and American Democracy» University of Chicago Press</em></p>
|
||||
|
||||
<h2>La democracia directa protege mejor los derechos humanos y los de las minorías que la representativa</h2>
|
||||
<p>Estudios de todos los referéndum suizos durante treinta años muestran que los referéndum cuando tratan sobre aumentar los derechos de las minorías se aprueban aproximadamente un 25% más que los que tratan de temas generales. En concreto, el 80% de los referéndum de este tipo a nivel federal fueron aprobados.</p>
|
||||
<p>Decisiones como eliminar el derecho a la vivienda de manera efectiva, el derecho de sanidad para las personas migrantes, o el iniciar guerras contra otros países, suelen darse a través de gobiernos representativos, y no en referéndum ciudadanos.</p>
|
||||
<p><em>B.S. Frey / M. Goette (1998), «Does the popular vote destroy civil rights?», American Journal of Political Science 42, p. 1343-1348</em></p>
|
||||
|
||||
<h2>En cualquier caso, la democracia directa no sustituye ni amenaza a la democracia representativa, la complementa. Y soluciona algunos problemas que no consigue la otra.</h2>
|
||||
<p>El año que más iniciativas ciudadanas se votaron en los diferentes estados con democracia directa de Estados Unidos, estas decisiones sólo representaron el 0,6% de todas las decisiones que tomaron los políticos en esos estados.</p>
|
||||
<p>Las decisiones directas de la ciudadanía no sustituyen en ningún lugar del mundo el sistema político representativo, sólo lo amplían y mejoran. Tampoco pretenden ser la solución a todos los problemas, también se toman decisiones equivocadas a través de las decisiones ciudadanas, pero se reduce el número de las decisiones erróneas que se toman teniendo sólo un sistema representativo.</p>
|
||||
<p><em>M.D. Waters (2002), «Initiative and referendum in the United States: a primer», Washington: Citizen Lawmaker Press</em></p>
|
||||
|
||||
<h2>Si los ciudadanos son capaces de elegir entre políticos que toman decisiones buenas o malas para el país, deben ser capaces de elegir directamente entre buenas y malas decisiones.</h2>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
50
app/views/pages/participation_world.html.erb
Normal file
50
app/views/pages/participation_world.html.erb
Normal file
@@ -0,0 +1,50 @@
|
||||
<div class="page row-full">
|
||||
<div class="row">
|
||||
<div class="menu small-12 medium-3 column">
|
||||
<i class="icon-angle-left left"></i>
|
||||
<%= link_to t("debates.show.back_link"), "/more_information", class: 'left back' %>
|
||||
<ul class="clear">
|
||||
<li>
|
||||
<a href="#i">La nueva ola global de participación ciudadana</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#ii">Participación ciudadana directa con experiencia</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="text small-12 medium-9 column">
|
||||
<h1>Participación ciudadana directa en el mundo</h1>
|
||||
<p>En el mundo existen sistemas de participación ciudadana muy similares al que vamos a implementar en Madrid, que llevan funcionando desde hace más de cien años y en países muy diferentes. La experiencia larga y variada de dichos sistemas demuestra que lo que ponemos en marcha en Madrid tendrá un impacto muy positivo en la sociedad, como ha tenido en esos otros países.</p>
|
||||
|
||||
<p>Además de los ejemplos clásicos, como Suiza, asistimos a un desarrollo muy fuerte de los sistemas de participación ciudadana en todo el mundo, en particular en los últimos años, gracias especialmente a las nuevas posibilidades que nos brinda Internet. Islandia, Finlandia, Brasil, Estados Unidos, son algunos de los países que más están apostando por una participación directa de la ciudadanía en la toma de decisiones.</p>
|
||||
|
||||
<h2 id="i">La nueva ola global de participación ciudadana</h2>
|
||||
|
||||
<p>Las nuevas formas de participación se están dirigiendo principalmente a que sean la ciudadanía quien decida qué caminos debe tomar la política de su país, a través de mecanismos de <strong>iniciativas ciudadanas</strong>. Finlandia es uno de los países donde se están desarrollando nuevas herramientas similares al nuevo portal de gobierno abierto de Madrid. Su plataforma <a href="http://openministry.info/" target="_blank">Open Ministry</a> permite a la población presentar y apoyar propuestas, y ha conseguido por ejemplo que se apruebe gracias a él la ley de matrimonio igualitario. Islandia también ha tenido una gran repercusión desde 2011, cuando lanzaron su plataforma Better Reykjavik, que ha permitido que el 58% de la población participe en el proceso de propuestas, seleccionando cada mes las 15 ideas más votadas.</p>
|
||||
|
||||
<p>Estonia es uno de los países que gracias a una apuesta clara por las nuevas tecnologías, ha podido situarse en cabeza de Europa en el nivel de uso por parte de la ciudadanía de Internet para la interacción con el gobierno. No sólo los ciudadanos y ciudadanas resuelven diariamente todos sus trámites a través de Internet, sino que han puesto en marcha plataformas como Rahvakogu, donde después de los escándalos políticos de 2012, 50.000 personas (de un total de 1.3 millones) participaron proponiendo medidas para mejorar la situación democrática del país.</p>
|
||||
|
||||
<p>Otra de las principales experiencias que se están extendiendo rápidamente por todo el mundo son los <strong>presupuestos participativos</strong>. Estos consisten en mecanismos, generalmente acompañados de una plataforma en Internet, por los cuales el gobierno reserva parte de sus presupuestos de inversión (los que no están comprometidos ya en cuestiones como limpieza o servicios sociales), para que sea la ciudadanía quien decida en qué se gasta dicho dinero.</p>
|
||||
|
||||
<p>Islandia es uno de los países de referencia al respecto, a través de su plataforma Betri Reykjavík-Betri Hverfi (Better District). Cada año se gastan 1.8 millones de euros en alrededor de 200 proyectos propuestos por la población para los distintos barrios de Reykjavík. Las ciudadanas y ciudadanos pueden participar y seguir el proyecto a través de la plataforma digital <a href="http://www.betrireykjavik.is" target="_blank">betrireykjavik</a>, en <a href="http://www.facebook.com/Betri.Reykjavik" target="_blank">Facebook</a> o a través de centros en sus distritos o comités distritales.</p>
|
||||
|
||||
<p>Otras experiencias de referencia incluyen París, donde los residentes decidirán hasta el 2020 cómo se gastan 426 millones de euros (lo que corresponde al 5% del presupuesto municipal de París); Nueva York, donde el año pasado dedicaron <a href="http://council.nyc.gov/html/action/pb.shtml" target="_blank">32 millones de euros a presupuestos participativos</a>; más de 100 ciudades brasileñas donde se han manejado <a href="http://www.washingtonpost.com/blogs/monkey-cage/wp/2014/01/22/brazil-let-its-citizens-make-decisions-about-city-budgets-heres-what-happened/" target="_blank">presupuestos participativos que han oscilado entre el 5% y el 15%</a>; entre muchas otras ciudades del mundo.</p>
|
||||
|
||||
<h2 id="ii">Participación ciudadana directa con experiencia</h2>
|
||||
|
||||
<p>En diferentes países del mundo existen sistemas de participación ciudadana directa que vienen funcionando desde hace mucho tiempo sin pasar por las nuevas tecnologías. Aunque estos sistemas no tengan la agilidad de las nuevas plataformas, los procesos que se dan en ellos son básicamente los mismos, y nos aseguran la calidad y los resultados de los mecanismos que se van a poner en marcha. Comentamos a continuación tres de los casos más importantes y resaltamos algunas cifras para entender de lo que hablamos:</p>
|
||||
|
||||
<h3>Suiza</h3>
|
||||
<p>Desde 1848 se han votado unos 600 referéndum a nivel federal (<a href="https://www.admin.ch/ch/f/pore/va/vab_2_2_4_1_gesamt.html" target="_blank">compilación en francés</a>), y se celebran cada año en todo el país del orden de 200 referéndum a todos los niveles (municipal, cantonal y federal).</p>
|
||||
<p>Aproximadamente una de cada dos leyes aprobadas en el Parlamento directamente, y luego consultada a la ciudadanía, fue anulada. Por otro lado, incluso aunque las iniciativas populares no tengan éxito, el gobierno acaba concediendo parte de las demandas propuestas, y se genera una atención nacional sobre el asunto tratado. Esto hace que aproximadamente la mitad de la gente que lanzó las iniciativas que no tuvieron éxito consideren que mereció la pena el esfuerzo y se obtuvo algo que no hubiera sido posible sin la iniciativa.</p>
|
||||
|
||||
<h3>Estados Unidos</h3>
|
||||
<p>En este país no se cuenta con procesos de iniciativas ciudadanas a nivel federal, pero 27 de los 51 estados cuentan con algún tipo sistema de democracia directa (cambiando mucho la regulación y el alcance de un estado a otro). A nivel local, aproximadamente la mitad de las ciudades cuentan con un sistema de iniciativas ciudadanas vinculantes.</p>
|
||||
<p>Entre 1904 y 2000 se convocaron casi 2.000 referéndum iniciados por la ciudadanía. En 1996 en los estados con mecanismos de iniciativas ciudadanas se convocaron 96 referéndum, frente a las más de 14.000 leyes y resoluciones aprobadas por los representantes de esos estados.</p>
|
||||
|
||||
<h3>Alemania</h3>
|
||||
<p>No existe en Alemania ningún mecanismo de democracia directa a nivel nacional, pero sí a nivel regional y local. Estos sistemas se introdujeron en su mayoría en los años 90. En 1996 el número de iniciativas ciudadanas fue de 318, reduciéndose en años posteriores, una vez tratados tantos temas pendientes anteriores a la introducción de estos mecanismos, a una media de 100 por año.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
105
app/views/pages/proposals_info.html.erb
Normal file
105
app/views/pages/proposals_info.html.erb
Normal file
@@ -0,0 +1,105 @@
|
||||
<div class="page row-full">
|
||||
<div class="row">
|
||||
<div class="menu small-12 medium-3 column">
|
||||
<i class="icon-angle-left left"></i>
|
||||
<%= link_to t("debates.show.back_link"), "/more_information", class: 'left back' %>
|
||||
<ul class="clear">
|
||||
<li>
|
||||
<a href="#i">Explicación detallada del proceso</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#ii">Preguntas Frecuentes</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#iii">Hojas de firmas para recoger apoyos</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="text small-12 medium-9 column">
|
||||
<h1>¿Cómo funcionan las propuestas ciudadanas?</h1>
|
||||
<p>El mecanismo de propuestas ciudadanas se resume en cuatro pasos muy sencillos:</p>
|
||||
<ol>
|
||||
<li><strong>¡Propones!</strong> Creas una propuesta en esta web.</li>
|
||||
<li><strong>¡Apoyas!</strong> La gente hace click en el botón de apoyar tu propuesta (necesitas el apoyo del 2% de los empadronados mayores de 16 años para pasar a la siguiente fase).</li>
|
||||
<li><strong>¡Decides!</strong> Si has conseguido suficientes apoyos, dejamos 45 días para que la gente pueda debatir sobre la propuesta, y después durante una semana se invita a toda la gente de Madrid a decidir si están a favor o en contra de tu propuesta, en esta misma web.</li>
|
||||
<li><strong>¡Se hace!</strong> Si hay más gente a favor de tu propuesta que en contra, el gobierno del Ayuntamiento de Madrid asumirá como propia la propuesta y la llevará a cabo.</li>
|
||||
</ol>
|
||||
|
||||
<p>Además no hace falta ni que tengas Internet, todos los pasos se pueden hacer en cualquiera de las 26 Oficinas de Atención al Ciudadano que hay por todo Madrid.</p>
|
||||
|
||||
<h2 id="i">Explicación detallada del proceso</h2>
|
||||
|
||||
<ol>
|
||||
<li><strong>Creación de una propuesta</strong>. Cualquier persona (sin necesidad siquiera de estar empadronada en Madrid) puede crear una propuesta. Lo único que hay que hacer es pulsar el botón “Crear una propuesta” y rellenar los campos requeridos. La propuesta puede ser tan sencilla como una simple frase, pero te recomendamos detallarla todo lo posible, incluso añadiendo material adicional, para que sea más completa e interesante. Una vez creada aparecerá en esta web para que cualquiera pueda apoyarla.</li>
|
||||
<li><strong>Apoyo de propuestas</strong>. Para apoyar una de las propuestas que aparece en la web, pulsamos el botón “apoyar esta propuesta” que aparece en cada una. Para este paso tendremos que estar empadronados en Madrid, así que al llevarlo a cabo por primera vez se nos pedirá que verifiquemos nuestra cuenta para estar seguros de este requerimiento. Se nos va a pedir que introduzcamos algunos datos para comprobar nuestra información de empadronamiento, y se nos enviará un código personal para que el proceso sea seguro. Las propuestas necesitan una cierta cantidad de apoyos para pasar a la siguiente fase; concretamente el 2% de los empadronados mayores de 16 años (que suponen 53.726 apoyos).</li>
|
||||
<li><strong>Decisión sobre propuestas</strong>. Cuando una propuesta consigue los apoyos necesarios, se anuncia en la web. Desde ese momento se dejan 45 días para que todo el mundo pueda debatir e informarse sobre la propuesta. Todas las otras propuestas que hayan conseguido los apoyos necesarios en los primeros 30 días del tiempo de debate se agruparán junto a la primera para decidir sobre ellas al mismo tiempo. Pasados los 45 días se exponen estas propuestas en un espacio especial de votación de la web, donde durante una semana cualquier persona empadronada en Madrid y mayor de 16 años podrá decidir si está a favor o rechaza la propuesta. Para participar en este paso tendrás que tener tu cuenta de usuario verificada completamente, de tal forma que nos aseguremos que cada persona no tiene más de una cuenta y el proceso es seguro.</li>
|
||||
<li><strong>Realización de las propuestas</strong>. En caso de que haya más gente a favor de una propuesta que rechazándola se aceptará como propuesta colectiva de la ciudadanía de Madrid, y el gobierno del Ayuntamiento de Madrid la asumirá como propia y la llevará a cabo. Para ello en un plazo máximo de un mes, se realizarán los informes técnicos correspondientes sobre su legalidad, viabilidad y coste económico, teniendo en cuenta a los sectores afectados y a la persona que haya lanzado la propuesta, para detallar la actuación correspondiente por parte del Ayuntamiento. Se publicarán en la web todos los informes realizados, y un seguimiento de las actuaciones que se lleven a cabo, para asegurar un correcto desarrollo de la propuesta.</li>
|
||||
</ol>
|
||||
|
||||
<p>Todas las acciones relacionadas con el proceso de propuestas ciudadanas pueden realizarse a través del portal de gobierno abierto, o presencialmente en cualquiera de las 26 Oficinas de Atención al Ciudadano existentes en Madrid. <a href="http://www.madrid.es/portales/munimadrid/es/Inicio/El-Ayuntamiento/Atencion-al-ciudadano/Oficinas-de-Atencion-al-Ciudadano?vgnextfmt=default&vgnextchannel=5b99cde2e09a4310VgnVCM1000000b205a0aRCRD" target="_blank">Ver la lista completa de oficinas y su ubicación</a>.</p>
|
||||
|
||||
<p>El proceso de recogida de apoyos de una propuesta puede realizarse también a través de hojas de firmas, cuyo modelo puede ser <a href="/docs/formulario_propuestas_ciudadanas.pdf" target="_blank">descargado en este enlace</a>. Los apoyos recogidos de esta manera se sumarán a los apoyos ya existentes en el portal de gobierno abierto. Las hojas pueden ser entregadas en cualquiera de los Registros del Ayuntamiento, presentes en cada una de las Juntas de Distrito. <a href="http://www.madrid.es/portales/munimadrid/es/Inicio/Ayuntamiento/Oposiciones-y-Empleo/Direcciones-y-telefonos/Oficinas-de-Registro-del-Ayuntamiento-de-Madrid?vgnextfmt=default&vgnextoid=adedb88db777f010VgnVCM2000000c205a0aRCRD&vgnextchannel=ddc3ca1c5a057010VgnVCM100000dc0ca8c0RCRD" target="_blank">Ver la lista completa de Oficinas de Registro</a>.</p>
|
||||
|
||||
|
||||
<h2 id="ii">Preguntas Frecuentes</h2>
|
||||
<ol>
|
||||
<li><strong>¿Cuáles son los requisitos que se solicitan para poder apoyar o votar propuestas?</strong><br>
|
||||
Estar empadronado en Madrid y ser mayor de 16 años. En caso de que se haga a través de Internet se requerirá que se haya verificado la cuenta de usuario de la web (encontramos el botón de verificación en el apartado “Mi cuenta” en la esquina superior derecha), proporcionando la información del padrón, y un medio de comunicación para obtener un código seguro de participación que introduciremos en la web para validar nuestra cuenta.
|
||||
</li>
|
||||
|
||||
<li><strong>¿Cómo va a controlarse que cada persona vote una única vez por propuesta?</strong><br>
|
||||
Las votaciones presenciales en las Oficinas de Atención al Ciudadano están controladas porque la persona tiene que presentar su DNI. Para la votación a través de Internet se verifica que la cuenta de usuario corresponde a un único ciudadano/a. Para ello se le facilita un código personal seguro de verificación de la cuenta que se comunica a través de canales de comunicación privados, como son teléfonos móviles que constan en el Ayuntamiento que pertenecen a la persona adecuada, o por correo a través del buzón que figura en la dirección de empadronamiento. De esta forma nos aseguramos de que sólo esa persona ha recibido el código. En caso de que dichos medios de comunicación no estén disponibles se solicitará a la persona que acuda presencialmente a alguna de las Oficinas de Atención al Ciudadano, para obtener su código.
|
||||
</li>
|
||||
|
||||
<li><strong>¿Se llevará a cabo cualquier propuesta que se acepte por mayoría en la web? ¿incluso aunque sean ilegales o atenten contra los derechos humanos? ¿y si no hay presupuesto para llevarla a cabo?</strong><br>
|
||||
Se establecen una serie de criterios objetivos por los que una propuesta no podrá ser aceptada como, por ejemplo, que tenga fines delictivos o que atente contra derechos fundamentales y libertades públicas. Además se excluyen del proceso las propuestas sobre otras modalidades de participación tales como presupuestos participativos, procesos revocatorios, audiencia pública o iniciativas normativas populares.
|
||||
<br>Este mecanismo de participación no cambia los límites ya existentes para el Ayuntamiento, lo que hace es trasladar quién toma la decisión de lo que haya que hacer, incluyendo a toda la ciudadanía en el proceso de toma de decisiones.
|
||||
<br>En el caso de las propuestas que quedan fuera de las competencias municipales el Ayuntamiento no podrá llevarlas a cabo, pero emprenderá actuaciones alternativas dentro de sus capacidades que intenten cumplir con la decisión de la propuesta. Lo mismo sucede con el presupuesto para llevar a cabo la propuesta; el ayuntamiento utilizará los recursos necesarios en cuanto sea posible, de la misma manera que se costean las decisiones adoptadas sin participación ciudadana.
|
||||
<br>También puede ocurrir que la actuación requiera la aprobación del Pleno, por lo que el resultado dependerá del posicionamiento de todas las fuerzas políticas respecto a la actuación presentada.</li>
|
||||
|
||||
<li><strong>¿Qué diferencia existe entre los debates y las propuestas?</strong><br>
|
||||
Aunque ambos pueden ser apoyados, los primeros no activan ningún mecanismo de actuación concreto, mientras que las segundas pasan a una fase de decisión colectiva y en caso de que sean aprobadas, son asumidas por el Ayuntamiento.</li>
|
||||
|
||||
<li><strong>¿Vota toda la gente de Madrid en cada propuesta? ¿incluso aunque haga referencia a un único distrito?</strong><br>
|
||||
Sí. El mecanismo actual se desarrolla a nivel de toda la ciudad. Lo que no entra en colisión con que a nivel distrital se puedan desarrollar mecanismos de participación ciudadana que afecten únicamente a cada distrito.</li>
|
||||
|
||||
<li><strong>¿Y si se presentan varias propuestas iguales? ¿Se plantea la posibilidad de unificarlas para evitar que se diversifiquen los apoyos y/o votos?</strong><br>
|
||||
Propuestas similares pueden ser marcadas como tales en la plataforma, lo que se señala al visualizar cada una de ellas. Más allá de eso no se unifican, dejando que sea la gente la que decida si apoyar a una o a otra.</li>
|
||||
|
||||
<li><strong>¿Durante cuanto tiempo se pueden recoger apoyos?</strong><br>
|
||||
Las propuestas pueden recoger apoyos durante 12 meses. Si en ese tiempo no consiguen alcanzar el 2% de los apoyos necesarios dejan de poder recibir más apoyos.</li>
|
||||
|
||||
<li><strong>¿Durante cuanto tiempo se votará cada propuesta?</strong><br>
|
||||
Una vez que las propuestas reciben el apoyo del 2% pasan a la fase de decisión final donde la gente puede votar aceptando o rechazando la propuesta durante un plazo de una semana.</li>
|
||||
|
||||
<li><strong>¿Pueden participar asociaciones, fundaciones y ONG´s? ¿Y empresas?</strong><br>
|
||||
Las propuestas tienen que ser presentadas individualmente, sin problema de que la persona que la presenta represente a una organización de cualquier tipo. Al registrar una propuesta en la web existe la posibilidad de señalar este caso como registro de asociaciones/colectivos.</li>
|
||||
|
||||
<li><strong>¿Cuánta gente tiene que votar una propuesta para que sea aprobada? ¿Qué quórum mínimo se necesita para que las votaciones sean vinculantes?</strong><br>
|
||||
El quórum es el mínimo de participación necesaria para considerar una votación vinculante de manera legal. Ningún reglamento del Ayuntamiento puede hacer que este mecanismo sea vinculante juridicamente, porque eso está en contra de la legislación española. La vinculación con el mecanismo es política y se asume de manera personal por los concejales y la Alcaldesa. Por ello no se considerará ningún quórum.</li>
|
||||
|
||||
<li><strong>¿Existen mecanismos presenciales para participar? ¿Se ha planteado llegar a los ciudadanos y ciudadanas con dificultades de acceso a Internet o en situación de exclusión?</strong><br>
|
||||
Todas las acciones relacionadas con el proceso de propuestas ciudadanas pueden realizarse presencialmente en cualquiera de las <a href="http://www.madrid.es/portales/munimadrid/es/Inicio/El-Ayuntamiento/Atencion-al-ciudadano/Oficinas-de-Atencion-al-Ciudadano?vgnextfmt=default&vgnextchannel=5b99cde2e09a4310VgnVCM1000000b205a0aRCRD" target="_blank">26 Oficinas de Atención al Ciudadano</a> repartidas por todos los distritos de Madrid. Además, el proceso de recogida de apoyos de una propuesta puede realizarse también a través de hojas de firmas, cuyo modelo puede ser <a href="/docs/formulario_propuestas_ciudadanas.pdf" target="_blank">descargado en este enlace</a>.
|
||||
<br>Adicionalmente se ha creado en el Área de Gobierno de Participación Ciudadana, Transparencia y Gobierno Abierto el Servicio de Inclusión, Neutralidad y Privacidad que pondrá en marcha una mesa de inclusión con personal del Ayuntamiento y asociaciones que trabajan con colectivos en situación de exclusión, para diseñar mecanismos especiales para que puedan participar dichos colectivos.</li>
|
||||
|
||||
<li><strong>¿Cómo puede participar la gente que no esté empadronada en Madrid?</strong><br>
|
||||
Presentando propuestas, participando en los debates, y difundiendo lo que ocurra en la plataforma.</li>
|
||||
|
||||
<li><strong>¿El voto es secreto? ¿el Ayuntamiento podrá tener acceso a los votos de los ciudadanos?</strong><br>
|
||||
El voto es totalmente secreto. Se encripta de manera conjunta con diferentes autoridades externas al Ayuntamiento, de tal manera que para poder conocer la identidad de un votante todas las autoridades tendrían que realizar fraude conjuntamente.</li>
|
||||
|
||||
<li><strong>¿Al ser electrónico el voto no se aumenta el riesgo de fraude?</strong>
|
||||
No, incluso lo reducimos. Hay una sensación subjetiva muy fuerte de diferencia de seguridad entre procesos en papel y procesos electrónicos que no se corresponde con la realidad. En las elecciones generales donde el voto es en papel, después de que las mesas hayan hecho el recuento, las papeletas de los votos se tiran a la basura, y la persona responsable se dirige en persona con el recuento en la mano al centro donde se comparten los datos. Y sin embargo pensemos por ejemplo en el sistema de tarjetas de crédito y cuentas bancarias, donde cada día confiamos la seguridad de nuestro dinero a un sistema electrónico. En el caso del Ayuntamiento, la votación está asegurada mediante diferentes entidades externas, y además cualquier votante puede tanto comprobar que su voto particular está en el recuento final, como realizar el recuento completo de todos los votos por su cuenta. Dos garantías de seguridad completamente imposibles en un votación tradicional.</li>
|
||||
|
||||
<li><strong>¿Cómo se sabe que una propuesta se ha cumplido?</strong><br>
|
||||
Cuando se aprueba una propuesta, el Ayuntamiento publica en la página web cuáles son los pasos que se van a realizar para ponerla en práctica, incluyendo los informes que las correspondientes áreas redacten y las acciones que se emprenden. La información es completa y transparente para que puedas hacer un seguimiento de cómo evoluciona cada propuesta ciudadana.</li>
|
||||
|
||||
<h2 id="iii">Hojas de firmas para recoger apoyos</h2>
|
||||
|
||||
<p>El proceso de recogida de apoyos de una propuesta, además de en la web, puede realizarse a través de hojas de firmas, cuyo modelo puede ser <a href="/docs/formulario_propuestas_ciudadanas.pdf" target="_blank">descargado en este enlace</a>.</p>
|
||||
<p>La hoja debe contener en las casillas superiores el código de la propuesta y su título, según figura en la página web específica de la propuesta, dentro del Portal de Gobierno Abierto.</p>
|
||||
<p>Los apoyos recogidos de esta manera se sumarán a los apoyos ya existentes en el portal de gobierno abierto. Las hojas pueden ser entregadas en cualquiera de los Registros del Ayuntamiento, presentes en cada una de las Juntas de Distrito. <a href="http://www.madrid.es/portales/munimadrid/es/Inicio/Ayuntamiento/Oposiciones-y-Empleo/Direcciones-y-telefonos/Oficinas-de-Registro-del-Ayuntamiento-de-Madrid?vgnextfmt=default&vgnextoid=adedb88db777f010VgnVCM2000000c205a0aRCRD&vgnextchannel=ddc3ca1c5a057010VgnVCM100000dc0ca8c0RCRD" target="_blank">Ver la lista completa de Oficinas de Registro</a>.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
10
app/views/proposals/_actions.html.erb
Normal file
10
app/views/proposals/_actions.html.erb
Normal file
@@ -0,0 +1,10 @@
|
||||
<% if can? :hide, proposal %>
|
||||
<%= link_to t("admin.actions.hide").capitalize, hide_moderation_proposal_path(proposal),
|
||||
method: :put, remote: true, data: { confirm: t('admin.actions.confirm') } %>
|
||||
<% end %>
|
||||
|
||||
<% if can? :hide, proposal.author %>
|
||||
|
|
||||
<%= link_to t("admin.actions.hide_author").capitalize, hide_moderation_user_path(proposal.author_id),
|
||||
method: :put, data: { confirm: t('admin.actions.confirm') } %>
|
||||
<% end %>
|
||||
29
app/views/proposals/_comments.html.erb
Normal file
29
app/views/proposals/_comments.html.erb
Normal file
@@ -0,0 +1,29 @@
|
||||
<% cache [locale_and_user_status, commentable_cache_key(@proposal), @all_visible_comments, @all_visible_comments.map(&:author), @proposal.comments_count, @comment_flags] do %>
|
||||
<section class="row-full comments">
|
||||
<div class="row">
|
||||
<div id="comments" class="small-12 column">
|
||||
<h2>
|
||||
<%= t("proposals.show.comments_title") %>
|
||||
<span>(<%= @proposal.comments_count %>)</span>
|
||||
</h2>
|
||||
|
||||
<% if user_signed_in? %>
|
||||
<%= render 'comments/form', {commentable: @proposal, parent_id: nil, toggeable: false} %>
|
||||
<% else %>
|
||||
<br>
|
||||
|
||||
<div class="alert-box radius info">
|
||||
<%= t("proposals.show.login_to_comment",
|
||||
signin: link_to(t("votes.signin"), new_user_session_path),
|
||||
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<% @root_comments.each do |comment| %>
|
||||
<%= render 'comments/comment', comment: comment %>
|
||||
<% end %>
|
||||
<%= paginate @root_comments %>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<% end %>
|
||||
23
app/views/proposals/_flag_actions.html.erb
Normal file
23
app/views/proposals/_flag_actions.html.erb
Normal file
@@ -0,0 +1,23 @@
|
||||
<span class="flag-content">
|
||||
<% if show_flag_action? proposal %>
|
||||
<a id="flag-expand-proposal-<%= proposal.id %>" data-dropdown="flag-drop-proposal-<%= proposal.id %>" aria-controls="flag-drop-proposal-<%= proposal.id %>" aria-expanded="false" title="<%= t('shared.flag') %>">
|
||||
<i class="icon-flag flag-disable"></i>
|
||||
</a>
|
||||
<ul id="flag-drop-proposal-<%= proposal.id %>" class="f-dropdown" data-dropdown-content aria-hidden="true" tabindex="-1">
|
||||
<li>
|
||||
<%= link_to t('shared.flag'), flag_proposal_path(proposal), method: :put, remote: true, id: "flag-proposal-#{ proposal.id }" %>
|
||||
</li>
|
||||
</ul>
|
||||
<% end %>
|
||||
|
||||
<% if show_unflag_action? proposal %>
|
||||
<a id="unflag-expand-proposal-<%= proposal.id %>" data-dropdown="unflag-drop-proposal-<%= proposal.id %>" aria-controls="unflag-drop-proposal-<%= proposal.id %>" aria-expanded="false" title="<%= t('shared.unflag') %>">
|
||||
<i class="icon-flag flag-active"></i>
|
||||
</a>
|
||||
<ul id="unflag-drop-proposal-<%= proposal.id %>" class="f-dropdown" data-dropdown-content aria-hidden="true" tabindex="-1">
|
||||
<li>
|
||||
<%= link_to t('shared.unflag'), unflag_proposal_path(proposal), method: :put, remote: true, id: "unflag-proposal-#{ proposal.id }" %>
|
||||
</li>
|
||||
</ul>
|
||||
<% end %>
|
||||
</span>
|
||||
84
app/views/proposals/_form.html.erb
Normal file
84
app/views/proposals/_form.html.erb
Normal file
@@ -0,0 +1,84 @@
|
||||
<%= form_for(@proposal) do |f| %>
|
||||
<%= render 'shared/errors', resource: @proposal %>
|
||||
|
||||
<div class="row">
|
||||
<div class="small-12 column">
|
||||
<%= f.label :title, t("proposals.form.proposal_title") %>
|
||||
<%= f.text_field :title, maxlength: Proposal.title_max_length, placeholder: t("proposals.form.proposal_title"), label: false %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.label :question, t("proposals.form.proposal_question") %>
|
||||
<span class="note-marked">
|
||||
<%= t("proposals.form.proposal_question_example_html") %>
|
||||
</span>
|
||||
<%= f.text_field :question, maxlength: Proposal.question_max_length, placeholder: t("proposals.form.proposal_question"), label: false %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.label :summary, t("proposals.form.proposal_summary") %>
|
||||
<span class="note"><%= t("proposals.form.proposal_summary_note") %></span>
|
||||
<%= f.text_area :summary, rows: 4, maxlength: 200, label: false,
|
||||
placeholder: t('proposals.form.proposal_summary') %>
|
||||
</div>
|
||||
|
||||
<div class="ckeditor small-12 column">
|
||||
<%= f.label :description, t("proposals.form.proposal_text") %>
|
||||
<%= f.cktext_area :description, maxlength: Proposal.description_max_length, ckeditor: { language: I18n.locale }, label: false %>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.label :video_url, t("proposals.form.proposal_video_url") %>
|
||||
<span class="note"><%= t("proposals.form.proposal_video_url_note") %></span>
|
||||
<%= f.text_field :video_url, placeholder: t("proposals.form.proposal_video_url"), label: false %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.label :external_url, t("proposals.form.proposal_external_url") %>
|
||||
<%= f.text_field :external_url, placeholder: t("proposals.form.proposal_external_url"), label: false %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.label :tag_list, t("proposals.form.tags_label") %>
|
||||
<span class="note"><%= t("proposals.form.tags_instructions") %></span>
|
||||
<span class="tags">
|
||||
<% @featured_tags.each do |tag| %>
|
||||
<a class="js-add-tag-link"><%= tag.name %></a>
|
||||
<% end %>
|
||||
</span>
|
||||
<%= f.text_field :tag_list, value: @proposal.tag_list.to_s, label: false, placeholder: t("proposals.form.tags_placeholder"), class: 'js-tag-list' %>
|
||||
</div>
|
||||
|
||||
<% if current_user.unverified? %>
|
||||
<div class="small-12 column">
|
||||
<%= f.label :responsible_name, t("proposals.form.proposal_responsible_name") %>
|
||||
<span class="note"><%= t("proposals.form.proposal_responsible_name_note") %></span>
|
||||
<%= f.text_field :responsible_name, placeholder: t("proposals.form.proposal_responsible_name"), label: false %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="small-12 column">
|
||||
<% if @proposal.new_record? %>
|
||||
<%= f.label :terms_of_service do %>
|
||||
<%= f.check_box :terms_of_service, label: false %>
|
||||
<span class="checkbox">
|
||||
<%= t("form.accept_terms",
|
||||
policy: link_to(t("form.policy"), "/privacy", target: "blank"),
|
||||
conditions: link_to(t("form.conditions"), "/conditions", target: "blank")).html_safe %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= f.simple_captcha input_html: { required: false } %>
|
||||
</div>
|
||||
|
||||
<div class="actions small-12 column">
|
||||
<%= f.submit(class: "button radius", value: t("proposals.#{action_name}.form.submit_button")) %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
||||
30
app/views/proposals/_proposal.html.erb
Normal file
30
app/views/proposals/_proposal.html.erb
Normal file
@@ -0,0 +1,30 @@
|
||||
<div id="<%= dom_id(proposal) %>" class="proposal clear">
|
||||
<div class="panel">
|
||||
<div class="row">
|
||||
|
||||
<div class="small-12 medium-9 column">
|
||||
<div class="proposal-content">
|
||||
<span class="label left"><%= t("proposals.proposal.proposal") %></span>
|
||||
<i class="icon-proposals"></i>
|
||||
<h3><%= link_to proposal.title, proposal %></h3>
|
||||
<p class="proposal-info">
|
||||
<i class="icon-comments"></i>
|
||||
<%= link_to t("proposals.proposal.comments", count: proposal.comments_count), proposal_path(proposal, anchor: "comments") %>
|
||||
<span class="bullet"> • </span>
|
||||
<%= l proposal.created_at.to_date %>
|
||||
</p>
|
||||
<div class="proposal-description">
|
||||
<%= link_to proposal.summary, proposal %>
|
||||
<div class="truncate"></div>
|
||||
</div>
|
||||
<%= render "shared/tags", proposal: proposal, limit: 5 %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="<%= dom_id(proposal) %>_votes" class="small-12 medium-3 column text-center">
|
||||
<%= render 'proposals/votes', proposal: proposal %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
1
app/views/proposals/_refresh_flag_actions.js.erb
Normal file
1
app/views/proposals/_refresh_flag_actions.js.erb
Normal file
@@ -0,0 +1 @@
|
||||
$("#<%= dom_id(@proposal) %> .js-flag-actions").html('<%= j render("proposals/flag_actions", proposal: @proposal) %>');
|
||||
51
app/views/proposals/_votes.html.erb
Normal file
51
app/views/proposals/_votes.html.erb
Normal file
@@ -0,0 +1,51 @@
|
||||
<div class="supports">
|
||||
|
||||
<div class="progress small-12 round">
|
||||
<span class="meter" style="width: <%= progress_bar_percentage(proposal) %>%;"></span>
|
||||
</div>
|
||||
|
||||
<span class="total-supports">
|
||||
<%= t("proposals.proposal.supports", count: proposal.total_votes) %>
|
||||
(<%= supports_percentage(proposal) %>)
|
||||
<span>
|
||||
<abbr title="<%= t("proposals.proposal.census_percent") %>">
|
||||
<%= t("proposals.proposal.supports_necessary") %>
|
||||
</abbr>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<div class="in-favor">
|
||||
<% if voted_for?(@proposal_votes, proposal) %>
|
||||
<div class="supported">
|
||||
<%= t("proposals.proposal.already_supported") %>
|
||||
</div>
|
||||
<% else %>
|
||||
<%= link_to vote_proposal_path(proposal, value: 'yes'),
|
||||
class: "button button-support tiny radius expand",
|
||||
title: t('proposals.proposal.support_title'), method: "post", remote: true do %>
|
||||
<%= t("proposals.proposal.support") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if user_signed_in? && current_user.organization? %>
|
||||
<div class="organizations-votes" style='display:none'>
|
||||
<p>
|
||||
<%= t("votes.organizations") %>
|
||||
</p>
|
||||
</div>
|
||||
<% elsif user_signed_in? && !proposal.votable_by?(current_user)%>
|
||||
<div class="anonymous-votes" style='display:none'>
|
||||
<p>
|
||||
<%= t("votes.verified_only",
|
||||
verify_account: link_to(t("votes.verify_account"), verification_path )).html_safe %>
|
||||
</p>
|
||||
</div>
|
||||
<% elsif !user_signed_in? %>
|
||||
<div class="not-logged" style='display:none'>
|
||||
<%= t("votes.unauthenticated",
|
||||
signin: link_to(t("votes.signin"), new_user_session_path),
|
||||
signup: link_to(t("votes.signup"), new_user_registration_path)).html_safe %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
17
app/views/proposals/edit.html.erb
Normal file
17
app/views/proposals/edit.html.erb
Normal file
@@ -0,0 +1,17 @@
|
||||
<div class="proposal-edit row">
|
||||
|
||||
<div class="small-12 column">
|
||||
<%= link_to proposals_path, class: "left back clear" do %>
|
||||
<i class="icon-angle-left left"></i>
|
||||
<%= t("proposals.edit.back_link") %>
|
||||
<% end %>
|
||||
|
||||
<div class="right">
|
||||
<%= link_to t("proposals.edit.show_link"), @proposal %>
|
||||
</div>
|
||||
|
||||
<h1><%= t("proposals.edit.editing") %></h1>
|
||||
|
||||
<%= render "form" %>
|
||||
</div>
|
||||
</div>
|
||||
58
app/views/proposals/index.html.erb
Normal file
58
app/views/proposals/index.html.erb
Normal file
@@ -0,0 +1,58 @@
|
||||
<% content_for :header_addon do %>
|
||||
<%= render "shared/search_form_header",
|
||||
search_path: proposals_path(page: 1),
|
||||
i18n_namespace: "proposals.index.search_form" %>
|
||||
<% end %>
|
||||
|
||||
<section role="main">
|
||||
<div class="wrap row">
|
||||
<div id="proposals" class="proposals-list small-12 medium-9 column">
|
||||
|
||||
<div class="filters">
|
||||
<div class="small-12 medium-7 left">
|
||||
<% if @search_terms %>
|
||||
<h2 class="margin-top">
|
||||
<%= page_entries_info @proposals %>
|
||||
<%= t("proposals.index.search_results", count: @proposals.size, search_term: @search_terms) %>
|
||||
</h2>
|
||||
<% elsif @tag_filter %>
|
||||
<h2 class="margin-top">
|
||||
<%= page_entries_info @proposals %>
|
||||
<%= t("proposals.index.filter_topic", count: @proposals.size, topic: @tag_filter) %>
|
||||
</h2>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<% if @tag_filter || @search_terms %>
|
||||
<div class="small-12 medium-5 margin-top margin-top inline-block proposals-order">
|
||||
<h6 class="inline-block">
|
||||
<%= t("proposals.index.select_order") %>
|
||||
</h6>
|
||||
<%= render 'shared/order_selector', i18n_namespace: "proposals.index" %>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="small-12 inline-block">
|
||||
<h2 class="inline-block">
|
||||
<%= t("proposals.index.select_order_long") %>
|
||||
</h2>
|
||||
<%= render 'shared/order_selector', i18n_namespace: "proposals.index" %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="show-for-small-only">
|
||||
<%= link_to t("proposals.index.start_proposal"), new_proposal_path, class: 'button radius expand' %>
|
||||
</div>
|
||||
|
||||
<%= render @proposals %>
|
||||
<%= paginate @proposals %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
<aside class="sidebar" role="complementary">
|
||||
<%= link_to t("proposals.index.start_proposal"), new_proposal_path, class: 'button radius expand' %>
|
||||
<%= render "shared/tag_cloud", taggable: 'proposal' %>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
26
app/views/proposals/new.html.erb
Normal file
26
app/views/proposals/new.html.erb
Normal file
@@ -0,0 +1,26 @@
|
||||
<div class="proposal-new row">
|
||||
|
||||
<div class="small-12 medium-9 column">
|
||||
<%= link_to proposals_path, class: "left back" do %>
|
||||
<i class="icon-angle-left left"></i>
|
||||
<%= t("proposals.new.back_link") %>
|
||||
<% end %>
|
||||
<h1><%= t("proposals.new.start_new") %></h1>
|
||||
<div class="alert-box info radius">
|
||||
<%= link_to "/proposals_info", target: "_blank" do %>
|
||||
<%= t("proposals.new.more_info")%>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= render "form" %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
<i class="icon-proposals right"></i>
|
||||
<h2><%= t("proposals.new.recommendations_title") %></h2>
|
||||
<ul class="recommendations">
|
||||
<li><%= t("proposals.new.recommendation_one") %></li>
|
||||
<li><%= t("proposals.new.recommendation_two") %></li>
|
||||
<li><%= t("proposals.new.recommendation_three") %></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
99
app/views/proposals/show.html.erb
Normal file
99
app/views/proposals/show.html.erb
Normal file
@@ -0,0 +1,99 @@
|
||||
<% cache [locale_and_user_status(@proposal), @proposal, @proposal.author, Flag.flagged?(current_user, @proposal), @proposal_votes] do %>
|
||||
<section class="proposal-show">
|
||||
<div id="<%= dom_id(@proposal) %>" class="row">
|
||||
<div class="small-12 medium-9 column">
|
||||
<i class="icon-angle-left left"></i>
|
||||
<%= link_to t("proposals.show.back_link"), proposals_path, class: 'left back' %>
|
||||
|
||||
<% if current_user && @proposal.editable_by?(current_user) %>
|
||||
<%= link_to edit_proposal_path(@proposal), class: 'edit-proposal button success tiny radius right' do %>
|
||||
<i class="icon-edit"></i>
|
||||
<%= t("proposals.show.edit_proposal_link") %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<h1><%= @proposal.title %></h1>
|
||||
<% if @proposal.conflictive? %>
|
||||
<div class="alert-box alert radius margin-top">
|
||||
<strong><%= t("proposals.show.flag") %></strong>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
||||
<div class="proposal-info">
|
||||
<%= avatar_image(@proposal.author, seed: @proposal.author_id, size: 32, class: 'author-photo') %>
|
||||
|
||||
<% if @proposal.author.hidden? %>
|
||||
<i class="icon-deleted author-deleted"></i>
|
||||
<span class="author">
|
||||
<%= t("proposals.show.author_deleted") %>
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="author">
|
||||
<%= @proposal.author.name %>
|
||||
</span>
|
||||
<% if @proposal.author.official? %>
|
||||
•
|
||||
<span class="label round level-<%= @proposal.author.official_level %>">
|
||||
<%= @proposal.author.official_position %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
<% if @proposal.author.verified_organization? %>
|
||||
•
|
||||
<span class="label round is-association">
|
||||
<%= t("shared.collective") %>
|
||||
</span>
|
||||
<% end %>
|
||||
|
||||
<span class="bullet"> • </span>
|
||||
<%= l @proposal.created_at.to_date %>
|
||||
<span class="bullet"> • </span>
|
||||
<i class="icon-comments"></i>
|
||||
<%= link_to t("proposals.show.comments", count: @proposal.comments_count), "#comments" %>
|
||||
<span class="bullet"> • </span>
|
||||
<%= @proposal.code %>
|
||||
<span class="bullet"> • </span>
|
||||
<span class="js-flag-actions">
|
||||
<%= render 'proposals/flag_actions', proposal: @proposal %>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div><%= @proposal.summary %></div>
|
||||
|
||||
<%= safe_html_with_links @proposal.description %>
|
||||
|
||||
<% if @proposal.external_url.present? %>
|
||||
<div><%= text_with_links @proposal.external_url %></div>
|
||||
<% end %>
|
||||
|
||||
<% if @proposal.video_url.present? %>
|
||||
<div><%= text_with_links @proposal.video_url %></div>
|
||||
<% end %>
|
||||
|
||||
<h4><%= @proposal.question %></h4>
|
||||
|
||||
<%= render 'shared/tags', proposal: @proposal %>
|
||||
|
||||
<div class='js-moderator-proposal-actions'>
|
||||
<%= render 'actions', proposal: @proposal %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<aside class="small-12 medium-3 column">
|
||||
<div class="sidebar-divider"></div>
|
||||
<h3><%= t("votes.supports") %></h3>
|
||||
<div class="text-center">
|
||||
<div id="<%= dom_id(@proposal) %>_votes">
|
||||
<%= render 'proposals/votes', proposal: @proposal %>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sidebar-divider"></div>
|
||||
<h3><%= t("proposals.show.share") %></h3>
|
||||
<%= social_share_button_tag(@proposal.title) %>
|
||||
</aside>
|
||||
</div>
|
||||
</section>
|
||||
<% end %>
|
||||
<%= render "comments" %>
|
||||
1
app/views/proposals/vote.js.erb
Normal file
1
app/views/proposals/vote.js.erb
Normal file
@@ -0,0 +1 @@
|
||||
$("#<%= dom_id(@proposal) %>_votes").html('<%= j render("proposals/votes", proposal: @proposal) %>');
|
||||
15
app/views/shared/_order_selector.html.erb
Normal file
15
app/views/shared/_order_selector.html.erb
Normal file
@@ -0,0 +1,15 @@
|
||||
<% # Params:
|
||||
#
|
||||
# i18n_namespace: for example "moderation.debates.index"
|
||||
%>
|
||||
|
||||
<form class="inline-block">
|
||||
<select class="js-location-changer js-order-selector" data-order="<%= @current_order %>" name="order-selector">
|
||||
<% @valid_orders.each do |order| %>
|
||||
<option <%= 'selected' if order == @current_order %>
|
||||
value='<%= current_path_with_query_params(order: order, page: 1) %>'>
|
||||
<%= t("#{i18n_namespace}.orders.#{order}") %>
|
||||
</option>
|
||||
<% end %>
|
||||
</select>
|
||||
</form>
|
||||
@@ -1,21 +1,27 @@
|
||||
<% # Params:
|
||||
#
|
||||
# search_path: for example debates_path
|
||||
# i18n_namespace: for example "debates.index.search_form"
|
||||
%>
|
||||
|
||||
<div class="search-form">
|
||||
<div class="sidebar-divider"></div>
|
||||
<h3><%= t("shared.search_form.search_title") %></h3>
|
||||
<h3><%= t("#{i18n_namespace}.title") %></h3>
|
||||
<br>
|
||||
<div class="row">
|
||||
<%= form_tag debates_path, method: :get do %>
|
||||
<%= form_tag search_path, method: :get do %>
|
||||
<div class="small-12 columns">
|
||||
<div class="row collapse">
|
||||
|
||||
<div class="small-9 medium-12 large-9 columns">
|
||||
<input type="text" name="search" placeholder="<%= t("shared.search_form.search_placeholder") %>" class="search-form">
|
||||
<input type="text" name="search" placeholder="<%= t("#{i18n_namespace}.placeholder") %>" class="search-form">
|
||||
</div>
|
||||
<div class="small-3 medium-12 large-3 columns">
|
||||
<input type="submit" class="button secondary postfix" value="<%= t('shared.search_form.search_button') %>">
|
||||
<input type="submit" class="button secondary postfix" value="<%= t("#{i18n_namespace}.button") %>">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
<% # Params:
|
||||
#
|
||||
# i18n_namespace: for example "debates.index.search_form"
|
||||
# search_path: for example debates_path
|
||||
%>
|
||||
|
||||
<div class="search-form">
|
||||
<div class="row">
|
||||
|
||||
<%= form_tag debates_path, method: :get do %>
|
||||
<%= form_tag search_path, method: :get do %>
|
||||
<div class="small-12 columns">
|
||||
<div class="row collapse">
|
||||
<div class="small-10 column">
|
||||
<input type="text" name="search" placeholder="<%= t("shared.search_form.search_placeholder") %>" class="search-form">
|
||||
<input type="text" name="search" placeholder="<%= t("#{i18n_namespace}.placeholder") %>" class="search-form">
|
||||
</div>
|
||||
<div class="small-2 column">
|
||||
<button type="submit" class="button postfix" title="<%= t('shared.search_form.search_button') %>">
|
||||
<button type="submit" class="button postfix" title="<%= t("#{i18n_namespace}.button") %>">
|
||||
<i class="icon-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
<h3><%= t("shared.tags_cloud.tags") %></h3>
|
||||
<br>
|
||||
<% tag_cloud @tag_cloud, %w[s m l] do |tag, css_class| %>
|
||||
<%= link_to sanitize("#{tag.name} <span class='label round info'>#{tag.taggings_count}</span>"), debates_path(tag: tag.name), class: css_class %>
|
||||
<%= link_to sanitize("#{tag.name} <span class='label round info'>#{tag.taggings_count}</span>"), taggable_path(taggable, tag.name), class: css_class %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<%- limit ||= nil %>
|
||||
<%- taggable = defined?(debate) ? debate : proposal %>
|
||||
|
||||
<% if debate.tags.any? %>
|
||||
<% if taggable.tags.any? %>
|
||||
<span class='tags'>
|
||||
<% debate.tag_list_with_limit(limit).each do |tag| %>
|
||||
<%= link_to sanitize(tag.name), debates_path(tag: tag.name) %>
|
||||
<% taggable.tag_list_with_limit(limit).each do |tag| %>
|
||||
<%= link_to sanitize(tag.name), send("#{taggable.class.to_s.downcase.pluralize}_path", tag: tag.name) %>
|
||||
<% end %>
|
||||
|
||||
<% if debate.tags_count_out_of_limit(limit) > 0 %>
|
||||
<%= link_to "#{debate.tags_count_out_of_limit(limit)}+", debate_path(debate) %>
|
||||
<% if taggable.tags_count_out_of_limit(limit) > 0 %>
|
||||
<%= link_to "#{taggable.tags_count_out_of_limit(limit)}+",
|
||||
send("#{taggable.class.to_s.downcase}_path", taggable) %>
|
||||
<% end %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
<div class="verification account row">
|
||||
|
||||
<div class="alert-box success radius">
|
||||
<%= t('verification.letter.create.flash.success') %>
|
||||
</div>
|
||||
|
||||
<div class="small-12 column">
|
||||
|
||||
<div class="text-center">
|
||||
@@ -26,6 +31,13 @@
|
||||
|
||||
<h1><%= t("verification.letter.edit.title") %></h1>
|
||||
|
||||
<%= t("verification.letter.new.explanation_html") %>
|
||||
|
||||
<%= link_to t("verification.letter.new.offices"), t("verification.letter.new.offices_url"),
|
||||
target: "_blank", class: "button radius inline-block"
|
||||
%>
|
||||
|
||||
|
||||
<div class="small-12 medium-6">
|
||||
<%= form_for @letter, as: "letter", url: letter_path, method: :put do |f| %>
|
||||
<%= f.text_field :verification_code, label: t("verification.letter.edit.confirmation_code") %>
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<% cache [locale_and_user_status, featured_debate, @debate_votes[featured_debate.id],'featured'] do %>
|
||||
<div class="small-12 medium-4 column end">
|
||||
<div id="<%= dom_id featured_debate %>" class="debate-featured">
|
||||
<div class="panel">
|
||||
|
||||
<div class="debate-content">
|
||||
<span class="label left"><%= t("debates.debate.debate") %></span>
|
||||
<i class="icon-debates right"></i>
|
||||
<h3><%= link_to featured_debate.title, featured_debate %></h3>
|
||||
<p class="debate-info">
|
||||
<i class="icon-comments"></i>
|
||||
<%= link_to t("debates.show.comments", count: featured_debate.comments_count), debate_path(featured_debate, anchor: "comments") %>
|
||||
</p>
|
||||
<div class="debate-description">
|
||||
<%= link_to featured_debate.description, featured_debate %>
|
||||
<div class="truncate"></div>
|
||||
</div>
|
||||
<%= render "shared/tags", debate: featured_debate, limit: 5 %>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div id="<%= dom_id(featured_debate) %>_votes" class="small-12 column">
|
||||
<%= render 'debates/votes', debate: featured_debate %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
27
app/views/welcome/highlights.html.erb
Normal file
27
app/views/welcome/highlights.html.erb
Normal file
@@ -0,0 +1,27 @@
|
||||
<% cache [locale_and_user_status, @list, @debate_votes, @proposal_votes, @paginator.current_page, @paginator.total_pages] do %>
|
||||
<section role="main">
|
||||
<div class="wrap row">
|
||||
<div id="activities" class="debates-list small-12 medium-9 column">
|
||||
|
||||
<div class="filters">
|
||||
|
||||
<div class="small-12 medium-7 left">
|
||||
<h2 class="margin-top">
|
||||
<%= t('welcome.signed_in_home_title') %>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<%= render @list %>
|
||||
<%= paginate @paginator %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
<aside class="sidebar" role="complementary">
|
||||
<%= link_to t("proposals.index.start_proposal"), new_proposal_path, class: 'button radius expand' %>
|
||||
<%= link_to t("debates.index.start_debate"), new_debate_path, class: 'button radius expand' %>
|
||||
</aside>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<% end %>
|
||||
@@ -1,12 +1,28 @@
|
||||
<% cache [locale_and_user_status, @featured_debates, @debate_votes, 'featured'] do %>
|
||||
<% cache [locale_and_user_status, @featured_debates, @featured_proposals, 'featured'] do %>
|
||||
<section role="main">
|
||||
<div class="filters row">
|
||||
<div class="small-12 column">
|
||||
<h2><%= t("welcome.last_debates") %></h2>
|
||||
<div class="row text-center">
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= image_tag("icon_home_debates.png") %>
|
||||
<h2><%= t("welcome.debates.title") %></h2>
|
||||
<p><%= t("welcome.debates.description") %></p>
|
||||
|
||||
</div>
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= image_tag("icon_home_propones.png") %>
|
||||
<h2><%= t("welcome.proposal.title") %></h2>
|
||||
<p><%= t("welcome.proposal.description") %></p>
|
||||
</div>
|
||||
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= image_tag("icon_home_decides.png") %>
|
||||
<h2><%= t("welcome.decide.title") %></h2>
|
||||
<p><%= t("welcome.decide.description") %></p>
|
||||
</div>
|
||||
<div class="small-12 medium-3 column">
|
||||
<%= image_tag("icon_home_sehace.png") %>
|
||||
<h2><%= t("welcome.do.title") %></h2>
|
||||
<p><%= t("welcome.do.description") %></p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="featured-debates" class="row">
|
||||
<%= render partial: "featured_debate", collection: @featured_debates %>
|
||||
</div>
|
||||
</section>
|
||||
<% end %>
|
||||
|
||||
@@ -104,11 +104,17 @@ ignore_unused:
|
||||
- 'admin.officials.level_*'
|
||||
- 'admin.comments.index.filter*'
|
||||
- 'admin.debates.index.filter*'
|
||||
- 'admin.proposals.index.filter*'
|
||||
- 'admin.organizations.index.filter*'
|
||||
- 'admin.users.index.filter*'
|
||||
- 'moderation.comments.index.filter*'
|
||||
- 'moderation.debates.index.filter*'
|
||||
- 'moderation.proposals.index.filter*'
|
||||
- 'moderation.proposals.index.order*'
|
||||
- 'debates.index.orders.*'
|
||||
- 'debates.index.search_form.*'
|
||||
- 'proposals.index.orders.*'
|
||||
- 'proposals.index.search_form.*'
|
||||
- 'helpers.page_entries_info.*' # kaminari
|
||||
- 'views.pagination.*' # kaminari
|
||||
# - '{devise,kaminari,will_paginate}.*'
|
||||
|
||||
@@ -8,3 +8,50 @@ Kaminari.configure do |config|
|
||||
# config.page_method_name = :page
|
||||
# config.param_name = :page
|
||||
end
|
||||
|
||||
|
||||
# Overrides for making Kaminari handle i18n pluralization correctly
|
||||
#
|
||||
# Remove everything below once https://github.com/amatsuda/kaminari/pull/694 is
|
||||
# merged in Kaminari and we have updated
|
||||
module Kaminari
|
||||
|
||||
module ActionViewExtension
|
||||
def page_entries_info(collection, options = {})
|
||||
entry_name = if options[:entry_name]
|
||||
options[:entry_name].pluralize(collection.size)
|
||||
else
|
||||
collection.entry_name(:count => collection.size).downcase
|
||||
end
|
||||
|
||||
if collection.total_pages < 2
|
||||
t('helpers.page_entries_info.one_page.display_entries', entry_name: entry_name, count: collection.total_count)
|
||||
else
|
||||
first = collection.offset_value + 1
|
||||
last = collection.last_page? ? collection.total_count : collection.offset_value + collection.limit_value
|
||||
t('helpers.page_entries_info.more_pages.display_entries', entry_name: entry_name, first: first, last: last, total: collection.total_count)
|
||||
end.html_safe
|
||||
end
|
||||
end
|
||||
|
||||
module ActiveRecordRelationMethods
|
||||
def entry_name(options = {})
|
||||
model_name.human(options.reverse_merge(default: model_name.human.pluralize(options[:count])))
|
||||
end
|
||||
end
|
||||
|
||||
module MongoidCriteriaMethods
|
||||
def entry_name(options = {})
|
||||
model_name.human(options.reverse_merge(default: model_name.human.pluralize(options[:count])))
|
||||
end
|
||||
end
|
||||
|
||||
class PaginatableArray < Array
|
||||
ENTRY = 'entry'.freeze
|
||||
|
||||
def entry_name(options = {})
|
||||
I18n.t('helpers.page_entries_info.entry', options.reverse_merge(default: ENTRY.pluralize(options[:count])))
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -3,6 +3,10 @@ ActsAsVotable::Vote.class_eval do
|
||||
where(votable_type: 'Debate', votable_id: debates)
|
||||
end
|
||||
|
||||
def self.for_proposals(proposals)
|
||||
where(votable_type: 'Proposal', votable_id: proposals)
|
||||
end
|
||||
|
||||
def value
|
||||
vote_flag
|
||||
end
|
||||
|
||||
@@ -16,6 +16,12 @@ en:
|
||||
description: Opinion
|
||||
terms_of_service: Terms of service
|
||||
title: Title
|
||||
proposal:
|
||||
author: Author
|
||||
title: Title
|
||||
question: Question
|
||||
description: Description
|
||||
terms_of_service: Terms of service
|
||||
user:
|
||||
email: Email
|
||||
username: Username
|
||||
|
||||
@@ -1,12 +1,33 @@
|
||||
es:
|
||||
activerecord:
|
||||
models:
|
||||
comment: Comentario
|
||||
debate: Debate
|
||||
tag: Tema
|
||||
user: Usuario
|
||||
vote: Voto
|
||||
organization: Organización
|
||||
comment:
|
||||
one: Comentario
|
||||
other: Comentarios
|
||||
debate:
|
||||
one: Debate
|
||||
other: Debates
|
||||
tag:
|
||||
one: Tema
|
||||
other: Temas
|
||||
user:
|
||||
one: Usuario
|
||||
other: Usuarios
|
||||
moderator:
|
||||
one: Moderador
|
||||
other: Moderadores
|
||||
administrator:
|
||||
one: Administrador
|
||||
other: Administradores
|
||||
vote:
|
||||
one: Voto
|
||||
other: Voto
|
||||
organization:
|
||||
one: Organización
|
||||
other: Organizaciones
|
||||
proposal:
|
||||
one: Propuesta ciudadana
|
||||
other: Propuestas ciudadanas
|
||||
attributes:
|
||||
comment:
|
||||
body: Comentario
|
||||
@@ -16,6 +37,12 @@ es:
|
||||
description: Opinión
|
||||
terms_of_service: Términos de servicio
|
||||
title: Título
|
||||
proposal:
|
||||
author: Autor
|
||||
title: Título
|
||||
question: Pregunta
|
||||
description: Descripción
|
||||
terms_of_service: Términos de servicio
|
||||
user:
|
||||
email: Correo electrónico
|
||||
username: Nombre de usuario
|
||||
|
||||
@@ -12,6 +12,7 @@ en:
|
||||
menu:
|
||||
settings: Global settings
|
||||
debate_topics: Debate topics
|
||||
hidden_proposals: Hidden proposals
|
||||
hidden_debates: Hidden debates
|
||||
hidden_comments: Hidden comments
|
||||
hidden_users: Blocked users
|
||||
@@ -71,6 +72,14 @@ en:
|
||||
all: All
|
||||
with_confirmed_hide: Confirmed
|
||||
without_confirmed_hide: Pending
|
||||
proposals:
|
||||
index:
|
||||
title: Hidden proposals
|
||||
filter: Filter
|
||||
filters:
|
||||
all: All
|
||||
with_confirmed_hide: Confirmed
|
||||
without_confirmed_hide: Pending
|
||||
users:
|
||||
index:
|
||||
title: Banned users
|
||||
|
||||
@@ -12,6 +12,7 @@ es:
|
||||
menu:
|
||||
settings: Configuración global
|
||||
debate_topics: Temas de debate
|
||||
hidden_proposals: Propuestas ocultas
|
||||
hidden_debates: Debates ocultos
|
||||
hidden_comments: Comentarios ocultos
|
||||
hidden_users: Usuarios bloqueados
|
||||
@@ -71,6 +72,14 @@ es:
|
||||
all: Todos
|
||||
with_confirmed_hide: Confirmados
|
||||
without_confirmed_hide: Pendientes
|
||||
proposals:
|
||||
index:
|
||||
title: Propuestas ocultos
|
||||
filter: Filtro
|
||||
filters:
|
||||
all: Todas
|
||||
with_confirmed_hide: Confirmadas
|
||||
without_confirmed_hide: Pendientes
|
||||
users:
|
||||
index:
|
||||
title: Usuarios bloqueados
|
||||
|
||||
@@ -12,23 +12,25 @@ en:
|
||||
open: "Open"
|
||||
participation: Participation
|
||||
open_city_title: "The city you want, it will be the city you want."
|
||||
open_city_slogan:
|
||||
open_city_slogan_html:
|
||||
"Start listening to Madrid.
|
||||
For that we open this digital Puerta del Sol, where all the locals can meet to discuss and share everything we want."
|
||||
# "Existen ciudades gobernadas directamente por sus habitantes, que <b>debaten</b> sobre temas que les preocupan, <b>proponen</b> ideas para mejorar
|
||||
# sus vidas y <b>deciden</b> entre todas y todos las que se llevan a cabo. Madrid ya es una de ellas."
|
||||
# open_city_text:
|
||||
# "Here every voice has its place and are citizens, and no one in their name, they decide to vote debates what issues are
|
||||
# most important of every time. Government officials have individual users with whom you may participate in the debates, and evaluated,
|
||||
# the same level as everyone else. Because the Madrid City Council works for its citizens, and must respond to them."
|
||||
# open_city_soon: "And soon... we'll open the section for citizen proposals."
|
||||
see_all_debates: See all debates
|
||||
see_all: See debates and proposals
|
||||
my_account_link: My account
|
||||
locale: "Language:"
|
||||
administration: Administration
|
||||
moderation: Moderation
|
||||
# welcome: Welcome
|
||||
highlights: "Highlights"
|
||||
more_information: "More information"
|
||||
debates: Debates
|
||||
# initiatives: Initiatives
|
||||
proposals: Proposals
|
||||
footer:
|
||||
description: "This portal use %{consul}, is %{open_source}. Madrid, for the whole world."
|
||||
open_source: "software libre"
|
||||
@@ -55,6 +57,7 @@ en:
|
||||
conditions: "Terms of use"
|
||||
user: account
|
||||
debate: debate
|
||||
proposal: proposal
|
||||
verification::sms: phone
|
||||
application:
|
||||
alert:
|
||||
@@ -73,6 +76,10 @@ en:
|
||||
filter_topic:
|
||||
one: " with the topic '%{topic}'"
|
||||
other: " with the topic '%{topic}'"
|
||||
search_form:
|
||||
title: Search
|
||||
button: Search
|
||||
placeholder: "Search debates..."
|
||||
search_results:
|
||||
one: " containing '%{search_term}'"
|
||||
other: " containing '%{search_term}'"
|
||||
@@ -86,20 +93,6 @@ en:
|
||||
zero: No votes
|
||||
one: 1 vote
|
||||
other: "%{count} votes"
|
||||
comment:
|
||||
author: Debate's author
|
||||
moderator: Moderator
|
||||
admin: Administrator
|
||||
deleted: This comment has been deleted
|
||||
user_deleted: Deleted user
|
||||
responses:
|
||||
zero: No Responses
|
||||
one: 1 Response
|
||||
other: "%{count} Responses"
|
||||
votes:
|
||||
zero: No votes
|
||||
one: 1 vote
|
||||
other: "%{count} votes"
|
||||
form:
|
||||
debate_title: Debate title
|
||||
debate_text: Initial text for debate
|
||||
@@ -143,11 +136,111 @@ en:
|
||||
update:
|
||||
form:
|
||||
submit_button: "Save changes"
|
||||
proposals:
|
||||
index:
|
||||
start_proposal: Start a proposal
|
||||
select_order: Order by
|
||||
select_order_long: Order proposals by
|
||||
orders:
|
||||
confidence_score: best rated
|
||||
hot_score: most active
|
||||
created_at: newest
|
||||
most_commented: most commented
|
||||
random: random
|
||||
filter_topic:
|
||||
one: " with the topic '%{topic}'"
|
||||
other: " with the topic '%{topic}'"
|
||||
search_form:
|
||||
title: Search
|
||||
button: Search
|
||||
placeholder: "Search proposals..."
|
||||
search_results:
|
||||
one: " containing '%{search_term}'"
|
||||
other: " containing '%{search_term}'"
|
||||
proposal:
|
||||
proposal: Proposal
|
||||
support: "Support"
|
||||
support_title: "Support this proposal"
|
||||
comments:
|
||||
zero: No comments
|
||||
one: 1 Comment
|
||||
other: "%{count} Comments"
|
||||
supports:
|
||||
zero: No supports
|
||||
one: 1 support
|
||||
other: "%{count} supports"
|
||||
supports_necessary: "53.726 necessary supports"
|
||||
census_percent: "2% of census"
|
||||
already_supported: "You already supported this proposal!"
|
||||
form:
|
||||
proposal_title: Proposal title
|
||||
proposal_question: Proposal question
|
||||
proposal_question_example_html: "Debe ser resumida en una pregunta cuya respuesta sea Sí o No. <em>Ej. '¿Está usted de acuerdo en peatonalizar la calle Mayor?'</em>"
|
||||
proposal_text: Initial text for proposal
|
||||
proposal_external_url: Link to additional documentation
|
||||
proposal_video_url: "Enlace a vídeo externo"
|
||||
proposal_video_url_note: "Puedes añadir un enlace a YouTube o Vimeo"
|
||||
proposal_summary: "Proposal summary"
|
||||
proposal_summary_note: "200 chars. maximum"
|
||||
proposal_responsible_name: "First and last name of the person making this proposal"
|
||||
proposal_responsible_name_note: "(individualmente o como representante de un colectivo; no se mostrará públicamente)"
|
||||
tags_label: Topics
|
||||
tags_instructions: >
|
||||
Tag this proposal. You can choose among our proposals on the list or add any other topic you want.
|
||||
tags_placeholder: "Add topics writing them separated by ','"
|
||||
show:
|
||||
back_link: Back
|
||||
author_deleted: Deleted user
|
||||
comments_title: Comments
|
||||
comments:
|
||||
zero: No comments
|
||||
one: 1 Comment
|
||||
other: "%{count} Comments"
|
||||
login_to_comment: "You need to %{signin} or %{signup} to comment."
|
||||
edit_proposal_link: Edit
|
||||
share: Share
|
||||
flag: "This proposal has been flag as innapropiate for some users."
|
||||
edit:
|
||||
editing: Edit proposal
|
||||
show_link: Show proposal
|
||||
back_link: Back
|
||||
form:
|
||||
submit_button: "Save changes"
|
||||
new:
|
||||
start_new: Start a proposal
|
||||
more_info: "¿Cómo funcionan las propuestas ciudadanas?"
|
||||
back_link: Back
|
||||
recommendations_title: Tips for creating a proposal
|
||||
recommendation_one: "Do not write the title of the proposal or whole sentences in capital. On the Internet this is considered shouting. And nobody likes to scream."
|
||||
recommendation_two: "Any discussion or comment that involves an illegal act will be eliminated, also intending to sabotage the proposal spaces, everything else is permitted."
|
||||
recommendation_three: "Enjoy this space, voices that fill it, it is yours too."
|
||||
form:
|
||||
submit_button: "Start a proposal"
|
||||
create:
|
||||
form:
|
||||
submit_button: "Start a proposal"
|
||||
update:
|
||||
form:
|
||||
submit_button: "Save changes"
|
||||
comments:
|
||||
form:
|
||||
leave_comment: Write a comment
|
||||
comment_as_moderator: Comment as moderator
|
||||
comment_as_admin: Comment as administrator
|
||||
comment:
|
||||
author: Author
|
||||
moderator: Moderator
|
||||
admin: Administrator
|
||||
deleted: This comment has been deleted
|
||||
user_deleted: Deleted user
|
||||
responses:
|
||||
zero: No Responses
|
||||
one: 1 Response
|
||||
other: "%{count} Responses"
|
||||
votes:
|
||||
zero: No votes
|
||||
one: 1 vote
|
||||
other: "%{count} votes"
|
||||
comments_helper:
|
||||
comment_link: Comment
|
||||
comment_button: Publish comment
|
||||
@@ -160,14 +253,15 @@ en:
|
||||
unauthenticated: "You need to %{signin} or %{signup} before continuing."
|
||||
signin: sign in
|
||||
signup: sign up
|
||||
anonymous: "This debate already has too much anonymous votes, %{verify_account} to vote."
|
||||
anonymous: "Too many anonymous votes, %{verify_account} to vote."
|
||||
verified_only: "Proposals can only be voted by verified users, %{verify_account}."
|
||||
verify_account: verify your account
|
||||
organizations: Organizations can not vote
|
||||
account:
|
||||
show:
|
||||
title: "My account"
|
||||
save_changes_submit: "Save changes"
|
||||
email_on_debate_comment_label: "Receive email when someone comments on my debates"
|
||||
email_on_comment_label: "Receive email when someone comments on my debates or proposals"
|
||||
email_on_comment_reply_label: "Receive email when someone replies to my comments"
|
||||
change_credentials_link: "Change my credentials"
|
||||
avatar: "Avatar"
|
||||
@@ -187,16 +281,16 @@ en:
|
||||
message:
|
||||
user: "secret code did not match with the image"
|
||||
debate: "secret code did not match with the image"
|
||||
proposal: "secret code did not match with the image"
|
||||
shared:
|
||||
tags_cloud:
|
||||
tags: Trend
|
||||
flag: Flag as inappropriate
|
||||
unflag: Undo flag
|
||||
collective: Collective
|
||||
search_form:
|
||||
search_title: Search
|
||||
search_button: Search
|
||||
search_placeholder: "Search on debates..."
|
||||
check: Select
|
||||
check_all: All
|
||||
check_none: None
|
||||
mailer:
|
||||
comment:
|
||||
subject: Someone has commented on your debate
|
||||
@@ -207,7 +301,20 @@ en:
|
||||
manage:
|
||||
all: "You are not authorized to %{action} %{subject}."
|
||||
welcome:
|
||||
last_debates: Last debates
|
||||
signed_in_home_title: Recent activity
|
||||
signed_in_home_title: Actividad reciente
|
||||
debates:
|
||||
title: "Debate"
|
||||
description: "Meet, discuss and share what we think is important in our city."
|
||||
proposal:
|
||||
title: "You propose"
|
||||
description: "Open to citizens proposals on the kind of city we want to live."
|
||||
decide:
|
||||
title: "You decide"
|
||||
description: "Citizenship decide whether to accept or reject the most supported proposals."
|
||||
do:
|
||||
title: "It does"
|
||||
description: "If the proposal is accepted mostly, the City Council makes his own and done."
|
||||
welcome:
|
||||
title: Account verification
|
||||
instructions_1_html: "Welcome to the public participation website."
|
||||
|
||||
@@ -12,23 +12,25 @@ es:
|
||||
open: "abierto"
|
||||
participation: Participación
|
||||
open_city_title: "La ciudad que quieres será la ciudad que quieras."
|
||||
open_city_slogan:
|
||||
"Empecemos escuchando qué tiene que decir Madrid.
|
||||
Para ello abrimos esta Puerta del Sol digital, donde toda la gente de Madrid podemos encontrarnos para debatir y compartir todo lo que queramos."
|
||||
open_city_slogan_html:
|
||||
"Existen ciudades gobernadas directamente por sus habitantes, que <b>debaten</b> sobre temas que les preocupan, <b>proponen</b> ideas para mejorar
|
||||
sus vidas y <b>deciden</b> entre todas y todos las que se llevan a cabo. Madrid ya es una de ellas."
|
||||
#"Empecemos escuchando qué tiene que decir Madrid.
|
||||
#Para ello abrimos esta Puerta del Sol digital, donde toda la gente de Madrid podemos encontrarnos para debatir y compartir todo lo que queramos."
|
||||
# open_city_text:
|
||||
# "Aquí cualquier voz tiene su espacio y son los ciudadanos y ciudadanas, y nadie en su nombre, quienes deciden votando los debates cuáles son los temas
|
||||
# más importantes de cada momento. Los responsables del gobierno tienen cuentas de usuario propias con las que podrán participar en los debates, y ser evaluados
|
||||
# al mismo nivel que todos los demás."
|
||||
# open_city_soon: "Muy pronto abriremos la sección de propuestas ciudadanas, donde cualquiera podrá presentar propuestas y, si reciben apoyo, serán puestas en marcha por el Ayuntamiento."
|
||||
see_all_debates: Ver todos los debates
|
||||
see_all: Ver debates y propuestas
|
||||
my_account_link: Mi cuenta
|
||||
locale: "Idioma:"
|
||||
administration: Administrar
|
||||
moderation: Moderar
|
||||
# welcome: Portada
|
||||
highlights: "Portada"
|
||||
more_information: "Más información"
|
||||
debates: Debates
|
||||
# initiatives: Iniciativas
|
||||
proposals: Propuestas ciudadanas
|
||||
footer:
|
||||
description: "Este portal usa la %{consul} que es %{open_source}. De Madrid, para el mundo entero."
|
||||
open_source: "software libre"
|
||||
@@ -55,6 +57,7 @@ es:
|
||||
conditions: "Condiciones de uso"
|
||||
user: la cuenta
|
||||
debate: el debate
|
||||
proposal: la propuesta
|
||||
verification::sms: el teléfono
|
||||
application:
|
||||
alert:
|
||||
@@ -73,6 +76,10 @@ es:
|
||||
filter_topic:
|
||||
one: " con el tema '%{topic}'"
|
||||
other: " con el tema '%{topic}'"
|
||||
search_form:
|
||||
title: Buscar
|
||||
button: Buscar
|
||||
placeholder: "Buscar debates..."
|
||||
search_results:
|
||||
one: " que contiene '%{search_term}'"
|
||||
other: " que contienen '%{search_term}'"
|
||||
@@ -86,27 +93,13 @@ es:
|
||||
zero: Sin votos
|
||||
one: 1 voto
|
||||
other: "%{count} votos"
|
||||
comment:
|
||||
author: Autor del debate
|
||||
moderator: Moderador
|
||||
admin: Administrador
|
||||
deleted: Este comentario ha sido eliminado
|
||||
user_deleted: Usuario eliminado
|
||||
responses:
|
||||
zero: Sin respuestas
|
||||
one: 1 Respuesta
|
||||
other: "%{count} Respuestas"
|
||||
votes:
|
||||
zero: Sin votos
|
||||
one: 1 voto
|
||||
other: "%{count} votos"
|
||||
form:
|
||||
debate_title: Título del debate
|
||||
debate_text: Texto inicial del debate
|
||||
tags_label: Temas
|
||||
tags_instructions: >
|
||||
Etiqueta este debate. Puedes elegir entre nuestras propuestas o introducir las que desees.
|
||||
tags_placeholder: "Escribe las etiquetas que desees separadas por ','"
|
||||
tags_placeholder: "Escribe las etiquetas que desees separadas por coma (',')"
|
||||
show:
|
||||
back_link: Volver
|
||||
author_deleted: Usuario eliminado
|
||||
@@ -143,11 +136,111 @@ es:
|
||||
update:
|
||||
form:
|
||||
submit_button: "Guardar cambios"
|
||||
proposals:
|
||||
index:
|
||||
start_proposal: Crea una propuesta
|
||||
select_order: Ordenar por
|
||||
select_order_long: Estás viendo las propuestas
|
||||
orders:
|
||||
confidence_score: "mejor valoradas"
|
||||
hot_score: "más activas"
|
||||
created_at: "más nuevas"
|
||||
most_commented: "más comentadas"
|
||||
random: "aleatorias"
|
||||
filter_topic:
|
||||
one: " con el tema '%{topic}'"
|
||||
other: " con el tema '%{topic}'"
|
||||
search_form:
|
||||
title: Search
|
||||
button: Search
|
||||
placeholder: "Buscar propuestas ciudadanas..."
|
||||
search_results:
|
||||
one: " que contiene '%{search_term}'"
|
||||
other: " que contienen '%{search_term}'"
|
||||
proposal:
|
||||
proposal: Propuesta
|
||||
support: "Apoyar"
|
||||
support_title: "Apoyar esta propuesta"
|
||||
comments:
|
||||
zero: Sin comentarios
|
||||
one: 1 Comentario
|
||||
other: "%{count} Comentarios"
|
||||
supports:
|
||||
zero: Sin apoyos
|
||||
one: 1 apoyo
|
||||
other: "%{count} apoyos"
|
||||
supports_necessary: "53.726 apoyos necesarios"
|
||||
census_percent: "2% del Censo"
|
||||
already_supported: "¡Ya has apoyado esta propuesta!"
|
||||
form:
|
||||
proposal_title: Título de la propuesta
|
||||
proposal_question: Pregunta de la propuesta
|
||||
proposal_question_example_html: "Debe ser resumida en una pregunta cuya respuesta sea Sí o No. <em>Ej. '¿Está usted de acuerdo en peatonalizar la calle Mayor?'</em>"
|
||||
proposal_summary: "Resumen de la propuesta"
|
||||
proposal_summary_note: "(máximo 200 caracteres)"
|
||||
proposal_text: Texto desarrollado de la propuesta
|
||||
proposal_external_url: Enlace a documentación adicional
|
||||
proposal_video_url: "Enlace a vídeo externo"
|
||||
proposal_video_url_note: "Puedes añadir un enlace a YouTube o Vimeo"
|
||||
proposal_responsible_name: "Nombre y apellidos de la persona que hace esta propuesta"
|
||||
proposal_responsible_name_note: "(individualmente o como representante de un colectivo; no se mostrará públicamente)"
|
||||
tags_label: Temas
|
||||
tags_instructions: >
|
||||
Etiqueta esta propuesta. Puedes elegir entre nuestras propuestas o introducir las que desees.
|
||||
tags_placeholder: "Escribe las etiquetas que desees separadas por una coma (',')"
|
||||
show:
|
||||
back_link: Volver
|
||||
author_deleted: Usuario eliminado
|
||||
comments_title: Comentarios
|
||||
comments:
|
||||
zero: Sin comentarios
|
||||
one: 1 Comentario
|
||||
other: "%{count} Comentarios"
|
||||
login_to_comment: "Necesitas %{signin} o %{signup} para comentar."
|
||||
edit_proposal_link: Editar
|
||||
share: Compartir
|
||||
flag: "Esta propuesta ha sido marcada como inapropiada por varios usuarios."
|
||||
edit:
|
||||
editing: Editar propuesta
|
||||
show_link: Ver propuesta
|
||||
back_link: Volver
|
||||
form:
|
||||
submit_button: "Guardar cambios"
|
||||
new:
|
||||
start_new: Crear una propuesta
|
||||
more_info: "¿Cómo funcionan las propuestas ciudadanas?"
|
||||
back_link: Volver
|
||||
recommendations_title: Recomendaciones para crear una propuesta
|
||||
recommendation_one: "No escribas el título de la propuesta o frases enteras en mayúsculas. En internet eso se considera gritar. Y a nadie le gusta que le griten."
|
||||
recommendation_two: "Cualquier propuesta o comentario que implique una acción ilegal será eliminada, también las que tengan la intención de sabotear los espacios de propuesta, todo lo demás está permitido."
|
||||
recommendation_three: "Disfruta de este espacio, de las voces que lo llenan, también es tuyo."
|
||||
form:
|
||||
submit_button: "Crear propuesta"
|
||||
create:
|
||||
form:
|
||||
submit_button: "Crear propuesta"
|
||||
update:
|
||||
form:
|
||||
submit_button: "Guardar cambios"
|
||||
comments:
|
||||
form:
|
||||
leave_comment: Deja tu comentario
|
||||
comment_as_moderator: Comentar como moderador
|
||||
comment_as_admin: Comentar como administrador
|
||||
comment:
|
||||
author: Autor
|
||||
moderator: Moderador
|
||||
admin: Administrador
|
||||
deleted: Este comentario ha sido eliminado
|
||||
user_deleted: Usuario eliminado
|
||||
responses:
|
||||
zero: Sin respuestas
|
||||
one: 1 Respuesta
|
||||
other: "%{count} Respuestas"
|
||||
votes:
|
||||
zero: Sin votos
|
||||
one: 1 voto
|
||||
other: "%{count} votos"
|
||||
comments_helper:
|
||||
comment_link: Comentar
|
||||
comment_button: Publicar comentario
|
||||
@@ -160,7 +253,8 @@ es:
|
||||
unauthenticated: "Necesitas %{signin} o %{signup} para continuar."
|
||||
signin: iniciar sesión
|
||||
signup: registrarte
|
||||
anonymous: "Este debate ya tiene demasiados votos anónimos, para poder votar %{verify_account}."
|
||||
anonymous: "Demasiados votos anónimos, para poder votar %{verify_account}."
|
||||
verified_only: "Las propuestas sólo pueden ser votadas por usuarios verificados, %{verify_account}."
|
||||
verify_account: verifica tu cuenta
|
||||
organizations: Las organizaciones no pueden votar
|
||||
account:
|
||||
@@ -168,7 +262,7 @@ es:
|
||||
title: "Mi cuenta"
|
||||
save_changes_submit: "Guardar cambios"
|
||||
change_credentials_link: "Cambiar mis datos de acceso"
|
||||
email_on_debate_comment_label: "Recibir un email cuando alguien comenta en mis debates"
|
||||
email_on_comment_label: "Recibir un email cuando alguien comenta en mis propuestas o debates"
|
||||
email_on_comment_reply_label: "Recibir un email cuando alguien contesta a mis comentarios"
|
||||
avatar: "Avatar"
|
||||
personal: "Datos personales"
|
||||
@@ -187,19 +281,19 @@ es:
|
||||
message:
|
||||
user: "el código secreto no coincide con la imagen"
|
||||
debate: "el código secreto no coincide con la imagen"
|
||||
proposal: "el código secreto no coincide con la imagen"
|
||||
shared:
|
||||
tags_cloud:
|
||||
tags: Tendencias
|
||||
flag: Denunciar como inapropiado
|
||||
unflag: Deshacer denuncia
|
||||
collective: Colectivo
|
||||
search_form:
|
||||
search_title: Buscar
|
||||
search_button: Buscar
|
||||
search_placeholder: "Buscar en debates..."
|
||||
check: Seleccionar
|
||||
check_all: Todos
|
||||
check_none: Ninguno
|
||||
mailer:
|
||||
comment:
|
||||
subject: Alguien ha comentado en tu debate
|
||||
subject: Alguien ha comentado en tu propuesta
|
||||
reply:
|
||||
subject: Alguien ha respondido a tu comentario
|
||||
unauthorized:
|
||||
@@ -207,7 +301,19 @@ es:
|
||||
manage:
|
||||
all: "No tienes permiso para realizar la acción '%{action}' sobre %{subject}."
|
||||
welcome:
|
||||
last_debates: Últimos debates
|
||||
signed_in_home_title: Actividad reciente
|
||||
debates:
|
||||
title: "Debates"
|
||||
description: "Encontrarnos, debatir y compartir lo que nos parece importante en nuestra ciudad."
|
||||
proposal:
|
||||
title: "Propones"
|
||||
description: "Espacio abierto para propuestas ciudadanas sobre el tipo de ciudad en el que queremos vivir."
|
||||
decide:
|
||||
title: "Decides"
|
||||
description: "La ciudadanía decide si acepta o rechaza las propuestas más apoyadas."
|
||||
do:
|
||||
title: "Se hace"
|
||||
description: "Si la propuesta es aceptada mayoritariamente, el Ayuntamiento la asume como propia y se hace."
|
||||
welcome:
|
||||
title: Verificación de cuenta
|
||||
instructions_1_html: "Bienvenido a la página de participación ciudadana"
|
||||
|
||||
@@ -8,10 +8,14 @@ en:
|
||||
truncate: "…"
|
||||
helpers:
|
||||
page_entries_info:
|
||||
entry:
|
||||
zero: "entries"
|
||||
one: "entry"
|
||||
other: "entries"
|
||||
one_page:
|
||||
display_entries:
|
||||
zero: "No %{entry_name} found"
|
||||
one: "Displaying <b>1</b> %{entry_name}"
|
||||
other: "Displaying <b>all %{count}</b> %{entry_name}"
|
||||
more_pages:
|
||||
display_entries: "Displaying %{entry_name} <b>%{first} - %{last}</b> of <b>%{total}</b> in total"
|
||||
display_entries: "Displaying %{entry_name} <b>%{first} - %{last}</b> of <b>%{total}</b> in total"
|
||||
|
||||
@@ -8,10 +8,14 @@ es:
|
||||
truncate: "…"
|
||||
helpers:
|
||||
page_entries_info:
|
||||
entry:
|
||||
zero: "entradas"
|
||||
one: "entrada"
|
||||
other: "entradas"
|
||||
one_page:
|
||||
display_entries:
|
||||
zero: "No se han encontrado %{entry_name}"
|
||||
one: "Encontrado <b>1</b> %{entry_name}"
|
||||
other: "Encontrados <b> %{count}</b> %{entry_name}"
|
||||
one: "Hay <b>1</b> %{entry_name}"
|
||||
other: "Hay <b> %{count}</b> %{entry_name}"
|
||||
more_pages:
|
||||
display_entries: "Se muestran <b> del %{first} al %{last}</b> de un total de <b>%{total}</b> %{entry_name}"
|
||||
display_entries: "Mostrando <b>%{first} - %{last}</b> de un total de <b>%{total}</b> %{entry_name}"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
en:
|
||||
moderation:
|
||||
menu:
|
||||
proposals: Proposals
|
||||
flagged_debates: Debates
|
||||
flagged_comments: Comments
|
||||
users: Ban users
|
||||
@@ -42,6 +43,25 @@ en:
|
||||
all: All
|
||||
pending_flag_review: Pending
|
||||
with_ignored_flag: Ignored
|
||||
proposals:
|
||||
index:
|
||||
hide_proposals: Hide proposals
|
||||
block_authors: Block authors
|
||||
ignore_flags: Ignore flags
|
||||
title: Proposals
|
||||
headers:
|
||||
proposal: Proposal
|
||||
moderate: Moderate
|
||||
filter: Filter
|
||||
filters:
|
||||
all: All
|
||||
pending_flag_review: Pending
|
||||
with_ignored_flag: Ignored
|
||||
order: Order
|
||||
orders:
|
||||
created_at: Newest
|
||||
flags: Most flagged
|
||||
confirm: Are you sure?
|
||||
bulk:
|
||||
index:
|
||||
title: Bulk moderation
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
es:
|
||||
moderation:
|
||||
menu:
|
||||
proposals: Propuestas
|
||||
flagged_debates: Debates
|
||||
flagged_comments: Comentarios
|
||||
users: Bloquear usuarios
|
||||
@@ -42,6 +43,25 @@ es:
|
||||
all: Todos
|
||||
pending_flag_review: Pendientes
|
||||
with_ignored_flag: Ignorados
|
||||
proposals:
|
||||
index:
|
||||
hide_proposals: Ocultar Propuestas
|
||||
block_authors: Bloquear autores
|
||||
ignore_flags: Marcar como revisadas
|
||||
title: Propuestas
|
||||
headers:
|
||||
proposal: Propuesta
|
||||
moderate: Moderar
|
||||
filter: Filtro
|
||||
filters:
|
||||
all: Todas
|
||||
pending_flag_review: Pendientes de revisión
|
||||
with_ignored_flag: Marcadas como revisadas
|
||||
order: Ordenar por
|
||||
orders:
|
||||
created_at: Más recientes
|
||||
flags: Más denunciadas
|
||||
confirm: ¿Estás seguro?
|
||||
bulk:
|
||||
index:
|
||||
title: Moderar en bloque
|
||||
|
||||
@@ -5,4 +5,7 @@ en:
|
||||
official_level_3_name: "Level 3 official positions"
|
||||
official_level_4_name: "Level 4 official positions"
|
||||
official_level_5_name: "Level 5 official positions"
|
||||
max_ratio_anon_votes_on_debates: "Max allowed percentage of anonymous votes per debate"
|
||||
max_ratio_anon_votes_on_debates: "Max allowed percentage of anonymous votes per Debate"
|
||||
max_votes_for_proposal_edit: "Number of votes where a Proposal is not editable anymore"
|
||||
proposal_code_prefix: "Prefix for Proposals codes"
|
||||
votes_for_proposal_success: "Number of votes needed for Proposal approval"
|
||||
@@ -5,4 +5,7 @@ es:
|
||||
official_level_3_name: "Cargos públicos de nivel 3"
|
||||
official_level_4_name: "Cargos públicos de nivel 4"
|
||||
official_level_5_name: "Cargos públicos de nivel 5"
|
||||
max_ratio_anon_votes_on_debates: "Porcentaje máximo de votos anónimos por debate"
|
||||
max_ratio_anon_votes_on_debates: "Porcentaje máximo de votos anónimos por Debate"
|
||||
max_votes_for_proposal_edit: "Número de votos en que una Propuesta deja de poderse editar"
|
||||
proposal_code_prefix: "Prefijo para los códigos de Propuestas"
|
||||
votes_for_proposal_success: "Número de votos necesarios para aprobar una Propuesta"
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user