Skip to content

Commit

Permalink
Merge pull request #6 from Platoniq/blueprint-cards
Browse files Browse the repository at this point in the history
Blueprint cards
  • Loading branch information
microstudi authored Nov 27, 2019
2 parents 482d8bf + 276bd67 commit 4125190
Show file tree
Hide file tree
Showing 33 changed files with 813 additions and 114 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ DEPENDENCIES
web-console (~> 3.5)

RUBY VERSION
ruby 2.6.5p114
ruby 2.6.3p62

BUNDLED WITH
2.0.2
82 changes: 38 additions & 44 deletions app/assets/javascripts/decidim/navigation_maps/admin/map_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ function NavigationMapEditor(map_object, table_object) {
};
});
self.table_object = table_object;
this.createAreaCallback = function () {};
this.editAreaCallback = function () {};
this.removeAreaCallback = function () {};
}

// NavigationMapEditor derives from NavigationMapView
Expand All @@ -31,76 +34,67 @@ NavigationMapEditor.prototype.createControls = function() {
self.map.on('pm:create', function(e) {
var geojson = e.layer.toGeoJSON();
self.blueprint[e.layer._leaflet_id] = geojson;
self.renderRow(e.layer, geojson);
self.attachEditorEvents(e.layer);
self.createAreaCallback(e.layer._leaflet_id, e.layer, self);
});

self.map.on('pm:remove', function(e) {
delete self.blueprint[e.layer._leaflet_id];
document.getElementById(self.rowId(e.layer._leaflet_id)).remove();
self.removeAreaCallback(e.layer._leaflet_id, e.layer, self);
});
};

NavigationMapEditor.prototype.editing = function() {
var pm = this.map.pm;
return pm.globalRemovalEnabled() || pm.globalDragModeEnabled() || pm.globalEditEnabled();
};

NavigationMapView.prototype.createAreas = function() {
var self = this;
self.forEachBlueprint(function(id, geoarea) {
new L.GeoJSON(geoarea, {
onEachFeature: function(feature, layer) {
layer._leaflet_id = id;
layer.on('mouseover', function(e) {
e.target.getElement().classList.add('selected')
document.getElementById(self.rowId(e.target._leaflet_id)).classList.add('selected');
});

layer.on('mouseout', function(e) {
e.target.getElement().classList.remove('selected')
document.getElementById(self.rowId(e.target._leaflet_id)).classList.remove('selected');
});

layer.on('pm:edit', function(e) {
self.blueprint[e.target._leaflet_id] = e.target.toGeoJSON();
});

self.renderRow(layer, feature);
self.attachEditorEvents(layer);
}
}).addTo(self.map);
});
};

NavigationMapEditor.prototype.renderRow = function (layer, feature) {
// register callback to handle area edits,removals and creations
NavigationMapView.prototype.onCreateArea = function(callback) {
this.createAreaCallback = callback;
};
NavigationMapView.prototype.onEditArea = function(callback) {
this.editAreaCallback = callback;
};
NavigationMapView.prototype.onRemoveArea = function(callback) {
this.removeCreateCallback = callback;
};

NavigationMapEditor.prototype.attachEditorEvents = function (layer) {
var self = this;
var tbody = self.table_object.getElementsByTagName('tbody')[0];
var tr = this.rowTemplate(layer._leaflet_id, feature);

tr.addEventListener("mouseover", function() {
layer.getElement().classList.add('selected')
layer.on('mouseover', function(e) {
e.target.getElement().classList.add('selected')
});

tr.addEventListener("mouseout", function() {
layer.getElement().classList.remove('selected')
layer.on('mouseout', function(e) {
e.target.getElement().classList.remove('selected')
});

tbody.appendChild(tr);
};

NavigationMapEditor.prototype.rowTemplate = function (area, feature) {
var link = feature.properties && feature.properties.link || '#';
var tr = document.createElement('tr');
tr.id = this.rowId(area);
tr.innerHTML = ' <td>' + area +'</td>'
+ ' <td><input type="text" id="' + tr.id + '-link" value="' + link + '"></td>';
return tr;
};
layer.on('pm:edit', function(e) {
self.blueprint[e.target._leaflet_id] = e.target.toGeoJSON();
self.editAreaCallback(e.target._leaflet_id, e.target, self);
});

NavigationMapEditor.prototype.rowId = function (id) {
return `map-editor-${this.id}-tr-${id}`;
layer.on('click', function(e) {
if(!self.editing()) {
self.clickAreaCallback(e.target._leaflet_id, e.target, self);
}
});
};

NavigationMapEditor.prototype.getBlueprint = function () {
var self = this;
self.forEachBlueprint(function(id, geoarea) {
var link = document.getElementById(self.rowId(id) + "-link");
geoarea.properties = geoarea && geoarea.properties || {link: '#'}
if(link) geoarea.properties.link = link.value;
});
return self.blueprint;
return this.blueprint;
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
//= require leaflet
//= require leaflet-geoman.min
//= require jquery.form
//= require decidim/navigation_maps/admin/map_editor
//= require_self
Expand All @@ -13,16 +11,60 @@ $(function() {
var $bar = $('.navigation_maps.admin .progress-meter');
var $loading = $('.navigation_maps.admin .loading');
var $callout = $('.navigation_maps.admin .callout');
var $modal = $('#mapEditModal');
var $form = $('form');
var $tabs = $('#navigation_maps-tabs');
var $accordion = $('.navigation_maps.admin .accordion');
var editors = {};
var new_areas = {};

$maps.each(function() {
var table = document.getElementById("navigation_maps-table-" + $(this).data('id'));
editors[$(this).data('id')] = new NavigationMapEditor(this, table);
var id = $(this).data('id');
var table = document.getElementById("navigation_maps-table-" + id);
editors[id] = new NavigationMapEditor(this, table);
editors[id].onCreateArea(function(area_id, area, obj) {
new_areas[area_id] = true;
});

editors[id].onClickArea(function(area_id, area, obj) {
$modal.find('.modal-content').html('');
$modal.addClass('loading').foundation('open');
$callout.hide();
$callout.removeClass('alert success');
// "new" form insted of editing
var rel = new_areas[area_id] ? 'new' : area_id;
$modal.find('.modal-content').load(`/admin/navigation_maps/blueprints/${id}/areas/${rel}`, function() {
var $input1 = $modal.find('input[name="blueprint_area[area_id]"]');
var $input2 = $modal.find('input[name="blueprint_area[area_type]"]');
var $input3 = $modal.find('input[name="blueprint_area[area]"]');
var a = area.toGeoJSON();
$modal.removeClass('loading');
if($input1.length) $input1.val(area_id);
if($input2.length) $input2.val(a.type);
if($input3.length) $input3.val(JSON.stringify(a));
});
});
});

// Rails AJAX events
document.body.addEventListener('ajax:error', function(responseText) {
$callout.contents('p').html(responseText.detail[0].message + ": <strong>" + responseText.detail[0].error + "</strong>");
$callout.addClass('alert');
});

document.body.addEventListener('ajax:success', function(responseText) {
if(new_areas[responseText.detail[0].area]) {
delete new_areas[responseText.detail[0].area]
}
$callout.contents('p').html(responseText.detail[0].message);
$callout.addClass('success');
});

document.body.addEventListener('ajax:complete', function(xhr, event) {
$callout.show();
$modal.foundation('close');
})

$tabs.on('change.zf.tabs', function(e, $tab, $content) {
var id = $content.find('.map').data('id');
if(id) {
Expand Down
25 changes: 22 additions & 3 deletions app/assets/javascripts/decidim/navigation_maps/map_view.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//= require leaflet
//= require leaflet-geoman.min
// Creates a map view

function NavigationMapView(map_object, callback) {
Expand All @@ -19,6 +21,7 @@ function NavigationMapView(map_object, callback) {
}
};
self.image.src = self.image_path;
this.clickAreaCallback = function () {};
}

NavigationMapView.prototype.createMap = function() {
Expand Down Expand Up @@ -59,14 +62,28 @@ NavigationMapView.prototype.createAreas = function() {
new L.GeoJSON(geoarea, {
onEachFeature: function(feature, layer) {
layer._leaflet_id = id;

layer.on('mouseover', function(e) {
e.target.getElement().classList.add('selected')
});

layer.on('mouseout', function(e) {
e.target.getElement().classList.remove('selected')
});

layer.on('click', function(e) {
if(feature.properties && feature.properties.link) location = feature.properties.link;
self.clickAreaCallback(e.target, self);
});
}
}).addTo(self.map);
});
};

// register callback to handle area clicks
NavigationMapView.prototype.onClickArea = function(callback) {
this.clickAreaCallback = callback;
};

NavigationMapView.prototype.forEachBlueprint = function (callback) {
for (var id in this.blueprint) {
var geoarea = this.blueprint[id];
Expand All @@ -77,6 +94,8 @@ NavigationMapView.prototype.forEachBlueprint = function (callback) {
};

NavigationMapView.prototype.reload = function () {
this.map.invalidateSize(true);
this.fitBounds();
if(this.map) {
this.map.invalidateSize(true);
this.fitBounds();
}
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
//= require leaflet
//= require leaflet-geoman.min
//= require decidim/navigation_maps/map_view
//= require_self

Expand All @@ -13,12 +11,16 @@ $(function() {
var maps = {};

$maps.each(function() {
maps[$(this).data('id')] = new NavigationMapView(this);
var id = $(this).data('id');
maps[id] = new NavigationMapView(this);
maps[id].onClickArea(function(area) {
if(area.feature.properties && area.feature.properties.link) location = area.feature.properties.link;
});
});

$tabs.on('change.zf.tabs', function(e, $tab, $content) {
var id = $content.find('.map').data('id');
maps[id].reload();
});

});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Variables

$leaflet-background-color: 34,98,204;
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
@import "decidim/variables";
@import "decidim/utils/settings";
@import "decidim/utils/mixins";

:root {
--leaflet-background-color: 34,98,204;
}
@import "decidim/navigation_maps/variables";

.navigation_maps.admin {
.accordion-item {
Expand All @@ -18,7 +15,7 @@
&.is-active {
.accordion-title {
background-color: #039be5;
border-color: rgba(var(--leaflet-background-color),1) !important;
border-color: "rgba(#{$leaflet-background-color}, 1)" !important;
}
}
}
Expand All @@ -44,7 +41,7 @@

}
.spinner {
@include spinner(25px, #aaa, var(--primary), 800ms);
@include spinner(25px, #aaa, var(--secondary), 800ms);
vertical-align: middle;
}
.progress {
Expand All @@ -55,7 +52,7 @@
}
.progress-meter {
color: #fff;
background-color: var(--primary);
background-color: var(--secondary);
width: 30%;
padding:0 0.5em;
font-size: 0.7em;
Expand All @@ -77,17 +74,9 @@
border-top: 1px solid $dark-gray;
padding: 1em 1em 0;
}
tbody > tr {
&.selected {
background-color: rgba(var(--leaflet-background-color), 0.5) !important;
}
&:hover {
background-color: rgba(var(--leaflet-background-color), 0.5) !important;
}
}
.leaflet-interactive {
fill: rgba(var(--leaflet-background-color), 1);
color: rgba(var(--leaflet-background-color), 1);
fill: "rgba(#{$leaflet-background-color}, 1)";
color: "rgba(#{$leaflet-background-color}, 1)";
weight: 3;
opacity: 0.6;
fill-opacity: 0.5;
Expand All @@ -96,4 +85,18 @@
}
}
}
}

}

.navigation_maps.modal {
.spinner {
@include spinner(25px, #aaa, var(--secondary), 800ms);
vertical-align: middle;
display: none;
}
&.loading {
.spinner {
display: inline-block;
}
}
}
Loading

0 comments on commit 4125190

Please sign in to comment.