Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactoring/tobias 117 convert leaflet to js #137

Merged
merged 54 commits into from
Jan 11, 2022

Conversation

JulianEgbert
Copy link
Contributor

We removed the ruby gem for leaflet and do the map with plain js.

@JulianEgbert JulianEgbert added the T.O.B.I.A.S. (TF1 & TF2) label Jan 6, 2022
@JulianEgbert
Copy link
Contributor Author

@TheGrayStone: There is a method called transform_target_to_marker that we are uncertain about right now. We made some changes to the map and just want to make sure, that your feature is still working because we weren't able to test it ourself. If there is a test for it, it should be fine but we just want to double check this.

@JulianEgbert JulianEgbert linked an issue Jan 6, 2022 that may be closed by this pull request
@codecov
Copy link

codecov bot commented Jan 6, 2022

Codecov Report

Merging #137 (a0aa143) into dev (db260ac) will decrease coverage by 2.93%.
The diff coverage is 73.91%.

Impacted file tree graph

@@            Coverage Diff             @@
##              dev     #137      +/-   ##
==========================================
- Coverage   98.52%   95.58%   -2.94%     
==========================================
  Files          25       25              
  Lines         406      408       +2     
==========================================
- Hits          400      390      -10     
- Misses          6       18      +12     
Impacted Files Coverage Δ
app/assets/constants/buildings.rb 100.00% <ø> (ø)
app/assets/constants/locations.rb 100.00% <ø> (ø)
app/helpers/routing_helper.rb 80.00% <ø> (-20.00%) ⬇️
app/controllers/building_map_controller.rb 72.72% <71.42%> (-27.28%) ⬇️
app/helpers/building_map_helper.rb 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update db260ac...a0aa143. Read the comment docs.

rdunker
rdunker previously approved these changes Jan 6, 2022
Copy link
Contributor

@rdunker rdunker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥳

app/views/building_map/index.html.erb Outdated Show resolved Hide resolved
@JulianEgbert
Copy link
Contributor Author

JulianEgbert commented Jan 6, 2022

Troubleshooting
We encountered problems when using a new node version so we started collecting these kind of issues in a wiki page: https://github.com/hpi-swt2/compass-portal-blue/wiki/Known-Issues

@niklasmohrin
Copy link
Contributor

@TheGrayStone told me earlier that their team is also working on something similar, let's refrain from merging and putting too much additional work into this before they clarify here @hpi-swt2/rh21

fixes Places::DESTINATIONS variable being dumped into HTML (introduced in #102)
app/views/building_map/index.html.erb Outdated Show resolved Hide resolved
app/javascript/packs/application.js Show resolved Hide resolved
config/initializers/leaflet.rb Show resolved Hide resolved
app/views/building_map/index.html.erb Outdated Show resolved Hide resolved
@niklasmohrin niklasmohrin mentioned this pull request Jan 6, 2022
@chrisma
Copy link
Contributor

chrisma commented Jan 10, 2022

Thanks for the investigation! Could the following still help, perhaps?

find(".active")
execute_script("$('.active').focus()")
Capybara will wait until a matching element is on the page, and then dispatch a JavaScript command which interacts with it.

@chrisma
Copy link
Contributor

chrisma commented Jan 10, 2022

The find method also takes a wait parameter to increase the default wait time, in case that might be needed: https://stackoverflow.com/questions/56837464/capybara-wait-until-button-is-enabled

@JulianEgbert
Copy link
Contributor Author

JulianEgbert commented Jan 11, 2022

The find method also takes a wait parameter to increase the default wait time, in case that might be needed: https://stackoverflow.com/questions/56837464/capybara-wait-until-button-is-enabled

I tested this with page.assert_selector("path.building", count: 15, wait: 5) for cases where we have muttiple results so find won't work (see here). It seems to be a bit better but the tests are still inconsistent.

Some tests (that then fail, like Building Map page map highlights buildings on the map throw the following error:

[0111/121442.075:INFO:CONSOLE(26188)] "Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'min')", source: http://127.0.0.1:62875/packs-test/js/application-bdd1e7e7bddd913eb135.js (26188)

although we never check for a property called "min".
And other times they also throw this error but pass the test.

This is the referenced js file:
jsFile.txt

Fixed this!
Problem seems to be the parallel execution via .then(...). Now we use await and it seems to work, at least for tests without routes.

@JulianEgbert
Copy link
Contributor Author

Coverage will increase with Issue #149, where we fix the tests that are currently only run locally (the features however work).

Copy link
Contributor

@postmartem postmartem left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems good

@Dassderdie
Copy link
Contributor

Fixed this! Problem seems to be the parallel execution via .then(...). Now we use await and it seems to work, at least for tests without routes.

I could imagine that there still is a race condition and it just doesn't appear by chance in the current tests.

You changed in 98d559e

// these operations are executed in parallel
getView().then((view) => {
    setView(view);
    addTargetMarker();
});

getBuildings().then((buildingPolygons) => {
    addPolygons(buildingPolygons);
});

getBuildingMarkers().then((buildingMarkers) => {
    addMarkers(buildingMarkers);
});

to

const view = await getView();
setView(view);
addTargetMarker();

const buildingPolygons = await getBuildings();
addPolygons(buildingPolygons);

const buildingMarkers = await getBuildingMarkers();
addMarkers(buildingMarkers);

From my understanding this should be equivalent to (except rejections error handling):

getView().then((view) => {
    setView(view);
    addTargetMarker();
    getBuildings().then((buildingPolygons) => {
        addPolygons(buildingPolygons);
        getBuildingMarkers().then((buildingMarkers) => {
            addMarkers(buildingMarkers);
        });
    });
});

I don't see how this could have fixed the errors...

Copy link
Contributor

@laugengebaeck laugengebaeck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good 😄 We will have to change lots of code in the other pull requests (because they stiil use JS inside the .html.erb file), but I'm glad this finally works!

import { displayRoute, setupMap } from './leafletMap.js';

let currentLocation;
const YOUR_LOCATION_MAGIC_STRING = "Your location" // TODO: Change this!!!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because we cannot execute Ruby code inside the JS file, right? It might be difficult to fix (and use the Ruby constant again), because afaik there is no such thing as a .js.erb.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't really pass things from ruby over to js. We might find a workaround, where we provide this thing from the server via an ajax request (like we did with the other constants) but maybe it won't be necessary due to the new UI which uses js as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AJAX just for getting a string constant seems a bit ugly (because we need new/separate endpoints for each constant), but I'm fine with leaving this as it is until we know how the new UI and translation is implemented. We should just keep this in mind.

Copy link
Contributor

@chrisma chrisma Jan 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using an Ajax call to get a string, you could also consider writing the value as a data attribute into an HTML element in the .erb template, which is read by the JS ($('.map').data('location')), i.e. <div class="map" data-location="Your location"></div>. Then the value is bound to the element that requires it. This pattern is sometimes called 'Unobtrusive JS': https://guides.rubyonrails.org/working_with_javascript_in_rails.html#unobtrusive-javascript

@JulianEgbert JulianEgbert merged commit 7ade7ad into dev Jan 11, 2022
@JulianEgbert JulianEgbert deleted the refactoring/tobias_117_convert_leaflet_to_js branch January 11, 2022 13:37
@Dassderdie
Copy link
Contributor

It seemed like there was a race condition. We resolved it by skipping the respective tests for now.

Tratori pushed a commit that referenced this pull request Jan 29, 2022
Refactor leaflet ruby gem to plain js.
This merge will remove the map on the location show page, as communicated with team @hpi-swt2/apmw21.
We moved functionality from server to client.

Coverage will be restored with Issue #149.

* Start working on refactoring to js

* Refactor map elements to js

* Remove style from head

* removed brackets as suggested

* Fix variable erroneously dumped to page

fixes Places::DESTINATIONS variable being dumped into HTML (introduced in #102)

* Restore package-lock.json and other feedback

* First steps on new js conversion

Co-authored-by: TheGrayStone <[email protected]>
Co-authored-by: Julian Schmidt <[email protected]>

* Refactor routing display

* Add Route to its own layer

* Trying to fix tests with js

* Comment on old magic constant

* Adapt tests for routing

* linting stuff

* Remove test for targets, minor fixes

* [CodeFactor] Apply fixes

* Remove old map from locations, needs more fixing

* Extra js file for leaflet Map

* prepare locations show

* Remove map from location page

* add debugging help to routing tests

* add waiting time for routing

* remove unnecessary code

* adding wait_for_ajax to route tests

* Remove old unused code (Commented for target)

* tag tests and improve backend routes

* improved tagging to new syntax

* exclude tests with the tag "local_only"

* add jQuery as requested

* code cleanup for jQuery

* enable indoor rooms from hg

* add target marker functionality

* remove old variable on index

* [CodeFactor] Apply fixes

* a try on fixing tests

* [CodeFactor] Apply fixes

* fix CodeFactor issue

* improve tests with find and waiting time

* edit tags for tests

* remove parallel execution in js

* remove wait_for_ajax

* run route tests only local

* restore yarn.lock

* add newline to yarn.lock

* Code improvements

* [CodeFactor] Apply fixes

* Fix magic string

* possible fix for routing tests

* Parallelize ajax requests

Co-authored-by: Julian Schmidt

* reverse changes for parallel ajax

* add comment about race condition

* Paralize ajax requests WITH tests

* remove tests for routing (race condition)

Co-authored-by: Lukas Rost <[email protected]>
Co-authored-by: TheGrayStone <[email protected]>
Co-authored-by: Julian Schmidt <[email protected]>
Co-authored-by: codefactor-io <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T.O.B.I.A.S. (TF1 & TF2)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Convert Leaflet to JS
10 participants