Skip to content

Commit 5b3bcad

Browse files
authored
Merge branch 'main' into dependabot/npm_and_yarn/braces-3.0.3
2 parents 0da3a23 + 2647e7a commit 5b3bcad

34 files changed

+1611
-468
lines changed

.github/workflows/test-postgis.yml

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ on:
1212
branches:
1313
- main
1414
- next
15+
workflow_dispatch:
1516

1617
jobs:
1718
test:
@@ -24,9 +25,17 @@ jobs:
2425
strategy:
2526
fail-fast: false
2627
matrix:
27-
redmine_version: [5.0-stable, master]
28-
ruby_version: ['3.0', '3.1']
29-
db_version: [12-3.0, 15-3.3]
28+
redmine_version: [5.0-stable, 5.1-stable, master]
29+
ruby_version: ['3.0', '3.1', '3.2']
30+
db_version: [12-3.4, 16-3.4]
31+
include:
32+
- system_test: true
33+
redmine_version: 5.1-stable
34+
ruby_version: '3.2'
35+
exclude:
36+
- redmine_version: 5.0-stable
37+
ruby_version: '3.2'
38+
- redmine_version: master
3039

3140
services:
3241
postgres:
@@ -40,29 +49,36 @@ jobs:
4049

4150
steps:
4251
- name: Checkout Redmine
43-
uses: actions/checkout@v3
52+
uses: actions/checkout@v4
4453
with:
4554
repository: redmine/redmine
4655
ref: ${{ matrix.redmine_version }}
4756
path: redmine
4857

4958
- name: Checkout Plugin
50-
uses: actions/checkout@v3
59+
uses: actions/checkout@v4
5160
with:
5261
path: redmine/plugins/${{ env.PLUGIN_NAME }}
5362

5463
- name: Update package archives
5564
run: apt-get update --yes --quiet
5665

5766
- name: Install package dependencies
58-
run: >
59-
apt-get install --yes --quiet
60-
postgresql-client
61-
gcc libpq-dev make patch libgeos-dev curl
67+
run: |
68+
apt-get install --yes --quiet \
69+
postgresql-client \
70+
gcc libpq-dev make patch libgeos-dev curl
71+
# For system test
72+
if [ ${{ matrix.system_test }} = "true" ]; then
73+
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
74+
sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
75+
apt-get -y update
76+
apt-get install -y google-chrome-stable
77+
fi
6278
6379
- name: Install Node/Yarn packages
6480
run: |
65-
curl -sL https://deb.nodesource.com/setup_16.x | bash -
81+
curl -sL https://deb.nodesource.com/setup_20.x | bash -
6682
curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
6783
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
6884
apt-get update --yes --quiet
@@ -122,8 +138,16 @@ jobs:
122138
- name: Run tests
123139
env:
124140
RAILS_ENV: test
141+
# For system test in plugin
142+
GOOGLE_CHROME_OPTS_ARGS: "headless,disable-gpu,no-sandbox,disable-dev-shm-usage"
125143
working-directory: redmine
126-
run: bundle exec rake redmine:plugins:test NAME=${{ env.PLUGIN_NAME }} RUBYOPT="-W0"
144+
run: |
145+
bundle exec rake redmine:plugins:test:units NAME=${{ env.PLUGIN_NAME }} RUBYOPT="-W0"
146+
bundle exec rake redmine:plugins:test:functionals NAME=${{ env.PLUGIN_NAME }} RUBYOPT="-W0"
147+
bundle exec rake redmine:plugins:test:integration NAME=${{ env.PLUGIN_NAME }} RUBYOPT="-W0"
148+
if [ ${{ matrix.system_test }} = "true" ]; then
149+
bundle exec rake redmine:plugins:test:system NAME=${{ env.PLUGIN_NAME }} RUBYOPT="-W0"
150+
fi
127151
128152
- name: Run uninstall test
129153
env:

Gemfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ gem "pg", "~> #{gem_versions[:pg]}"
1616
gem "rgeo-activerecord", "~> #{gem_versions[:rgeo_activerecord]}"
1717
gem 'activerecord-postgis-adapter', "~> #{gem_versions[:activerecord_postgis_adapter]}"
1818
gem 'rails-controller-testing' # This gem brings back assigns to your controller tests as well as assert_template to both controller and integration tests.
19+
gem 'blankslate', '~> 3.1.3'

app/helpers/gtt_map_helper.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ def map_tag(map: nil, layers: map&.layers,
3333
data[:upload] = upload
3434
data[:collapsed] = collapsed if collapsed
3535
data[:geocoding] = true if Setting.plugin_redmine_gtt['enable_geocoding_on_map'] == 'true'
36+
data[:measure] = true if Setting.plugin_redmine_gtt['default_measure_enabled'] == 'true'
37+
data[:target] = true if Setting.plugin_redmine_gtt['default_target_enabled'] == 'true'
3638

3739
uid = "ol-" + rand(36**8).to_s(36)
3840

@@ -68,6 +70,13 @@ def map_tag(map: nil, layers: map&.layers,
6870
window.createGttClient(target);
6971
contentObserver();
7072
}, { once: true });
73+
var target = document.getElementById('#{uid}');
74+
if (
75+
document.readyState === 'complete'
76+
&& !target.hasChildNodes()
77+
) {
78+
window.createGttClient(target);
79+
}
7180
}
7281
document.addEventListener('DOMContentLoaded', function(){
7382
var target = document.getElementById('#{uid}');

app/views/gtt_map_layers/_form.html.erb

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
<p>
1212
<%= f.select :layer,
1313
options_for_select(
14-
['Image','Tile','MapboxVector','Vector','VectorTile'],
14+
['Image','Tile','MapboxVector','Vector','VectorTile','WebGLTile'],
1515
selected: f.object.layer ),
1616
{ include_blank: t('map_layer.layer_options_select'), required: true }
1717
%>
@@ -22,7 +22,7 @@
2222
<p>
2323
<%= f.select :source,
2424
options_for_select(
25-
['BingMaps','CartoDB','ImageStatic','ImageWMS','OSM','Raster','Stamen',
25+
['BingMaps','CartoDB','Google','ImageStatic','ImageWMS','OSM','Raster',
2626
'TileJSON','TileWMS','UTFGrid','Vector','VectorTile','WMTS','XYZ'],
2727
selected: f.object.source ),
2828
{ include_blank: t('map_layer.source_options_select') }
@@ -51,10 +51,11 @@
5151
document.addEventListener('DOMContentLoaded', function() {
5252
const map_layer_config = {
5353
'Image': ['ImageStatic','ImageWMS','Raster'],
54-
'Tile': ['BingMaps','CartoDB','OSM','Stamen','TileJSON','TileWMS','UTFGrid','WMTS','XYZ'],
54+
'Tile': ['BingMaps','CartoDB','OSM','TileJSON','TileWMS','UTFGrid','WMTS','XYZ'],
5555
'MapboxVector': [],
5656
'Vector': ['Vector'],
5757
'VectorTile': ['VectorTile'],
58+
'WebGLTile': ['Google'],
5859
};
5960

6061
const map_format_config = {
@@ -211,5 +212,19 @@
211212
},
212213
'format': 'ol.format.MVT',
213214
'format_options': {}
215+
},{
216+
'name': 'Google Maps',
217+
'layer': 'WebGLTile',
218+
'layer_options': {},
219+
'source': 'Google',
220+
'source_options': {
221+
'key': 'YOUR_API_KEY',
222+
'mapType': 'roadmap',
223+
'language': 'ja_JP',
224+
'scale': 'scaleFactor2x',
225+
'layerTypes': ['layerTraffic'],
226+
},
227+
'format': '',
228+
'format_options': {}
214229
}];
215230
</script>

app/views/issues/show.api.rsb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ api.issue do
2323
api.total_spent_hours(@issue.total_spent_hours)
2424
end
2525

26-
if @issue.geom
26+
if @issue.geom.present?
2727
api.geojson (params[:format] == "json") ? @issue.geojson : @issue.geojson.to_json
2828
else
2929
api.geojson nil
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
<% if @project.nil? or @project.module_enabled?(:gtt) %>
2-
<%= map_tag map: @issue.map, geom: (@issue.as_geojson(include_properties: { only: %i(tracker_id status_id) }) if @issue), rotation: @project.map_rotation %>
2+
<% if @issue.geom.present? or !Setting.plugin_redmine_gtt['hide_map_for_invalid_geom'] %>
3+
<%= map_tag map: @issue.map,
4+
geom: (@issue.as_geojson(include_properties: { only: %i(tracker_id status_id) }) if @issue),
5+
rotation: @project.map_rotation %>
6+
<% else %>
7+
<div class="flash nodata"><%= l(:gtt_hide_map_for_invalid_geom_info) %></div>
8+
<% end %>
39
<% end %>
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
<% if (@project.nil? or @project.module_enabled?(:gtt)) &&
1+
<% if issue.project && issue.project.module_enabled?(:gtt) &&
22
((issue.new_record? && User.current.allowed_to?(:add_issues, issue.project)) ||
33
User.current.allowed_to?(:edit_issues, issue.project))
44
%>
5-
<%= map_form_field form, issue.map, bounds: issue.project.map.bounds, rotation: @project.map_rotation,
5+
<%= map_form_field form, issue.map, bounds: issue.project.map.bounds, rotation: issue.project.map_rotation || 0,
66
edit_mode: Setting.plugin_redmine_gtt['editable_geometry_types_on_issue_map'] && Setting.plugin_redmine_gtt['editable_geometry_types_on_issue_map'].join(' '),
77
upload: Setting.plugin_redmine_gtt['enable_geojson_upload_on_issue_map'] == "true" %>
88
<% end %>
9-

app/views/settings/gtt/_general.html.erb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
@settings['default_map_fit_maxzoom_level'],
4141
:size => 10) %>
4242
</p>
43+
4344
</div>
4445

4546
<div class="box tabular settings">
@@ -62,3 +63,22 @@
6263
<%= check_box_tag 'settings[enable_geojson_upload_on_issue_map]', true, @settings[:enable_geojson_upload_on_issue_map] %>
6364
</p>
6465
</div>
66+
67+
<div class="box tabular settings">
68+
<h3><%= l(:select_other_gtt_settings) %></h3>
69+
70+
<p>
71+
<%= content_tag(:label, l(:label_default_target_enabled)) %>
72+
<%= check_box_tag 'settings[default_target_enabled]', true, @settings[:default_target_enabled] %>
73+
</p>
74+
75+
<p>
76+
<%= content_tag(:label, l(:label_default_measure_enabled)) %>
77+
<%= check_box_tag 'settings[default_measure_enabled]', true, @settings[:default_measure_enabled] %>
78+
</p>
79+
80+
<p>
81+
<%= content_tag(:label, l(:label_hide_map_for_invalid_geom)) %>
82+
<%= check_box_tag 'settings[hide_map_for_invalid_geom]', 1, Setting.plugin_redmine_gtt['hide_map_for_invalid_geom'] %>
83+
</p>
84+
</div>

app/views/settings/gtt/_geocoder.html.erb

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@
66
<%= check_box_tag 'settings[enable_geocoding_on_map]', true, @settings[:enable_geocoding_on_map] %>
77
</p>
88

9+
<p>
10+
<%= content_tag(:label, l(:geocoder_provider)) %>
11+
<%= select_tag 'settings[default_geocoder_provider]',
12+
options_for_select([
13+
['Google', 'google'],
14+
['Nominatim (OSM)', 'nominatim'],
15+
['Photon', 'photon'],
16+
['Custom', 'custom', {disabled: true}]
17+
], @settings['default_geocoder_provider']),
18+
include_blank: true %>
19+
<%= link_to t('geocoder_load_example'), '#', id: 'geocoder_load_example', class: 'info' %>
20+
</p>
21+
922
<p>
1023
<%= content_tag(:label, l(:geocoder_options)) %>
1124
<%= text_area_tag('settings[default_geocoder_options]',
@@ -15,3 +28,30 @@
1528
:cols => 100) %>
1629
</p>
1730
</div>
31+
32+
<script>
33+
document.getElementById('geocoder_load_example').addEventListener('click', (event) => {
34+
event.preventDefault();
35+
const provider = document.getElementById('settings_default_geocoder_provider').value;
36+
const example = geocoder_examples.find((example) => example.name === provider);
37+
document.getElementById('settings_default_geocoder_options').value = example?.options ? JSON.stringify(example.options, undefined, 2) : "{}";
38+
});
39+
40+
const geocoder_examples = [{
41+
'name': 'nominatim',
42+
'options': {}
43+
}, {
44+
'name': 'google',
45+
'options': {
46+
'apiKey': 'YOUR_API_KEY'
47+
}
48+
}, {
49+
'name': 'photon',
50+
'options': {}
51+
}, {
52+
'name': 'custom',
53+
'options': {
54+
'url': 'https://example.com/geocoder'
55+
}
56+
}];
57+
</script>

app/views/settings/gtt/_settings.html.erb

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,33 @@
44
{ :name => :geocoder, :partial => 'settings/gtt/geocoder', :label => :gtt_settings_label_geocoder }
55
] %>
66

7-
87
<%= render_tabs plugin_tabs %>
98

109
<%= javascript_tag do %>
10+
// Read query parameter
11+
function getQueryParam(param) {
12+
var urlParams = new URLSearchParams(window.location.search);
13+
return urlParams.get(param);
14+
}
15+
16+
// Activate tab by name
17+
function activateTab(tabName) {
18+
var tabLinks = document.querySelectorAll('.tabs a');
19+
tabLinks.forEach(function(link) {
20+
if (link.href.includes('tab=' + tabName)) {
21+
link.click();
22+
}
23+
});
24+
}
25+
26+
// Activate tab if it is specified in the URL
27+
document.addEventListener('DOMContentLoaded', function() {
28+
var tab = getQueryParam('tab');
29+
if (tab) {
30+
activateTab(tab);
31+
}
32+
});
33+
34+
// Apply settings
1135
window.gtt_setting()
1236
<% end %>

0 commit comments

Comments
 (0)