decidim-decidim_geo 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE-AGPLv3.txt +661 -0
- data/README.md +172 -0
- data/Rakefile +119 -0
- data/app/cells/decidim/geo/content_blocks/geo_maps/show.erb +15 -0
- data/app/cells/decidim/geo/content_blocks/geo_maps_cell.rb +114 -0
- data/app/cells/decidim/geo/content_blocks/geo_maps_settings_form_cell.rb +14 -0
- data/app/cells/decidim/geo/geo_collection_map/show.erb +4 -0
- data/app/cells/decidim/geo/geo_collection_map_cell.rb +102 -0
- data/app/commands/decidim/admin/create_scope.rb +56 -0
- data/app/commands/decidim/admin/create_scope_type.rb +47 -0
- data/app/commands/decidim/admin/update_scope.rb +60 -0
- data/app/commands/decidim/admin/update_scope_type.rb +62 -0
- data/app/commands/decidim/geo/admin/create_shapefile.rb +51 -0
- data/app/commands/decidim/geo/admin/update_geo_config.rb +54 -0
- data/app/commands/decidim/geo/command.rb +14 -0
- data/app/controllers/decidim/admin/scopes_controller.rb +115 -0
- data/app/controllers/decidim/geo/admin/application_controller.rb +21 -0
- data/app/controllers/decidim/geo/admin/geo_configs_controller.rb +44 -0
- data/app/controllers/decidim/geo/admin/shapefiles_controller.rb +41 -0
- data/app/controllers/decidim/geo/application_controller.rb +13 -0
- data/app/controllers/decidim/geo/shapefile_controller.rb +11 -0
- data/app/forms/decidim/admin/scope_form.rb +43 -0
- data/app/forms/decidim/admin/scope_type_form.rb +27 -0
- data/app/forms/decidim/geo/admin/geo_config_form.rb +20 -0
- data/app/forms/decidim/geo/admin/shapefile_form.rb +23 -0
- data/app/helpers/decidim/admin/scopes_helper.rb +72 -0
- data/app/jobs/decidim/geo/shp2pgsql_job.rb +14 -0
- data/app/models/decidim/debates/debate.rb +226 -0
- data/app/models/decidim/geo/application_record.rb +10 -0
- data/app/models/decidim/geo/geo_config.rb +28 -0
- data/app/models/decidim/geo/shapedata.rb +23 -0
- data/app/models/decidim/geo/shapefile.rb +27 -0
- data/app/models/decidim/geo/space_location.rb +16 -0
- data/app/models/decidim/scope.rb +111 -0
- data/app/models/decidim/scope_type.rb +26 -0
- data/app/overrides/decidim/assemblies/admin/assemblies/_form/insert_location_form.html.erb.deface +13 -0
- data/app/overrides/decidim/assemblies/assemblies/show/insert_location.html.erb.deface +7 -0
- data/app/overrides/decidim/participatory_processes/admin/participatory_processes/_form/insert_location_form.html.erb.deface +13 -0
- data/app/overrides/decidim/participatory_processes/participatory_process_groups/show/insert_map.html.erb.deface +6 -0
- data/app/overrides/layouts/decidim/_assembly_header/insert_map.html.erb.deface +25 -0
- data/app/overrides/layouts/decidim/_process_header/insert_map.html.erb.deface +22 -0
- data/app/overrides/layouts/decidim/_wrapper/insert_map.html.erb.deface +5 -0
- data/app/overrides/remove_default_meetings_map.rb +4 -0
- data/app/overrides/remove_default_proposals_map.rb +4 -0
- data/app/packs/entrypoints/decidim_geo.js +3 -0
- data/app/packs/images/decidim/geo/not-geolocated.svg +3 -0
- data/app/packs/src/decidim/geo/actions/index.js +25 -0
- data/app/packs/src/decidim/geo/api/index.js +53 -0
- data/app/packs/src/decidim/geo/api/queries.js +77 -0
- data/app/packs/src/decidim/geo/bootstrap.js +6 -0
- data/app/packs/src/decidim/geo/index.js +101 -0
- data/app/packs/src/decidim/geo/models/configStore.js +44 -0
- data/app/packs/src/decidim/geo/models/dropdownFilterStore.js +65 -0
- data/app/packs/src/decidim/geo/models/filterStore.js +121 -0
- data/app/packs/src/decidim/geo/models/geoDatasourceNode/GeoDatasourceNode.js +124 -0
- data/app/packs/src/decidim/geo/models/geoDatasourceNode/index.js +1 -0
- data/app/packs/src/decidim/geo/models/geoScope/GeoScope.js +128 -0
- data/app/packs/src/decidim/geo/models/geoScope/index.js +1 -0
- data/app/packs/src/decidim/geo/models/geoStore.js +118 -0
- data/app/packs/src/decidim/geo/models/pointStore.js +134 -0
- data/app/packs/src/decidim/geo/models/scopeDropdownStore.js +20 -0
- data/app/packs/src/decidim/geo/ui/DrawerDetail/fallback.js +42 -0
- data/app/packs/src/decidim/geo/ui/DrawerDetail/index.js +2 -0
- data/app/packs/src/decidim/geo/ui/DrawerDetail/meetings.js +75 -0
- data/app/packs/src/decidim/geo/ui/DrawerMenuItem/fallback.js +45 -0
- data/app/packs/src/decidim/geo/ui/DrawerMenuItem/index.js +2 -0
- data/app/packs/src/decidim/geo/ui/DrawerMenuItem/meetings.js +62 -0
- data/app/packs/src/decidim/geo/ui/createClasses.js +7 -0
- data/app/packs/src/decidim/geo/ui/createCustomMarker.js +14 -0
- data/app/packs/src/decidim/geo/ui/createDomElement.js +2 -0
- data/app/packs/src/decidim/geo/ui/createDrawer.js +170 -0
- data/app/packs/src/decidim/geo/ui/createDrawerActions.js +197 -0
- data/app/packs/src/decidim/geo/ui/createFilterDropdown.js +320 -0
- data/app/packs/src/decidim/geo/ui/createGeoScopeLayer.js +20 -0
- data/app/packs/src/decidim/geo/ui/createGeoScopeMenuItem.js +8 -0
- data/app/packs/src/decidim/geo/ui/createNodeMarker.js +9 -0
- data/app/packs/src/decidim/geo/ui/createNodeMenuItem.js +13 -0
- data/app/packs/src/decidim/geo/ui/index.js +8 -0
- data/app/packs/src/decidim/geo/ui/initMap.js +22 -0
- data/app/packs/src/decidim/geo/utils/index.js +30 -0
- data/app/packs/src/decidim/geo/utils/saveConfig.js +15 -0
- data/app/packs/stylesheets/decidim/geo/_geo.scss +2 -0
- data/app/packs/stylesheets/decidim/geo/geo/_decidim_geo_decidimGeo.scss +476 -0
- data/app/packs/stylesheets/decidim/geo/geo/_decidim_geo_override.scss +65 -0
- data/app/permissions/decidim/geo/admin/permissions.rb +24 -0
- data/app/permissions/decidim/geo/permissions.rb +15 -0
- data/app/uploaders/decidim/geo/shapefile_uploader.rb +14 -0
- data/app/validators/geocoding_validator.rb +30 -0
- data/app/views/decidim/admin/scope_types/_form.html.erb +10 -0
- data/app/views/decidim/admin/scope_types/index.html.erb +46 -0
- data/app/views/decidim/admin/scopes/_form.html.erb +20 -0
- data/app/views/decidim/admin/scopes/index.html.erb +55 -0
- data/app/views/decidim/geo/admin/geo_configs/_form.html.erb +47 -0
- data/app/views/decidim/geo/admin/geo_configs/index.html.erb +8 -0
- data/app/views/decidim/geo/admin/shapefiles/_form.html.erb +29 -0
- data/app/views/decidim/geo/admin/shapefiles/index.html.erb +38 -0
- data/app/views/decidim/geo/admin/shapefiles/new.html.erb +8 -0
- data/app/views/layouts/decidim/decidim_geo/admin/application.html.erb +19 -0
- data/config/assets.rb +9 -0
- data/config/i18n-tasks.yml +10 -0
- data/config/locales/de.yml +102 -0
- data/config/locales/en.yml +108 -0
- data/config/locales/fr.yml +102 -0
- data/db/migrate/20221019184712_add_postgis_extension_to_database.rb +5 -0
- data/db/migrate/20221025195520_create_decidim_geo.rb +22 -0
- data/db/migrate/20231013082325_create_decidim_geo_config.rb +11 -0
- data/db/migrate/20231206115531_add_spaces_config_to_decidim_geo_configs.rb +6 -0
- data/db/migrate/20240309004347_add_organization_to_shapefiles.rb +6 -0
- data/db/migrate/20240326052727_create_space_locations.rb +18 -0
- data/lib/decidim/api/geo_config_type.rb +15 -0
- data/lib/decidim/api/geo_coordinates_type.rb +22 -0
- data/lib/decidim/api/geo_datasource_type.rb +147 -0
- data/lib/decidim/api/geo_dates_type.rb +15 -0
- data/lib/decidim/api/geo_query_extension.rb +25 -0
- data/lib/decidim/api/geo_scope_api_type.rb +26 -0
- data/lib/decidim/api/geo_shapedata_type.rb +18 -0
- data/lib/decidim/api/geo_shapefile_type.rb +22 -0
- data/lib/decidim/api/input_filters/assembly_input_filter.rb +13 -0
- data/lib/decidim/api/input_filters/geo_datasource_input_filter.rb +18 -0
- data/lib/decidim/api/input_filters/geoencoded_input_filter.rb +13 -0
- data/lib/decidim/api/input_filters/has_scopeable_input_filter.rb +17 -0
- data/lib/decidim/api/input_filters/process_input_filter.rb +13 -0
- data/lib/decidim/api/input_filters/resource_type_input_filter.rb +13 -0
- data/lib/decidim/api/input_filters/scope_input_filter.rb +13 -0
- data/lib/decidim/api/input_filters/time_input_filter.rb +13 -0
- data/lib/decidim/api/meetings_input_filter.rb +14 -0
- data/lib/decidim/api/query_extension.rb +320 -0
- data/lib/decidim/api/shapefile_query_extention.rb +18 -0
- data/lib/decidim/api/shapefile_type.rb +18 -0
- data/lib/decidim/decidim_geo/admin.rb +10 -0
- data/lib/decidim/decidim_geo/admin_engine.rb +69 -0
- data/lib/decidim/decidim_geo/api.rb +23 -0
- data/lib/decidim/decidim_geo/engine.rb +58 -0
- data/lib/decidim/decidim_geo/load_shp/app_load_shp.rb +85 -0
- data/lib/decidim/decidim_geo/space_location/assembly_create_command_override.rb +26 -0
- data/lib/decidim/decidim_geo/space_location/assembly_form_override.rb +33 -0
- data/lib/decidim/decidim_geo/space_location/assembly_update_command_override.rb +21 -0
- data/lib/decidim/decidim_geo/space_location/participatory_process_command_override.rb +21 -0
- data/lib/decidim/decidim_geo/space_location/participatory_process_form_override.rb +33 -0
- data/lib/decidim/decidim_geo/space_location/space_override.rb +15 -0
- data/lib/decidim/decidim_geo/test/factories.rb +13 -0
- data/lib/decidim/decidim_geo/version.rb +14 -0
- data/lib/decidim/decidim_geo.rb +25 -0
- data/lib/tasks/decidim_geo_webpacker_tasks.rake +61 -0
- metadata +335 -0
data/README.md
ADDED
@@ -0,0 +1,172 @@
|
|
1
|
+
<h1 align="center"><img src="https://github.com/octree-gva/meta/blob/main/decidim/static/header.png?raw=true" alt="Decidim - Octree Participatory democracy on a robust and open source solution" /></h1>
|
2
|
+
<h4 align="center">
|
3
|
+
<a href="https://octreegva.notion.site/Roadmap-Decidim-GEO-f191fcb9e220401f8135514a7bd41aab">Roadmap</a> |
|
4
|
+
<a href="https://drive.google.com/file/d/1lfQJumDg0Ic-RZi-R3MM8frYtKN7PB_S/view?usp=sharing">Presentation</a> |
|
5
|
+
<a href="https://github.com/octree-gva/decidim-module-geo/issues">Issues</a> <br/>
|
6
|
+
<a href="https://www.octree.ch">Octree</a> |
|
7
|
+
<a href="https://octree.ch/en/contact-us/">Contact Us</a> |
|
8
|
+
<a href="https://blog.octree.ch">Our Blog (FR)</a><br/><br/>
|
9
|
+
<a href="https://decidim.org">Decidim</a> |
|
10
|
+
<a href="https://docs.decidim.org/en/">Decidim Docs</a> |
|
11
|
+
<a href="https://meta.decidim.org">Participatory Governance (meta decidim)</a><br/><br/>
|
12
|
+
<a href="https://matrix.to/#/+decidim:matrix.org">Decidim Community (Matrix+Element.io)</a>
|
13
|
+
</h4>
|
14
|
+
<p align="center">
|
15
|
+
<a href="https://participer.lausanne.ch">
|
16
|
+
<img
|
17
|
+
src="https://github.com/octree-gva/meta/blob/main/decidim/static/participer_lausanne/chip.png?raw=true"
|
18
|
+
alt="Lausanne Participe — Une plateforme de participation pour imaginer et réaliser ensemble" />
|
19
|
+
</a>
|
20
|
+
<a href="https://opencollective.com/voca">
|
21
|
+
<img
|
22
|
+
src="https://github.com/octree-gva/meta/blob/main/decidim/static/opencollective_chip.png?raw=true"
|
23
|
+
alt="Voca – Open-Source SaaS platform for Decidim" />
|
24
|
+
</a>
|
25
|
+
</p>
|
26
|
+
|
27
|
+
|
28
|
+
# Decidim::Geo
|
29
|
+
Have you ever wondered to centralize all the participation in a map? Well, we do and that is the purpose of Decidim GEO.
|
30
|
+
Participation on the map, means:
|
31
|
+
|
32
|
+
* Overview participation: Be able to consult what happens where.
|
33
|
+
* Participate: Be able to pin points, select zones, etc. while participating
|
34
|
+
|
35
|
+
This project is its early stage, and has it is quiet ambicious, we open CO-FUNDING and setup a public Roadmap here: [https://octreegva.notion.site/Roadmap-Decidim-GEO-f191fcb9e220401f8135514a7bd41aab](https://octreegva.notion.site/Roadmap-Decidim-GEO-f191fcb9e220401f8135514a7bd41aab).
|
36
|
+
|
37
|
+
If you are curious on how it started, [we've made some slide to present the project](https://drive.google.com/file/d/1lfQJumDg0Ic-RZi-R3MM8frYtKN7PB_S/view?usp=sharing).
|
38
|
+
|
39
|
+
|
40
|
+
## How it works?
|
41
|
+
|
42
|
+
Postgis can load Shapefiles that can represents anything: neighbourghoods, cities, states, trees, public spaces.
|
43
|
+
We use this module to map a shape to an application zone, to be able to geo-references all the participatory processes of the platform. This way we can offer better consultation experience, and open new perspective for participation.
|
44
|
+
|
45
|
+
<img
|
46
|
+
src="https://github.com/octree-gva/meta/blob/main/decidim/static/geo/admin.png?raw=true"
|
47
|
+
alt="Administration of the GEO space" />
|
48
|
+
<img
|
49
|
+
src="https://github.com/octree-gva/meta/blob/main/decidim/static/geo/consult.png?raw=true"
|
50
|
+
alt="Administration of the GEO space" />
|
51
|
+
|
52
|
+
|
53
|
+
## Installation
|
54
|
+
This gem supports decidim version `0.26.x` and `0.27.x`.
|
55
|
+
|
56
|
+
Read the [needed dependancies for `rgeo` gem](https://github.com/rgeo/rgeo?tab=readme-ov-file#dependencies). If you have `libgeos-dev`, be sure you have a postgis database with postgres > 14.0.
|
57
|
+
|
58
|
+
Add this line to your application's Gemfile:
|
59
|
+
```ruby
|
60
|
+
gem "decidim-decidim_geo"
|
61
|
+
```
|
62
|
+
|
63
|
+
Update your database adapter to postgis adapter (already installed as dependancy of this gem):
|
64
|
+
```
|
65
|
+
# config/database.yml
|
66
|
+
default: &default
|
67
|
+
adapter: postgis
|
68
|
+
```
|
69
|
+
|
70
|
+
Update your `DATABASE_URL` environment with `postgis://`:
|
71
|
+
```
|
72
|
+
DATABASE_URL="postgis://myuser:mypass@localhost/somedatabase"
|
73
|
+
```
|
74
|
+
|
75
|
+
And then execute:
|
76
|
+
|
77
|
+
```bash
|
78
|
+
bundle
|
79
|
+
bundle exec rails decidim_geo:install:migrations
|
80
|
+
bundle exec rails db:migrate
|
81
|
+
```
|
82
|
+
|
83
|
+
## Testing
|
84
|
+
```
|
85
|
+
bundle exec rake test_app
|
86
|
+
```
|
87
|
+
|
88
|
+
## Local development
|
89
|
+
First, you need to run an empty database with a decidim dev container which runs nothing.
|
90
|
+
```
|
91
|
+
docker-compose down -v --remove-orphans
|
92
|
+
docker-compose up -d
|
93
|
+
```
|
94
|
+
Once created, you access the decidim container
|
95
|
+
```
|
96
|
+
# Get the id of the decidim dev container
|
97
|
+
docker ps --format {{.ID}} --filter=label=org.label-schema.name=decidim
|
98
|
+
# f16bd5314386
|
99
|
+
docker exec -it f16bd5314386 bash
|
100
|
+
```
|
101
|
+
You are now in bash, run manually `docker-entrypoint`.
|
102
|
+
```
|
103
|
+
# Will check your environment and do migrations if needed
|
104
|
+
docker-entrypoint
|
105
|
+
```
|
106
|
+
You are now ready to use your container in the way you want for development:
|
107
|
+
|
108
|
+
* Run a rails server: `bundle exec rails s -b 0.0.0.0`
|
109
|
+
* Have live-reload on your assets: `bin/webpack-dev-server`
|
110
|
+
* Execute tasks, like `bundle exec rails g migration AddSomeColumn`
|
111
|
+
* etc.
|
112
|
+
```
|
113
|
+
bundle exec rails s -b 0.0.0.0 # rails server
|
114
|
+
bin/webpack-dev-server
|
115
|
+
etc.
|
116
|
+
```
|
117
|
+
|
118
|
+
To stop everything, uses:
|
119
|
+
- `docker-compose down` to stop the containers
|
120
|
+
- `docker-compose down -v` to stop the containers and remove all previously saved data.
|
121
|
+
|
122
|
+
### Debugging
|
123
|
+
To debug something on the container:
|
124
|
+
1. Ensure `decidim-app` is running
|
125
|
+
```bash
|
126
|
+
docker ps --all
|
127
|
+
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
128
|
+
# f16bd5314386 decidim-geo-development-app "sleep infinity" 13 hours ago Up 13 hours 0.0.0.0:3000->3000/tcp, 0.0.0.0:3035->3035/tcp decidim-app <-------- THIS ONE
|
129
|
+
# b56adf6404d8 decidim-geo-development-app "bin/webpack-dev-ser…" 54 seconds ago Up 46 seconds 0.0.0.0:3035->3035/tcp decidim-webpacker decidim-installer
|
130
|
+
# bc1e912c3d8a postgis/postgis:14-3.3-alpine "docker-entrypoint.s…" 13 hours ago Up 13 hours 0.0.0.0:5432->5432/tcp decidim-module-geo-pg-1
|
131
|
+
```
|
132
|
+
|
133
|
+
2. Run `docker exec -it decidim-app bash`
|
134
|
+
3. Run
|
135
|
+
- `tail -f $ROOT/log/development.log` to **access logs**
|
136
|
+
- `bundle exec rails restart` to **restart rails server AND keeps webpacker running**
|
137
|
+
- `cd $ROOT` to access the `development_app`
|
138
|
+
- `cd $ROOT/../decidim_module_geo` to access the module directory
|
139
|
+
|
140
|
+
### FAQ
|
141
|
+
|
142
|
+
**I can't see logs on the `decidim-app`?**
|
143
|
+
`decidim-app` runs here in development `webpacker-dev-server` AND a puma server, on the same container.
|
144
|
+
Thus, we just run both, and only one will be displayed on STDOUT. To see puma log: `docker exec decidim-app tail -f /home/app/decidim/log/development.log`
|
145
|
+
|
146
|
+
**It takes for ever to pull the image?**
|
147
|
+
Try to pull from docker hub before doing your install script. `docker pull hfroger/decidim:0.26.8-dev` can help.
|
148
|
+
|
149
|
+
**Why must I access to `127.0.0.1` and not `localhost`?**
|
150
|
+
`webpack-dev-server` run a websocket server on port 3535, and the rails server needs to connect to it.
|
151
|
+
`localhost` won't make the trick, and you need to use a "real" ip, like `127.0.0.1`. [More info](https://stackoverflow.com/a/54102318)
|
152
|
+
|
153
|
+
## Contributing
|
154
|
+
|
155
|
+
We are not yet ready for contributions, but we are working on a goood workflow
|
156
|
+
|
157
|
+
# Why it's not on MetaDecidim?
|
158
|
+
We think Decidim is already over complicated to install and setup. This module uses PosGis extensions on a postgres database, that can be hard to install. We block the proposal to metadecidim until these points are solved:
|
159
|
+
|
160
|
+
- We have stable release.
|
161
|
+
- We have feedbacks from participants that it is actually usefull.
|
162
|
+
- We have feedbacks from Decidim's admins that this is actually improving participation.
|
163
|
+
- Decidim run primarly on docker, with an updated documentation on installation. (We, at Octree is working on it for a while)
|
164
|
+
|
165
|
+
## License
|
166
|
+
|
167
|
+
This engine is distributed under the [GNU AFFERO GENERAL PUBLIC LICENSE](LICENSE-AGPLv3.txt)
|
168
|
+
|
169
|
+
<br /><br />
|
170
|
+
<p align="center">
|
171
|
+
<img src="https://raw.githubusercontent.com/octree-gva/meta/main/decidim/static/octree_and_decidim.png" height="90" alt="Decidim Installation by Octree" />
|
172
|
+
</p>
|
data/Rakefile
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "decidim/dev/common_rake"
|
4
|
+
|
5
|
+
def install_module(path)
|
6
|
+
Dir.chdir(path) do
|
7
|
+
system("bundle exec rake decidim_geo:install:migrations")
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def seed_db(path)
|
12
|
+
Dir.chdir(path) do
|
13
|
+
system("bundle exec rake db:seed")
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Tasks for test_app
|
19
|
+
##
|
20
|
+
|
21
|
+
desc "Prepare for testing"
|
22
|
+
task :prepare_tests do
|
23
|
+
# Remove previous existing db, and recreate one.
|
24
|
+
Dir.chdir("development_app") do
|
25
|
+
system("bundle exec rake db:drop")
|
26
|
+
system("bundle exec rake db:create")
|
27
|
+
end
|
28
|
+
ENV["RAILS_ENV"] = "test"
|
29
|
+
databaseYml = {
|
30
|
+
"test" => {
|
31
|
+
"adapter" => "postgis",
|
32
|
+
"encoding" => "unicode",
|
33
|
+
"host" => ENV.fetch("DATABASE_HOST", "localhost"),
|
34
|
+
"port" => ENV.fetch("DATABASE_PORT", "5432").to_i,
|
35
|
+
"username" => ENV.fetch("DATABASE_USERNAME", "decidim"),
|
36
|
+
"password" => ENV.fetch("DATABASE_PASSWORD", "insecure-password"),
|
37
|
+
"database" => "#{base_app_name}_test"
|
38
|
+
}
|
39
|
+
}
|
40
|
+
config_file = File.expand_path("spec/decidim_dummy_app/config/database.yml", __dir__)
|
41
|
+
File.open(config_file, "w") { |f| YAML.dump(databaseYml, f) }
|
42
|
+
Dir.chdir("spec/decidim_dummy_app") do
|
43
|
+
system("bundle exec rails db:migrate")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
desc "Generates a decidim_dummy_app app for testing"
|
48
|
+
task :test_app do
|
49
|
+
Bundler.with_original_env do
|
50
|
+
generate_decidim_app(
|
51
|
+
"spec/decidim_dummy_app",
|
52
|
+
"--app_name",
|
53
|
+
"#{base_app_name}",
|
54
|
+
"--path",
|
55
|
+
"../..",
|
56
|
+
"--skip_spring",
|
57
|
+
"--demo",
|
58
|
+
"--force_ssl",
|
59
|
+
"false",
|
60
|
+
"--locales",
|
61
|
+
"en,fr,es"
|
62
|
+
)
|
63
|
+
end
|
64
|
+
install_module("spec/decidim_dummy_app")
|
65
|
+
Rake::Task["prepare_tests"].invoke
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Tasks for developement_app
|
70
|
+
##
|
71
|
+
|
72
|
+
desc "Prepare for development"
|
73
|
+
task :prepare_dev do
|
74
|
+
# Remove previous existing db, and recreate one.
|
75
|
+
Dir.chdir("development_app") do
|
76
|
+
system("bundle exec rake db:drop")
|
77
|
+
system("bundle exec rake db:create")
|
78
|
+
end
|
79
|
+
ENV["RAILS_ENV"] = "development"
|
80
|
+
databaseYml = {
|
81
|
+
"development" => {
|
82
|
+
"adapter" => "postgis",
|
83
|
+
"encoding" => "unicode",
|
84
|
+
"host" => ENV.fetch("DATABASE_HOST", "localhost"),
|
85
|
+
"port" => ENV.fetch("DATABASE_PORT", "5432").to_i,
|
86
|
+
"username" => ENV.fetch("DATABASE_USERNAME", "decidim"),
|
87
|
+
"password" => ENV.fetch("DATABASE_PASSWORD", "insecure-password"),
|
88
|
+
"database" => "#{base_app_name}_development",
|
89
|
+
}
|
90
|
+
}
|
91
|
+
config_file = File.expand_path("development_app/config/database.yml", __dir__)
|
92
|
+
File.open(config_file, "w") { |f| YAML.dump(databaseYml, f) }
|
93
|
+
Dir.chdir("development_app") do
|
94
|
+
system("bundle exec rake db:migrate")
|
95
|
+
system("npm install -D webpack-dev-server")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
desc "Generates a development app"
|
100
|
+
task :development_app do
|
101
|
+
Bundler.with_original_env do
|
102
|
+
generate_decidim_app(
|
103
|
+
"development_app",
|
104
|
+
"--app_name",
|
105
|
+
"#{base_app_name}",
|
106
|
+
"recreate_db",
|
107
|
+
"--path",
|
108
|
+
"..",
|
109
|
+
"--skip_spring",
|
110
|
+
"--demo",
|
111
|
+
"--force_ssl",
|
112
|
+
"false",
|
113
|
+
"--demo"
|
114
|
+
)
|
115
|
+
end
|
116
|
+
|
117
|
+
install_module("development_app")
|
118
|
+
Rake::Task["prepare_dev"].invoke
|
119
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.2/dist/leaflet.css" integrity="sha256-sA+zWATbFveLLNqWO2gtiw3HL/lh1giY/Inf1BJ0z14=" crossorigin="">
|
2
|
+
<script src="https://unpkg.com/leaflet@1.9.2/dist/leaflet.js" integrity="sha256-o9N1jGDZrf5tS+Ft4gbIK7mYMipq9lqpVJ91xHSyKhg=" crossorigin=""></script>
|
3
|
+
|
4
|
+
<style>
|
5
|
+
.decidimgeo__map {
|
6
|
+
height: 640px;
|
7
|
+
width: 100%;
|
8
|
+
max-width: 100%;
|
9
|
+
max-height: 100%;
|
10
|
+
}
|
11
|
+
</style>
|
12
|
+
|
13
|
+
<%= javascript_pack_tag "decidim_geo" %>
|
14
|
+
|
15
|
+
<%= insert_map %>
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Geo
|
5
|
+
module ContentBlocks
|
6
|
+
class GeoMapsCell < Decidim::ViewModel
|
7
|
+
#delegate :current_user, to: :controller
|
8
|
+
include Decidim::SanitizeHelper
|
9
|
+
|
10
|
+
def show
|
11
|
+
render unless @options.empty?
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def insert_map
|
17
|
+
id = @options[:id] || "HomePage"
|
18
|
+
filters = @options[:filters] || []
|
19
|
+
config = {
|
20
|
+
locale: current_locale,
|
21
|
+
space_ids: @options[:scopes] || [],
|
22
|
+
selected_component: current_component || nil,
|
23
|
+
selected_point: current_component? && params[:id] ? params[:id] : nil,
|
24
|
+
images: {
|
25
|
+
not_geolocated: ActionController::Base.helpers.asset_pack_path("media/images/not-geolocated.svg")
|
26
|
+
},
|
27
|
+
filters: @options[:filters] || [],
|
28
|
+
map_config: {
|
29
|
+
lat: geo_config[:latitude],
|
30
|
+
lng: geo_config[:longitude],
|
31
|
+
tile_layer: geo_config[:tile],
|
32
|
+
zoom: geo_config[:zoom]
|
33
|
+
}
|
34
|
+
}.with_indifferent_access
|
35
|
+
|
36
|
+
content_tag(
|
37
|
+
:div,
|
38
|
+
'',
|
39
|
+
id: "DecidimGeo",
|
40
|
+
class: [
|
41
|
+
"js-decidimgeo",
|
42
|
+
"decidimgeo__map",
|
43
|
+
"decidimgeo__map--#{id.underscore}"
|
44
|
+
],
|
45
|
+
"data-config" => config.to_json,
|
46
|
+
"data-i18n" => geo_i18n.to_json
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
def geo_i18n
|
51
|
+
supported_models = [
|
52
|
+
Decidim::Meetings::Meeting,
|
53
|
+
Decidim::Proposals::Proposal,
|
54
|
+
Decidim::ParticipatoryProcess,
|
55
|
+
Decidim::Assembly,
|
56
|
+
Decidim::Debates::Debate
|
57
|
+
]
|
58
|
+
geo_i18n = supported_models.map { |klass| [klass.name, klass.model_name.human] }.to_h
|
59
|
+
geo_i18n = {
|
60
|
+
**geo_i18n,
|
61
|
+
"decidim_geo.scopes.all": t('decidim.geo.scopes.all'),
|
62
|
+
"decidim_geo.scopes.dropdown": t('decidim.geo.scopes.dropdown'),
|
63
|
+
"decidim_geo.filters.back": t('decidim.geo.filters.back'),
|
64
|
+
"decidim_geo.filters.button": t('decidim.geo.filters.button'),
|
65
|
+
"decidim_geo.filters.geo.label": t('decidim.geo.filters.geo.label'),
|
66
|
+
"decidim_geo.filters.geo.all": t('decidim.geo.filters.geo.all'),
|
67
|
+
"decidim_geo.filters.geo.only_geoencoded": t('decidim.geo.filters.geo.only_geoencoded'),
|
68
|
+
"decidim_geo.filters.geo.only_virtual": t('decidim.geo.filters.geo.only_virtual'),
|
69
|
+
"decidim_geo.filters.time.label": t('decidim.geo.filters.time.label'),
|
70
|
+
"decidim_geo.filters.time.all": t('decidim.geo.filters.time.all'),
|
71
|
+
"decidim_geo.filters.time.only_past": t('decidim.geo.filters.time.only_past'),
|
72
|
+
"decidim_geo.filters.time.only_active": t('decidim.geo.filters.time.only_active'),
|
73
|
+
"decidim_geo.filters.time.only_future": t('decidim.geo.filters.time.only_future'),
|
74
|
+
"decidim_geo.filters.type.label": t('decidim.geo.filters.type.label'),
|
75
|
+
"decidim_geo.filters.type.all": t('decidim.geo.filters.type.all'),
|
76
|
+
"decidim_geo.filters.type.only_processes": t('decidim.geo.filters.type.only_processes'),
|
77
|
+
"decidim_geo.filters.type.only_assemblies": t('decidim.geo.filters.type.only_assemblies'),
|
78
|
+
"decidim_geo.filters.type.only_proposals": t('decidim.geo.filters.type.only_proposals'),
|
79
|
+
"decidim_geo.filters.type.only_meetings": t('decidim.geo.filters.type.only_meetings'),
|
80
|
+
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
def current_locale
|
86
|
+
I18n.locale.to_s
|
87
|
+
end
|
88
|
+
|
89
|
+
def current_component
|
90
|
+
return request.env["decidim.current_component"].id if current_component?
|
91
|
+
"none"
|
92
|
+
end
|
93
|
+
|
94
|
+
def current_component?
|
95
|
+
request.env["decidim.current_component"].present?
|
96
|
+
end
|
97
|
+
|
98
|
+
def geo_config
|
99
|
+
{
|
100
|
+
latitude: model.try(:latitude).nil? ? geo_config_default.latitude : model.latitude,
|
101
|
+
longitude: model.try(:longitude).nil? ? geo_config_default.longitude: model.longitude,
|
102
|
+
tile: Decidim::Geo::GeoConfig.geo_config_default.tile,
|
103
|
+
zoom: Decidim::Geo::GeoConfig.geo_config_default.zoom
|
104
|
+
}.to_h
|
105
|
+
end
|
106
|
+
|
107
|
+
def geo_config_default
|
108
|
+
Decidim::Geo::GeoConfig.geo_config_default
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Geo
|
5
|
+
class GeoCollectionMapCell < Decidim::ViewModel
|
6
|
+
delegate :current_user, to: :controller
|
7
|
+
include Decidim::SanitizeHelper
|
8
|
+
|
9
|
+
def show
|
10
|
+
render
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
def participatory_space?
|
15
|
+
[
|
16
|
+
"decidim/assemblies/assemblies:index",
|
17
|
+
"decidim/participatory_processes/participatory_processes:index"
|
18
|
+
].include? "#{params[:controller]}:#{params[:action]}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def search_controller?
|
22
|
+
params[:controller] == "decidim/searches"
|
23
|
+
end
|
24
|
+
|
25
|
+
def search_options
|
26
|
+
param_filter = params[:filter]
|
27
|
+
return {} if param_filter.nil?
|
28
|
+
param_filter.permit!
|
29
|
+
filters = param_filter.keys.map do |key|
|
30
|
+
case "#{key}"
|
31
|
+
when "resource_type"
|
32
|
+
{resourceTypeFilter: {resourceType: param_filter[key]}}
|
33
|
+
when "term"
|
34
|
+
{termFilter: {term: param_filter[key]}}
|
35
|
+
when "decidim_scope_id"
|
36
|
+
{scopeFilter: {scopeId: [param_filter[key]]}}
|
37
|
+
when "space_state"
|
38
|
+
{termFilter: {space_state: param_filter[key]}}
|
39
|
+
end
|
40
|
+
end.select {|v| !v.nil?}
|
41
|
+
{
|
42
|
+
id: "Search",
|
43
|
+
filters: filters,
|
44
|
+
scopes: []
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def collection_options
|
49
|
+
case "#{params[:controller]}:#{params[:action]}"
|
50
|
+
when "decidim/assemblies/assemblies:index"
|
51
|
+
{
|
52
|
+
id: "Assemblies",
|
53
|
+
filters: assemblies_filter,
|
54
|
+
scopes: assemblies_scopes
|
55
|
+
}
|
56
|
+
when "decidim/participatory_processes/participatory_processes:index"
|
57
|
+
{
|
58
|
+
id: "Processes",
|
59
|
+
filters: processes_filter,
|
60
|
+
scopes: processes_scopes
|
61
|
+
}
|
62
|
+
else
|
63
|
+
{}
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def visible_processes
|
68
|
+
Decidim::ParticipatoryProcess.visible_for(
|
69
|
+
current_user
|
70
|
+
)
|
71
|
+
end
|
72
|
+
def processes_scopes
|
73
|
+
visible_processes.map { |a| a.scopes.map{ |s| s.id} }.flatten.uniq
|
74
|
+
end
|
75
|
+
def visible_assemblies
|
76
|
+
Decidim::Assembly.visible_for(
|
77
|
+
current_user
|
78
|
+
)
|
79
|
+
end
|
80
|
+
def assemblies_scopes
|
81
|
+
visible_assemblies.map { |a| a.scopes.map{ |s| s.id} }.flatten.uniq
|
82
|
+
end
|
83
|
+
|
84
|
+
def assemblies_filter
|
85
|
+
return [{resourceTypeFilter: {resourceType: "Decidim::Assembly"}}] if geo_config.only_assemblies
|
86
|
+
# Filter only content that are bound to one of the displayed assemblies
|
87
|
+
visible_assemblies.map {|assembly| {assemblyFilter: {assemblyId: assembly.id}} }
|
88
|
+
end
|
89
|
+
|
90
|
+
def processes_filter
|
91
|
+
return [{resourceTypeFilter: {resourceType: "Decidim::ParticipatoryProcess"}}] if geo_config.only_processes
|
92
|
+
# Filter only content that are bound to one of the displayed processes
|
93
|
+
visible_processes.map {|process| {processFilter: {processId: process.id}} }
|
94
|
+
end
|
95
|
+
|
96
|
+
def geo_config
|
97
|
+
Decidim::Geo::GeoConfig.geo_config_default
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Admin
|
5
|
+
# A command with all the business logic when creating a static scope.
|
6
|
+
class CreateScope < Decidim::Geo::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
# form - A form object with the params.
|
10
|
+
# parent_scope - A parent scope for the scope to be created
|
11
|
+
def initialize(form, parent_scope = nil)
|
12
|
+
@form = form
|
13
|
+
@parent_scope = parent_scope
|
14
|
+
end
|
15
|
+
|
16
|
+
# Executes the command. Broadcasts these events:
|
17
|
+
#
|
18
|
+
# - :ok when everything is valid.
|
19
|
+
# - :invalid if the form wasn't valid and we couldn't proceed.
|
20
|
+
#
|
21
|
+
# Returns nothing.
|
22
|
+
def call
|
23
|
+
return broadcast(:invalid) if form.invalid?
|
24
|
+
|
25
|
+
scope = create_scope
|
26
|
+
broadcast(:ok, :scope=>scope)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :form
|
32
|
+
|
33
|
+
def create_scope
|
34
|
+
Decidim.traceability.create!(
|
35
|
+
Scope,
|
36
|
+
form.current_user,
|
37
|
+
{
|
38
|
+
name: form.name,
|
39
|
+
organization: form.organization,
|
40
|
+
code: form.code,
|
41
|
+
scope_type: form.scope_type,
|
42
|
+
parent: @parent_scope
|
43
|
+
},
|
44
|
+
extra: {
|
45
|
+
parent_name: @parent_scope.try(:name),
|
46
|
+
scope_type_name: form.scope_type.try(:name)
|
47
|
+
}
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
def shapedata
|
52
|
+
Decidim::Geo::Shapedata.find_by_id(form.shapedata)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Decidim
|
4
|
+
module Admin
|
5
|
+
# A command with all the business logic when creating a scope type.
|
6
|
+
class CreateScopeType < Decidim::Geo::Command
|
7
|
+
# Public: Initializes the command.
|
8
|
+
#
|
9
|
+
# form - A form object with the params.
|
10
|
+
def initialize(form, user = nil)
|
11
|
+
@form = form
|
12
|
+
@user = user
|
13
|
+
end
|
14
|
+
|
15
|
+
# Executes the command. Broadcasts these events:
|
16
|
+
#
|
17
|
+
# - :ok when everything is valid.
|
18
|
+
# - :invalid if the form wasn't valid and we couldn't proceed.
|
19
|
+
#
|
20
|
+
# Returns nothing.
|
21
|
+
def call
|
22
|
+
return broadcast(:invalid) if form.invalid?
|
23
|
+
|
24
|
+
create_scope_type
|
25
|
+
broadcast(:ok)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :form
|
31
|
+
|
32
|
+
def create_scope_type
|
33
|
+
scope_type = ScopeType.create!(
|
34
|
+
name: form.name,
|
35
|
+
organization: form.organization,
|
36
|
+
plural: form.plural
|
37
|
+
)
|
38
|
+
scope_type.shapefile = shapefile
|
39
|
+
scope_type.save!
|
40
|
+
end
|
41
|
+
|
42
|
+
def shapefile
|
43
|
+
Decidim::Geo::Shapefile.find_by_id(form.shapefile)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|