Merge branch 'master' into poll-shifts

This commit is contained in:
Raimond Garcia
2017-09-05 14:45:31 +02:00
committed by GitHub
127 changed files with 2421 additions and 293 deletions

View File

@@ -1,22 +1,46 @@
# Código de conducta
# Código de Conducta convenido para Contribuyentes
Como las personas encargadas de contribuir código y responsables de mantener este proyecto, y con la intención de crear una comunidad abierta en la que sentirse bienvenido acordamos respetar a toda persona que contribuya al proyecto reportando incidencias, creando peticiones de funcionalidades, actualizando la documentación, enviando parches de código o de alguna otra manera.
## Nuestro compromiso
Estamos comprometidos a hacer de la participación en este proyecto una experiencia libre de acoso para todo el mundo, independientemente del nivel de experiencia, género, identidad y expresión de género, orientación sexual, discapacidad, apariencia personal, raza, etnia, edad, religión o nacionalidad.
En el interés de fomentar una comunidad abierta y acogedora, nosotros como contribuyentes y administradores nos comprometemos a hacer de la participación en nuestro proyecto y nuestra comunidad una experiencia libre de acoso para todos, independientemente de la edad, dimensión corporal, discapacidad, etnia, identidad y expresión de género, nivel de experiencia, nacionalidad, apariencia física, raza, religión, identidad u orientación sexual.
Ejemplos de comportamiento inaceptable por parte de los participantes incluyen:
## Nuestros estándares
* El uso de imágenes o lenguaje sexual
* Ataques personales
* Comentarios insultantes/despectivos
Ejemplos de comportamiento que contribuyen a crear un ambiente positivo:
* Uso de lenguaje amable e inclusivo
* Respeto a diferentes puntos de vista y experiencias
* Aceptación de críticas constructivas
* Enfocarse en lo que es mejor para la comunidad
* Mostrar empatía a otros miembros de la comunidad
Ejemplos de comportamiento inaceptable por participantes:
* Uso de lenguaje o imágenes sexuales y atención sexual no deseada
* Comentarios insultantes o despectivos (*trolling*) y ataques personales o políticos
* Acoso público o privado
* Publicación de información privada de terceros, como la dirección física o electrónica, sin permiso explícito
* Otras conductas poco éticas o no profesionales
* Publicación de información privada de terceros sin su consentimiento, como direcciones físicas o electrónicas
* Otros tipos de conducta que pudieran considerarse inapropiadas en un entorno profesional.
Los administradores del proyecto tienen el derecho y la responsabilidad de eliminar, editar o rechazar comentarios, commits, código, ediciones de wikis, incidencias y otro tipo de aportaciones que no estén en línea con este Código de Conducta. Por el hecho de adoptar este Código de Conducta, los responsables del proyecto se comprometen a aplicar sus principios de manera justa y consistente en todos los aspectos relacionados con el desarrollo del proyecto. Los responsables del proyecto que no sigan ni obliguen a cumplir este código de conducta pueden ser apartados del equipo del proyecto.
## Nuestras responsabilidades
Este código de conducta tiene validez tanto en el proyecto como en espacios públicos en los que un individuo esté representando al proyecto o a su comunidad.
Los administradores del proyecto son responsables de clarificar los estándares de comportamiento aceptable y se espera que tomen medidas correctivas y apropiadas en respuesta a situaciones de conducta inaceptable.
Las ocurrencias de abuso, acoso u otro comportamiento inaceptable se puede reportar abriendo una incidencia o contactando a uno o más de los miembros del equipo responsable del proyecto.
Los administradores del proyecto tienen el derecho y la responsabilidad de eliminar, editar o rechazar comentarios, *commits*, código, ediciones de documentación, *issues*, y otras contribuciones que no estén alineadas con este Código de Conducta, o de prohibir temporal o permanentemente a cualquier colaborador cuyo comportamiento sea inapropiado, amenazante, ofensivo o perjudicial.
Este Código de Conducta es una adaptación del [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, disponible en [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/)
## Alcance
Este código de conducta aplica tanto a espacios del proyecto como a espacios públicos donde un individuo esté en representación del proyecto o comunidad. Ejemplos de esto incluye el uso de la cuenta oficial de correo electrónico, publicaciones a través de las redes sociales oficiales, o presentaciones con personas designadas en eventos *online* u *offline*. La representación del proyecto puede ser clarificada explicitamente por los administradores del proyecto.
## Aplicación
Ejemplos de abuso, acoso u otro tipo de comportamiento inaceptable puede ser reportado al equipo del proyecto en consul@madrid.es. Todas las quejas serán revisadas e investigadas, generando un resultado apropiado a las circunstancias. El equipo del proyecto está obligado a mantener confidencialidad de la persona que reportó el incidente. Detalles específicos acerca de las políticas de aplicación pueden ser publicadas por separado.
Administradores que no sigan o que no hagan cumplir este Código de Conducta pueden ser eliminados de forma temporal o permanente del equipo administrador.
## Atribución
Este Código de Conducta es una adaptación del [Contributor Covenant][homepage], versión 1.4, disponible en [http://contributor-covenant.org/version/1/4/es/][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/es/

View File

@@ -1,12 +1,12 @@
# Customization
You can modify your own Consul to have your custom visual style, but first you'll have to create a fork from [https://github.com/consul/consul](https://github.com/consul/consul) using Github's "fork" button on top right corner. You can use any other service like Gitlab, but don't forget to put a reference link back to Consul on the footer to comply with project's license (GPL Affero 3).
You can modify your own CONSUL to have your custom visual style, but first you'll have to create a fork from [https://github.com/consul/consul](https://github.com/consul/consul) using Github's "fork" button on top right corner. You can use any other service like Gitlab, but don't forget to put a reference link back to CONSUL on the footer to comply with project's license (GPL Affero 3).
We've created an specific structure where you can overwrite and customize the application in a way that will let you keep updating it from Consul's main repository, without having conflicts on code merging or risking loosing your customization changes. We try to make Consul as vanilla as possible to help other developers onboard the codebase.
We've created an specific structure where you can overwrite and customize the application in a way that will let you keep updating it from CONSUL's main repository, without having conflicts on code merging or risking loosing your customization changes. We try to make CONSUL as vanilla as possible to help other developers onboard the codebase.
## Special Folders and Files
In order to customize your Consul fork, you'll make use of some `custom` folders on the following paths:
In order to customize your CONSUL fork, you'll make use of some `custom` folders on the following paths:
* `config/locales/custom/`
* `app/assets/images/custom/`
@@ -207,7 +207,7 @@ TODO
## Updating
We recommend you to add consul as remote:
We recommend you to add CONSUL as remote:
```
git remote add consul https://github.com/consul/consul

View File

@@ -1,12 +1,12 @@
# Personalización
Puedes modificar consul y ponerle tu propia imagen, para esto debes primero hacer un fork de [https://github.com/consul/consul](https://github.com/consul/consul) creando un repositorio nuevo en Github. Puedes usar otro servicio como Gitlab, pero no te olvides de poner el enlace en el footer a tu repositorio en cumplimiento con la licencia de este proyecto (GPL Affero 3).
Puedes modificar CONSUL y ponerle tu propia imagen, para esto debes primero hacer un fork de [https://github.com/consul/consul](https://github.com/consul/consul) creando un repositorio nuevo en Github. Puedes usar otro servicio como Gitlab, pero no te olvides de poner el enlace en el footer a tu repositorio en cumplimiento con la licencia de este proyecto (GPL Affero 3).
Hemos creado una estructura específica donde puedes sobreescribir y personalizar la aplicación para que puedas actualizar sin que tengas problemas al hacer merge y se sobreescriban por error tus cambios. Intentamos que Consul sea una aplicación Ruby on Rails lo más plain vanilla posible para facilitar el acceso de nuevas desarrolladoras.
Hemos creado una estructura específica donde puedes sobreescribir y personalizar la aplicación para que puedas actualizar sin que tengas problemas al hacer merge y se sobreescriban por error tus cambios. Intentamos que CONSUL sea una aplicación Ruby on Rails lo más plain vanilla posible para facilitar el acceso de nuevas desarrolladoras.
## Ficheros y directorios especiales
Para adaptarlo puedes hacerlo a través de los directorios que están en custom dentro de:
Para adaptar tu fork de CONSUL puedes utilizar alguno de los directorios `custom` que están en las rutas:
* `config/locales/custom/`
* `app/assets/images/custom/`
@@ -207,7 +207,7 @@ TODO
## Actualizar
Te recomendamos que agregues el remote de consul para facilitar este proceso de merge:
Te recomendamos que agregues el remote de CONSUL para facilitar este proceso de merge:
```
git remote add consul https://github.com/consul/consul

View File

@@ -33,6 +33,7 @@ gem 'omniauth-facebook', '~> 4.0.0'
gem 'omniauth-google-oauth2', '~> 0.4.0'
gem 'omniauth-twitter', '~> 1.4.0'
gem 'paperclip', '~> 5.1.0'
gem 'jquery-fileupload-rails'
gem 'paranoia', '~> 2.3.1'
gem 'pg', '~> 0.20.0'
gem 'pg_search', '~> 2.0.1'

View File

@@ -52,7 +52,7 @@ GEM
safely_block (>= 0.1.1)
user_agent_parser
uuidtools
airbrussh (1.2.0)
airbrussh (1.3.0)
sshkit (>= 1.6.1, != 1.7.0)
akami (1.3.1)
gyoku (>= 0.4.0)
@@ -73,7 +73,7 @@ GEM
uniform_notifier (~> 1.10.0)
byebug (9.0.6)
cancancan (1.16.0)
capistrano (3.8.1)
capistrano (3.8.2)
airbrussh (>= 1.0.0)
i18n
rake (>= 10.0.0)
@@ -87,7 +87,7 @@ GEM
capistrano3-delayed-job (1.7.3)
capistrano (~> 3.0, >= 3.0.0)
daemons (~> 1.2.4)
capybara (2.14.0)
capybara (2.14.4)
addressable
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
@@ -95,17 +95,17 @@ GEM
rack-test (>= 0.5.4)
xpath (~> 2.0)
chronic (0.10.2)
ckeditor (4.2.3)
ckeditor (4.2.4)
cocaine
orm_adapter (~> 0.5.0)
climate_control (0.1.0)
climate_control (0.2.0)
cliver (0.3.2)
cocaine (0.5.8)
climate_control (>= 0.0.3, < 1.0)
cocoon (1.2.9)
coffee-rails (4.2.1)
cocoon (1.2.10)
coffee-rails (4.2.2)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.2.x)
railties (>= 4.0.0)
coffee-script (2.4.1)
coffee-script-source
execjs
@@ -120,11 +120,11 @@ GEM
daemons (1.2.4)
dalli (2.7.6)
database_cleaner (1.5.3)
debug_inspector (0.0.2)
delayed_job (4.1.2)
activesupport (>= 3.0, < 5.1)
delayed_job_active_record (4.1.1)
activerecord (>= 3.0, < 5.1)
debug_inspector (0.0.3)
delayed_job (4.1.3)
activesupport (>= 3.0, < 5.2)
delayed_job_active_record (4.1.2)
activerecord (>= 3.0, < 5.2)
delayed_job (>= 3.0, < 5)
devise (3.5.10)
bcrypt (~> 3.0)
@@ -144,10 +144,10 @@ GEM
json
thread
thread_safe
email_spec (2.1.0)
email_spec (2.1.1)
htmlentities (~> 4.3.3)
launchy (~> 2.1)
mail (~> 2.6.3)
mail (~> 2.6)
errbase (0.0.3)
erubis (2.7.0)
execjs (2.7.0)
@@ -158,7 +158,7 @@ GEM
railties (>= 3.0.0)
faker (1.7.3)
i18n (~> 0.5)
faraday (0.11.0)
faraday (0.12.1)
multipart-post (>= 1.2, < 3)
foundation-rails (6.2.4.0)
railties (>= 3.1.0)
@@ -170,12 +170,12 @@ GEM
activesupport (>= 4.1)
railties (>= 4.1)
tzinfo (~> 1.2, >= 1.2.2)
geocoder (1.4.3)
geocoder (1.4.4)
globalid (0.4.0)
activesupport (>= 4.2.0)
graphiql-rails (1.4.1)
graphiql-rails (1.4.2)
rails
graphql (1.6.3)
graphql (1.6.4)
groupdate (3.2.0)
activesupport (>= 3)
gyoku (1.3.1)
@@ -183,9 +183,10 @@ GEM
hashie (3.5.5)
highline (1.7.8)
htmlentities (4.3.4)
httpi (2.4.1)
httpi (2.4.2)
rack
i18n (0.8.4)
socksify
i18n (0.8.6)
i18n-tasks (0.9.15)
activesupport (>= 4.0.2)
ast (>= 2.1.0)
@@ -198,8 +199,12 @@ GEM
terminal-table (>= 1.5.1)
initialjs-rails (0.2.0.5)
railties (>= 3.1, < 6.0)
invisible_captcha (0.9.2)
invisible_captcha (0.9.3)
rails (>= 3.2.0)
jquery-fileupload-rails (0.4.7)
actionpack (>= 3.1)
railties (>= 3.1)
sass (>= 3.2)
jquery-rails (4.3.1)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
@@ -224,7 +229,7 @@ GEM
knapsack (1.13.3)
rake
timecop (>= 0.1.0)
kramdown (1.13.2)
kramdown (1.14.0)
launchy (2.4.3)
addressable (~> 2.3)
letter_opener (1.4.1)
@@ -246,7 +251,7 @@ GEM
mime-types-data (3.2016.0521)
mimemagic (0.3.2)
mini_portile2 (2.2.0)
minitest (5.10.2)
minitest (5.10.3)
mixlib-cli (1.7.0)
mixlib-config (2.2.4)
multi_json (1.12.1)
@@ -259,9 +264,9 @@ GEM
nokogiri (1.8.0)
mini_portile2 (~> 2.2.0)
nori (2.6.0)
oauth (0.5.1)
oauth2 (1.3.1)
faraday (>= 0.8, < 0.12)
oauth (0.5.3)
oauth2 (1.4.0)
faraday (>= 0.8, < 0.13)
jwt (~> 1.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
@@ -328,7 +333,7 @@ GEM
bundler (>= 1.3.0, < 2.0)
railties (= 4.2.9)
sprockets-rails
rails-assets-markdown-it (8.2.1)
rails-assets-markdown-it (8.2.2)
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
rails-dom-testing (1.0.8)
@@ -363,7 +368,7 @@ GEM
rspec-mocks (3.6.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0)
rspec-rails (3.6.0)
rspec-rails (3.6.1)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
@@ -386,14 +391,14 @@ GEM
sshkit (>= 1.2)
safely_block (0.2.0)
errbase
sass (3.4.23)
sass (3.4.25)
sass-rails (5.0.6)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
savon (2.11.1)
savon (2.11.2)
akami (~> 1.2)
builder (>= 2.1.2)
gyoku (~> 1.2)
@@ -408,12 +413,13 @@ GEM
docile (~> 1.1.0)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.0)
simplecov-html (0.10.1)
sitemap_generator (5.3.1)
builder (~> 3.0)
social-share-button (0.10.0)
coffee-rails
spring (2.0.1)
socksify (1.7.1)
spring (2.0.2)
activesupport (>= 4.2)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
@@ -424,23 +430,23 @@ GEM
babel-source (>= 5.8.11)
babel-transpiler
sprockets (>= 3.0.0)
sprockets-rails (3.2.0)
sprockets-rails (3.2.1)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sshkit (1.13.1)
sshkit (1.14.0)
net-scp (>= 1.1.2)
net-ssh (>= 2.8.0)
term-ansicolor (1.6.0)
tins (~> 1.0)
terminal-table (1.7.3)
unicode-display_width (~> 1.1.1)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thor (0.19.4)
thread (0.2.2)
thread_safe (0.3.6)
tilt (2.0.7)
timecop (0.8.1)
tins (1.13.2)
timecop (0.9.1)
tins (1.15.0)
turbolinks (2.5.3)
coffee-rails
turnout (2.4.0)
@@ -452,14 +458,14 @@ GEM
thread_safe (~> 0.1)
uglifier (3.2.0)
execjs (>= 0.3.0, < 3)
unicode-display_width (1.1.3)
unicode-display_width (1.3.0)
unicorn (5.3.0)
kgio (~> 2.6)
raindrops (~> 0.7)
uniform_notifier (1.10.0)
user_agent_parser (2.3.0)
user_agent_parser (2.3.1)
uuidtools (2.1.5)
warden (1.2.6)
warden (1.2.7)
rack (>= 1.0)
wasabi (3.5.0)
httpi (~> 2.0)
@@ -473,7 +479,7 @@ GEM
websocket-extensions (0.1.2)
whenever (0.9.7)
chronic (>= 0.6.3)
xpath (2.0.0)
xpath (2.1.0)
nokogiri (~> 1.3)
PLATFORMS
@@ -515,6 +521,7 @@ DEPENDENCIES
i18n-tasks (~> 0.9.15)
initialjs-rails (~> 0.2.0.5)
invisible_captcha (~> 0.9.2)
jquery-fileupload-rails
jquery-rails (~> 4.3.1)
jquery-ui-rails (~> 6.0.1)
kaminari (~> 1.0.1)
@@ -559,4 +566,4 @@ DEPENDENCIES
whenever (~> 0.9.7)
BUNDLED WITH
1.15.1
1.15.3

View File

@@ -1,6 +1,6 @@
![Logo of Consul](https://raw.githubusercontent.com/consul/consul/master/public/consul_logo.png)
![Logo of CONSUL](https://raw.githubusercontent.com/consul/consul/master/public/consul_logo.png)
# Consul
# CONSUL
Citizen Participation and Open Government Application
@@ -17,7 +17,7 @@ Citizen Participation and Open Government Application
[![Join the chat at https://gitter.im/consul/consul](https://badges.gitter.im/consul/consul.svg)](https://gitter.im/consul/consul?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/consul/consul/issues?q=is%3Aissue+is%3Aopen+label%3APRs-welcome)
This is the opensource code repository of the eParticipation website originally developed for the Madrid City government eParticipation website
This is the opensource code repository of the eParticipation website CONSUL, originally developed for the Madrid City government eParticipation website
## Current state
@@ -33,7 +33,7 @@ Frontend tools used include [SCSS](http://sass-lang.com/) over [Foundation](http
**NOTE**: For more detailed instructions check the [docs](https://github.com/consul/consul/tree/master/doc/en/dev_test_setup.md)
Prerequisites: install git, Ruby 2.3.2, bundler gem, ghostscript and PostgreSQL (>=9.4).
Prerequisites: install git, Ruby 2.3.2, bundler gem, and PostgreSQL (>=9.4).
```
git clone https://github.com/consul/consul.git
@@ -104,3 +104,7 @@ Code published under AFFERO GPL v3 (see [LICENSE-AGPLv3.txt](LICENSE-AGPLv3.txt)
## Contributions
See [CONTRIBUTING.md](CONTRIBUTING.md)
## Brand guidelines
If you want to use CONSUL logo you can [download the guidelines](https://raw.githubusercontent.com/consul/consul/master/public/consul_brand.zip) which contains a use guide and different versions and sizes of the logo.

View File

@@ -1,6 +1,6 @@
![Logotipo de Consul](https://raw.githubusercontent.com/consul/consul/master/public/consul_logo.png)
![Logotipo de CONSUL](https://raw.githubusercontent.com/consul/consul/master/public/consul_logo.png)
# Consul
# CONSUL
Aplicación de Participación Ciudadana y Gobierno Abierto
@@ -17,7 +17,7 @@ Aplicación de Participación Ciudadana y Gobierno Abierto
[![Join the chat at https://gitter.im/consul/consul](https://badges.gitter.im/consul/consul.svg)](https://gitter.im/consul/consul?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://github.com/consul/consul/issues?q=is%3Aissue+is%3Aopen+label%3APRs-welcome)
Este es el repositorio de código abierto de la Aplicación de Participación Ciudadana Consul, creada originariamente por el Ayuntamiento de Madrid.
Este es el repositorio de código abierto de la Aplicación de Participación Ciudadana CONSUL, creada originariamente por el Ayuntamiento de Madrid.
## Estado del proyecto
@@ -32,7 +32,7 @@ Las herramientas utilizadas para el frontend no están cerradas aún. Los estilo
**NOTA**: para unas instrucciones más detalladas consulta la [documentación](https://github.com/consul/consul/tree/master/doc/es/dev_test_setup.md)
Prerequisitos: tener instalado git, Ruby 2.3.2, la gema `bundler`, ghostscript y PostgreSQL (9.4 o superior).
Prerequisitos: tener instalado git, Ruby 2.3.2, la gema `bundler` y PostgreSQL (9.4 o superior).
```
@@ -101,3 +101,7 @@ El código de este proyecto está publicado bajo la licencia AFFERO GPL v3 (ver
## Contribuciones
Ver fichero [CONTRIBUTING_ES.md](CONTRIBUTING_ES.md)
## Guía de estilo
Si quieres usar el logo de CONSUL puedes [descargar la guía de estilo](https://raw.githubusercontent.com/consul/consul/master/public/consul_brand.zip) que contiene una guía de uso y diferentes versiones y tamaños del logo.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -14,6 +14,7 @@
//= require jquery_ujs
//= require jquery-ui/widgets/datepicker
//= require jquery-ui/i18n/datepicker-es
//= require jquery-fileupload/basic
//= require foundation
//= require turbolinks
//= require ckeditor/loader
@@ -59,6 +60,7 @@
//= require legislation_annotatable
//= require watch_form_changes
//= require followable
//= require documentable
//= require tree_navigator
//= require custom
@@ -94,6 +96,7 @@ var initialize_modules = function() {
App.LegislationAnnotatable.initialize();
App.WatchFormChanges.initialize();
App.TreeNavigator.initialize();
App.Documentable.initialize();
};
$(function(){

View File

@@ -0,0 +1,101 @@
App.Documentable =
initialize: ->
@initializeDirectUploads()
@initializeInterface()
initializeDirectUploads: ->
$('input.document_ajax_attachment[type=file]').fileupload
paramName: "document[attachment]"
formData: null
add: (e, data) ->
wrapper = $(e.target).closest('.document')
index = $(e.target).data('index')
is_nested_document = $(e.target).data('nested-document')
$(wrapper).find('.progress-bar-placeholder').empty()
data.progressBar = $(wrapper).find('.progress-bar-placeholder').html('<div class="progress-bar"><div class="loading-bar uploading"></div></div>')
$(wrapper).find('.progress-bar-placeholder').css('display','block')
data.formData = {
"document[title]": $(wrapper).find('input.document-title').val() || data.files[0].name
"index": index,
"nested_document": is_nested_document
}
data.submit()
change: (e, data) ->
wrapper = $(e.target).parent()
$.each(data.files, (index, file)->
$(wrapper).find('.file-name').text(file.name)
)
progress: (e, data) ->
progress = parseInt(data.loaded / data.total * 100, 10)
$(data.progressBar).find('.loading-bar').css 'width', progress + '%'
return
initializeInterface: ->
input_files = $('input.document_ajax_attachment[type=file]')
$.each input_files, (index, file) ->
wrapper = $(file).parent()
App.Documentable.watchRemoveDocumentbutton(wrapper)
watchRemoveDocumentbutton: (wrapper) ->
remove_document_button = $(wrapper).find('.remove-document')
$(remove_document_button).on 'click', (e) ->
e.preventDefault()
$(wrapper).remove()
$('#new_document_link').show()
$('.max-documents-notice').hide()
uploadNestedDocument: (id, nested_document, result) ->
$('#' + id).replaceWith(nested_document)
@updateLoadingBar(id, result)
@initialize()
uploadPlainDocument: (id, nested_document, result) ->
$('#' + id).replaceWith(nested_document)
@updateLoadingBar(id, result)
@initialize()
updateLoadingBar: (id, result) ->
if result
$('#' + id).find('.loading-bar').addClass 'complete'
else
$('#' + id).find('.loading-bar').addClass 'errors'
$('#' + id).find('.progress-bar-placeholder').css('display','block')
new: (nested_fields) ->
$(".documents-list").append(nested_fields)
@initialize()
destroyNestedDocument: (id, notice) ->
$('#' + id).remove()
@updateNotice(notice)
replacePlainDocument: (id, notice, plain_document) ->
$('#' + id).replaceWith(plain_document)
@updateNotice(notice)
@initialize()
updateNotice: (notice) ->
if $('[data-alert]').length > 0
$('[data-alert]').replaceWith(notice)
else
$("body").append(notice)
updateNewDocumentButton: (link) ->
if $('.document').length >= $('.documents').data('max-documents')
$('#new_document_link').hide()
$('.max-documents-notice').removeClass('hide')
$('.max-documents-notice').show()
else if $('#new_document_link').length > 0
$('#new_document_link').replaceWith(link)
$('.max-documents-notice').hide()
else
$('.max-documents-notice').hide()
$(link).insertBefore('.documents hr:last')

View File

@@ -43,6 +43,7 @@ $budget: #7e328a;
$budget-hover: #7571bf;
$highlight: #e7f2fc;
$highlight-soft: #f3f8fd;
$light: #f5f7fa;
$featured: #ffdc5c;

View File

@@ -15,3 +15,4 @@
@import 'annotator_overrides';
@import 'jquery-ui/datepicker';
@import 'datepicker_overrides';
@import 'documentable';

View File

@@ -0,0 +1,59 @@
.progress-bar-placeholder {
display: none;
}
.document-form {
.document .file-name {
margin-top: 0;
}
.progress-bar-placeholder {
margin-bottom: 15px;
}
.document .loading-bar.errors {
margin-top: $line-height * 2;
}
}
.document {
.button {
font-weight: normal;
}
.progress-bar {
width: 100%;
background-color: $light-gray;
}
input.document_ajax_attachment[type=file]{
display: none;
}
.file-name {
margin-top: $line-height / 2;
}
.loading-bar {
height: 5px;
width: 0;
transition: width 500ms ease-out;
&.uploading {
background-color: $dark-gray;
}
&.complete {
background-color: $success-color;
width: 100%;
}
&.errors {
background-color: $alert-color;
width: 100%;
margin-top: $line-height / 2;
}
}
.loading-bar.no-transition {
transition: none;
}
}

View File

@@ -97,6 +97,10 @@
content: '\72';
}
.icon-documents::before {
content: '\68';
}
.icon-proposals::before {
content: '\68';
}

View File

@@ -18,6 +18,7 @@
// 16. Flags
// 17. Activity
// 18. Banners
// 19. Documents
//
// 01. Global styles
@@ -91,6 +92,11 @@ a {
color: $link;
}
.button.hollow.error {
border-color: $alert-border;
color: $color-alert;
}
.postfix.button {
padding: 0;
}
@@ -216,9 +222,8 @@ a {
}
.menu.vertical {
background: #fff;
margin: $line-height 0;
padding: $line-height;
padding: $line-height 0;
li {
margin-bottom: $line-height;
@@ -319,6 +324,10 @@ a {
background: $brand;
}
.align-top {
vertical-align: top;
}
// 02. Header
// ----------
@@ -416,6 +425,7 @@ header {
.menu {
&.is-dropdown-submenu {
background: #fff;
margin: 0;
margin-top: rem-calc(-24);
padding: 0;
@@ -1821,6 +1831,7 @@ table {
.divider {
color: $text-light;
display: inline-block;
}
form {
@@ -2128,3 +2139,125 @@ table {
text-decoration: none;
}
}
// 19. Documents
.document-form form {
.radio-buttons {
label {
margin-right: $line-height;
}
}
.source-option-link {
input {
padding-bottom: 0;
}
.error {
margin-bottom: $line-height;
}
label {
&.error {
margin-bottom: 0;
}
}
}
.source-option-file {
.file-name {
label {
@include breakpoint(small medium) {
float: none;
}
@include breakpoint(large) {
float: left;
}
}
p {
@include breakpoint(small medium) {
float: none;
margin-top: 0;
margin-left: 0;
margin-bottom: 0;
}
@include breakpoint(large) {
float: left;
margin-bottom: 0;
margin-top: $line-height / 2;
margin-left: $line-height;
}
}
}
}
.attachment-errors {
margin-bottom: $line-height;
}
}
.documents-list {
table {
border: 0;
}
td {
position: relative;
@include breakpoint(small) {
float: left;
width: 100%;
}
@include breakpoint(medium) {
float: none;
}
a {
width: 100%;
}
&:first-child {
padding-left: $line-height * 1.5;
@include breakpoint(small) {
width: 100%;
}
@include breakpoint(medium) {
width: 70%;
}
@include breakpoint(large) {
width: 80%;
}
}
&:first-child::before {
color: #007bb7;
content: 'G';
font-family: "icons" !important;
font-size: rem-calc(24);
left: rem-calc(6);
position: absolute;
top: 0;
@include breakpoint(small) {
padding-top: rem-calc(12);
}
@include breakpoint(medium) {
padding-top: rem-calc(22);
}
}
}
}

View File

@@ -248,11 +248,13 @@
.debate-form,
.proposal-form,
.budget-investment-form,
.spending-proposal-form {
.spending-proposal-form,
.document-form {
.icon-debates,
.icon-proposals,
.icon-budget {
.icon-budget,
.icon-documents {
font-size: rem-calc(50);
line-height: $line-height;
opacity: 0.5;
@@ -262,7 +264,8 @@
color: $debates;
}
.icon-proposals {
.icon-proposals,
.icon-documents {
color: $proposals;
}
@@ -294,7 +297,8 @@
}
}
.proposal-form {
.proposal-form,
.document-form {
.recommendations li::before {
color: $proposals;
@@ -311,7 +315,8 @@
.polls-show,
.debate-quiz,
.budget-investment-show,
.draft-panels {
.draft-panels,
.debate-questions {
p {
word-wrap: break-word;
@@ -328,10 +333,13 @@
.whatsapp::before {
background-color: #43d854;
color: #fff;
font-size: 1.7em;
margin-left: rem-calc(0.5);
padding: rem-calc(9.5) rem-calc(9.8);
vertical-align: rem-calc(10);
display: inline-block;
font-size: rem-calc(30);
height: rem-calc(48);
padding-top: rem-calc(9);
text-align: center;
vertical-align: top;
width: rem-calc(48);
}
.edit-debate,
@@ -424,33 +432,30 @@
.document-link,
.video-link {
border: 1px solid $border;
background: $highlight-soft;
border: 1px solid $highlight;
display: block;
margin: $line-height / 2 0;
padding: $line-height / 2;
position: relative;
a {
padding-left: rem-calc(24);
word-wrap: break-word;
}
::before {
color: #007bb7;
content: 'G';
font-family: "icons" !important;
[class^="icon-"] {
display: inline-block;
font-size: rem-calc(24);
left: rem-calc(6);
padding-top: rem-calc(3);
position: absolute;
top: 0;
line-height: $line-height;
vertical-align: middle;
}
}
.video-link {
.icon-document {
color: #007bb7;
}
::before {
.icon-video {
color: #cc181e;
content: 'D';
}
}
@@ -745,6 +750,12 @@
display: none;
}
.document-form{
max-width: 75rem;
margin-left: auto;
margin-right: auto;
}
.more-info {
clear: both;
color: $text-medium;
@@ -874,6 +885,20 @@
}
}
.help-link {
margin-left: $line-height;
position: relative;
&::before {
color: $link;
content: '\4e';
font-family: 'icons';
position: absolute;
left: -24px;
top: -2px;
}
}
// 05. Featured
// ------------
@@ -1480,13 +1505,9 @@
.poll,
.poll-question {
background: #fff;
border-radius: rem-calc(6);
border: 1px solid $border;
margin-bottom: $line-height / 2;
}
.poll {
padding: $line-height;
padding: $line-height / 2;
position: relative;
.icon-poll-answer {

View File

@@ -44,10 +44,12 @@ module Budgets
set_comment_flags(@comment_tree.comments)
load_investment_votes(@investment)
@investment_ids = [@investment.id]
@document = Document.new(documentable: @investment)
end
def create
@investment.author = current_user
recover_documents_from_cache(@investment)
if @investment.save
Mailer.budget_investment_created(@investment).deliver_later
@@ -104,7 +106,8 @@ module Budgets
def investment_params
params.require(:budget_investment).permit(:title, :description, :external_url, :heading_id, :tag_list,
:organization_name, :location, :terms_of_service)
:organization_name, :location, :terms_of_service,
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id])
end
def load_ballot

View File

@@ -58,6 +58,8 @@ module CommentableActions
def update
resource.assign_attributes(strong_params)
recover_documents_from_cache(resource)
if resource.save
redirect_to resource, notice: t("flash.actions.update.#{resource_name.underscore}")
else
@@ -110,4 +112,11 @@ module CommentableActions
nil
end
def recover_documents_from_cache(resource)
return false unless resource.try(:documents)
resource.documents = resource.documents.each do |document|
document.set_attachment_from_cached_attachment if document.cached_attachment.present?
end
end
end

View File

@@ -0,0 +1,100 @@
class DocumentsController < ApplicationController
before_action :authenticate_user!
before_filter :find_documentable, except: :destroy
before_filter :prepare_new_document, only: [:new, :new_nested]
before_filter :prepare_document_for_creation, only: :create
load_and_authorize_resource except: :upload
skip_authorization_check only: :upload
def new
end
def new_nested
end
def create
recover_attachments_from_cache
if @document.save
flash[:notice] = t "documents.actions.create.notice"
redirect_to params[:from]
else
flash[:alert] = t "documents.actions.create.alert"
render :new
end
end
def destroy
respond_to do |format|
format.html do
if @document.destroy
flash[:notice] = t "documents.actions.destroy.notice"
else
flash[:alert] = t "documents.actions.destroy.alert"
end
redirect_to params[:from]
end
format.js do
if @document.destroy
flash.now[:notice] = t "documents.actions.destroy.notice"
else
flash.now[:alert] = t "documents.actions.destroy.alert"
end
end
end
end
def destroy_upload
@document = Document.new(cached_attachment: params[:path])
@document.set_attachment_from_cached_attachment
@document.documentable = @documentable
if @document.attachment.destroy
flash.now[:notice] = t "documents.actions.destroy.notice"
else
flash.now[:alert] = t "documents.actions.destroy.alert"
end
render :destroy
end
def upload
@document = Document.new(document_params.merge(user: current_user))
@document.documentable = @documentable
if @document.valid?
@document.attachment.save
@document.set_cached_attachment_from_attachment(URI(request.url))
else
@document.attachment.destroy
end
end
private
def document_params
params.require(:document).permit(:title, :documentable_type, :documentable_id,
:attachment, :cached_attachment, :user_id)
end
def find_documentable
@documentable = params[:documentable_type].constantize.find_or_initialize_by(id: params[:documentable_id])
end
def prepare_new_document
@document = Document.new(documentable: @documentable, user_id: current_user.id)
end
def prepare_document_for_creation
@document = Document.new(document_params)
@document.documentable = @documentable
@document.user = current_user
end
def recover_attachments_from_cache
if @document.attachment.blank? && @document.cached_attachment.present?
@document.set_attachment_from_cached_attachment
end
end
end

View File

@@ -19,11 +19,13 @@ class ProposalsController < ApplicationController
def show
super
@notifications = @proposal.notifications
@document = Document.new(documentable: @proposal)
redirect_to proposal_path(@proposal), status: :moved_permanently if request.path != proposal_path(@proposal)
end
def create
@proposal = Proposal.new(proposal_params.merge(author: current_user))
recover_documents_from_cache(@proposal)
if @proposal.save
redirect_to share_proposal_path(@proposal), notice: I18n.t('flash.actions.create.proposal')
@@ -75,7 +77,8 @@ class ProposalsController < ApplicationController
def proposal_params
params.require(:proposal).permit(:title, :question, :summary, :description, :external_url, :video_url,
:responsible_name, :tag_list, :terms_of_service, :geozone_id)
:responsible_name, :tag_list, :terms_of_service, :geozone_id,
documents_attributes: [:id, :title, :attachment, :cached_attachment, :user_id] )
end
def retired_params
@@ -121,4 +124,5 @@ class ProposalsController < ApplicationController
def load_successful_proposals
@proposal_successful_exists = Proposal.successful.exists?
end
end

View File

@@ -0,0 +1,41 @@
module DocumentablesHelper
def documentable_class(documentable)
documentable.class.name.parameterize('_')
end
def max_documents_allowed(documentable)
documentable.class.max_documents_allowed
end
def max_file_size(documentable)
bytesToMeg(documentable.class.max_file_size)
end
def accepted_content_types(documentable)
documentable.class.accepted_content_types
end
def accepted_content_types_extensions(documentable_class)
documentable_class.accepted_content_types
.collect{ |content_type| ".#{content_type.split("/").last}" }
.join(",")
end
def humanized_accepted_content_types(documentable)
documentable.class.accepted_content_types
.collect{ |content_type| content_type.split("/").last }
.join(", ")
end
def documentables_note(documentable)
t "documents.form.note", max_documents_allowed: max_documents_allowed(documentable),
accepted_content_types: humanized_accepted_content_types(documentable),
max_file_size: max_file_size(documentable)
end
def max_documents_allowed?(documentable)
documentable.documents.count >= documentable.class.max_documents_allowed
end
end

View File

@@ -0,0 +1,89 @@
module DocumentsHelper
def document_attachment_file_name(document)
document.attachment_file_name
end
def errors_on_attachment(document)
document.errors[:attachment].join(', ') if document.errors.key?(:attachment)
end
def bytesToMeg(bytes)
bytes / Numeric::MEGABYTE
end
def document_nested_field_name(document, index, field)
parent = document.documentable_type.parameterize.underscore
"#{parent.parameterize}[documents_attributes][#{index}][#{field}]"
end
def document_nested_field_id(document, index, field)
parent = document.documentable_type.parameterize.underscore
"#{parent.parameterize}_documents_attributes_#{index}_#{field}"
end
def document_nested_field_wrapper_id(index)
"document_#{index}"
end
def render_destroy_document_link(document, index)
if document.persisted?
link_to t('documents.form.delete_button'),
document_path(document, index: index, nested_document: true),
method: :delete,
remote: true,
data: { confirm: t('documents.actions.destroy.confirm') },
class: "delete float-right"
elsif !document.persisted? && document.cached_attachment.present?
link_to t('documents.form.delete_button'),
destroy_upload_documents_path(path: document.cached_attachment,
nested_document: true,
index: index,
documentable_type: document.documentable_type,
documentable_id: document.documentable_id),
method: :delete,
remote: true,
class: "delete float-right"
else
link_to t('documents.form.delete_button'),
"#",
class: "delete float-right remove-document"
end
end
def render_attachment(document, index)
html = file_field_tag :attachment,
accept: accepted_content_types_extensions(document.documentable_type.constantize),
class: 'document_ajax_attachment',
data: {
url: document_direct_upload_url(document),
cached_attachment_input_field: document_nested_field_id(document, index, :cached_attachment),
multiple: false,
index: index,
nested_document: true
},
name: document_nested_field_name(document, index, :attachment),
id: document_nested_field_id(document, index, :attachment)
if document.attachment.blank? && document.cached_attachment.blank?
klass = document.errors[:attachment].any? ? "error" : ""
html += label_tag document_nested_field_id(document, index, :attachment),
t("documents.form.attachment_label"),
class: "button hollow #{klass}"
if document.errors[:attachment].any?
html += content_tag :small, class: "error" do
errors_on_attachment(document)
end
end
end
html
end
def document_direct_upload_url(document)
upload_documents_url(
documentable_type: document.documentable_type,
documentable_id: document.documentable_id,
format: :js
)
end
end

View File

@@ -40,6 +40,26 @@ module UsersHelper
current_user && current_user.administrator?
end
def current_moderator?
current_user && current_user.moderator?
end
def current_valuator?
current_user && current_user.valuator?
end
def current_manager?
current_user && current_user.manager?
end
def current_poll_officer?
current_user && current_user.poll_officer?
end
def show_admin_menu?
current_administrator? || current_moderator? || current_valuator? || current_manager? || current_poll_officer?
end
def interests_title_text(user)
if current_user == user
t('account.show.public_interests_my_title_list')

View File

@@ -73,6 +73,7 @@ module Abilities
can [:manage], ::Legislation::Question
cannot :comment_as_moderator, [::Legislation::Question, Legislation::Annotation]
can [:create, :destroy], Document
end
end
end

View File

@@ -36,6 +36,9 @@ module Abilities
can [:create, :destroy], Follow
can [:create, :destroy, :new], Document, documentable: { author_id: user.id }
can [:new_nested, :upload, :destroy_upload], Document
unless user.organization?
can :vote, Debate
can :vote, Comment

View File

@@ -1,12 +1,16 @@
class Budget
class Investment < ActiveRecord::Base
include Measurable
include Sanitizable
include Taggable
include Searchable
include Reclassification
include Followable
include Documentable
documentable max_documents_allowed: 3,
max_file_size: 3.megabytes,
accepted_content_types: [ "application/pdf" ]
accepts_nested_attributes_for :documents, allow_destroy: true
acts_as_votable
acts_as_paranoid column: :hidden_at

View File

@@ -0,0 +1,20 @@
module Documentable
extend ActiveSupport::Concern
included do
has_many :documents, as: :documentable, dependent: :destroy
end
module ClassMethods
attr_reader :max_documents_allowed, :max_file_size, :accepted_content_types
private
def documentable(options= {})
@max_documents_allowed = options[:max_documents_allowed]
@max_file_size = options[:max_file_size]
@accepted_content_types = options[:accepted_content_types]
end
end
end

81
app/models/document.rb Normal file
View File

@@ -0,0 +1,81 @@
class Document < ActiveRecord::Base
include DocumentsHelper
include DocumentablesHelper
has_attached_file :attachment, path: ":rails_root/public/system/:class/:prefix/:style/:filename"
attr_accessor :cached_attachment
belongs_to :user
belongs_to :documentable, polymorphic: true
# Disable paperclip security validation due to polymorphic configuration
# Paperclip do not allow to user Procs on valiations definition
do_not_validate_attachment_file_type :attachment
validate :attachment_presence
validate :validate_attachment_content_type, if: -> { attachment.present? }
validate :validate_attachment_size, if: -> { attachment.present? }
validates :title, presence: true
validates :user_id, presence: true
validates :documentable_id, presence: true, if: -> { persisted? }
validates :documentable_type, presence: true, if: -> { persisted? }
after_save :remove_cached_document, if: -> { valid? && persisted? && cached_attachment.present? }
def set_cached_attachment_from_attachment(prefix)
self.cached_attachment = if Paperclip::Attachment.default_options[:storage] == :filesystem
attachment.path
else
prefix + attachment.url
end
end
def set_attachment_from_cached_attachment
self.attachment = if Paperclip::Attachment.default_options[:storage] == :filesystem
File.open(cached_attachment)
else
URI.parse(cached_attachment)
end
end
Paperclip.interpolates :prefix do |attachment, style|
attachment.instance.prefix(attachment, style)
end
def prefix(attachment, style)
if !attachment.instance.persisted?
"cached_attachments/user/#{attachment.instance.user_id}"
else
":attachment/:id_partition"
end
end
private
def validate_attachment_size
if documentable.present? &&
attachment_file_size > documentable.class.max_file_size
errors[:attachment] = I18n.t("documents.errors.messages.in_between",
min: "0 Bytes",
max: "#{max_file_size(documentable)} MB")
end
end
def validate_attachment_content_type
if documentable.present? &&
!accepted_content_types(documentable).include?(attachment_content_type)
errors[:attachment] = I18n.t("documents.errors.messages.wrong_content_type",
content_type: attachment_content_type,
accepted_content_types: humanized_accepted_content_types(documentable))
end
end
def attachment_presence
if attachment.blank? && cached_attachment.blank?
errors[:attachment] = I18n.t("errors.messages.blank")
end
end
def remove_cached_document
File.delete(cached_attachment) if File.exists?(cached_attachment)
end
end

View File

@@ -9,6 +9,11 @@ class Proposal < ActiveRecord::Base
include HasPublicAuthor
include Graphqlable
include Followable
include Documentable
documentable max_documents_allowed: 3,
max_file_size: 3.megabytes,
accepted_content_types: [ "application/pdf" ]
accepts_nested_attributes_for :documents, allow_destroy: true
acts_as_votable
acts_as_paranoid column: :hidden_at

View File

@@ -1,14 +1,9 @@
<% provide :title do %><%= t('budgets.index.title') %><% end %>
<% content_for :canonical do %>
<%= render "shared/canonical", href: budgets_url %>
<% end %>
<div class="expanded budget no-margin-top padding">
<div class="row">
<div class="small-12 column">
<h1><%= t('budgets.index.title') %></h1>
</div>
</div>
</div>
<%= render "shared/section_header", i18n_namespace: "budgets.index.section_header", image: "budgets" %>
<div class="row margin-top">
<div class="small-12 medium-9 column">
@@ -32,5 +27,16 @@
<% end %>
</tbody>
</table>
<div id="section_help" class="margin" data-magellan-target="section_help">
<p class="lead">
<strong><%= t("budgets.index.section_footer.title") %></strong>
</p>
<p><%= t("budgets.index.section_footer.help_text_1") %></p>
<p><%= t("budgets.index.section_footer.help_text_2") %></p>
<p><%= t("budgets.index.section_footer.help_text_3",
org: link_to(setting['org_name'], new_user_registration_path)).html_safe %></p>
<p><%= t("budgets.index.section_footer.help_text_4") %></p>
</div>
</div>
</div>

View File

@@ -17,6 +17,14 @@
</h3>
<% end %>
</li>
<li class="tabs-title">
<%= link_to "#tab-documents" do %>
<h3>
<%= t("documents.tab") %>
(<%= @investment.documents.count %>)
</h3>
<% end %>
</li>
</ul>
</div>
</div>

View File

@@ -21,6 +21,10 @@
<%= f.text_field :external_url %>
</div>
<div class="documents small-12 column" data-max-documents="<%= Budget::Investment.max_documents_allowed %>">
<%= render 'documents/nested_documents', documentable: @investment %>
</div>
<div class="small-12 column">
<%= f.text_field :location %>
</div>

View File

@@ -4,6 +4,12 @@
<div class="small-12 medium-9 column">
<%= back_link_to budget_investments_path(investment.budget, heading_id: investment.heading) %>
<% if can?(:create, @document) && investment.documents.size < Budget::Investment.max_documents_allowed %>
<%= link_to t("documents.upload_document"),
new_document_path(documentable_id:investment, documentable_type: investment.class.name, from: request.url),
class: 'button hollow float-right' %>
<% end %>
<h1><%= investment.title %></h1>
<div class="budget-investment-info">
@@ -14,7 +20,6 @@
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<%= investment.heading.name %>
</div>
<br>
<p id="investment_code">
<%= t("budgets.investments.show.code_html", code: investment.id) %>
@@ -51,6 +56,7 @@
<h2><%= t('budgets.investments.show.price_explanation') %></h2>
<p><%= investment.price_explanation %></p>
<% end %>
</div>
<aside class="small-12 medium-3 column">

View File

@@ -19,4 +19,11 @@
comment_flags: @comment_flags,
display_comments_count: false } %>
</div>
<div class="tabs-panel" id="tab-documents">
<%= render 'documents/documents',
documents: @investment.documents,
max_documents_allowed: Budget::Investment.max_documents_allowed %>
</div>
</div>

View File

@@ -2,9 +2,9 @@
style="<%= results_type != :compatible ? 'display: none' : '' %>"
id="<%= results_type %>-container">
<h3 class="inline-block">
<h4 class="inline-block">
<%= title %>
</h3>
</h4>
<table id="budget-investments-<%= results_type %>" class="table-for-mobile">
<thead>

View File

@@ -37,21 +37,20 @@
<div class="row">
<div class="small-12 medium-3 large-2 column">
<div class="row">
<ul class="menu vertical no-margin-top no-padding-top">
<h3>
<%= t("budgets.results.heading_selection_title") %>
</h3>
<h3 class="margin-bottom">
<%= t("budgets.results.heading_selection_title") %>
</h3>
<ul class="menu vertical no-margin-top no-padding-top">
<% @budget.headings.order('id ASC').each do |heading| %>
<li>
<%= link_to heading.name,
budget_results_path(@budget, heading_id: heading.to_param),
class: heading.to_param == @heading.to_param ? 'active' : '' %>
</li>
<% end %>
</ul>
</div>
<% @budget.headings.order('id ASC').each do |heading| %>
<li>
<%= link_to heading.name,
budget_results_path(@budget, heading_id: heading.to_param),
class: heading.to_param == @heading.to_param ? 'active' : '' %>
</li>
<% end %>
</ul>
</div>
<span class="float-right"><%= link_to t("budgets.results.show_all_link"), "#", class: "js-toggle-link button hollow margin-bottom", data: {'toggle-selector' => '.js-discarded', 'toggle-text' => t("budgets.results.hide_discarded_link")} %></span>

View File

@@ -6,13 +6,13 @@
title="<%= t('shared.flag') %>">
<span class="icon-flag flag-disable"></span>
</a>
<div id="flag-drop-comment-<%= comment.id %>"
<span id="flag-drop-comment-<%= comment.id %>"
class="dropdown-pane"
data-dropdown
data-auto-focus="true">
<%= link_to t("shared.flag"), flag_comment_path(comment), method: :put,
remote: true, id: "flag-comment-#{comment.id}" %>
</div>
</span>
<% end %>
<% if show_unflag_action? comment %>
@@ -22,9 +22,9 @@
title="<%= t('shared.unflag') %>">
<span class="icon-flag flag-active"></span>
</a>
<div class="dropdown-pane" id="unflag-drop-comment-<%= comment.id %>" data-dropdown data-auto-focus="true">
<span class="dropdown-pane" id="unflag-drop-comment-<%= comment.id %>" data-dropdown data-auto-focus="true">
<%= link_to t("shared.unflag"), unflag_comment_path(comment), method: :put,
remote: true, id: "unflag-comment-#{comment.id}" %>
</div>
</span>
<% end %>
</span>

View File

@@ -3,17 +3,17 @@
<a id="flag-expand-debate-<%= debate.id %>" data-toggle="flag-drop-debate-<%= debate.id %>" title="<%= t('shared.flag') %>">
<span class="icon-flag flag-disable"></span>
</a>
<div class="dropdown-pane" id="flag-drop-debate-<%= debate.id %>" data-dropdown data-auto-focus="true">
<span class="dropdown-pane" id="flag-drop-debate-<%= debate.id %>" data-dropdown data-auto-focus="true">
<%= link_to t('shared.flag'), flag_debate_path(debate), method: :put, remote: true, id: "flag-debate-#{ debate.id }" %>
</div>
</span>
<% end %>
<% if show_unflag_action? debate %>
<a id="unflag-expand-debate-<%= debate.id %>" data-toggle="unflag-drop-debate-<%= debate.id %>" title="<%= t('shared.unflag') %>">
<span class="icon-flag flag-active"></span>
</a>
<div class="dropdown-pane" id="unflag-drop-debate-<%= debate.id %>" data-dropdown data-auto-focus="true">
<span class="dropdown-pane" id="unflag-drop-debate-<%= debate.id %>" data-dropdown data-auto-focus="true">
<%= link_to t('shared.unflag'), unflag_debate_path(debate), method: :put, remote: true, id: "unflag-debate-#{ debate.id }" %>
</div>
</span>
<% end %>
</span>

View File

@@ -9,8 +9,6 @@
<% end %>
<main>
<h1 class="show-for-sr"><%= t("shared.outline.debates") %></h1>
<% if @search_terms || @advanced_search_terms || @tag_filter %>
<div class="highlight no-margin-top padding margin-bottom">
<div class="row">
@@ -33,6 +31,8 @@
</div>
</div>
</div>
<% else %>
<%= render "shared/section_header", i18n_namespace: "debates.index.section_header", image: "debates" %>
<% end %>
<div class="row">
@@ -56,6 +56,21 @@
<%= render @debates %>
<%= paginate @debates %>
<% unless @search_terms || @advanced_search_terms || @tag_filter %>
<div id="section_help" class="margin" data-magellan-target="section_help">
<p class="lead">
<strong><%= t("debates.index.section_footer.title") %></strong>
</p>
<p><%= t("debates.index.section_footer.help_text_1") %></p>
<p><%= t("debates.index.section_footer.help_text_2",
org: link_to(setting['org_name'], new_user_registration_path)).html_safe %></p>
<p><%= t("debates.index.section_footer.help_text_3",
proposal: link_to(t("debates.index.section_footer.proposals_link"), proposals_path),
budget: link_to(t("debates.index.section_footer.budget_link"), budgets_path)).html_safe %>
</p>
</div>
<% end %>
</div>
<div class="small-12 medium-3 column">

View File

@@ -0,0 +1,20 @@
<tr id="<%= dom_id(document)%>">
<td class="document-link">
<%= document.title %>
</td>
<td class="text-center">
<%= link_to t('documents.buttons.download_document'),
document.attachment.url,
target: "_blank",
rel: "nofollow",
class: 'button hollow' %>
</td>
<td class="text-center">
<% if can? :destroy, Document %>
<%= link_to t('documents.buttons.destroy_document'),
document_path(document, from: request.url), method: :delete,
data: { confirm: t('documents.actions.destroy.confirm') },
class: 'button hollow alert' %>
<% end %>
</td>
</tr>

View File

@@ -0,0 +1,35 @@
<% if documents.any? %>
<% if documents.size == max_documents_allowed && can?(:create, Document) %>
<div class="row documents-list">
<div class="small-12 column">
<div class="callout warning text-center">
<%= t "documents.max_documents_allowed_reached_html" %>
</div>
</div>
</div>
<% end %>
<div class="row documents-list">
<div class="small-12 column">
<table>
<tbody>
<% documents.each do |document| %>
<%= render "documents/document", document: document %>
<% end %>
</tbody>
</table>
</div>
</div>
<% else %>
<div class="row">
<div class="small-12 column">
<div class="callout primary text-center">
<%= t('documents.no_documents') %>
</div>
</div>
</div>
<% end %>

View File

@@ -0,0 +1,20 @@
<%= form_for @document,
url: documents_path(
documentable_type: @document.documentable_type,
documentable_id: @document.documentable_id,
from: params[:from]
),
html: { multipart: true, class: "documentable"},
data: { direct_upload_url: upload_documents_url(documentable_type: @document.documentable_type, documentable_id: @document.documentable_id) } do |f| %>
<%= render 'shared/errors', resource: @document %>
<div class="row">
<%= render 'plain_fields', document: @document %>
<div class="actions small-12 medium-6 large-4 end column">
<%= f.submit(t("documents.form.submit_button"), class: "button expanded") %>
</div>
</div>
<% end %>

View File

@@ -0,0 +1,22 @@
<div class="documents-list">
<%= label_tag :documents, t("documents.form.title") %>
<p class="help-text"><%= documentables_note(documentable) %></p>
<% documentable.documents.each_with_index do |document, index| %>
<%= render 'documents/nested_fields', document: document, index: index, documentable: documentable %>
<% end %>
</div>
<% unless max_documents_allowed?(documentable) %>
<%= link_to t("documents.form.add_new_document"),
new_nested_documents_path(documentable_type: documentable.class.name, index: documentable.documents.size),
remote: true,
id: "new_document_link",
class: "button hollow" %>
<% end %>
<div class="max-documents-notice callout warning text-center <%= "hide" unless max_documents_allowed?(documentable) %>">
<%= t "documents.max_documents_allowed_reached_html" %>
</div>
<hr>

View File

@@ -0,0 +1,31 @@
<div id="<%= document_nested_field_wrapper_id(index) %>" class="document">
<%= hidden_field_tag :id,
document.id,
name: document_nested_field_name(document, index, :id),
id: document_nested_field_id(document, index, :id) if document.persisted? %>
<%= hidden_field_tag :user_id,
current_user.id,
name: document_nested_field_name(document, index, :user_id),
id: document_nested_field_id(document, index, :user_id) %>
<%= hidden_field_tag :cached_attachment,
document.cached_attachment,
name: document_nested_field_name(document, index, :cached_attachment),
id: document_nested_field_id(document, index, :cached_attachment) %>
<%= label_tag :title, t("activerecord.attributes.document.title") %>
<%= text_field_tag :title,
document.title,
name: document_nested_field_name(document, index, :title),
id: document_nested_field_id(document, index, :title),
class: "document-title" %>
<% if document.errors[:title].any? %>
<small class="error"><%= document.errors[:title].join(", ") %></small>
<% end %>
<%= render_attachment(document, index) %>
<%= render_destroy_document_link(document, index) %>
<p class="file-name"><%= document_attachment_file_name(document) %></p>
<div class="progress-bar-placeholder"><div class="loading-bar"></div></div>
<hr>
</div>

View File

@@ -0,0 +1,50 @@
<div id="plain_document_fields" class="document">
<div class="small-12 column">
<%= label_tag :document_title, t("activerecord.attributes.document.title") %>
<%= text_field_tag :document_title, document.title, name: "document[title]", class: "document-title" %>
<% if document.errors.has_key?(:title) %>
<small class="error"><%= document.errors[:title].join(", ") %></small>
<% end %>
</div>
<div class="small-12 column">
<%= hidden_field_tag :cached_attachment, document.cached_attachment, name: "document[cached_attachment]" %>
<%= file_field_tag :attachment,
accept: accepted_content_types_extensions(document.documentable.class),
label: false,
class: 'document_ajax_attachment',
data: {
url: upload_documents_url(documentable_type: document.documentable_type, documentable_id: document.documentable_id),
cached_attachment_input_field: "document_cached_attachment",
multiple: false,
nested_document: false
},
id: "document_attachment",
name: "document[attachment]" %>
<% if document.cached_attachment.blank? %>
<%= label_tag :document_attachment, t("documents.form.attachment_label"), class: 'button hollow' %>
<% else %>
<%= link_to t('documents.form.delete_button'),
destroy_upload_documents_path(path: document.cached_attachment,
nested_document: false,
documentable_type: document.documentable_type,
documentable_id: document.documentable_id),
method: :delete,
remote: true,
class: "delete float-right" %>
<% end %>
<% if document.errors.has_key?(:attachment) %>
<div class="small-12 column source-option-file">
<div class="attachment-errors">
<small class="error"><%= errors_on_attachment(document) %></small>
</div>
</div>
<% end %>
<p class="file-name"><%= document_attachment_file_name(document) %></p>
<div class="progress-bar-placeholder"><div class="loading-bar"></div></div>
</div>
</div>

View File

@@ -0,0 +1,17 @@
<% if params[:nested_document] == "true" %>
App.Documentable.destroyNestedDocument("<%= document_nested_field_wrapper_id(params[:index]) %>", "<%= j render('layouts/flash') %>")
<% new_document_link = link_to t("documents.form.add_new_document"),
new_nested_documents_path(documentable_type: @document.documentable_type, index: params[:index]),
remote: true,
id: "new_document_link",
class: "button hollow" %>
App.Documentable.updateNewDocumentButton("<%= j new_document_link %>")
<% else %>
App.Documentable.replacePlainDocument("plain_document_fields",
"<%= j render('layouts/flash') %>",
"<%= j render('plain_fields', document: @document) %>")
<% end %>

View File

@@ -0,0 +1,27 @@
<div class="document-form <%= documentable_class(@document.documentable) %> row">
<div class="small-12 medium-9 column">
<%= back_link_to params[:from] %>
<h1><%= t("documents.new.title") %></h1>
<%= render "documents/form", form_url: documents_url %>
</div>
<div class="small-12 medium-3 column">
<span class="icon-documents float-right"></span>
<h2><%= t("documents.recommendations_title") %></h2>
<ul class="recommendations">
<li>
<%= t "documents.recommendation_one_html",
max_documents_allowed: max_documents_allowed(@document.documentable) %>
</li>
<li>
<%= t "documents.recommendation_two_html",
accepted_content_types: humanized_accepted_content_types(@document.documentable) %>
</li>
<li>
<%= t "documents.recommendation_three_html",
max_file_size: max_file_size(@document.documentable) %>
</li>
</ul>
</div>
</div>

View File

@@ -0,0 +1,9 @@
<%
new_document_link = link_to t("documents.form.add_new_document"),
new_nested_documents_path(documentable_type: params[:documentable_type], index: params[:index].to_i + 1),
remote: true,
id: "new_document_link",
class: "button hollow"
%>
App.Documentable.new("<%= j render('documents/nested_fields', document: @document, index: params[:index]) %>")
App.Documentable.updateNewDocumentButton("<%= j new_document_link %>")

View File

@@ -0,0 +1,12 @@
<% if params[:nested_document] == "true" %>
App.Documentable.uploadNestedDocument("<%= document_nested_field_wrapper_id(params[:index]) %>",
"<%= j render('documents/nested_fields', document: @document, index: params[:index]) %>",
<%= @document.cached_attachment.present? %>)
<% else %>
App.Documentable.uploadPlainDocument("plain_document_fields",
"<%= j render('documents/plain_fields', document: @document) %>",
<%= @document.cached_attachment.present? %>)
<% end %>

View File

@@ -18,7 +18,7 @@
<aside class="small-12 medium-3 column">
<div class="sidebar-divider"></div>
<h2><%= t('legislation.shared.share') %></h2>
<%= render '/legislation/shared/share_buttons',
<%= render '/shared/social_share',
title: t('legislation.shared.share_comment', version_name: @draft_version.title.downcase, process_name: @process.title),
url: legislation_process_draft_version_path(process, draft_version)
%>

View File

@@ -33,7 +33,7 @@
<aside class="small-12 medium-3 column">
<div class="sidebar-divider"></div>
<h2><%= t('legislation.shared.share') %></h2>
<%= render '/legislation/shared/share_buttons',
<%= render '/shared/social_share',
title: t('legislation.shared.share_comment', version_name: @draft_version.title.downcase, process_name: @process.title),
url: legislation_process_draft_version_annotations_path(@process, @draft_version)
%>

View File

@@ -2,12 +2,13 @@
<%= t("layouts.header.collaborative_legislation") %> - <%= t("legislation.processes.index.filters.#{@current_filter}") %>
<% end %>
<div class="row">
<div class="legislation-categories small-12 medium-3 column">
<%= render 'shared/filter_subnav', i18n_namespace: "legislation.processes.index" %>
</div>
<%= render "shared/section_header", i18n_namespace: "legislation.processes.index.section_header", image: "legislation_processes" %>
<div class="row">
<div id="legislation" class="legislation-list small-12 medium-9 column">
<%= render 'shared/filter_subnav', i18n_namespace: "legislation.processes.index" %>
<div id="legislation-list">
<% if @processes.any? %>
<%= render @processes %>
@@ -17,6 +18,16 @@
<%= t(".no_#{@current_filter}_processes") %>
</div>
<% end %>
<div id="section_help" class="margin" data-magellan-target="section_help">
<p class="lead">
<strong><%= t("legislation.processes.index.section_footer.title") %></strong>
</p>
<p><%= t("legislation.processes.index.section_footer.help_text_1") %></p>
<p><%= t("legislation.processes.index.section_footer.help_text_2",
org: setting['org_name']) %></p>
<p><%= t("legislation.processes.index.section_footer.help_text_3") %></p>
</div>
</div>
</div>
</div>

View File

@@ -38,7 +38,7 @@
<aside class="small-12 medium-3 column">
<div id="social-share" class="sidebar-divider"></div>
<h3><%= t('.share') %></h3>
<%= render '/legislation/shared/share_buttons', title: @question.title, url: legislation_process_question_url(@question.process, @question) %>
<%= render '/shared/social_share', title: @question.title, url: legislation_process_question_url(@question.process, @question) %>
</aside>
</div>

View File

@@ -1,9 +0,0 @@
<div class="social-share-full">
<%= social_share_button_tag("#{title} #{setting['twitter_hashtag']}") %>
<% if browser.device.mobile? %>
<a href="whatsapp://send?text=<%= title %> <%= url %>" data-action="share/whatsapp/share">
<span class="icon-whatsapp whatsapp"></span>
<span class="show-for-sr"><%= t("social.whatsapp") %></span>
</a>
<% end %>
</div>

View File

@@ -1,23 +1,14 @@
<% provide :title do %><%= t("polls.index.title") %><% end %>
<% content_for :wrapper_class, "light" %>
<% content_for :canonical do %>
<%= render "shared/canonical", href: polls_url %>
<% end %>
<div class="expanded no-margin-top dark-heading">
<div class="row">
<div class="small-12 medium-6 column padding">
<h1><%= t("polls.index.title") %></h1>
</div>
</div>
</div>
<%= render "shared/section_header", i18n_namespace: "polls.index.section_header", image: "polls" %>
<div class="row">
<div class="small-12 medium-3 column">
<%= render 'shared/filter_subnav_vertical', i18n_namespace: "polls.index" %>
</div>
<div class="small-12 medium-9 column">
<%= render 'shared/filter_subnav', i18n_namespace: "polls.index" %>
<div class="small-12 medium-9 column margin-top">
<% polls_by_geozone_restriction = @polls.group_by(&:geozone_restricted) %>
<% if polls_by_geozone_restriction[false].present? %>
@@ -31,5 +22,15 @@
<% end %>
<%= paginate @polls %>
<div id="section_help" class="margin" data-magellan-target="section_help">
<p class="lead">
<strong><%= t("polls.index.section_footer.title") %></strong>
</p>
<p><%= t("polls.index.section_footer.help_text_1") %></p>
<p><%= t("polls.index.section_footer.help_text_2",
org: link_to(setting['org_name'], new_user_registration_path)).html_safe %></p>
</p>
</div>
</div>
</div>

View File

@@ -1,5 +1,4 @@
<% provide :title do %><%= @poll.name %><% end %>
<% content_for :wrapper_class, "light" %>
<div class="polls-show">
<div class="expanded no-margin-top dark-heading polls-show-header">

View File

@@ -17,6 +17,14 @@
</h3>
<% end %>
</li>
<li class="tabs-title">
<%= link_to "#tab-documents" do %>
<h3>
<%= t("documents.tab") %>
(<%= @proposal.documents.count %>)
</h3>
<% end %>
</li>
</ul>
</div>
</div>

View File

@@ -4,18 +4,18 @@
<a id="flag-expand-proposal-<%= proposal.id %>" data-toggle="flag-drop-proposal-<%= proposal.id %>" title="<%= t('shared.flag') %>">
<span class="icon-flag flag-disable"></span>
</a>
<div class="dropdown-pane" id="flag-drop-proposal-<%= proposal.id %>" data-dropdown data-auto-focus="true">
<span class="dropdown-pane" id="flag-drop-proposal-<%= proposal.id %>" data-dropdown data-auto-focus="true">
<%= link_to t('shared.flag'), flag_proposal_path(proposal), method: :put, remote: true, id: "flag-proposal-#{ proposal.id }" %>
</div>
</span>
<% end %>
<% if show_unflag_action? proposal %>
<a id="unflag-expand-proposal-<%= proposal.id %>" data-toggle="unflag-drop-proposal-<%= proposal.id %>" title="<%= t('shared.unflag') %>">
<span class="icon-flag flag-active"></span>
</a>
<div class="dropdown-pane" id="unflag-drop-proposal-<%= proposal.id %>" data-dropdown data-auto-focus="true">
<span class="dropdown-pane" id="unflag-drop-proposal-<%= proposal.id %>" data-dropdown data-auto-focus="true">
<%= link_to t('shared.unflag'), unflag_proposal_path(proposal), method: :put, remote: true, id: "unflag-proposal-#{ proposal.id }" %>
</div>
</span>
<% end %>
</span>
</span>

View File

@@ -34,7 +34,6 @@
<%= 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") %>
<p class="help-text" id="video-url-help-text"><%= t("proposals.form.proposal_video_url_note") %></p>
@@ -47,6 +46,10 @@
<%= f.text_field :external_url, placeholder: t("proposals.form.proposal_external_url"), label: false %>
</div>
<div class="documents small-12 column" data-max-documents="<%= Proposal.max_documents_allowed %>">
<%= render 'documents/nested_documents', documentable: @proposal %>
</div>
<div class="small-12 medium-6 column">
<%= f.label :geozone_id, t("proposals.form.geozone") %>
<%= f.select :geozone_id, geozone_select_options, {include_blank: t("geozones.none"), label: false} %>

View File

@@ -9,8 +9,6 @@
<% end %>
<main>
<h1 class="show-for-sr"><%= t("shared.outline.proposals") %></h1>
<% if @search_terms || @advanced_search_terms || @tag_filter || params[:retired].present? %>
<div class="highlight no-margin-top padding margin-bottom">
<div class="row">
@@ -35,6 +33,8 @@
</div>
</div>
</div>
<% else %>
<%= render "shared/section_header", i18n_namespace: "proposals.index.section_header", image: "proposals" %>
<% end %>
<div class="row">
@@ -61,13 +61,27 @@
<%= render 'shared/order_links', i18n_namespace: "proposals.index" %>
<div class="show-for-small-only">
<%= link_to t("proposals.index.start_proposal"), new_proposal_path, class: 'button expanded' %>
</div>
<% if @proposals.any? %>
<div class="show-for-small-only">
<%= link_to t("proposals.index.start_proposal"), new_proposal_path, class: 'button expanded' %>
</div>
<% end %>
<div id="proposals-list">
<%= render partial: 'proposals/proposal', collection: @proposals %>
<%= paginate @proposals %>
<% unless @search_terms || @advanced_search_terms || @tag_filter %>
<div id="section_help" class="margin" data-magellan-target="section_help">
<p class="lead">
<strong><%= t("proposals.index.section_footer.title") %></strong>
</p>
<p><%= t("proposals.index.section_footer.help_text_1") %></p>
<p><%= t("proposals.index.section_footer.help_text_2",
org: link_to(setting['org_name'], new_user_registration_path)).html_safe %></p>
<p><%= t("proposals.index.section_footer.help_text_3") %></p>
</div>
<% end %>
</div>
</div>

View File

@@ -16,6 +16,12 @@
<div class="small-12 medium-9 column">
<%= back_link_to %>
<% if can?(:create, @document) && @proposal.documents.size < Proposal.max_documents_allowed %>
<%= link_to t("documents.upload_document"),
new_document_path(documentable_id: @proposal, documentable_type: @proposal.class.name, from: request.url),
class: 'button hollow float-right' %>
<% end %>
<% if author_of?(@proposal, current_user) %>
<%= link_to t("proposals.show.send_notification"), new_proposal_notification_path(proposal_id: @proposal.id),
class: 'button hollow float-right' %>
@@ -77,14 +83,23 @@
<% if @proposal.external_url.present? %>
<div class="document-link">
<%= text_with_links @proposal.external_url %>
<p>
<span class="icon-document"></span>&nbsp;
<strong><%= t('proposals.show.title_external_url') %></strong>
</p>
<%= text_with_links @proposal.external_url %>
</div>
<% end %>
<% if @proposal.video_url.present? %>
<div class="video-link">
<p>
<span class="icon-video"></span>&nbsp;
<strong><%= t('proposals.show.title_video_url') %></strong>
</p>
<%= text_with_links @proposal.video_url %>
</div>
<% end %>
<h4><%= @proposal.question %></h4>
@@ -156,4 +171,10 @@
<div class="tabs-panel is-active" id="tab-comments">
<%= render "proposals/comments" %>
</div>
<div class="tabs-panel" id="tab-documents">
<%= render 'documents/documents',
documents: @proposal.documents,
max_documents_allowed: Proposal.max_documents_allowed %>
</div>
</div>

View File

@@ -1,4 +1,4 @@
<% if current_user %>
<% if show_admin_menu? %>
<li>
<%= link_to t("layouts.header.administration_menu"), "#", rel: "nofollow" %>
<ul class="menu">

View File

@@ -0,0 +1,10 @@
<div class="highlight jumbo">
<div class="row">
<div class="small-12 medium-9 column" data-magellan>
<%= image_tag "help/help_icon_#{image}.png", alt: t("#{i18n_namespace}.icon_alt"), class: "align-top" %>
<h1 class="inline-block"><%= t("#{i18n_namespace}.title") %></h1>
<p class="lead"><%= t("#{i18n_namespace}.description") %></p>
<%= link_to t("#{i18n_namespace}.help"), "#section_help", class: "help-link" %>
</div>
</div>
</div>

View File

@@ -4,7 +4,7 @@
<% end %>
<div class="social-share-full">
<%= social_share_button_tag("#{title} #{setting['twitter_hashtag']}") %>
<a href="whatsapp://send?text=<%= title.gsub(/\s/, '%20') %>&nbsp;<%= url %>"
<a href="whatsapp://send?text=<%= CGI.escape(title) %>&nbsp;<%= url %>"
class="show-for-small-only" data-action="share/whatsapp/share">
<span class="icon-whatsapp whatsapp"></span>
<span class="show-for-sr"><%= t("social.whatsapp") %></span>

View File

@@ -7,28 +7,34 @@
<% if proposal.retired? %>
<td class="text-center">
<td class="text-center" colspan="2">
<span class="label alert"><%= t('users.proposals.retired') %></span>
</td>
<% elsif author?(proposal) %>
<td class="text-center">
<td>
<%= link_to t("users.proposals.send_notification"),
new_proposal_notification_path(proposal_id: proposal.id),
class: 'button hollow' %>
class: 'button hollow expanded' %>
</td>
<td class="text-center">
<td>
<% if proposal.retired? %>
<span class="label alert"><%= t('users.proposals.retired') %></span>
<% else %>
<%= link_to t('users.proposals.retire'),
retire_form_proposal_path(proposal),
class: 'button hollow alert' %>
class: 'button hollow alert expanded' %>
<% end %>
</td>
<% else %>
<td class="text-center" colspan="2">
<%= link_to t('users.proposals.see'), proposal, class: 'button hollow' %>
</td>
<% end %>
</tr>

View File

@@ -2,45 +2,50 @@
<%= render "shared/canonical", href: root_url %>
<% end %>
<div class="expanded highlight padding no-margin-top">
<div class="jumbo highlight">
<div class="row">
<div class="small-12 medium-6 column">
<div class="small-12 medium-9 small-centered column text-center">
<h1><%= t("layouts.header.open_city_title") %></h1>
<p>
<%= t("layouts.header.open_city_slogan_html") %>&nbsp;
<%= link_to t("layouts.header.more_info"), more_info_path %>
<p class="lead">
<%= t("layouts.header.open_city_slogan_html") %>
</p>
<div class="small-12 medium-6">
<%= link_to t("layouts.header.see_all"), proposals_path, class: "button see-more expanded" %>
<div class="small-12 medium-6 large-4 small-centered">
<%= link_to t("layouts.header.more_info"), more_info_path, class: "button expanded large" %>
</div>
</div>
<div class="hide-for-small-only small-12 medium-5 column text-center">
<%= image_tag(image_path_for("icon_home.png"), size: "330x240", alt:"") %>
</div>
</div>
</div>
<% cache [locale_and_user_status, @featured_debates, @featured_proposals, 'featured'] do %>
<main>
<div class="row text-center margin">
<div class="small-12 medium-3 column">
<h2><%= t("welcome.debates.title") %></h2>
<p><%= t("welcome.debates.description") %></p>
<div class="row">
<div class="small-12 medium-6 column">
<p>
<span class="lead"><strong><%= t("welcome.debates.title") %></strong></span><br>
<%= t("welcome.debates.description") %>
</p>
</div>
<div class="small-12 medium-3 column">
<h2><%= t("welcome.proposal.title") %></h2>
<p><%= t("welcome.proposal.description") %></p>
<div class="small-12 medium-6 column">
<p>
<span class="lead"><strong><%= t("welcome.proposal.title") %></strong></span><br>
<%= t("welcome.proposal.description") %>
</p>
</div>
</div>
<div class="small-12 medium-3 column">
<h2><%= t("welcome.decide.title") %></h2>
<p><%= t("welcome.decide.description") %></p>
<div class="row margin-top">
<div class="small-12 medium-6 column">
<p>
<span class="lead"><strong><%= t("welcome.decide.title") %></strong></span><br>
<%= t("welcome.decide.description") %>
</p>
</div>
<div class="small-12 medium-3 column">
<h2><%= t("welcome.do.title") %></h2>
<p><%= t("welcome.do.description") %></p>
<div class="small-12 medium-6 column">
<p>
<span class="lead"><strong><%= t("welcome.do.title") %></strong></span><br>
<%= t("welcome.do.description") %>
</p>
</div>
</div>
</main>

View File

@@ -35,7 +35,7 @@ module Consul
config.time_zone = 'Madrid'
config.active_job.queue_adapter = :delayed_job
# Consul specific custom overrides
# CONSUL specific custom overrides
# Read more on documentation:
# * English: https://github.com/consul/consul/blob/master/CUSTOMIZE_EN.md
# * Spanish: https://github.com/consul/consul/blob/master/CUSTOMIZE_ES.md

View File

@@ -46,7 +46,7 @@ Rails.application.configure do
# Use the lowest log level to ensure availability of diagnostic information
# when problems arise.
config.log_level = :debug
config.log_level = :warn
# Prepend all log lines with the following tags.
# config.log_tags = [ :subdomain, :uuid ]

View File

@@ -37,6 +37,7 @@ data:
- config/locales/%{locale}/officing.yml
- config/locales/%{locale}/budgets.yml
- config/locales/%{locale}/legislation.yml
- config/locales/%{locale}/documents.yml
# Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom:
# `i18n-tasks normalize -p` will force move the keys according to these rules
@@ -114,6 +115,7 @@ ignore_missing:
ignore_unused:
- 'budgets.phase.*'
- 'budgets.investments.index.orders.*'
- 'budgets.index.section_header.*'
- 'activerecord.*'
- 'activemodel.*'
- 'unauthorized.*'
@@ -148,16 +150,20 @@ ignore_unused:
- 'valuation.budget_investments.index.filter*'
- 'users.show.filters.*'
- 'polls.index.filters.*'
- 'polls.index.section_header.*'
- 'debates.index.select_order'
- 'debates.index.orders.*'
- 'debates.index.section_header.*'
- 'proposals.index.select_order'
- 'proposals.index.orders.*'
- 'proposals.index.section_header.*'
- 'spending_proposals.index.search_form.*'
- '*.index.search_form.*'
- 'notifications.index.comments_on*'
- 'notifications.index.replies_to*'
- 'notifications.index.proposal_notification*'
- 'legislation.processes.index.filter*'
- 'legislation.processes.index.section_header.*'
- 'helpers.page_entries_info.*' # kaminari
- 'views.pagination.*' # kaminari
- 'shared.suggest.*'

View File

@@ -76,6 +76,9 @@ en:
legislation/answers:
one: "Answer"
other: "Answers"
documents:
one: "Document"
other: "Documents"
attributes:
budget:
name: "Name"
@@ -197,6 +200,9 @@ en:
value: Value
legislation/annotation:
text: Comment
document:
title: Title
attachment: Attachment
errors:
models:
user:

View File

@@ -879,7 +879,7 @@ en:
content_blocks:
form:
content_blocks_information: Information about content blocks
content_block_about: You can create HTML content blocks to be inserted in the header or the footer of your Consul.
content_block_about: You can create HTML content blocks to be inserted in the header or the footer of your CONSUL.
content_block_top_links_html: "<strong>Header blocks (top_links)</strong> are blocks of links that must have this format:"
content_block_footer_html: "<strong>Footer blocks</strong> can have any format and can be used to insert Javascript, CSS or custom HTML."
create:

View File

@@ -38,6 +38,17 @@ en:
finished: Finished budget
index:
title: Participatory budgets
section_header:
icon_alt: Participatory budgets icon
title: Participatory budgets
description: With the participatory budgets the citizens decide to which projects presented by the neighbors is destined a part of the municipal budget.
help: Help about participatory budgets
section_footer:
title: Help about participatory budgets
help_text_1: "Participatory budgets are processes in which citizens decide directly on what is spent part of the municipal budget. Any registered person over 16 years old can propose an investment project that is preselected in a phase of citizen supports."
help_text_2: "The most voted projects are evaluated and passed to a final vote in which they decide the actions to be carried out by the City Council once the municipal budgets of the next year are approved."
help_text_3: "The presentation of participatory budgeting projects takes place from January and over a period of one and a half months. To participate and propose proposals for the entire city and / or districts, you must sign up on %{org} and verify your account."
help_text_4: "To get as many supports and votes as possible, choose a descriptive and understandable headline for your project. Then you have a space to develop the approach of your proposal. Provide all the data and explanations, and even documents and images, to help other participants to better understand what you are proposing."
investments:
form:
tag_category_label: "Categories"

View File

@@ -0,0 +1,35 @@
en:
documents:
tab: Documents
no_documents: Don't have uploaded documents
upload_document: Upload document
max_documents_allowed_reached_html: You have reached the maximum number of documents allowed! <strong>You have to delete one before you can upload another.</strong>
form:
title: Documents
attachment_label: Choose document
submit_button: Upload document
delete_button: Remove document
note: "You can upload up to a maximum of %{max_documents_allowed} documents of following content types: %{accepted_content_types}, up to %{max_file_size} MB per file."
add_new_document: Add new document
new:
title: Upload document
recommendations_title: File upload tips
recommendation_one_html: You can upload up to a <strong>maximum of %{max_documents_allowed} documents</strong>.
recommendation_two_html: You can upload <strong>%{accepted_content_types}</strong> files.
recommendation_three_html: You can upload files up to <strong>%{max_file_size} MB</strong>.
actions:
create:
notice: Document was created successfully.
alert: Cannot create document. Check form errors and try again.
destroy:
notice: Document was deleted successfully.
alert: Cannot destroy document.
confirm: Are you sure you want to delete the document? This action cannot be undone!
buttons:
download_document: Dowload file
destroy_document: Destroy
errors:
messages:
in_between: must be in between %{min} and %{max}
wrong_content_type: content type %{content_type} does not match any of accepted content types %{accepted_content_types}

View File

@@ -118,6 +118,18 @@ en:
select_order: Order by
start_debate: Start a debate
title: Debates
section_header:
icon_alt: Debates icon
title: Debates
description: Start a debate to share opinions with others about the topics you are concerned about.
help: Help about debates
section_footer:
title: Help about debates
help_text_1: "The space for citizen debates is aimed at anyone who can expose issues of their concern and those who want to share opinions with other people."
help_text_2: 'To open a debate you need to sign up on %{org}. Users can also comment on open debates and rate them with the "I agree" or "I disagree" buttons found in each of them.'
help_text_3: "Keep in mind that a debate does not start any specific action. If you want to make a %{proposal} for the city or raise a investment project of %{budget} when the phase is open, go to the corresponding section."
proposals_link: proposal
budget_link: participatory budgeting
new:
form:
submit_button: Start a debate
@@ -165,6 +177,7 @@ en:
user: Account
verification/sms: phone
signature_sheet: Signature sheet
document: Document
geozones:
none: All city
all: All scopes
@@ -177,10 +190,10 @@ en:
footer:
accessibility: Accessibility
conditions: Terms and conditions of use
consul: Consul application
consul: CONSUL application
consul_url: https://github.com/consul/consul
contact_us: For technical assistance enters
copyright: Consul, %{year}
copyright: CONSUL, %{year}
description: This portal uses the %{consul} which is %{open_source}.
faq: technical assistance
open_data_text: Every detail about the City Council is yours to access.
@@ -205,7 +218,7 @@ en:
external_link_transparency: Transparency
external_link_transparency_url: https://transparency.consul
locale: 'Language:'
logo: Consul logo
logo: CONSUL logo
management: Management
moderation: Moderation
valuation: Valuation
@@ -220,11 +233,10 @@ en:
no_notifications: "You don't have new notifications"
open: open
open_city_slogan_html: There are cities that are governed directly by their inhabitants, who <b>discuss</b> the topics they are concerned about, <b>propose</b> ideas to improve their lives and <b>decide</b> among themselves which ones will be carried out.
open_city_title: Love the city, and it will become a city you love.
open_city_title: Love the city, and it will become a city you love
open_gov: Open government
proposals: Proposals
poll_questions: Voting
see_all: See proposals
budgets: Participatory budgeting
spending_proposals: Spending Proposals
admin:
@@ -351,6 +363,16 @@ en:
title: Proposals
top: Top weekly
top_link_proposals: The most supported proposals by category
section_header:
icon_alt: Proposals icon
title: Proposals
description: Make a citizen proposal. If it gets enough supports it will go to voting phase, so you can get all the citizens to decide how they want their city to be.
help: Help about proposals
section_footer:
title: Help about proposals
help_text_1: "The citizen proposals are an opportunity for neighbours and collectives to decide directly how they want to shape their city. Any person can make a proposal about a topic or concern of their interest, for the City Council to make it, after it gets enough supports to be put to a citizens vote."
help_text_2: "To create a proposal, you must sign up on %{org}. The proposals that get the support of 1% of the users in the web, goes to voting phase. To support proposals it is necessary to have a verified account."
help_text_3: "A citizen vote is celebrated when the proposals get the necessary supports. Once celebrated, if there are more people in favor than against, the City Council assumes the proposal and carries it out."
new:
form:
submit_button: Create proposal
@@ -406,6 +428,8 @@ en:
send_notification: Send notification
no_notifications: "This proposal has any notifications."
embed_video_title: "Video on %{proposal}"
title_external_url: "Additional documentation"
title_video_url: "External video"
update:
form:
submit_button: Save changes
@@ -431,6 +455,15 @@ en:
cant_answer_not_logged_in: "You must sign in or sign up to participate"
cant_answer_verify: "You must verify your account in order to answer"
already_answer: "You already have participated in this poll"
section_header:
icon_alt: Voting icon
title: Voting
description: Sign up to vote on citizen proposals and questions the City Council ask to the neighbors. Make municipal decisions directly.
help: Help about voting
section_footer:
title: Help about voting
help_text_1: "Voting takes place when a citizen proposal supports reaches 1% of the census with voting rights. Voting can also include questions that the City Council ask to the citizens decision."
help_text_2: "To participate in the next vote you have to sign up on %{org} and verify your account. All registered voters in the city over 16 years old can vote. The results of all votes are binding on the government."
show:
dates_title: "Participation dates"
cant_answer_not_logged_in: "You must %{signin} or %{signup} to participate."
@@ -554,8 +587,6 @@ en:
unfollow: "Unfollow"
unfollow_entity: "Unfollow %{entity}"
outline:
debates: Debates
proposals: Proposals
budget: Participatory budget
searcher: Searcher
go_to_page: "Go to page of "
@@ -674,7 +705,8 @@ en:
proposals:
send_notification: "Send notification"
retire: "Retire"
retired: "Retired"
retired: "Retired proposal"
see: "See proposal"
votes:
agree: I agree
anonymous: Too many anonymous votes to admit vote %{verify_account}.

View File

@@ -64,6 +64,16 @@ en:
no_open_processes: There aren't open processes
no_next_processes: There aren't planned processes
no_past_processes: There aren't past processes
section_header:
icon_alt: Legislation processes icon
title: Legislation processes
description: Participate in the debates and processes prior to the approval of a ordinance or a municipal action. Your opinion will be consider by the City Council.
help: Help about legislation processes
section_footer:
title: Help about legislation processes
help_text_1: "In participatory processes, the City Council offers to its citizens the opportunity to participate in the drafting and modification of regulations, affecting the city and to be able to give their opinion on certain actions that it plans to carry out."
help_text_2: "People registered in %{org} can participate with contributions in the public consultation of new ordinances, regulations and guidelines, among others. Your comments are analyzed by the corresponding area and considered for the final drafting of the ordinances."
help_text_3: "The City Council also opens processes to receive contributions and opinions on municipal actions."
phase_not_open:
not_open: This phase is not open yet
phase_empty:

View File

@@ -23,7 +23,7 @@ en:
document_verifications:
already_verified: This user account is already verified.
has_no_account_html: In order to create an account, go to %{link} and click in <b>'Register'</b> in the upper-left part of the screen.
link: Consul
link: CONSUL
in_census_has_following_permissions: 'This user can participate in the website with the following permissions:'
not_in_census: This document is not registered.
not_in_census_info: 'Citizens not in the Census can participate in the website with the following permissions:'

View File

@@ -63,9 +63,9 @@ en:
text: |-
Use it in your local government or help us to improve it, it is free software.
This Open Government Portal use the [Consul app](https://github.com/ayuntamientomadrid 'consul github') that is free software, with [licence AGPLv3](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ), that means in simple words that anyone can use the code freely, copy it, see it in detail, modify it and redistribute it to the word with the modifications he wants (allowing others to do the same). Because we think culture is better and richer when it is released.
This Open Government Portal use the [CONSUL app](https://github.com/ayuntamientomadrid 'consul github') that is free software, with [licence AGPLv3](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ), that means in simple words that anyone can use the code freely, copy it, see it in detail, modify it and redistribute it to the word with the modifications he wants (allowing others to do the same). Because we think culture is better and richer when it is released.
If you are a programmer, you can see the code and help us to improve it at [Consul app](https://github.com/ayuntamientomadrid 'consul github').
If you are a programmer, you can see the code and help us to improve it at [CONSUL app](https://github.com/ayuntamientomadrid 'consul github').
titles:
how_to_use: Use it in your local government
privacy: Privacy Policy

View File

@@ -221,7 +221,8 @@ en:
time:
am: am
formats:
datetime: "%Y-%m-%d %H:%M:%S"
default: "%a, %d %b %Y %H:%M:%S %z"
long: "%B %d, %Y %H:%M"
short: "%d %b %H:%M"
pm: pm
pm: pm

View File

@@ -76,6 +76,9 @@ es:
legislation/answers:
one: "Respuesta"
other: "Respuestas"
documents:
one: "Documento"
other: "Documentos"
attributes:
budget:
name: "Nombre"
@@ -192,6 +195,9 @@ es:
value: Valor
legislation/annotation:
text: Comentario
document:
title: Título
attachment: Archivo adjunto
errors:
models:
user:

View File

@@ -879,7 +879,7 @@ es:
content_blocks:
form:
content_blocks_information: Información sobre los bloques de texto
content_block_about: Puedes crear bloques de HTML que se incrustarán en la cabecera o el pie de tu Cónsul.
content_block_about: Puedes crear bloques de HTML que se incrustarán en la cabecera o el pie de tu CONSUL.
content_block_top_links_html: "Los <strong>bloques de la cabecera (top_links)</strong> son bloques de enlaces que deben crearse con este formato:"
content_block_footer_html: "Los <strong>bloques del pie (footer)</strong> pueden tener cualquier formato y se pueden utilizar para guardar huellas Javascript, contenido CSS o contenido HTML personalizado."
create:

View File

@@ -38,6 +38,17 @@ es:
finished: Resultados
index:
title: Presupuestos participativos
section_header:
icon_alt: Icono de Presupuestos participativos
title: Presupuestos participativos
description: Con los presupuestos participativos la ciudadanía decide a qué proyectos presentados por los vecinos y vecinas va destinada una parte del presupuesto municipal.
help: Ayuda sobre presupuestos participativos
section_footer:
title: Ayuda sobre presupuestos participativos
help_text_1: "Los presupuestos participativos son unos procesos en los que la ciudadanía decide de forma directa en qué se gasta una parte del presupuesto municipal. Cualquier persona empadronada mayor de 16 años puede proponer un proyecto de gasto que se preselecciona en una fase de apoyos ciudadanos."
help_text_2: "Los proyectos más votados se evalúan y pasan a una votación final en la que se deciden las actuaciones que llevará a cabo el Ayuntamiento una vez se aprueben los presupuestos municipales del año próximo."
help_text_3: "La presentación de proyectos de presupuestos participativos se lleva a cabo desde enero y a lo largo de un periodo de mes y medio, aproximadamente. Para participar y plantear propuestas para toda la ciudad y/ los distritos hay que registrarse en %{org} y verificar la cuenta."
help_text_4: "Para conseguir el mayor número de apoyos y votos posible, elige un titular descriptivo y comprensible de tu proyecto. Después tienes un espacio para desarrollar el planteamiento de tu propuesta. Aporta todos los datos y explicaciones, e incluso documentos e imágenes, para ayudar a otras personas participantes a entender mejor lo que planteas."
investments:
form:
tags_instructions: "Etiqueta esta propuesta. Puedes elegir entre las categorías propuestas o introducir las que desees"

View File

@@ -0,0 +1,34 @@
es:
documents:
tab: Documentos
no_documents: No hay documentos subidos
upload_document: Subir documento
max_documents_allowed_reached_html: ¡Has alcanzado el número máximo de documentos permitidos! <strong>Tienes que eliminar uno antes de poder subir otro.</strong>
form:
title: Documentos
attachment_label: Selecciona un documento
submit_button: Subir documento
delete_button: Eliminar documento
note: "Puedes subir hasta un máximo de %{max_documents_allowed} documentos en los formatos: %{accepted_content_types}, y de hasta %{max_file_size} MB por archivo."
add_new_document: Añadir nuevo documento
new:
title: Subir un documento
recommendations_title: Consejos para subir archivos
recommendation_one_html: Puedes subir hasta un máximo de <strong>%{max_documents_allowed} documentos</strong>
recommendation_two_html: Sólo puedes subir <strong>archivos %{accepted_content_types}</strong>.
recommendation_three_html: Puedes subir archivos de hasta <strong>%{max_file_size} MB</strong>
actions:
create:
notice: "El documento se ha creado correctamente."
alert: "El documento no se ha podido crear. Revise los errores del formulario."
destroy:
notice: "El documento se ha eliminado correctamente."
alert: "El documento no se ha podido eliminar."
confirm: "¿Está seguro de que desea eliminar el documento? Esta acción no se puede deshacer!"
buttons:
download_document: Descargar archivo
destroy_document: Eliminar
errors:
messages:
in_between: debe estar entre %{min} y %{max}
wrong_content_type: El tipo de contenido %{content_type} del archivo no coincide con ninguno de los tipos de contenido aceptados %{accepted_content_types}

View File

@@ -118,6 +118,18 @@ es:
select_order: Ordenar por
start_debate: Empieza un debate
title: Debates
section_header:
icon_alt: Icono de Debates
title: Debates
description: Inicia un debate para compartir puntos de vista con otras personas sobre los temas que te preocupan.
help: Ayuda sobre los debates
section_footer:
title: Ayuda sobre los debates
help_text_1: "El espacio de debates ciudadanos está dirigido a que cualquier persona pueda exponer temas que le preocupan y sobre los que quiera compartir puntos de vista con otras personas."
help_text_2: 'Para abrir un debate es necesario registrarse en %{org}. Los usuarios ya registrados también pueden comentar los debates abiertos y valorarlos con los botones de "Estoy de acuerdo" o "No estoy de acuerdo" que se encuentran en cada uno de ellos.'
help_text_3: "Ten en cuenta que un debate no activa ningún mecanismo de actuación concreto. Si quieres hacer una %{proposal} para la ciudad o plantear un proyecto de %{budget} cuando se abra la convocatoria, ve a la sección correspondiente."
proposals_link: propuesta
budget_link: presupuestos participativos
new:
form:
submit_button: Empieza un debate
@@ -165,6 +177,7 @@ es:
user: la cuenta
verification/sms: el teléfono
signature_sheet: la hoja de firmas
document: el documento
geozones:
none: Toda la ciudad
all: Todos los ámbitos de actuación
@@ -177,10 +190,10 @@ es:
footer:
accessibility: Accesibilidad
conditions: Condiciones de uso
consul: aplicación Consul
consul: aplicación CONSUL
consul_url: https://github.com/consul/consul
contact_us: Para asistencia técnica entra en
copyright: Consul, %{year}
copyright: CONSUL, %{year}
description: Este portal usa la %{consul} que es %{open_source}.
faq: Asistencia técnica
open_data_text: Todos los datos del Ayuntamiento son tuyos.
@@ -205,7 +218,7 @@ es:
external_link_transparency: Transparencia
external_link_transparency_url: https://transparency.consul
locale: 'Idioma:'
logo: Consul logo
logo: CONSUL logo
management: Gestión
moderation: Moderar
valuation: Evaluación
@@ -220,11 +233,10 @@ es:
no_notifications: No tienes notificaciones nuevas
open: abierto
open_city_slogan_html: Existen ciudades gobernadas directamente por sus habitantes, que <strong>debaten</strong> sobre temas que les preocupan, <strong>proponen</strong> ideas para mejorar sus vidas y <strong>deciden</strong> entre todas y todos las que se llevan a cabo.
open_city_title: La ciudad que quieres será la ciudad que quieras.
open_city_title: La ciudad que quieres será la ciudad que quieras
open_gov: Gobierno %{open}
proposals: Propuestas
poll_questions: Votaciones
see_all: Ver propuestas
budgets: Presupuestos participativos
spending_proposals: "Propuestas de inversión"
admin:
@@ -351,6 +363,16 @@ es:
title: Propuestas ciudadanas
top: Top semanal
top_link_proposals: Propuestas más apoyadas por categoría
section_header:
icon_alt: Icono de Propuestas
title: Propuestas
description: Haz una propuesta ciudadana. Si obtiene los apoyos suficientes y pasa a votación, puedes conseguir que todos los habitantes decidan cómo quieren que sea nuestra ciudad.
help: Ayuda sobre las propuestas
section_footer:
title: Ayuda sobre las propuestas
help_text_1: "Las propuestas ciudadanas son una oportunidad para que los vecinos y colectivos decidan directamente cómo quieren que sea su ciudad. Cualquier persona puede hacer una propuesta sobre un tema que le interese o preocupe para que el ayuntamiento la lleve a cabo, después de conseguir los apoyos suficientes y de someterse a votación ciudadana."
help_text_2: "Para crear una propuesta hay que registrarse en %{org}. Las propuestas que consigan el apoyo del 1% de la gente en la web, pasan a votación. Para apoyar propuestas es necesario tener una cuenta verificada."
help_text_3: "Se convoca una votación ciudadana cuando las propuestas consiguen los apoyos necesarios. Una vez celebrada, si hay más gente a favor que en contra, el Consistorio asume la propuesta y la lleva a cabo."
new:
form:
submit_button: Crear propuesta
@@ -406,6 +428,8 @@ es:
share: Compartir
no_notifications: "Esta propuesta no tiene notificaciones."
embed_video_title: "Vídeo en %{proposal}"
title_external_url: "Documentación adicional"
title_video_url: "Vídeo externo"
update:
form:
submit_button: Guardar cambios
@@ -431,6 +455,15 @@ es:
cant_answer_not_logged_in: "Necesitas iniciar sesión o registrarte para participar"
cant_answer_verify: "Por favor verifica tu cuenta para poder responder"
already_answer: "Ya has participado en esta votación"
section_header:
icon_alt: Icono de Votaciones
title: Votaciones
description: Regístrate para poder votar propuestas ciudadanas y las cuestiones que pregunta a sus vecinos el Ayuntamiento. Toma decisiones municipales de forma directa.
help: Ayuda sobre las votaciones
section_footer:
title: Ayuda sobre las votaciones
help_text_1: "Las votaciones se convocan cuando una propuesta ciudadana alcanza el 1% de apoyos del censo con derecho a voto. En las votaciones también se pueden incluir cuestiones que el Ayuntamiento somete a decisión directa de la ciudadanía."
help_text_2: "Para participar en la próxima votación tienes que registrarte en %{org} y verificar tu cuenta. Pueden votar todas las personas empadronadas en la ciudad mayores de 16 años. Los resultados de todas las votaciones serán vinculantes para el gobierno."
show:
dates_title: "Fechas de participación"
cant_answer_not_logged_in: "Necesitas %{signin} o %{signup} para participar."
@@ -554,8 +587,6 @@ es:
unfollow: Dejar de seguir
unfollow_entity: "Dejar de seguir %{entity}"
outline:
debates: Debates
proposals: Propuestas
budget: Presupuestos participativos
searcher: Buscador
go_to_page: "Ir a la página de "
@@ -674,7 +705,8 @@ es:
proposals:
send_notification: "Enviar notificación"
retire: "Retirar"
retired: "Retirada"
retired: "Propuesta retirada"
see: "Ver propuesta"
votes:
agree: Estoy de acuerdo
anonymous: Demasiados votos anónimos, para poder votar %{verify_account}.

View File

@@ -64,6 +64,16 @@ es:
no_open_processes: No hay procesos activos
no_next_processes: No hay procesos planeados
no_past_processes: No hay procesos terminados
section_header:
icon_alt: Icono de Procesos legislativos
title: Procesos legislativos
description: Participa en los debates y procesos previos a la aprobación de una norma o de una actuación municipal. Tu opinión será tenida en cuenta por el Ayuntamiento.
help: Ayuda sobre procesos legislativos
section_footer:
title: Ayuda sobre procesos legislativos
help_text_1: "En los procesos participativos, el Ayuntamiento ofrece a la ciudadanía la oportunidad de participar en la elaboración y modificación de normativa que afecta a la ciudad y de dar su opinión sobre ciertas actuaciones que tiene previsto llevar a cabo."
help_text_2: "Las personas registradas en %{org} pueden participar con aportaciones en la consulta pública de nuevas ordenanzas, reglamentos y directrices, entre otros. Sus comentarios son analizados por el área correspondiente y tenidos en cuenta de cara a la redacción final de las normas."
help_text_3: "El Ayuntamiento también abre procesos para recibir aportaciones y opiniones sobre actuaciones municipales."
phase_not_open:
not_open: Esta fase del proceso todavía no está abierta
phase_empty:

View File

@@ -23,7 +23,7 @@ es:
document_verifications:
already_verified: Esta cuenta de usuario ya está verificada.
has_no_account_html: Para crear un usuario entre en %{link} y haga clic en la opción <b>'Registrarse'</b> en la parte superior derecha de la pantalla.
link: Consul
link: CONSUL
in_census_has_following_permissions: 'Este usuario puede participar en el Portal de Gobierno Abierto con las siguientes posibilidades:'
not_in_census: Este documento no está registrado.
not_in_census_info: 'Las personas no empadronadas pueden participar en el Portal de Gobierno Abierto con las siguientes posibilidades:'

View File

@@ -63,9 +63,9 @@ es:
text: |-
Utilízalo en tu municipio libremente o ayúdanos a mejorarlo, es software libre.
Este Portal de Gobierno Abierto usa la [aplicación Consul](https://github.com/ayuntamientomadrid 'github consul') que es software libre, con [licencia AGPLv3](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ), 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.
Este Portal de Gobierno Abierto usa la [aplicación CONSUL](https://github.com/ayuntamientomadrid 'github consul') que es software libre, con [licencia AGPLv3](http://www.gnu.org/licenses/agpl-3.0.html 'AGPLv3 gnu' ), 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.
Si eres programador, puedes ver el código y ayudarnos a mejorarlo en [aplicación Consul](https://github.com/ayuntamientomadrid 'github consul').
Si eres programador, puedes ver el código y ayudarnos a mejorarlo en [aplicación CONSUL](https://github.com/ayuntamientomadrid 'github consul').
titles:
how_to_use: Utilízalo en tu municipio
privacy: Política de Privacidad

View File

@@ -14,7 +14,7 @@ common: &default_settings
# Your application name. Renaming here affects where data displays in New
# Relic. For more details, see https://docs.newrelic.com/docs/apm/new-relic-apm/maintenance/renaming-applications
app_name: Consul
app_name: CONSUL
# To disable the agent regardless of other settings, uncomment the following:
# agent_enabled: false
@@ -28,7 +28,7 @@ common: &default_settings
# If your application has other named environments, configure them here.
development:
<<: *default_settings
app_name: Consul (Development)
app_name: CONSUL (Development)
# NOTE: There is substantial overhead when running in developer mode.
# Do not use for production or load testing.
@@ -41,7 +41,7 @@ test:
staging:
<<: *default_settings
app_name: Consul (Staging)
app_name: CONSUL (Staging)
production:
<<: *default_settings

View File

@@ -95,6 +95,14 @@ Rails.application.routes.draw do
resources :follows, only: [:create, :destroy]
resources :documents, only: [:new, :create, :destroy] do
collection do
get :new_nested
delete :destroy_upload
post :upload
end
end
resources :stats, only: [:index]
resources :legacy_legislations, only: [:show], path: 'legislations'

View File

@@ -18,13 +18,13 @@ Setting.create(key: 'comments_body_max_length', value: '1000')
Setting.create(key: 'twitter_handle', value: '@consul_dev')
Setting.create(key: 'twitter_hashtag', value: '#consul_dev')
Setting.create(key: 'facebook_handle', value: 'consul')
Setting.create(key: 'youtube_handle', value: 'consul')
Setting.create(key: 'telegram_handle', value: 'consul')
Setting.create(key: 'instagram_handle', value: 'consul')
Setting.create(key: 'facebook_handle', value: 'CONSUL')
Setting.create(key: 'youtube_handle', value: 'CONSUL')
Setting.create(key: 'telegram_handle', value: 'CONSUL')
Setting.create(key: 'instagram_handle', value: 'CONSUL')
Setting.create(key: 'blog_url', value: '/blog')
Setting.create(key: 'url', value: 'http://localhost:3000')
Setting.create(key: 'org_name', value: 'Consul')
Setting.create(key: 'org_name', value: 'CONSUL')
Setting.create(key: 'place_name', value: 'City')
Setting.create(key: 'feature.debates', value: "true")
Setting.create(key: 'feature.polls', value: "true")
@@ -39,7 +39,7 @@ Setting.create(key: 'feature.legislation', value: "true")
Setting.create(key: 'per_page_code_head', value: "")
Setting.create(key: 'per_page_code_body', value: "")
Setting.create(key: 'comments_body_max_length', value: '1000')
Setting.create(key: 'mailer_from_name', value: 'Consul')
Setting.create(key: 'mailer_from_name', value: 'CONSUL')
Setting.create(key: 'mailer_from_address', value: 'noreply@consul.dev')
Setting.create(key: 'meta_description', value: 'Citizen Participation and Open Government Application')
Setting.create(key: 'meta_keywords', value: 'citizen participation, open government')
@@ -84,6 +84,7 @@ manager.create_manager
valuator = create_user('valuator@consul.dev', 'valuator')
valuator.create_valuator
valuator.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1", verified_at: Time.current, document_number: "2111111111")
poll_officer = create_user('poll_officer@consul.dev', 'Paul O. Fisher')
poll_officer.create_poll_officer

View File

@@ -0,0 +1,14 @@
class CreateDocuments < ActiveRecord::Migration
def change
create_table :documents do |t|
t.string :title
t.attachment :attachment
t.references :user, index: true, foreign_key: true
t.references :documentable, polymorphic: true, index: true
t.timestamps null: false
end
add_index :documents, [:user_id, :documentable_type, :documentable_id], name: "access_documents"
end
end

Some files were not shown because too many files have changed in this diff Show More