]> git.openstreetmap.org Git - rails.git/commitdiff
Merge pull request #5390 from AntonKhorev/trace-resourceful-routes
authorAndy Allan <git@gravitystorm.co.uk>
Wed, 11 Dec 2024 14:04:19 +0000 (14:04 +0000)
committerGitHub <noreply@github.com>
Wed, 11 Dec 2024 14:04:19 +0000 (14:04 +0000)
Resourceful routes for traces API

20 files changed:
Gemfile.lock
app/assets/javascripts/index.js
app/assets/javascripts/leaflet.map.js
app/assets/stylesheets/browse.scss [deleted file]
app/assets/stylesheets/common.scss
app/helpers/browse_helper.rb
app/helpers/user_blocks_helper.rb
app/views/browse/_containing_relation.html.erb
app/views/browse/_node.html.erb
app/views/browse/_relation.html.erb
app/views/browse/_relation_member.html.erb
app/views/browse/_way.html.erb
app/views/changesets/_elements.html.erb
app/views/user_blocks/_block.html.erb
app/views/user_blocks/_page.html.erb
config/browse_icons.yml [new file with mode: 0644]
config/initializers/browse_icons.rb [new file with mode: 0644]
config/layers.yml
config/locales/en.yml
test/helpers/browse_helper_test.rb

index d909ddad6af5fd325fe5d0684b1dbb57ed7445b0..455ae2bdaa2c8c303b7af1071b7a38de15b96948 100644 (file)
@@ -3,29 +3,29 @@ GEM
   specs:
     aasm (5.5.0)
       concurrent-ruby (~> 1.0)
-    actioncable (7.2.2)
-      actionpack (= 7.2.2)
-      activesupport (= 7.2.2)
+    actioncable (7.2.2.1)
+      actionpack (= 7.2.2.1)
+      activesupport (= 7.2.2.1)
       nio4r (~> 2.0)
       websocket-driver (>= 0.6.1)
       zeitwerk (~> 2.6)
-    actionmailbox (7.2.2)
-      actionpack (= 7.2.2)
-      activejob (= 7.2.2)
-      activerecord (= 7.2.2)
-      activestorage (= 7.2.2)
-      activesupport (= 7.2.2)
+    actionmailbox (7.2.2.1)
+      actionpack (= 7.2.2.1)
+      activejob (= 7.2.2.1)
+      activerecord (= 7.2.2.1)
+      activestorage (= 7.2.2.1)
+      activesupport (= 7.2.2.1)
       mail (>= 2.8.0)
-    actionmailer (7.2.2)
-      actionpack (= 7.2.2)
-      actionview (= 7.2.2)
-      activejob (= 7.2.2)
-      activesupport (= 7.2.2)
+    actionmailer (7.2.2.1)
+      actionpack (= 7.2.2.1)
+      actionview (= 7.2.2.1)
+      activejob (= 7.2.2.1)
+      activesupport (= 7.2.2.1)
       mail (>= 2.8.0)
       rails-dom-testing (~> 2.2)
-    actionpack (7.2.2)
-      actionview (= 7.2.2)
-      activesupport (= 7.2.2)
+    actionpack (7.2.2.1)
+      actionview (= 7.2.2.1)
+      activesupport (= 7.2.2.1)
       nokogiri (>= 1.8.5)
       racc
       rack (>= 2.2.4, < 3.2)
@@ -36,39 +36,39 @@ GEM
       useragent (~> 0.16)
     actionpack-page_caching (1.2.4)
       actionpack (>= 4.0.0)
-    actiontext (7.2.2)
-      actionpack (= 7.2.2)
-      activerecord (= 7.2.2)
-      activestorage (= 7.2.2)
-      activesupport (= 7.2.2)
+    actiontext (7.2.2.1)
+      actionpack (= 7.2.2.1)
+      activerecord (= 7.2.2.1)
+      activestorage (= 7.2.2.1)
+      activesupport (= 7.2.2.1)
       globalid (>= 0.6.0)
       nokogiri (>= 1.8.5)
-    actionview (7.2.2)
-      activesupport (= 7.2.2)
+    actionview (7.2.2.1)
+      activesupport (= 7.2.2.1)
       builder (~> 3.1)
       erubi (~> 1.11)
       rails-dom-testing (~> 2.2)
       rails-html-sanitizer (~> 1.6)
     active_record_union (1.3.0)
       activerecord (>= 4.0)
-    activejob (7.2.2)
-      activesupport (= 7.2.2)
+    activejob (7.2.2.1)
+      activesupport (= 7.2.2.1)
       globalid (>= 0.3.6)
-    activemodel (7.2.2)
-      activesupport (= 7.2.2)
-    activerecord (7.2.2)
-      activemodel (= 7.2.2)
-      activesupport (= 7.2.2)
+    activemodel (7.2.2.1)
+      activesupport (= 7.2.2.1)
+    activerecord (7.2.2.1)
+      activemodel (= 7.2.2.1)
+      activesupport (= 7.2.2.1)
       timeout (>= 0.4.0)
-    activerecord-import (1.8.1)
+    activerecord-import (2.0.0)
       activerecord (>= 4.2)
-    activestorage (7.2.2)
-      actionpack (= 7.2.2)
-      activejob (= 7.2.2)
-      activerecord (= 7.2.2)
-      activesupport (= 7.2.2)
+    activestorage (7.2.2.1)
+      actionpack (= 7.2.2.1)
+      activejob (= 7.2.2.1)
+      activerecord (= 7.2.2.1)
+      activesupport (= 7.2.2.1)
       marcel (~> 1.0)
-    activesupport (7.2.2)
+    activesupport (7.2.2.1)
       base64
       benchmark (>= 0.3)
       bigdecimal
@@ -92,7 +92,7 @@ GEM
     autoprefixer-rails (10.4.19.0)
       execjs (~> 2)
     aws-eventstream (1.3.0)
-    aws-partitions (1.1016.0)
+    aws-partitions (1.1019.0)
     aws-sdk-core (3.214.0)
       aws-eventstream (~> 1, >= 1.3.0)
       aws-partitions (~> 1, >= 1.992.0)
@@ -101,7 +101,7 @@ GEM
     aws-sdk-kms (1.96.0)
       aws-sdk-core (~> 3, >= 3.210.0)
       aws-sigv4 (~> 1.5)
-    aws-sdk-s3 (1.175.0)
+    aws-sdk-s3 (1.176.0)
       aws-sdk-core (~> 3, >= 3.210.0)
       aws-sdk-kms (~> 1)
       aws-sigv4 (~> 1.5)
@@ -208,7 +208,7 @@ GEM
       activerecord (>= 3.0, < 9.0)
       delayed_job (>= 3.0, < 5)
     docile (1.4.1)
-    doorkeeper (5.8.0)
+    doorkeeper (5.8.1)
       railties (>= 5)
     doorkeeper-i18n (5.2.7)
       doorkeeper (>= 5.2)
@@ -265,7 +265,7 @@ GEM
     factory_bot_rails (6.4.4)
       factory_bot (~> 6.5)
       railties (>= 5.0.0)
-    faraday (2.12.1)
+    faraday (2.12.2)
       faraday-net_http (>= 2.0, < 3.5)
       json
       logger
@@ -373,7 +373,7 @@ GEM
     mini_portile2 (2.8.8)
     mini_racer (0.9.0)
       libv8-node (~> 18.19.0.0)
-    minitest (5.25.2)
+    minitest (5.25.4)
     minitest-focus (1.4.0)
       minitest (>= 4, < 6)
     msgpack (1.7.5)
@@ -393,7 +393,7 @@ GEM
     net-smtp (0.5.0)
       net-protocol
     nio4r (2.7.4)
-    nokogiri (1.16.8)
+    nokogiri (1.17.1)
       mini_portile2 (~> 2.8.2)
       racc (~> 1.4)
     oauth (1.1.0)
@@ -461,7 +461,7 @@ GEM
     pg (1.5.9)
     popper_js (2.11.8)
     progress (3.6.0)
-    pstore (0.1.3)
+    pstore (0.1.4)
     psych (5.2.1)
       date
       stringio
@@ -487,20 +487,20 @@ GEM
     rackup (1.0.1)
       rack (< 3)
       webrick
-    rails (7.2.2)
-      actioncable (= 7.2.2)
-      actionmailbox (= 7.2.2)
-      actionmailer (= 7.2.2)
-      actionpack (= 7.2.2)
-      actiontext (= 7.2.2)
-      actionview (= 7.2.2)
-      activejob (= 7.2.2)
-      activemodel (= 7.2.2)
-      activerecord (= 7.2.2)
-      activestorage (= 7.2.2)
-      activesupport (= 7.2.2)
+    rails (7.2.2.1)
+      actioncable (= 7.2.2.1)
+      actionmailbox (= 7.2.2.1)
+      actionmailer (= 7.2.2.1)
+      actionpack (= 7.2.2.1)
+      actiontext (= 7.2.2.1)
+      actionview (= 7.2.2.1)
+      activejob (= 7.2.2.1)
+      activemodel (= 7.2.2.1)
+      activerecord (= 7.2.2.1)
+      activestorage (= 7.2.2.1)
+      activesupport (= 7.2.2.1)
       bundler (>= 1.15.0)
-      railties (= 7.2.2)
+      railties (= 7.2.2.1)
     rails-controller-testing (1.0.5)
       actionpack (>= 5.0.1.rc1)
       actionview (>= 5.0.1.rc1)
@@ -518,9 +518,9 @@ GEM
     rails_param (1.3.1)
       actionpack (>= 3.2.0)
       activesupport (>= 3.2.0)
-    railties (7.2.2)
-      actionpack (= 7.2.2)
-      activesupport (= 7.2.2)
+    railties (7.2.2.1)
+      actionpack (= 7.2.2.1)
+      activesupport (= 7.2.2.1)
       irb (~> 1.13)
       rackup (>= 1.0.0)
       rake (>= 12.2)
@@ -639,7 +639,7 @@ GEM
       concurrent-ruby (~> 1.0)
     unicode-display_width (2.6.0)
     uri (0.13.1)
-    useragent (0.16.10)
+    useragent (0.16.11)
     validates_email_format_of (1.8.2)
       i18n (>= 0.8.0)
       simpleidn
index 9df0f0ad5a432b34be12258c6ead602362fa05d0..56495b31a31c87fd18ca8b864ac492b84f1f0240 100644 (file)
@@ -207,7 +207,7 @@ $(document).ready(function () {
   if (OSM.MATOMO) {
     map.on("layeradd", function (e) {
       if (e.layer.options) {
-        var goal = OSM.MATOMO.goals[e.layer.options.keyid];
+        var goal = OSM.MATOMO.goals[e.layer.options.layerId];
 
         if (goal) {
           $("body").trigger("matomogoal", goal);
index f478f4351b58a644ab0b5b35015021b28abaf48c..02ed318acffc89eded8d0dccad99a682c8e2d05f 100644 (file)
@@ -26,8 +26,6 @@ L.OSM.Map = L.Map.extend({
       for (const [property, value] of Object.entries(layerDefinition)) {
         if (property === "credit") {
           layerOptions.attribution = makeAttribution(value);
-        } else if (property === "keyId") {
-          layerOptions.keyid = value;
         } else if (property === "nameId") {
           layerOptions.name = I18n.t(`javascripts.map.base.${value}`);
         } else if (property === "apiKeyId") {
@@ -134,7 +132,7 @@ L.OSM.Map = L.Map.extend({
   getMapBaseLayerId: function () {
     var baseLayerId;
     this.eachLayer(function (layer) {
-      if (layer.options && layer.options.keyid) baseLayerId = layer.options.keyid;
+      if (layer.options && layer.options.layerId) baseLayerId = layer.options.layerId;
     });
     return baseLayerId;
   },
diff --git a/app/assets/stylesheets/browse.scss b/app/assets/stylesheets/browse.scss
deleted file mode 100644 (file)
index 2dac602..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-$map-sidebar-icons: (
-
-  /* Nodes (and ways as areas) */
-
-  ".aeroway.aerodrome": ("filename": "aerodrome.p.16.png"),
-  
-  ".amenity.atm": ("filename": "amenity_atm.16.png", "invert": true),
-  ".amenity.bank": ("filename": "amenity_bank.16.png", "invert": true),
-  ".amenity.bar": ("filename": "amenity_bar.16.png", "invert": true),
-  ".amenity.bench": ("filename": "amenity_bench.16.png", "invert": true),
-  ".amenity.biergarten": ("filename": "amenity_biergarten.16.png", "invert": true),
-  ".amenity.bicycle_parking": ("filename": "amenity_bicycle_parking.16.png"),
-  ".amenity.bicycle_rental": ("filename": "transport_rental_bicycle.16.png"),
-  ".amenity.bus_station": ("filename": "bus_station.n.16.png"),
-  ".amenity.cafe": ("filename": "amenity_cafe.16.png", "invert": true),
-  ".amenity.car_rental": ("filename": "transport_rental_car.16.png"),
-  ".amenity.car_sharing": ("filename": "car_share.p.16.png"),
-  ".amenity.childcare": ("filename": "amenity_childcare.p.16.png"),
-  ".amenity.cinema": ("filename": "amenity_cinema.16.png", "invert": true),
-  ".amenity.courthouse": ("filename": "amenity_courthouse.16.png", "invert": true),
-  ".amenity.dentist": ("filename": "amenity_dentist.16.png"),
-  ".amenity.doctors": ("filename": "amenity_doctors.16.png"),
-  ".amenity.drinking_water": ("filename": "amenity_drinking_water.16.png", "invert": true),
-  ".amenity.fast_food": ("filename": "amenity_fast_food.16.png", "invert": true),
-  ".amenity.fire_station": ("filename": "amenity_fire_station.16.png", "invert": true),
-  ".amenity.fuel": ("filename": "amenity_fuel.16.png"),
-  ".amenity.hospital": ("filename": "amenity_hospital.16.png"),
-  ".amenity.kindergarten": ("filename": "amenity_childcare.p.16.png"),
-  ".amenity.library": ("filename": "library.p.16.png", "invert": true),
-  ".amenity.nightclub": ("filename": "amenity_nightclub.16.png", "invert": true),
-  ".amenity.parking": ("filename": "parking.p.16.png"),
-  ".amenity.pharmacy": ("filename": "amenity_pharmacy.16.png"),
-  ".amenity.place_of_worship": ("filename": "amenity_place_of_worship.16.png", "invert": true),
-  ".amenity.police": ("filename": "amenity_police.16.png", "invert": true),
-  ".amenity.post_box": ("filename": "post_box.p.16.png", "invert": true),
-  ".amenity.post_office": ("filename": "post_office.p.16.png", "invert": true),
-  ".amenity.prison": ("filename": "amenity_prison.16.png", "invert": true),
-  ".amenity.pub": ("filename": "amenity_pub.16.png", "invert": true),
-  ".amenity.restaurant": ("filename": "amenity_restaurant.16.png", "invert": true),
-  ".amenity.recycling": ("filename": "amenity_recycling.16.png", "invert": true),
-  ".amenity.school": ("filename": "education_school.p.16.png"),
-  ".amenity.shelter": ("filename": "shelter2.p.16.png"),
-  ".amenity.taxi": ("filename": "amenity_taxi.16.png"),
-  ".amenity.telephone": ("filename": "telephone.p.16.png", "invert": true),
-  ".amenity.theatre": ("filename": "amenity_theatre.16.png", "invert": true),
-  ".amenity.toilets": ("filename": "amenity_toilets.16.png", "invert": true),
-  ".amenity.townhall": ("filename": "amenity_townhall.16.png", "invert": true),
-  ".amenity.university": ("filename": "education_university.p.16.png"),
-  ".amenity.veterinary": ("filename": "health_veterinary.p.16.png"),
-  ".amenity.waste_basket": ("filename": "amenity_waste_basket.16.png", "invert": true),
-
-  ".barrier.gate": ("filename": "gate2.p.16.png", "invert": true),
-
-  ".highway.bus_stop": ("filename": "highway_bus_stop.16.png"),
-  ".highway.mini_roundabout": ("filename": "mini_round.p.16.png"),
-  ".highway.traffic_signals": ("filename": "traffic_light.png", "invert": true),
-  ".highway.turning_circle": ("filename": "turning_circle.p.16.png"),
-
-  ".historic.archaeological_site": ("filename": "historic_archaeological_site.16.png", "invert": true),
-  ".historic.castle": ("filename": "tourist_castle.p.16.png", "invert": true),
-  ".historic.memorial": ("filename": "historic_memorial.16.png", "invert": true),
-  ".historic.monument": ("filename": "historic_monument.16.png", "invert": true),
-  ".historic.ruins": ("filename": "tourist_ruins.p.16.png", "invert": true),
-  ".historic.wreck": ("filename": "tourist_wreck.p.16.png", "invert": true),
-
-  ".man_made.lighthouse": ("filename": "man_made_lighthouse.16.png"),
-  ".man_made.water_tower": ("filename": "man_made_water_tower.16.png", "invert": true),
-  ".man_made.windmill": ("filename": "man_made_windmill.16.png", "invert": true),
-
-  ".natural.tree": ("filename": "tree.p.16.png"),
-
-  ".office.diplomatic": ("filename": "office_diplomatic.16.png"),
-  ".office.estate_agent": ("filename": "shop_estateagent.16.png"),
-
-  ".railway.halt": ("filename": "halt.p.16.png"),
-  ".railway.station": ("filename": "station.p.16.png"),
-  ".railway.level_crossing": ("filename": "level_crossing.p.16.png", "invert": true),
-
-  ".shop": ("filename": "shop_convenience.p.16.png"),
-  ".shop.alcohol": ("filename": "shop_alcohol.16.png"),
-  ".shop.bakery": ("filename": "shop_bakery.16.png"),
-  ".shop.bicycle": ("filename": "shop_bicycle.16.png"),
-  ".shop.books": ("filename": "shop_books.16.png"),
-  ".shop.butcher": ("filename": "shop_butcher.p.16.png"),
-  ".shop.clothes": ("filename": "shop_clothes.16.png"),
-  ".shop.car_parts": ("filename": "shop_car_parts.16.png"),
-  ".shop.car_repair": ("filename": "shop_car_repair.16.png"),
-  ".shop.convenience": ("filename": "shop_convenience.p.16.png"),
-  ".shop.doityourself": ("filename": "shop_doityourself.16.png"),
-  ".shop.electronics": ("filename": "shop_electronics.16.png"),
-  ".shop.estate_agent": ("filename": "shop_estateagent.16.png"),
-  ".shop.fashion": ("filename": "shop_clothes.16.png"),
-  ".shop.florist": ("filename": "shop_florist.16.png"),
-  ".shop.furniture": ("filename": "shop_furniture.16.png"),
-  ".shop.garden_centre": ("filename": "shop_florist.16.png"),
-  ".shop.gift": ("filename": "shop_gift.16.png"),
-  ".shop.greengrocer": ("filename": "shop_greengrocer.p.16.png"),
-  ".shop.hardware": ("filename": "shop_doityourself.16.png"),
-  ".shop.hairdresser": ("filename": "shop_hairdresser.16.png"),
-  ".shop.jewelry": ("filename": "shop_jewelry.16.png"),
-  ".shop.mobile_phone": ("filename": "shop_mobile_phone.16.png"),
-  ".shop.optician": ("filename": "shop_optician.16.png"),
-  ".shop.pet": ("filename": "shop_pet.16.png"),
-  ".shop.seafood": ("filename": "shop_seafood.16.png"),
-  ".shop.shoes": ("filename": "shop_shoes.16.png"),
-  ".shop.supermarket": ("filename": "shop_supermarket.p.16.png"),
-
-  ".tourism.alpine_hut": ("filename": "tourism_alpine_hut.16.png"),
-  ".tourism.camp_site": ("filename": "tourism_camp_site.16.png"),
-  ".tourism.caravan_site": ("filename": "tourism_caravan_site.16.png"),
-  ".tourism.hostel": ("filename": "tourism_hostel.16.png"),
-  ".tourism.hotel": ("filename": "tourism_hotel.16.png"),
-  ".tourism.motel": ("filename": "tourism_motel.16.png"),
-  ".tourism.museum": ("filename": "tourism_museum.16.png", "invert": true),
-  ".tourism.picnic_site": ("filename": "tourism_picnic_site.16.png", "invert": true),
-  ".tourism.viewpoint": ("filename": "view_point.p.16.png", "invert": true),
-  ".tourism.wilderness_hut": ("filename": "tourism_wilderness_hut.16.png"),
-
-  /* Ways */
-
-  ".aeroway.runway": ("filename": "runway.20.png"),
-  ".aeroway.taxiway": ("filename": "taxiway.20.png"),
-
-  ".barrier.wall": ("filename": "wall.20.png"),
-
-  ".building": ("filename": "building.png"),
-
-  ".highway.bridleway": ("filename": "bridleway.20.png"),
-  ".highway.cycleway": ("filename": "cycleway.20.png"),
-  ".highway.footway": ("filename": "footway.20.png"),
-  ".highway.motorway": ("filename": "motorway.20.png"),
-  ".highway.motorway_link": ("filename": "motorway.20.png"),
-  ".highway.path": ("filename": "path.20.png"),
-  ".highway.pedestrian": ("filename": "service.20.png"),
-  ".highway.primary": ("filename": "primary.20.png"),
-  ".highway.primary_link": ("filename": "primary.20.png"),
-  ".highway.residential": ("filename": "unclassified.20.png"),
-  ".highway.secondary": ("filename": "secondary.20.png"),
-  ".highway.secondary_link": ("filename": "secondary.20.png"),
-  ".highway.service": ("filename": "service.20.png"),
-  ".highway.tertiary": ("filename": "tertiary.20.png"),
-  ".highway.track": ("filename": "track.20.png"),
-  ".highway.trunk": ("filename": "trunk.20.png"),
-  ".highway.trunk_link": ("filename": "trunk.20.png"),
-  ".highway.unclassified": ("filename": "unclassified.20.png"),
-
-  ".landuse.brownfield": ("filename": "brownfield.png"),
-  ".landuse.cemetery": ("filename": "cemetery.png"),
-  ".landuse.commercial": ("filename": "commercial.png"),
-  ".landuse.farmland": ("filename": "farmland.png"),
-  ".landuse.farmyard": ("filename": "farmyard.png"),
-  ".landuse.forest": ("filename": "forest.png"),
-  ".landuse.grass": ("filename": "grass.png"),
-  ".landuse.industrial": ("filename": "industrial.png"),
-  ".landuse.meadow": ("filename": "meadow.png"),
-  ".landuse.military": ("filename": "military.png"),
-  ".landuse.residential": ("filename": "residential.png"),
-  ".landuse.retail": ("filename": "retail.png"),
-  ".landuse.tourism": ("filename": "tourism.png"),
-
-  ".leisure.golf_course": ("filename": "golf.png"),
-  ".leisure.park": ("filename": "park.png"),
-  ".leisure.picnic_table": ("filename": "tourism_picnic_site.16.png", "invert": true),
-  ".leisure.playground": ("filename": "leisure_playground.16.png", "invert": true),
-  ".leisure.pitch": ("filename": "pitch.png"),
-  ".leisure.nature_reserve": ("filename": "reserve.png"),
-  ".leisure.water_park": ("filename": "leisure_water_park.16.png", "invert": true),
-
-  ".natural.grassland": ("filename": "grassland.png"),
-  ".natural.heath": ("filename": "heathland.png"),
-  ".natural.scrub": ("filename": "scrub.png"),
-  ".natural.water": ("filename": "lake.png"),
-  ".natural.wood": ("filename": "wood.png"),
-
-  ".railway.light_rail": ("filename": "light_rail.20.png"),
-  ".railway.rail": ("filename": "rail.20.png"),
-  ".railway.subway": ("filename": "subway.20.png"),
-  ".railway.tram": ("filename": "tram.20.png"),
-
-)
index 668d050d8bbbc42da49826961dc97fcd2fd03563..c5e2d14b1577a8a35e90747739616b5f56b6b672 100644 (file)
@@ -1,6 +1,5 @@
 @use "sass:map";
 @import "parameters";
-@import "browse";
 @import "bootstrap";
 @import "rails_bootstrap_forms";
 
@@ -970,34 +969,20 @@ img.trace_image {
 
 /* Rules for map sidebar icons */
 
-.browse-section {
-  .node::before,
-  .way::before,
-  .relation::before {
-    display: inline-block;
-    width: 25px;
-    margin-left: -25px;
-  }
+.browse-section .browse-element-list {
+  line-height: 1.25rem;
 
-  .node, .way, .relation {
-    margin-left: 25px;
+  .browse-icon {
+    height: 1.25rem;
   }
 
-  .node::before     { content: image-url('browse/node.svg'); }
-  .way::before      { content: image-url('browse/way.svg'); }
-  .relation::before { content: image-url('browse/relation.svg'); }
-}
-
-@each $class, $item in $map-sidebar-icons {
-  .browse-section #{$class}::before {
-    content: image-url('browse/#{map.get($item, "filename")}');
+  .d-flex > .browse-icon {
+    height: max(20px, 1.25rem);
   }
 
-  @if map.get($item, "invert") {
-    @include color-mode(dark) {
-      .browse-section #{$class}::before {
-        filter: invert(.8) hue-rotate(180deg);
-      }
+  @include color-mode(dark) {
+    .browse-icon-invertible {
+      filter: invert(.8) hue-rotate(180deg);
     }
   }
 }
index 69a8f8fa2e57eb5b76a717f98506c5f4752c33da..482503e8ae66b3c48e5be261e5974c5d66aba821 100644 (file)
@@ -1,15 +1,38 @@
 module BrowseHelper
+  def element_icon(type, object)
+    selected_icon_data = { :filename => "#{type}.svg", :priority => 1 }
+
+    unless object.redacted?
+      target_tags = object.tags.find_all { |k, _v| BROWSE_ICONS.key? k }.sort
+      title = target_tags.map { |k, v| "#{k}=#{v}" }.to_sentence unless target_tags.empty?
+
+      target_tags.each do |k, v|
+        icon_data = BROWSE_ICONS[k][v] || BROWSE_ICONS[k][:*]
+        selected_icon_data = icon_data if icon_data && icon_data[:priority] > selected_icon_data[:priority]
+      end
+    end
+
+    image_tag "browse/#{selected_icon_data[:filename]}",
+              :size => 20,
+              :class => ["align-bottom object-fit-none browse-icon", { "browse-icon-invertible" => selected_icon_data[:invert] }],
+              :title => title
+  end
+
   def element_single_current_link(type, object)
-    link_to object, { :class => element_class(type, object), :title => element_title(object), :rel => (link_follow(object) if type == "node") } do
+    link_to object, { :rel => (link_follow(object) if type == "node") } do
       element_strikethrough object do
         printable_element_name object
       end
     end
   end
 
-  def element_list_item(type, object, &block)
-    tag.li :class => element_class(type, object), :title => element_title(object) do
-      element_strikethrough object, &block
+  def element_list_item(type, object, &)
+    tag.li(tag.div(element_icon(type, object) + tag.div(:class => "align-self-center", &), :class => "d-flex gap-1"))
+  end
+
+  def element_list_item_with_strikethrough(type, object, &)
+    element_list_item type, object do
+      element_strikethrough object, &
     end
   end
 
@@ -52,20 +75,6 @@ module BrowseHelper
     end
   end
 
-  def element_class(type, object)
-    classes = [type]
-    classes += icon_tags(object).flatten.map { |t| h(t) } unless object.redacted?
-    classes.join(" ")
-  end
-
-  def element_title(object)
-    if object.redacted?
-      ""
-    else
-      h(icon_tags(object).map { |k, v| "#{k}=#{v}" }.to_sentence)
-    end
-  end
-
   def link_follow(object)
     "nofollow" if object.tags.empty?
   end
@@ -107,12 +116,6 @@ module BrowseHelper
 
   private
 
-  ICON_TAGS = %w[aeroway amenity barrier building highway historic landuse leisure man_made natural office railway shop tourism waterway].freeze
-
-  def icon_tags(object)
-    object.tags.find_all { |k, _v| ICON_TAGS.include? k }.sort
-  end
-
   def name_locales(object)
     object.tags.keys.map { |k| Regexp.last_match(1) if k =~ /^name:(.*)$/ }.flatten
   end
index e2770eb69ea5bf655866b04499708eadd70a575e..8a3a8a3eb460f2b8c550d7daeba3c99e724e48f2 100644 (file)
@@ -25,6 +25,48 @@ module UserBlocksHelper
     end
   end
 
+  def block_short_status(block)
+    if block.active?
+      if block.needs_view?
+        if block.ends_at > Time.now.utc
+          t("user_blocks.helper.short.active_unread")
+        else
+          t("user_blocks.helper.short.expired_unread")
+        end
+      else
+        t("user_blocks.helper.short.active")
+      end
+    else
+      if block.revoker_id.nil?
+        if block.updated_at > block.ends_at
+          t("user_blocks.helper.short.read_html", :time => block_short_time_in_past(block.updated_at))
+        else
+          t("user_blocks.helper.short.ended")
+        end
+      else
+        t("user_blocks.helper.short.revoked_html", :name => link_to(block.revoker.display_name, block.revoker,
+                                                                    :class => "username d-inline-block text-truncate text-wrap align-bottom",
+                                                                    :dir => "auto"))
+      end
+    end
+  end
+
+  def block_short_time_in_future(time)
+    tag.time l(time.to_date),
+             :datetime => time.xmlschema,
+             :title => t("user_blocks.helper.short.time_in_future_title",
+                         :time_absolute => l(time, :format => :friendly),
+                         :time_relative => time_ago_in_words(time))
+  end
+
+  def block_short_time_in_past(time)
+    tag.time l(time.to_date),
+             :datetime => time.xmlschema,
+             :title => t("user_blocks.helper.short.time_in_past_title",
+                         :time_absolute => l(time, :format => :friendly),
+                         :time_relative => time_ago_in_words(time, :scope => :"datetime.distance_in_words_ago"))
+  end
+
   def block_duration_in_words(duration)
     # Ensure the requested duration isn't negative, even by a millisecond
     duration = 0 if duration.negative?
index 2ab0fcf9785d6bd445cabdbdcbbc0eef77af011d..2c107236497a8a7f445d10051fbd53e4f1865ee9 100644 (file)
@@ -1,7 +1,8 @@
-<li><%= linked_name = link_to printable_element_name(containing_relation.relation), containing_relation.relation, :class => "relation"
-        if containing_relation.member_role.blank?
-          linked_name
-        else
-          t ".entry_role_html", :relation_name => linked_name, :relation_role => containing_relation.member_role
-        end %>
-</li>
+<%= element_list_item "relation", containing_relation.relation do %>
+  <%= linked_name = link_to printable_element_name(containing_relation.relation), containing_relation.relation
+      if containing_relation.member_role.blank?
+        linked_name
+      else
+        t ".entry_role_html", :relation_name => linked_name, :relation_role => containing_relation.member_role
+      end %>
+<% end %>
index 0ffe7c68b82dd01c9cbafe2ca6966295d4b8532a..52939d3a1c5587272d64ba7e42b06c96853a6be4 100644 (file)
       <% unless node.ways.empty? %>
         <details <%= "open" if node.ways.count < 10 %>>
           <summary><%= t "browse.part_of_ways", :count => node.ways.uniq.count %></summary>
-          <ul class="list-unstyled">
+          <ul class="list-unstyled browse-element-list">
             <% node.ways.uniq.each do |way| %>
-              <li><%= element_single_current_link "way", way %></li>
+              <%= element_list_item "way", way do %>
+                <%= element_single_current_link "way", way %>
+              <% end %>
             <% end %>
           </ul>
         </details>
@@ -25,7 +27,7 @@
       <% unless node.containing_relation_members.empty? %>
         <details <%= "open" if node.containing_relation_members.count < 10 %>>
           <summary><%= t "browse.part_of_relations", :count => node.containing_relation_members.uniq.count %></summary>
-          <ul class="list-unstyled">
+          <ul class="list-unstyled browse-element-list">
             <%= render :partial => "browse/containing_relation", :collection => node.containing_relation_members.uniq %>
           </ul>
         </details>
index 5dcdffa47f6cc683d657fa8ad215adf546234c7f..44706790044d6153452ad91d4b41661e15c26a56 100644 (file)
@@ -14,7 +14,7 @@
       <h4><%= t "browse.part_of" %></h4>
       <details <%= "open" if relation.containing_relation_members.count < 10 %>>
         <summary><%= t "browse.part_of_relations", :count => relation.containing_relation_members.uniq.count %></summary>
-        <ul class="list-unstyled">
+        <ul class="list-unstyled browse-element-list">
           <%= render :partial => "browse/containing_relation", :collection => relation.containing_relation_members.uniq %>
         </ul>
       </details>
@@ -24,7 +24,7 @@
       <h4><%= t ".members" %></h4>
       <details <%= "open" if relation.relation_members.count < 10 %>>
         <summary><%= t ".members_count", :count => relation.relation_members.count %></summary>
-        <ul class="list-unstyled">
+        <ul class="list-unstyled browse-element-list">
           <%= render :partial => "browse/relation_member", :collection => relation.relation_members %>
         </ul>
       </details>
index d122f0edfed8f327f2c81893a317cbfb588073d8..c00396fbd84388c31abc8f6c3374d3a7394e16de 100644 (file)
@@ -1,6 +1,6 @@
 <% linked_name = link_to printable_element_name(relation_member.member), relation_member.member, { :rel => link_follow(relation_member.member) }
    type_str = t ".type.#{relation_member.member_type.downcase}" %>
-<%= element_list_item relation_member.member_type.downcase, relation_member.member do %>
+<%= element_list_item_with_strikethrough relation_member.member_type.downcase, relation_member.member do %>
   <%= if relation_member.member_role.blank?
         t ".entry_html", :type => type_str, :name => linked_name
       else
index d04eff14030183432704277a9e07802b378c2083..9181a3e0804d7f5e5e198bfba4c27fca7b30bdf4 100644 (file)
@@ -14,7 +14,7 @@
       <h4><%= t "browse.part_of" %></h4>
       <details <%= "open" if way.containing_relation_members.count < 10 %>>
         <summary><%= t "browse.part_of_relations", :count => way.containing_relation_members.uniq.count %></summary>
-        <ul class="list-unstyled">
+        <ul class="list-unstyled browse-element-list">
           <%= render :partial => "browse/containing_relation", :collection => way.containing_relation_members.uniq %>
         </ul>
       </details>
       <h4><%= t ".nodes" %></h4>
       <details <%= "open" if way.way_nodes.count < 10 %>>
         <summary><%= t ".nodes_count", :count => way.way_nodes.count %></summary>
-        <ul class="list-unstyled">
+        <ul class="list-unstyled browse-element-list">
           <% way.way_nodes.each do |wn| %>
-            <li>
+            <%= element_list_item "node", wn.node do %>
               <%= element_single_current_link "node", wn.node %>
               <% related_ways = wn.node.ways.reject { |w| w.id == wn.way_id } %>
+              <% icon_connector = " " %>
               <% if related_ways.size > 0 then %>
                 (<%= t ".also_part_of_html",
                        :count => related_ways.size,
-                       :related_ways => to_sentence(related_ways.map { |w| element_single_current_link "way", w }) %>)
+                       :related_ways => to_sentence(related_ways.map { |w| element_icon("way", w) + icon_connector + element_single_current_link("way", w) }) %>)
               <% end %>
-            </li>
+            <% end %>
           <% end %>
         </ul>
       </details>
index fd5dd8a26a3cd16ca6aeb5fd9a9b0f47b58fdbcc..a95bed6fa3ab5d73bd55da685cbab8d5c7b9897a 100644 (file)
@@ -1,12 +1,12 @@
 <%= turbo_frame_tag "changeset_#{type.pluralize}" do %>
   <%= render :partial => "paging_nav", :locals => { :type => type, :pages => pages } %>
-  <ul class="list-unstyled" data-turbo="false">
+  <ul class="list-unstyled browse-element-list" data-turbo="false">
     <% elements.each do |element| %>
-      <%= element_list_item type, element do
-            t "printable_name.current_and_old_links_html",
+      <%= element_list_item_with_strikethrough type, element do %>
+        <%= t "printable_name.current_and_old_links_html",
               :current_link => link_to(printable_element_name(element), :controller => type.pluralize, :action => :show, :id => element.id[0]),
-              :old_link => link_to(printable_element_version(element), :controller => "old_#{type.pluralize}", :action => :show, :id => element.id[0], :version => element.version)
-          end %>
+              :old_link => link_to(printable_element_version(element), :controller => "old_#{type.pluralize}", :action => :show, :id => element.id[0], :version => element.version) %>
+      <% end %>
     <% end %>
   </ul>
 <% end %>
index 8ae1408c609babe4efe469118e6ba09130342235..cbc2ee23c0b39297c07f4aac73acd2c6121a0082 100644 (file)
@@ -6,14 +6,13 @@
   <td><%= link_to block.creator.display_name, block.creator, :class => "username d-inline-block text-truncate text-wrap", :dir => "auto" %></td>
   <% end %>
   <td><%= h truncate(block.reason) %></td>
-  <td><%= h block_status(block) %></td>
-  <td>
-    <% if block.revoker_id.nil? %>
-      <%= t(".not_revoked") %>
-    <% else %>
-      <%= link_to block.revoker.display_name, block.revoker, :class => "username d-inline-block text-truncate text-wrap", :dir => "auto" %>
-    <% end %>
-  </td>
+  <td><%= block_short_time_in_past(block.created_at) %></td>
+  <% if block.ends_at > Time.now.utc %>
+  <td><%= block_short_time_in_future(block.ends_at) %></td>
+  <% else %>
+  <td><%= block_short_time_in_past(block.ends_at) %></td>
+  <% end %>
+  <td><%= h block_short_status(block) %></td>
   <td><%= link_to t(".show"), block %></td>
   <td><% if can?(:edit, block) %><%= link_to t(".edit"), edit_user_block_path(block) %><% end %></td>
 </tr>
index 8c8557f606e358b196d170209ecbb5779947ccd1..c2e516170a2ee655c65aca2dfbaf8cca5f9967e8 100644 (file)
@@ -9,8 +9,9 @@
         <th><%= t ".creator_name" %></th>
         <% end %>
         <th><%= t ".reason" %></th>
+        <th><%= t ".start" %></th>
+        <th><%= t ".end" %></th>
         <th><%= t ".status" %></th>
-        <th><%= t ".revoker_name" %></th>
         <th></th>
         <th></th>
       </tr>
diff --git a/config/browse_icons.yml b/config/browse_icons.yml
new file mode 100644 (file)
index 0000000..f24d767
--- /dev/null
@@ -0,0 +1,186 @@
+aeroway:
+  aerodrome: { filename: "aerodrome.p.16.png" }
+
+  runway: { filename: "runway.20.png" }
+  taxiway: { filename: "taxiway.20.png" }
+
+amenity:
+  atm: { filename: "amenity_atm.16.png", invert: true }
+  bank: { filename: "amenity_bank.16.png", invert: true }
+  bar: { filename: "amenity_bar.16.png", invert: true }
+  bench: { filename: "amenity_bench.16.png", invert: true }
+  biergarten: { filename: "amenity_biergarten.16.png", invert: true }
+  bicycle_parking: { filename: "amenity_bicycle_parking.16.png" }
+  bicycle_rental: { filename: "transport_rental_bicycle.16.png" }
+  bus_station: { filename: "bus_station.n.16.png" }
+  cafe: { filename: "amenity_cafe.16.png", invert: true }
+  car_rental: { filename: "transport_rental_car.16.png" }
+  car_sharing: { filename: "car_share.p.16.png" }
+  childcare: { filename: "amenity_childcare.p.16.png" }
+  cinema: { filename: "amenity_cinema.16.png", invert: true }
+  courthouse: { filename: "amenity_courthouse.16.png", invert: true }
+  dentist: { filename: "amenity_dentist.16.png" }
+  doctors: { filename: "amenity_doctors.16.png" }
+  drinking_water: { filename: "amenity_drinking_water.16.png", invert: true }
+  fast_food: { filename: "amenity_fast_food.16.png", invert: true }
+  fire_station: { filename: "amenity_fire_station.16.png", invert: true }
+  fuel: { filename: "amenity_fuel.16.png" }
+  hospital: { filename: "amenity_hospital.16.png" }
+  kindergarten: { filename: "amenity_childcare.p.16.png" }
+  library: { filename: "library.p.16.png", invert: true }
+  nightclub: { filename: "amenity_nightclub.16.png", invert: true }
+  parking: { filename: "parking.p.16.png" }
+  pharmacy: { filename: "amenity_pharmacy.16.png" }
+  place_of_worship: { filename: "amenity_place_of_worship.16.png", invert: true }
+  police: { filename: "amenity_police.16.png", invert: true }
+  post_box: { filename: "post_box.p.16.png", invert: true }
+  post_office: { filename: "post_office.p.16.png", invert: true }
+  prison: { filename: "amenity_prison.16.png", invert: true }
+  pub: { filename: "amenity_pub.16.png", invert: true }
+  restaurant: { filename: "amenity_restaurant.16.png", invert: true }
+  recycling: { filename: "amenity_recycling.16.png", invert: true }
+  school: { filename: "education_school.p.16.png" }
+  shelter: { filename: "shelter2.p.16.png" }
+  taxi: { filename: "amenity_taxi.16.png" }
+  telephone: { filename: "telephone.p.16.png", invert: true }
+  theatre: { filename: "amenity_theatre.16.png", invert: true }
+  toilets: { filename: "amenity_toilets.16.png", invert: true }
+  townhall: { filename: "amenity_townhall.16.png", invert: true }
+  university: { filename: "education_university.p.16.png" }
+  veterinary: { filename: "health_veterinary.p.16.png" }
+  waste_basket: { filename: "amenity_waste_basket.16.png", invert: true }
+
+barrier:
+  gate: { filename: "gate2.p.16.png", invert: true }
+
+  wall: { filename: "wall.20.png" }
+
+building:
+  :*: { filename: "building.png" }
+
+highway:
+  bus_stop: { filename: "highway_bus_stop.16.png" }
+  mini_roundabout: { filename: "mini_round.p.16.png" }
+  traffic_signals: { filename: "traffic_light.png", invert: true }
+  turning_circle: { filename: "turning_circle.p.16.png" }
+
+  bridleway: { filename: "bridleway.20.png" }
+  cycleway: { filename: "cycleway.20.png" }
+  footway: { filename: "footway.20.png" }
+  motorway: { filename: "motorway.20.png" }
+  motorway_link: { filename: "motorway.20.png" }
+  path: { filename: "path.20.png" }
+  pedestrian: { filename: "service.20.png" }
+  primary: { filename: "primary.20.png" }
+  primary_link: { filename: "primary.20.png" }
+  residential: { filename: "unclassified.20.png" }
+  secondary: { filename: "secondary.20.png" }
+  secondary_link: { filename: "secondary.20.png" }
+  service: { filename: "service.20.png" }
+  tertiary: { filename: "tertiary.20.png" }
+  track: { filename: "track.20.png" }
+  trunk: { filename: "trunk.20.png" }
+  trunk_link: { filename: "trunk.20.png" }
+  unclassified: { filename: "unclassified.20.png" }
+
+historic:
+  archaeological_site: { filename: "historic_archaeological_site.16.png", invert: true }
+  castle: { filename: "tourist_castle.p.16.png", invert: true }
+  memorial: { filename: "historic_memorial.16.png", invert: true }
+  monument: { filename: "historic_monument.16.png", invert: true }
+  ruins: { filename: "tourist_ruins.p.16.png", invert: true }
+  wreck: { filename: "tourist_wreck.p.16.png", invert: true }
+
+landuse:
+  brownfield: { filename: "brownfield.png" }
+  cemetery: { filename: "cemetery.png" }
+  commercial: { filename: "commercial.png" }
+  farmland: { filename: "farmland.png" }
+  farmyard: { filename: "farmyard.png" }
+  forest: { filename: "forest.png" }
+  grass: { filename: "grass.png" }
+  industrial: { filename: "industrial.png" }
+  meadow: { filename: "meadow.png" }
+  military: { filename: "military.png" }
+  residential: { filename: "residential.png" }
+  retail: { filename: "retail.png" }
+  tourism: { filename: "tourism.png" }
+
+leisure:
+  golf_course: { filename: "golf.png" }
+  park: { filename: "park.png" }
+  picnic_table: { filename: "tourism_picnic_site.16.png", invert: true }
+  playground: { filename: "leisure_playground.16.png", invert: true }
+  pitch: { filename: "pitch.png" }
+  nature_reserve: { filename: "reserve.png" }
+  water_park: { filename: "leisure_water_park.16.png", invert: true }
+
+man_made:
+  lighthouse: { filename: "man_made_lighthouse.16.png" }
+  water_tower: { filename: "man_made_water_tower.16.png", invert: true }
+  windmill: { filename: "man_made_windmill.16.png", invert: true }
+
+natural:
+  tree: { filename: "tree.p.16.png" }
+
+  grassland: { filename: "grassland.png" }
+  heath: { filename: "heathland.png" }
+  scrub: { filename: "scrub.png" }
+  water: { filename: "lake.png" }
+  wood: { filename: "wood.png" }
+
+office:
+  diplomatic: { filename: "office_diplomatic.16.png" }
+  estate_agent: { filename: "shop_estateagent.16.png" }
+
+railway:
+  halt: { filename: "halt.p.16.png" }
+  station: { filename: "station.p.16.png" }
+  level_crossing: { filename: "level_crossing.p.16.png", invert: true }
+
+  light_rail: { filename: "light_rail.20.png" }
+  rail: { filename: "rail.20.png" }
+  subway: { filename: "subway.20.png" }
+  tram: { filename: "tram.20.png" }
+
+shop:
+  :*: { filename: "shop_convenience.p.16.png", priority: 20 }
+  alcohol: { filename: "shop_alcohol.16.png" }
+  bakery: { filename: "shop_bakery.16.png" }
+  bicycle: { filename: "shop_bicycle.16.png" }
+  books: { filename: "shop_books.16.png" }
+  butcher: { filename: "shop_butcher.p.16.png" }
+  clothes: { filename: "shop_clothes.16.png" }
+  car_parts: { filename: "shop_car_parts.16.png" }
+  car_repair: { filename: "shop_car_repair.16.png" }
+  convenience: { filename: "shop_convenience.p.16.png" }
+  doityourself: { filename: "shop_doityourself.16.png" }
+  electronics: { filename: "shop_electronics.16.png" }
+  estate_agent: { filename: "shop_estateagent.16.png" }
+  fashion: { filename: "shop_clothes.16.png" }
+  florist: { filename: "shop_florist.16.png" }
+  furniture: { filename: "shop_furniture.16.png" }
+  garden_centre: { filename: "shop_florist.16.png" }
+  gift: { filename: "shop_gift.16.png" }
+  greengrocer: { filename: "shop_greengrocer.p.16.png" }
+  hardware: { filename: "shop_doityourself.16.png" }
+  hairdresser: { filename: "shop_hairdresser.16.png" }
+  jewelry: { filename: "shop_jewelry.16.png" }
+  mobile_phone: { filename: "shop_mobile_phone.16.png" }
+  optician: { filename: "shop_optician.16.png" }
+  pet: { filename: "shop_pet.16.png" }
+  seafood: { filename: "shop_seafood.16.png" }
+  shoes: { filename: "shop_shoes.16.png" }
+  supermarket: { filename: "shop_supermarket.p.16.png" }
+
+tourism:
+  alpine_hut: { filename: "tourism_alpine_hut.16.png" }
+  camp_site: { filename: "tourism_camp_site.16.png" }
+  caravan_site: { filename: "tourism_caravan_site.16.png" }
+  hostel: { filename: "tourism_hostel.16.png" }
+  hotel: { filename: "tourism_hotel.16.png" }
+  motel: { filename: "tourism_motel.16.png" }
+  museum: { filename: "tourism_museum.16.png", invert: true }
+  picnic_site: { filename: "tourism_picnic_site.16.png", invert: true }
+  viewpoint: { filename: "view_point.p.16.png", invert: true }
+  wilderness_hut: { filename: "tourism_wilderness_hut.16.png" }
diff --git a/config/initializers/browse_icons.rb b/config/initializers/browse_icons.rb
new file mode 100644 (file)
index 0000000..a55df97
--- /dev/null
@@ -0,0 +1,13 @@
+begin
+  BROWSE_ICONS = YAML.load_file(Rails.root.join("config/browse_icons.yml")).transform_values do |tag_key_data|
+    transformed_tag_key_data = {}
+    tag_key_data.each do |tag_value, tag_value_data|
+      tag_value_data = tag_value_data.deep_symbolize_keys
+      tag_value_data[:priority] ||= tag_value == :* ? 10 : 100
+      transformed_tag_key_data[tag_value] = tag_value_data
+    end
+    transformed_tag_key_data
+  end
+rescue StandardError
+  BROWSE_ICONS = {}.freeze
+end
index 3b5bc944fe14a2c321cd86cf36e8d491edbbda07..4f883cc9403eea879eaad8128882e27e2d04b31f 100644 (file)
@@ -1,6 +1,6 @@
 - leafletOsmId: "Mapnik"
   code: "M"
-  keyId: "mapnik"
+  layerId: "mapnik"
   nameId: "standard"
   credit:
     id: "make_a_donation"
@@ -9,7 +9,7 @@
 
 - leafletOsmId: "CyclOSM"
   code: "Y"
-  keyId: "cyclosm"
+  layerId: "cyclosm"
   nameId: "cyclosm"
   credit:
     id: "cyclosm_credit"
@@ -23,7 +23,7 @@
 
 - leafletOsmId: "CycleMap"
   code: "C"
-  keyId: "cyclemap"
+  layerId: "cyclemap"
   nameId: "cycle_map"
   apiKeyId: "THUNDERFOREST_KEY"
   credit:
@@ -35,7 +35,7 @@
 
 - leafletOsmId: "TransportMap"
   code: "T"
-  keyId: "transportmap"
+  layerId: "transportmap"
   nameId: "transport_map"
   apiKeyId: "THUNDERFOREST_KEY"
   credit:
@@ -47,7 +47,7 @@
 
 - leafletOsmId: "TracestrackTopo"
   code: "P"
-  keyId: "tracestracktopo"
+  layerId: "tracestracktopo"
   nameId: "tracestracktop_topo"
   apiKeyId: "TRACESTRACK_KEY"
   credit:
@@ -59,7 +59,7 @@
 
 - leafletOsmId: "HOT"
   code: "H"
-  keyId: "hot"
+  layerId: "hot"
   nameId: "hot"
   credit:
     id: "hotosm_credit"
index c423de766639981d375023147fe282ac9e8115c8..c3a0c5aed0802f2afe1c8acaf4eafee1f5c7e8e4 100644 (file)
@@ -2898,6 +2898,15 @@ en:
         years:
           one: "%{count} year"
           other: "%{count} years"
+      short:
+        ended: "ended"
+        revoked_html: "revoked by %{name}"
+        active: "active"
+        active_unread: "active unread"
+        expired_unread: "expired unread"
+        read_html: "read at %{time}"
+        time_in_future_title: "%{time_absolute}; in %{time_relative}"
+        time_in_past_title: "%{time_absolute}; %{time_relative}"
     blocks_on:
       title: "Blocks on %{name}"
       heading_html: "List of Blocks on %{name}"
@@ -2916,15 +2925,15 @@ en:
       reason: "Reason for block:"
       revoker: "Revoker:"
     block:
-      not_revoked: "(not revoked)"
       show: "Show"
       edit: "Edit"
     page:
       display_name: "Blocked User"
       creator_name: "Creator"
       reason: "Reason for block"
+      start: "Start"
+      end: "End"
       status: "Status"
-      revoker_name: "Revoked by"
     navigation:
       all_blocks: "All Blocks"
       blocks_on_me: "Blocks on Me"
index 4cf0ab69ad3aab53863c4c2872ffda8a45a03073..4162223d1b88919b8b537f9e114499706f1b09a5 100644 (file)
@@ -66,7 +66,7 @@ class BrowseHelperTest < ActionView::TestCase
     assert_equal "<s>test</s>", deleted_output
   end
 
-  def test_element_class
+  def test_element_icon
     node = create(:node, :with_history, :version => 2)
     node_v1 = node.old_nodes.find_by(:version => 1)
     node_v2 = node.old_nodes.find_by(:version => 2)
@@ -76,60 +76,35 @@ class BrowseHelperTest < ActionView::TestCase
     add_old_tags_selection(node_v2)
     add_old_tags_selection(node_v1)
 
-    assert_equal "node", element_class("node", create(:node))
-    assert_equal "node", element_class("node", create(:node, :deleted))
-
-    assert_equal "node building yes shop gift tourism museum", element_class("node", node)
-    assert_equal "node building yes shop gift tourism museum", element_class("node", node_v2)
-    assert_equal "node", element_class("node", node_v1)
-  end
-
-  def test_element_title
-    node = create(:node, :with_history, :version => 2)
-    node_v1 = node.old_nodes.find_by(:version => 1)
-    node_v2 = node.old_nodes.find_by(:version => 2)
-    node_v1.redact!(create(:redaction))
-
-    add_tags_selection(node)
-    add_old_tags_selection(node_v2)
-    add_old_tags_selection(node_v1)
-
-    assert_equal "", element_title(create(:node))
-    assert_equal "", element_title(create(:node, :deleted))
-
-    assert_equal "building=yes, shop=gift, and tourism=museum", element_title(node)
-    assert_equal "building=yes, shop=gift, and tourism=museum", element_title(node_v2)
-    assert_equal "", element_title(node_v1)
-  end
-
-  def test_icon_tags
-    node = create(:node, :with_history, :version => 2)
-    node_v1 = node.old_nodes.find_by(:version => 1)
-    node_v2 = node.old_nodes.find_by(:version => 2)
-    node_v1.redact!(create(:redaction))
+    icon = element_icon("node", create(:node))
+    icon_dom = Rails::Dom::Testing.html_document_fragment.parse(icon)
+    assert_dom icon_dom, "img:root", :count => 1 do
+      assert_dom "> @title", 0
+    end
 
-    add_tags_selection(node)
+    icon = element_icon("node", create(:node, :deleted))
+    icon_dom = Rails::Dom::Testing.html_document_fragment.parse(icon)
+    assert_dom icon_dom, "img:root", :count => 1 do
+      assert_dom "> @title", 0
+    end
 
-    tags = icon_tags(node)
-    assert_equal 3, tags.count
-    assert_includes tags, %w[building yes]
-    assert_includes tags, %w[tourism museum]
-    assert_includes tags, %w[shop gift]
+    icon = element_icon("node", node)
+    icon_dom = Rails::Dom::Testing.html_document_fragment.parse(icon)
+    assert_dom icon_dom, "img:root", :count => 1 do
+      assert_dom "> @title", "building=yes, shop=gift, and tourism=museum"
+    end
 
-    add_old_tags_selection(node_v2)
-    add_old_tags_selection(node_v1)
+    icon = element_icon("node", node_v2)
+    icon_dom = Rails::Dom::Testing.html_document_fragment.parse(icon)
+    assert_dom icon_dom, "img:root", :count => 1 do
+      assert_dom "> @title", "building=yes, shop=gift, and tourism=museum"
+    end
 
-    tags = icon_tags(node_v2)
-    assert_equal 3, tags.count
-    assert_includes tags, %w[building yes]
-    assert_includes tags, %w[tourism museum]
-    assert_includes tags, %w[shop gift]
-
-    tags = icon_tags(node_v1)
-    assert_equal 3, tags.count
-    assert_includes tags, %w[building yes]
-    assert_includes tags, %w[tourism museum]
-    assert_includes tags, %w[shop gift]
+    icon = element_icon("node", node_v1)
+    icon_dom = Rails::Dom::Testing.html_document_fragment.parse(icon)
+    assert_dom icon_dom, "img:root", :count => 1 do
+      assert_dom "> @title", 0
+    end
   end
 
   private