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
@@ -0,0 +1,118 @@
|
|
1
|
+
import { createStore } from "zustand/vanilla";
|
2
|
+
import { subscribeWithSelector } from "zustand/middleware";
|
3
|
+
import dataPointStore from "./pointStore";
|
4
|
+
import filterStore from "./filterStore";
|
5
|
+
import dropdownFilterStore from "./dropdownFilterStore";
|
6
|
+
|
7
|
+
const store = createStore(
|
8
|
+
subscribeWithSelector((set) => ({
|
9
|
+
/**
|
10
|
+
* Filters given by the backend
|
11
|
+
*/
|
12
|
+
defaultFilters: [],
|
13
|
+
/**
|
14
|
+
* data point that is currently clicked
|
15
|
+
*/
|
16
|
+
selectedPoint: undefined,
|
17
|
+
/**
|
18
|
+
*
|
19
|
+
*/
|
20
|
+
selectedScope: undefined,
|
21
|
+
previousState: null,
|
22
|
+
/**
|
23
|
+
* Action when we click on a point.
|
24
|
+
*/
|
25
|
+
selectPoint: (point) => {
|
26
|
+
set((state) => ({
|
27
|
+
...state,
|
28
|
+
selectedScope: point ? dataPointStore.getState().scopeForId(point.scopeId) : undefined,
|
29
|
+
selectedPoint: point,
|
30
|
+
previousState: state
|
31
|
+
}));
|
32
|
+
},
|
33
|
+
/**
|
34
|
+
* Action when a scope is selected.
|
35
|
+
* - select the scope if any
|
36
|
+
* -
|
37
|
+
*/
|
38
|
+
selectScope: (scope) => {
|
39
|
+
set((state) => ({
|
40
|
+
selectedScope: scope,
|
41
|
+
...(`${scope?.id}` !== `${state.selectedScope?.id}`
|
42
|
+
? { previousState: state }
|
43
|
+
: {}),
|
44
|
+
// unselect point when moving away from its scope
|
45
|
+
selectedPoint:
|
46
|
+
state.selectedPoint && state.selectedPoint.scopeId === scope?.id
|
47
|
+
? state.selectedPoint
|
48
|
+
: undefined
|
49
|
+
}));
|
50
|
+
if(scope)
|
51
|
+
scope.repaint();
|
52
|
+
},
|
53
|
+
/**
|
54
|
+
* Go back to previous state
|
55
|
+
*/
|
56
|
+
goBack: () => {
|
57
|
+
set((state) => ({
|
58
|
+
...state.previousState
|
59
|
+
}));
|
60
|
+
}
|
61
|
+
}))
|
62
|
+
);
|
63
|
+
|
64
|
+
store.subscribe(
|
65
|
+
(state) => [state.selectedScope],
|
66
|
+
([selectedScope]) => {
|
67
|
+
// Close the drowp down
|
68
|
+
dropdownFilterStore.getState().close();
|
69
|
+
|
70
|
+
// Update filter associated to the scope
|
71
|
+
const { activeFilters, setFilters, scopeFilter, defaultFilters } =
|
72
|
+
filterStore.getState();
|
73
|
+
const filtersWithoutScopes = activeFilters.filter(({ scopeFilter }) => {
|
74
|
+
return !scopeFilter;
|
75
|
+
});
|
76
|
+
const currentScopeFilterId = scopeFilter(activeFilters);
|
77
|
+
if (`${currentScopeFilterId}` === `${selectedScope?.id}`) return;
|
78
|
+
if (selectedScope?.id) {
|
79
|
+
const matchFilter = activeFilters.find(
|
80
|
+
({ scopeFilter }) => scopeFilter?.scopeId === selectedScope.id
|
81
|
+
);
|
82
|
+
if (!matchFilter)
|
83
|
+
setFilters(
|
84
|
+
filtersWithoutScopes.concat({ scopeFilter: { scopeId: selectedScope.id } })
|
85
|
+
);
|
86
|
+
} else {
|
87
|
+
const defaultScopeFilter = defaultFilters.find(({ scopeFiler }) => scopeFilter);
|
88
|
+
if (defaultScopeFilter) setFilters(filtersWithoutScopes.concat(defaultScopeFilter));
|
89
|
+
else setFilters(filtersWithoutScopes);
|
90
|
+
}
|
91
|
+
}
|
92
|
+
);
|
93
|
+
|
94
|
+
store.subscribe(
|
95
|
+
(state) => [state.selectedScope],
|
96
|
+
([selectedScope], [previousScope]) => {
|
97
|
+
// Close the filter dropdown
|
98
|
+
dropdownFilterStore.getState().close();
|
99
|
+
if (previousScope) previousScope.repaint();
|
100
|
+
if (selectedScope) {
|
101
|
+
selectedScope.repaint();
|
102
|
+
}
|
103
|
+
}
|
104
|
+
);
|
105
|
+
|
106
|
+
store.subscribe(
|
107
|
+
(state) => [state.selectedPoint],
|
108
|
+
async ([selectedPoint], [previousPoint]) => {
|
109
|
+
if (!selectedPoint || selectedPoint === previousPoint) return;
|
110
|
+
// Close the filter dropdown
|
111
|
+
dropdownFilterStore.getState().close();
|
112
|
+
// Center to the marker
|
113
|
+
selectedPoint.repaint();
|
114
|
+
await selectedPoint.panToMarker();
|
115
|
+
if (previousPoint) previousPoint.repaint();
|
116
|
+
}
|
117
|
+
);
|
118
|
+
export default store;
|
@@ -0,0 +1,134 @@
|
|
1
|
+
import { createStore } from "zustand/vanilla";
|
2
|
+
import configStore from "./configStore";
|
3
|
+
import geoStore from "./geoStore";
|
4
|
+
import { getGeoDatasource, getGeoScopes } from "../api";
|
5
|
+
import GeoDatasourceNode from "./geoDatasourceNode";
|
6
|
+
import GeoScope from "./geoScope";
|
7
|
+
import { subscribeWithSelector } from "zustand/middleware";
|
8
|
+
import _ from "lodash";
|
9
|
+
|
10
|
+
const store = createStore(
|
11
|
+
subscribeWithSelector((set) => ({
|
12
|
+
/**
|
13
|
+
* Data Points
|
14
|
+
*/
|
15
|
+
points: [],
|
16
|
+
scopes: [],
|
17
|
+
isLoading: 0,
|
18
|
+
_lastFilter: "",
|
19
|
+
_lastResponse: [],
|
20
|
+
scopeForId: (scopeId) => {
|
21
|
+
return store.getState().scopes.find(({ data }) => `${data.id}` === `${scopeId}`);
|
22
|
+
},
|
23
|
+
clearCache: () => {
|
24
|
+
set(() => ({ _lastFilter: "", _lastResponse: [] }));
|
25
|
+
},
|
26
|
+
addProcess: () => {
|
27
|
+
set(({ isLoading }) => ({ isLoading: isLoading + 1 }));
|
28
|
+
},
|
29
|
+
removeProcess: () => {
|
30
|
+
set(({ isLoading }) => ({ isLoading: isLoading - 1 }));
|
31
|
+
},
|
32
|
+
getFilteredPoints: () => store.getState()._lastResponse,
|
33
|
+
fetchAll: async (filters = []) => {
|
34
|
+
const { points: fetchedPoints } = store.getState();
|
35
|
+
if (fetchedPoints.length > 0) return;
|
36
|
+
const locale = configStore.getState().locale;
|
37
|
+
set(({ isLoading }) => ({ isLoading: isLoading + 1 }));
|
38
|
+
const data = await getGeoDatasource(
|
39
|
+
{
|
40
|
+
variables: { filters: filters, locale: locale }
|
41
|
+
},
|
42
|
+
true
|
43
|
+
);
|
44
|
+
const points = data.nodes
|
45
|
+
.map((node) => {
|
46
|
+
const point = new GeoDatasourceNode({
|
47
|
+
node
|
48
|
+
});
|
49
|
+
if (point.init()) {
|
50
|
+
return point;
|
51
|
+
}
|
52
|
+
return undefined;
|
53
|
+
})
|
54
|
+
.filter(Boolean);
|
55
|
+
|
56
|
+
set(() => ({
|
57
|
+
points: points
|
58
|
+
}));
|
59
|
+
const scopes = await getGeoScopes({
|
60
|
+
variables: { locale: locale }
|
61
|
+
});
|
62
|
+
const geoScopes = scopes
|
63
|
+
.map((scope) => {
|
64
|
+
const geoScope = new GeoScope({
|
65
|
+
geoScope: scope
|
66
|
+
});
|
67
|
+
geoScope.init();
|
68
|
+
return geoScope.isEmpty() ? undefined : geoScope;
|
69
|
+
})
|
70
|
+
.filter(Boolean);
|
71
|
+
set(() => ({
|
72
|
+
scopes: geoScopes
|
73
|
+
}));
|
74
|
+
set(({ isLoading }) => ({
|
75
|
+
isLoading: isLoading - 1
|
76
|
+
}));
|
77
|
+
},
|
78
|
+
pointsForFilters: async (filters = []) => {
|
79
|
+
const locale = configStore.getState().locale;
|
80
|
+
const {
|
81
|
+
points,
|
82
|
+
_lastFilter: lastFilter,
|
83
|
+
_lastResponse: lastResponse
|
84
|
+
} = store.getState();
|
85
|
+
const cacheKey = JSON.stringify(filters);
|
86
|
+
// cache
|
87
|
+
if (cacheKey === lastFilter) {
|
88
|
+
return lastResponse;
|
89
|
+
}
|
90
|
+
|
91
|
+
set(({ isLoading }) => ({ isLoading: isLoading + 1 }));
|
92
|
+
const ids = await getGeoDatasource(
|
93
|
+
{
|
94
|
+
variables: { filters, locale: locale }
|
95
|
+
},
|
96
|
+
false
|
97
|
+
);
|
98
|
+
if (!ids?.nodes) {
|
99
|
+
return [];
|
100
|
+
}
|
101
|
+
const filteredPoints = ids.nodes
|
102
|
+
.map(({ id: needleId, type: needleType }) => {
|
103
|
+
return points.find(({ id }) => `${needleType}::${needleId}` === id);
|
104
|
+
})
|
105
|
+
.filter(Boolean);
|
106
|
+
|
107
|
+
set(({ isLoading }) => ({
|
108
|
+
_lastFilter: cacheKey,
|
109
|
+
_lastResponse: filteredPoints,
|
110
|
+
isLoading: isLoading - 1
|
111
|
+
}));
|
112
|
+
return filteredPoints;
|
113
|
+
}
|
114
|
+
}))
|
115
|
+
);
|
116
|
+
|
117
|
+
store.subscribe(
|
118
|
+
(state) => [state.scopes],
|
119
|
+
async ([scopes], [previousScopes]) => {
|
120
|
+
if (scopes.length === previousScopes.length) return;
|
121
|
+
|
122
|
+
const { selectedScope, selectScope } = geoStore.getState();
|
123
|
+
if (!!selectedScope) return;
|
124
|
+
|
125
|
+
const { space_ids } = configStore.getState();
|
126
|
+
if (space_ids.length === 1) {
|
127
|
+
const { scopeForId } = store.getState();
|
128
|
+
const scope = scopeForId(space_ids[0]);
|
129
|
+
if (scope) selectScope(scope);
|
130
|
+
}
|
131
|
+
}
|
132
|
+
);
|
133
|
+
|
134
|
+
export default store;
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { createStore } from "zustand/vanilla";
|
2
|
+
import { subscribeWithSelector } from "zustand/middleware";
|
3
|
+
import dropdownFilterStore from "./dropdownFilterStore";
|
4
|
+
const store = createStore(
|
5
|
+
subscribeWithSelector((set) => ({
|
6
|
+
isOpen: false,
|
7
|
+
toggleOpen: () => set((state) => ({ isOpen: !state.isOpen })),
|
8
|
+
close: () => set(() => ({ isOpen: false }))
|
9
|
+
}))
|
10
|
+
);
|
11
|
+
|
12
|
+
store.subscribe(
|
13
|
+
(state) => [state.isOpen],
|
14
|
+
([isOpen]) => {
|
15
|
+
if (isOpen) {
|
16
|
+
dropdownFilterStore.getState().close();
|
17
|
+
}
|
18
|
+
}
|
19
|
+
);
|
20
|
+
export default store;
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import _ from "lodash";
|
2
|
+
import configStore from "../../models/configStore";
|
3
|
+
import createClasses from "../createClasses";
|
4
|
+
const fallback = (container, node) => {
|
5
|
+
const { i18n, images } = configStore.getState();
|
6
|
+
if (!_.isEmpty(node.bannerImage)) {
|
7
|
+
const image = L.DomUtil.create(
|
8
|
+
"img",
|
9
|
+
"decidimGeo__drawer__listCardImg decidimGeo__drawer__listCardImg--large",
|
10
|
+
container
|
11
|
+
);
|
12
|
+
image.src = node.bannerImage;
|
13
|
+
container.className += " decidimGeo__drawer__listCardInfo--image";
|
14
|
+
}
|
15
|
+
|
16
|
+
const infoType = L.DomUtil.create("div", "decidimGeo__drawer__listCardType", container);
|
17
|
+
infoType.textContent += i18n[node.type];
|
18
|
+
const notGeoEncodedIcon = L.DomUtil.create(
|
19
|
+
"img",
|
20
|
+
createClasses("decidimGeo__drawer__listCardIcon", [node.coordinates && "hidden"]),
|
21
|
+
infoType
|
22
|
+
);
|
23
|
+
notGeoEncodedIcon.src = images?.not_geolocated;
|
24
|
+
|
25
|
+
const infoTitle = L.DomUtil.create(
|
26
|
+
"div",
|
27
|
+
"decidimGeo__drawer__listCardTitle",
|
28
|
+
container
|
29
|
+
);
|
30
|
+
infoTitle.textContent += node.title.translation;
|
31
|
+
if (node.description) {
|
32
|
+
const infoDescription = L.DomUtil.create(
|
33
|
+
"div",
|
34
|
+
"decidimGeo__drawer__listCardDescription decidimGeo__drawer__listCardDescription--large",
|
35
|
+
container
|
36
|
+
);
|
37
|
+
infoDescription.textContent = _.truncate(node.description.translation, {
|
38
|
+
length: 2500
|
39
|
+
});
|
40
|
+
}
|
41
|
+
};
|
42
|
+
export default fallback;
|
@@ -0,0 +1,75 @@
|
|
1
|
+
import _ from "lodash";
|
2
|
+
import configStore from "../../models/configStore";
|
3
|
+
import createClasses from "../createClasses";
|
4
|
+
import { format, isSameDay } from "date-fns";
|
5
|
+
|
6
|
+
const meetings = (container, node) => {
|
7
|
+
const { i18n, images } = configStore.getState();
|
8
|
+
if (!_.isEmpty(node.bannerImage)) {
|
9
|
+
const image = L.DomUtil.create(
|
10
|
+
"img",
|
11
|
+
"decidimGeo__drawer__listCardImg decidimGeo__drawer__listCardImg--large",
|
12
|
+
container
|
13
|
+
);
|
14
|
+
image.src = node.bannerImage;
|
15
|
+
container.className += " decidimGeo__drawer__listCardInfo--image";
|
16
|
+
}
|
17
|
+
|
18
|
+
const infoType = L.DomUtil.create("div", "decidimGeo__drawer__listCardType", container);
|
19
|
+
infoType.textContent += i18n[node.type];
|
20
|
+
const notGeoEncodedIcon = L.DomUtil.create(
|
21
|
+
"img",
|
22
|
+
createClasses("decidimGeo__drawer__listCardIcon", [node.coordinates && "hidden"]),
|
23
|
+
infoType
|
24
|
+
);
|
25
|
+
notGeoEncodedIcon.src = images?.not_geolocated;
|
26
|
+
const infoTitle = L.DomUtil.create(
|
27
|
+
"div",
|
28
|
+
"decidimGeo__drawer__listCardTitle",
|
29
|
+
container
|
30
|
+
);
|
31
|
+
infoTitle.textContent += node.title.translation;
|
32
|
+
const infoDescription = L.DomUtil.create(
|
33
|
+
"div",
|
34
|
+
"decidimGeo__drawer__listCardDate",
|
35
|
+
container
|
36
|
+
);
|
37
|
+
const infoStart = L.DomUtil.create(
|
38
|
+
"strong",
|
39
|
+
"decidimGeo__drawer__listCardStartDate",
|
40
|
+
infoDescription
|
41
|
+
);
|
42
|
+
let displayedDate =
|
43
|
+
format(node.startTime, "dd/MM/yy") + " — " + format(node.endTime, "dd/MM/yy");
|
44
|
+
if (isSameDay(node.startTime, node.endTime)) {
|
45
|
+
displayedDate = format(node.startTime, "dd/MM/yy");
|
46
|
+
}
|
47
|
+
infoStart.textContent = displayedDate;
|
48
|
+
|
49
|
+
const infoStartSep = L.DomUtil.create(
|
50
|
+
"div",
|
51
|
+
"decidimGeo__drawer__listCardStartDateSep",
|
52
|
+
infoDescription
|
53
|
+
);
|
54
|
+
infoStartSep.textContent = "·";
|
55
|
+
|
56
|
+
const infoStartTime = L.DomUtil.create(
|
57
|
+
"div",
|
58
|
+
"decidimGeo__drawer__listCardStartTime",
|
59
|
+
infoDescription
|
60
|
+
);
|
61
|
+
infoStartTime.textContent =
|
62
|
+
format(node.startTime, "kk:mm") + "-" + format(node.endTime, "kk:mm");
|
63
|
+
|
64
|
+
if (node.description) {
|
65
|
+
const infoDescription = L.DomUtil.create(
|
66
|
+
"div",
|
67
|
+
"decidimGeo__drawer__listCardDescription decidimGeo__drawer__listCardDescription--large decidimGeo__drawer__listCardDescription--meetings",
|
68
|
+
container
|
69
|
+
);
|
70
|
+
infoDescription.textContent = _.truncate(node.description.translation, {
|
71
|
+
length: 2500
|
72
|
+
});
|
73
|
+
}
|
74
|
+
};
|
75
|
+
export default meetings;
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import configStore from "../../models/configStore";
|
2
|
+
import createClasses from "../createClasses";
|
3
|
+
import { createDomElement } from "../createDomElement";
|
4
|
+
import _ from "lodash";
|
5
|
+
|
6
|
+
const fallback = (node) => {
|
7
|
+
const { i18n, images } = configStore.getState();
|
8
|
+
const hasImage = !_.isEmpty(node.bannerImage);
|
9
|
+
const listCard = createDomElement("li", "decidimGeo__drawer__listCard");
|
10
|
+
|
11
|
+
const info = createDomElement(
|
12
|
+
"div",
|
13
|
+
createClasses("decidimGeo__drawer__listCardInfo", [!hasImage && "large"]),
|
14
|
+
listCard
|
15
|
+
);
|
16
|
+
|
17
|
+
const infoType = createDomElement("div", "decidimGeo__drawer__listCardType", info);
|
18
|
+
infoType.textContent += i18n[node.type];
|
19
|
+
const notGeoEncodedIcon = createDomElement(
|
20
|
+
"img",
|
21
|
+
createClasses("decidimGeo__drawer__listCardIcon", [node.coordinates && "hidden"]),
|
22
|
+
infoType
|
23
|
+
);
|
24
|
+
notGeoEncodedIcon.src = images?.not_geolocated;
|
25
|
+
|
26
|
+
const infoTitle = createDomElement("div", "decidimGeo__drawer__listCardTitle", info);
|
27
|
+
infoTitle.textContent += node.title.translation;
|
28
|
+
|
29
|
+
if (node.shortDescription) {
|
30
|
+
const infoDescription = createDomElement(
|
31
|
+
"div",
|
32
|
+
"decidimGeo__drawer__listCardDescription",
|
33
|
+
info
|
34
|
+
);
|
35
|
+
infoDescription.textContent += node.shortDescription.translation;
|
36
|
+
}
|
37
|
+
|
38
|
+
if (hasImage) {
|
39
|
+
const image = createDomElement("img", "decidimGeo__drawer__listCardImg", listCard);
|
40
|
+
image.src = node.bannerImage;
|
41
|
+
}
|
42
|
+
return listCard;
|
43
|
+
};
|
44
|
+
|
45
|
+
export default fallback;
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import configStore from "../../models/configStore";
|
2
|
+
import createClasses from "../createClasses";
|
3
|
+
import { createDomElement } from "../createDomElement";
|
4
|
+
import _ from "lodash";
|
5
|
+
import { format, isSameDay } from "date-fns";
|
6
|
+
|
7
|
+
const meetings = (node) => {
|
8
|
+
const { i18n, images } = configStore.getState();
|
9
|
+
const listCard = createDomElement("li", "decidimGeo__drawer__listCard");
|
10
|
+
const info = createDomElement(
|
11
|
+
"div",
|
12
|
+
"decidimGeo__drawer__listCardInfo decidimGeo__drawer__listCardInfo--large",
|
13
|
+
listCard
|
14
|
+
);
|
15
|
+
|
16
|
+
const infoType = createDomElement("div", "decidimGeo__drawer__listCardType", info);
|
17
|
+
infoType.textContent = i18n[node.type];
|
18
|
+
const notGeoEncodedIcon = createDomElement(
|
19
|
+
"img",
|
20
|
+
createClasses("decidimGeo__drawer__listCardIcon", [node.coordinates && "hidden"]),
|
21
|
+
infoType
|
22
|
+
);
|
23
|
+
notGeoEncodedIcon.src = images?.not_geolocated;
|
24
|
+
|
25
|
+
const infoTitle = createDomElement("div", "decidimGeo__drawer__listCardTitle", info);
|
26
|
+
infoTitle.textContent = node.title.translation;
|
27
|
+
|
28
|
+
const infoDescription = createDomElement(
|
29
|
+
"div",
|
30
|
+
"decidimGeo__drawer__listCardDate",
|
31
|
+
info
|
32
|
+
);
|
33
|
+
const infoStart = createDomElement(
|
34
|
+
"strong",
|
35
|
+
"decidimGeo__drawer__listCardStartDate",
|
36
|
+
infoDescription
|
37
|
+
);
|
38
|
+
let displayedDate =
|
39
|
+
format(node.startTime, "dd/MM/yy") + " — " + format(node.endTime, "dd/MM/yy");
|
40
|
+
if (isSameDay(node.startTime, node.endTime)) {
|
41
|
+
displayedDate = format(node.startTime, "dd/MM/yy");
|
42
|
+
}
|
43
|
+
infoStart.textContent = displayedDate;
|
44
|
+
|
45
|
+
const infoStartSep = createDomElement(
|
46
|
+
"span",
|
47
|
+
"decidimGeo__drawer__listCardStartDateSep",
|
48
|
+
infoDescription
|
49
|
+
);
|
50
|
+
infoStartSep.textContent = "·";
|
51
|
+
|
52
|
+
const infoStartTime = createDomElement(
|
53
|
+
"span",
|
54
|
+
"decidimGeo__drawer__listCardStartTime",
|
55
|
+
infoDescription
|
56
|
+
);
|
57
|
+
infoStartTime.textContent =
|
58
|
+
format(node.startTime, "kk:mm") + "-" + format(node.endTime, "kk:mm");
|
59
|
+
return listCard;
|
60
|
+
};
|
61
|
+
|
62
|
+
export default meetings;
|
@@ -0,0 +1,14 @@
|
|
1
|
+
const createCustomMarker = (location) => {
|
2
|
+
return new L.circleMarker(location, {
|
3
|
+
radius: 6,
|
4
|
+
fillColor: "#ffffff",
|
5
|
+
fillOpacity: 1,
|
6
|
+
color: "#404040",
|
7
|
+
opacity: 1,
|
8
|
+
weight: 5,
|
9
|
+
className: "decidimGeo__marker",
|
10
|
+
riseOnHover: true
|
11
|
+
});
|
12
|
+
};
|
13
|
+
|
14
|
+
export default createCustomMarker;
|