Skip to content

Smart origin/lot2#4358

Closed
brunobesson wants to merge 62 commits into
masterfrom
smart-origin/lot2
Closed

Smart origin/lot2#4358
brunobesson wants to merge 62 commits into
masterfrom
smart-origin/lot2

Conversation

@brunobesson
Copy link
Copy Markdown
Member

@brunobesson brunobesson commented Jul 17, 2025

Summary by CodeRabbit

  • New Features

    • Added public transport trip planning and nearby stop display to route and waypoint views, including interactive maps and journey details.
    • Introduced components for checking and displaying public transport accessibility of locations.
    • Integrated new APIs for journey planning, public transport stops, and user profile retrieval.
    • Enhanced map interactions for highlighting, zooming, and recentering on stops and waypoints.
  • Bug Fixes

    • Improved map styling and interaction logic for new waypoint and stop types.
  • Documentation

    • Extended French translations for new public transport and trip planning features.
  • Chores

    • Updated API endpoint configurations for development and preproduction environments.
    • Adjusted ESLint and Prettier configuration for consistent code formatting.
    • Modified Nginx configuration to disable proxy protocol support.

lgourdin and others added 30 commits January 24, 2025 12:58
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jul 17, 2025

Hey there and thank you for opening this pull request! 👋🏼

We require pull request titles to follow the Conventional Commits specification and it looks like your proposed title needs to be adjusted.

Details:

No release type found in pull request title "Smart origin/lot2". Add a prefix to indicate what kind of release this pull request corresponds to. For reference, see https://www.conventionalcommits.org/

Available types:
 - feat
 - fix
 - docs
 - style
 - refactor
 - perf
 - test
 - chore
 - revert
 - i18n

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jul 17, 2025

Walkthrough

This update introduces a comprehensive suite of features for public transport integration, including new API services, map enhancements, and interactive UI components for route planning and transport accessibility. It adds French translations for transport-related features, updates configuration for local development, and refines style and event handling in map and transport modules.

Changes

File(s) Change Summary
.eslintrc.json Added Prettier formatting rule with auto end-of-line handling.
docker/nginx.conf Disabled proxy protocol in listen directive; original kept as comment.
src/components/map/OlMap.vue Enhanced map event handling for stops/waypoints; added methods for highlighting, zooming, and recentering; updated feature styling logic.
src/components/map/map-utils.js Added/updated document types and styles; improved zIndex and color logic; extended line style function with new properties.
src/js/apis/c2c/UserProfileService.js Added getProfile(user_Id) method for fetching user profiles.
src/js/apis/navitia-service.js Introduced NavitiaService class for journey planning with multiple methods and utilities; exported as singleton.
src/js/apis/transport-service.js New TransportService class with methods for fetching stop areas, reachability, and aggregating stops for documents; exported as singleton.
src/translations/fr.json Added numerous French translations for public transport, trip planning, and map features.
src/views/document/RouteView.vue Added is-reachable-by-public-transports-box and transports-box components to sidebar and main content.
src/views/document/WaypointView.vue Added transports-box component after external resources section.
src/views/document/utils/boxes/IsReachableByPublicTransportsBox.vue New component: shows if a location is accessible by public transport; queries backend for reachability; displays info box.
src/views/document/utils/boxes/NearbyStopsSection.vue New component: displays and groups nearby public transport stops; integrates with map; manages stop selection and highlighting.
src/views/document/utils/boxes/PlanATripSection.vue New component: full-featured trip planner with address input, journey calculation, timeline display, and map integration.
src/views/document/utils/boxes/TransportsBox.vue New component: toggles between nearby stops and trip planning sections; manages state and integrates child components.
src/views/document/utils/document-view-mixin.js Registered new transport components for use in document views.
vue.config.js Switched API endpoints to preproduction; added localhost config; set localhost as default for development.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant RouteView/WaypointView
    participant TransportsBox
    participant NearbyStopsSection
    participant PlanATripSection
    participant TransportService
    participant NavitiaService
    participant OlMap

    User->>RouteView/WaypointView: Open document view
    RouteView/WaypointView->>TransportsBox: Render with document prop
    TransportsBox->>NearbyStopsSection: Render (Show nearby stops)
    NearbyStopsSection->>TransportService: fetchStopsForDocuments(documents)
    TransportService->>NearbyStopsSection: Return grouped stops
    NearbyStopsSection->>OlMap: Update map with stops
    User->>TransportsBox: Switch to "Plan a public transport trip"
    TransportsBox->>PlanATripSection: Render (with document)
    User->>PlanATripSection: Enter addresses, select waypoints, set time
    PlanATripSection->>NavitiaService: getJourneys(params)
    NavitiaService->>PlanATripSection: Return journey options
    PlanATripSection->>OlMap: Show journey on map
Loading

Poem

🐇
A rabbit hops through stops and lines,
New journeys planned, the UI shines.
With maps that zoom and trips to plot,
Transport boxes show what's hot.
From French translations to local dev,
This code now helps you plan and rev!
🚍🗺️✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE package: '@achrinza/node-ipc@9.2.6',
npm warn EBADENGINE required: {
npm warn EBADENGINE node: '8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 || 17 || 18 || 19'
npm warn EBADENGINE },
npm warn EBADENGINE current: { node: 'v24.3.0', npm: '11.4.2' }
npm warn EBADENGINE }
npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-07-17T20_12_21_019Z-debug-0.log

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 15

🧹 Nitpick comments (18)
src/views/document/RouteView.vue (1)

14-14: Consider adding null safety for associations.waypoints.

The component integration looks good, but accessing document.associations.waypoints directly could cause runtime errors if associations is undefined.

Consider adding optional chaining or a null check:

-        <is-reachable-by-public-transports-box :document="document.associations.waypoints" />
+        <is-reachable-by-public-transports-box :document="document.associations?.waypoints" />
src/views/document/utils/boxes/IsReachableByPublicTransportsBox.vue (1)

100-103: Use English for error messages.

The error message is in French while the rest of the codebase appears to use English for logging. This inconsistency could make debugging harder for international teams.

-            console.error(
-              `Erreur lors de la vérification de l'accessibilité pour le waypoint ${waypointIds[index]} :`,
-              error
-            );
+            console.error(
+              `Error checking accessibility for waypoint ${waypointIds[index]}:`,
+              error
+            );
src/components/map/map-utils.js (2)

78-83: Extract hardcoded colors as constants.

The hardcoded color values for bus styling should be defined as constants for better maintainability and consistency.

Add these constants at the top of the file:

const BUS_FILL_COLOR = 'rgba(255, 255, 255, 1)';
const BUS_HIGHLIGHT_COLOR = '#4baf50';
const BUS_DEFAULT_COLOR = '#337ab7';
const DEFAULT_CIRCLE_FILL = 'rgba(255, 255, 255, 0.5)';
const DEFAULT_CIRCLE_STROKE = '#ddd';

Then use them in the function:

-  let circleFillColor = 'rgba(255, 255, 255, 0.5)';
-  let circleStrokeColor = '#ddd';
+  let circleFillColor = DEFAULT_CIRCLE_FILL;
+  let circleStrokeColor = DEFAULT_CIRCLE_STROKE;

  if (svgSrc.includes('bus')) {
-    circleFillColor = highlight ? '#4baf50' : '#337ab7';
+    circleFillColor = highlight ? BUS_HIGHLIGHT_COLOR : BUS_DEFAULT_COLOR;
  }

190-190: Remove redundant fallback logic.

The fallback || icon({ prefix: 'waypoint', iconName: 'access' }).html[0] will never execute because svgSrcByDocumentType['z'] is already defined at line 104.

-    svgSrc = svgSrcByDocumentType['z'] || icon({ prefix: 'waypoint', iconName: 'access' }).html[0];
+    svgSrc = svgSrcByDocumentType['z'];
src/views/document/utils/boxes/TransportsBox.vue (2)

82-84: Use a more efficient deep cloning method.

Using JSON.parse(JSON.stringify()) for deep cloning has limitations (loses functions, dates, undefined values) and performance implications. Consider using a proper deep clone utility.

-      const accessPointsCopy = JSON.parse(JSON.stringify(accessPoints));
+      // Option 1: Use lodash cloneDeep if available
+      const accessPointsCopy = _.cloneDeep(accessPoints);
+      
+      // Option 2: Use structuredClone (modern browsers)
+      const accessPointsCopy = structuredClone(accessPoints);
+      
+      // Option 3: Manual deep clone for this specific use case
+      const accessPointsCopy = accessPoints.map(point => ({
+        ...point,
+        maps: point.maps ? [...point.maps] : []
+      }));

183-183: Use English for code comments.

For consistency with the rest of the codebase, use English for comments.

-      left: 12px; // Ajustez selon votre padding
+      left: 12px; // Adjust according to your padding
src/js/apis/transport-service.js (1)

5-9: Consider using ES6 class syntax.

The prototype pattern works but ES6 classes provide cleaner, more modern syntax that's easier to read and maintain.

-function TransportService() {
-  this.axios = axios.create({
-    baseURL: config.urls.api,
-  });
-}
+class TransportService {
+  constructor() {
+    this.axios = axios.create({
+      baseURL: config.urls.api,
+    });
+  }
+}

Then update all prototype methods to class methods:

-TransportService.prototype.getStopareas = function (waypointId) {
+  getStopareas(waypointId) {
src/js/apis/navitia-service.js (1)

5-9: Use ES6 class syntax for consistency.

Like the transport-service, this should use ES6 classes for consistency and modern JavaScript practices.

-function NavitiaService() {
-  this.axios = axios.create({
-    baseURL: config.urls.api,
-  });
-}
+class NavitiaService {
+  constructor() {
+    this.axios = axios.create({
+      baseURL: config.urls.api,
+    });
+  }
+}
src/components/map/OlMap.vue (2)

1320-1375: Consider using OpenLayers utilities for extent calculation.

While the implementation works, there are opportunities for improvement:

  1. The manual extent calculation with Infinity values is error-prone. Consider using ol.extent.createEmpty() and ol.extent.extend().
  2. The method only processes LineString geometries. Consider handling other geometry types if needed.
  3. The coordinate system detection (line 1336-1338) could be more robust.

Here's a more robust approach using OpenLayers utilities:

recenterOnDocuments() {
  if (!this.map || !this.documents || this.documents.length === 0) {
    console.warn('Cannot recenter - map or documents not available');
    return;
  }

- const extent = [Infinity, Infinity, -Infinity, -Infinity];
+ let extent = ol.extent.createEmpty();

  this.documents.forEach((doc) => {
    try {
      if (doc.geometry?.geom_detail) {
        const geom = JSON.parse(doc.geometry.geom_detail);
-
-       if (geom.type === 'LineString' && geom.coordinates?.length > 0) {
-         geom.coordinates.forEach((coord) => {
-           const [x, y] =
-             Math.abs(coord[0]) <= 180 && Math.abs(coord[1]) <= 90
-               ? ol.proj.transform([coord[0], coord[1]], 'EPSG:4326', 'EPSG:3857')
-               : [coord[0], coord[1]];
-
-           extent[0] = Math.min(extent[0], x);
-           extent[1] = Math.min(extent[1], y);
-           extent[2] = Math.max(extent[2], x);
-           extent[3] = Math.max(extent[3], y);
-         });
-       }
+       const feature = geoJSONFormat.readFeature(geom, {
+         dataProjection: 'EPSG:4326',
+         featureProjection: 'EPSG:3857'
+       });
+       ol.extent.extend(extent, feature.getGeometry().getExtent());
      }
    } catch (e) {
      console.error('Error processing document geometry:', e);
    }
  });

- if (extent[0] !== Infinity && extent[2] !== -Infinity) {
+ if (!ol.extent.isEmpty(extent)) {
    const padding = 50;
    const mapSize = this.map.getSize();
    const ratio = padding / Math.min(mapSize[0], mapSize[1]);
-
-   const width = extent[2] - extent[0];
-   const height = extent[3] - extent[1];
-
-   const paddedExtent = [
-     extent[0] - width * ratio,
-     extent[1] - height * ratio,
-     extent[2] + width * ratio,
-     extent[3] + height * ratio,
-   ];
+   const paddedExtent = ol.extent.buffer(extent, Math.max(ol.extent.getWidth(extent), ol.extent.getHeight(extent)) * ratio);

    this.map.getView().fit(paddedExtent, {
      duration: 1000,
      maxZoom: 18,
    });
  } else {
    this.map.getView().fit(DEFAULT_EXTENT);
    console.warn('No valid geometries found - using default extent');
  }
}

1378-1391: Consider improving readability of the type check.

The implementation is correct, but the condition could be more readable.

documentsSource.forEachFeature((feature) => {
- if (feature.values_.document.type !== 'w' && feature.values_.document.type !== 'z') {
+ const documentType = feature.get('document')?.type;
+ if (!['w', 'z'].includes(documentType)) {
    feature.setStyle(feature.get('normalStyle'));
  }
});
src/views/document/utils/boxes/NearbyStopsSection.vue (4)

9-9: Consider using a more robust approach for dynamic refs.

Using dynamic refs with string concatenation (:ref="'stopCard_' + stopGroup[0].id") can be fragile. Consider using a single ref with a data attribute or a Map to track elements.

<div
  v-for="(stopGroup, stopName) in groupedStops"
  :key="stopName"
  class="stop-card"
- :ref="'stopCard_' + stopGroup[0].id"
+ :data-stop-id="stopGroup[0].id"
+ ref="stopCards"
  :class="{ 'selected-stop': isStopGroupSelected(stopGroup) }"
  @mouseover="selectStopGroup(stopGroup)"
  @click="seeLineDetails(stopGroup)"
>

Then in methods:

getStopCardElement(stopId) {
  const cards = this.$refs.stopCards;
  if (Array.isArray(cards)) {
    return cards.find(el => el.dataset.stopId === stopId);
  }
  return cards?.dataset.stopId === stopId ? cards : null;
}

188-194: Consider avoiding direct mutation of document properties.

Directly mutating the public_transportation_rating property on documents could lead to unexpected side effects. Consider maintaining this state separately or using Vue.set for reactivity.

documents.forEach((doc) => {
  if (!result.documentResults[doc.document_id]) {
-   doc.public_transportation_rating = 'no service';
+   this.$set(doc, 'public_transportation_rating', 'no service');
  } else {
-   doc.public_transportation_rating = 'service available';
+   this.$set(doc, 'public_transportation_rating', 'service available');
  }
});

217-265: Well-implemented deduplication logic with good error handling.

The use of reduce with a coordsMap for deduplication is efficient. The error handling for individual stops ensures robustness.

Consider extracting the stop document creation logic into a separate method for better readability.


514-514: Avoid using !important in CSS.

The use of !important in media queries should be avoided. Consider increasing specificity instead.

@media only screen and (max-width: 600px) {
  .public-transports-section {
-   display: inline !important;
+   display: inline;

If needed, increase specificity by adding more specific selectors rather than using !important.

src/views/document/utils/boxes/PlanATripSection.vue (4)

463-463: Address or clarify the TODO comment.

The TODO comment lacks context. Please either implement the required change or provide more details about what needs to be changed.

Would you like me to help clarify what needs to be changed here or open an issue to track this task?


543-691: Consider reducing boilerplate in computed properties.

The current pattern creates many repetitive computed properties. Consider using a helper function to generate these dynamically or restructuring the component to reduce this boilerplate.

// Helper method to create computed properties
methods: {
  createDataProperty(propertyName) {
    return {
      get() { return this.currentData[propertyName]; },
      set(value) { this.currentData[propertyName] = value; }
    };
  }
},
computed: {
  currentData() {
    return this.activeTab === 'outbound' ? this.outboundData : this.returnData;
  },
  // Use spread operator to create all properties at once
  ...Object.fromEntries(
    ['fromAddress', 'selectedAddress', 'addressPropositions', /* etc */]
      .map(prop => [prop, this.createDataProperty(prop)])
  )
}

212-212: Optimize dynamic image imports for better performance.

Using require() with dynamic paths in the template can impact performance and may not work with all bundlers. Consider importing all transport icons statically.

// At the top of the script section
import busIcon from '@/assets/img/boxes/bus.svg';
import tramIcon from '@/assets/img/boxes/tram.svg';
import trainIcon from '@/assets/img/boxes/train.svg';
// ... other icons

// In data or computed
transportIcons: {
  bus: busIcon,
  tram: tramIcon,
  train: trainIcon,
  // ...
},

// In getTransportIcon method
getTransportIcon(section) {
  // ... existing logic
  const iconType = /* determine icon type */;
  return this.transportIcons[iconType] || this.transportIcons.bus;
}

// In template
<img :src="getTransportIcon(section)" alt="transport" />

Also applies to: 938-949


1-2094: Consider splitting this large component into smaller sub-components.

This component is over 2000 lines and handles many responsibilities. Consider extracting some parts into separate components for better maintainability:

  • Address input with autocomplete
  • Journey timeline display
  • Time modification buttons
  • Tab navigation

This would improve code organization, reusability, and testability.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6dea8da and 8a0725d.

⛔ Files ignored due to path filters (27)
  • src/assets/img/boxes/after.svg is excluded by !**/*.svg
  • src/assets/img/boxes/before.svg is excluded by !**/*.svg
  • src/assets/img/boxes/bus.svg is excluded by !**/*.svg
  • src/assets/img/boxes/chevron_right.svg is excluded by !**/*.svg
  • src/assets/img/boxes/correspondance.svg is excluded by !**/*.svg
  • src/assets/img/boxes/date.svg is excluded by !**/*.svg
  • src/assets/img/boxes/end.svg is excluded by !**/*.svg
  • src/assets/img/boxes/geoloc-2.svg is excluded by !**/*.svg
  • src/assets/img/boxes/geoloc.svg is excluded by !**/*.svg
  • src/assets/img/boxes/handi_accessible.svg is excluded by !**/*.svg
  • src/assets/img/boxes/itineraire-2.svg is excluded by !**/*.svg
  • src/assets/img/boxes/itineraire.svg is excluded by !**/*.svg
  • src/assets/img/boxes/next_day.svg is excluded by !**/*.svg
  • src/assets/img/boxes/point_acces.svg is excluded by !**/*.svg
  • src/assets/img/boxes/public_transport.svg is excluded by !**/*.svg
  • src/assets/img/boxes/public_transport_2.svg is excluded by !**/*.svg
  • src/assets/img/boxes/start.svg is excluded by !**/*.svg
  • src/assets/img/boxes/swap.svg is excluded by !**/*.svg
  • src/assets/img/boxes/time.svg is excluded by !**/*.svg
  • src/assets/img/boxes/toggle_minus.svg is excluded by !**/*.svg
  • src/assets/img/boxes/toggle_plus.svg is excluded by !**/*.svg
  • src/assets/img/boxes/train.svg is excluded by !**/*.svg
  • src/assets/img/boxes/tram.svg is excluded by !**/*.svg
  • src/assets/img/boxes/transport_not_found.svg is excluded by !**/*.svg
  • src/assets/img/boxes/velo.svg is excluded by !**/*.svg
  • src/assets/img/boxes/walk.svg is excluded by !**/*.svg
  • src/assets/img/boxes/warning.svg is excluded by !**/*.svg
📒 Files selected for processing (16)
  • .eslintrc.json (1 hunks)
  • docker/nginx.conf (1 hunks)
  • src/components/map/OlMap.vue (3 hunks)
  • src/components/map/map-utils.js (4 hunks)
  • src/js/apis/c2c/UserProfileService.js (1 hunks)
  • src/js/apis/navitia-service.js (1 hunks)
  • src/js/apis/transport-service.js (1 hunks)
  • src/translations/fr.json (28 hunks)
  • src/views/document/RouteView.vue (2 hunks)
  • src/views/document/WaypointView.vue (1 hunks)
  • src/views/document/utils/boxes/IsReachableByPublicTransportsBox.vue (1 hunks)
  • src/views/document/utils/boxes/NearbyStopsSection.vue (1 hunks)
  • src/views/document/utils/boxes/PlanATripSection.vue (1 hunks)
  • src/views/document/utils/boxes/TransportsBox.vue (1 hunks)
  • src/views/document/utils/document-view-mixin.js (2 hunks)
  • vue.config.js (3 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/components/map/map-utils.js

[error] 242-242: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🪛 GitHub Actions: Continuous integration
src/views/document/utils/boxes/PlanATripSection.vue

[error] 1923-1923: stylelint: Unexpected empty block (block-no-empty)

🔇 Additional comments (18)
.eslintrc.json (1)

14-14: Good addition for cross-platform development.

The endOfLine: "auto" option helps normalize line endings across different operating systems, which is essential for teams working on various platforms. The "warn" level is appropriate for formatting issues.

docker/nginx.conf (1)

2-3: No proxy_protocol usage found elsewhere; removal is safe

  • Verified only occurrence of proxy_protocol is the commented line in docker/nginx.conf.
  • No other references in configuration files, load-balancer hints, or Kubernetes/Helm manifests.
  • Removing it from this Docker‐based Nginx config won’t affect other parts of the codebase.
  • If your production Nginx or LB requires proxy_protocol, configure it outside this local Docker setup.
src/js/apis/c2c/UserProfileService.js (1)

114-116: Well-implemented API method addition.

The new getProfile method follows the established patterns in the service with consistent naming, appropriate parameter handling, and REST-compliant endpoint structure.

vue.config.js (1)

95-95: Verify production API URL change doesn't affect live deployments.

The demo configuration API URL has been changed from production to preproduction. Ensure this change is intentional and doesn't impact live demo environments.

src/views/document/utils/document-view-mixin.js (4)

5-5: Good addition of transport accessibility component.

The import follows the established pattern and naming convention in the file.


10-10: Good addition of transport component.

The import follows the established pattern and naming convention in the file.


38-38: Proper component registration.

The component is correctly registered in the components object following the established pattern.


46-46: Proper component registration.

The component is correctly registered in the components object following the established pattern.

src/views/document/WaypointView.vue (1)

132-132: LGTM! Clean integration of transport component.

The placement of transports-box between the main content and routes section is logical. The array wrapping pattern [document] suggests the component is designed to handle multiple documents, which provides good flexibility for future enhancements.

src/views/document/RouteView.vue (1)

128-128: LGTM! Consistent transport component placement.

The transports-box component is well-positioned in the main content area and follows a clean integration pattern.

src/translations/fr.json (1)

15-15: Excellent comprehensive French localization for transport features.

The translation additions provide thorough coverage of the new public transport integration features. The French translations are accurate and contextually appropriate, covering:

  • Proximity and accessibility indicators
  • Trip planning interface elements
  • Timing and scheduling controls
  • Map interaction labels
  • Status messages and error handling
  • Geographic and transport-specific terminology

The translations follow consistent naming patterns and integrate well with the existing localization structure.

Also applies to: 37-38, 70-70, 79-79, 99-99, 113-113, 186-188, 216-216, 224-225, 228-228, 266-267, 319-319, 385-385, 398-399, 401-401, 407-407, 415-415, 444-444, 478-478, 482-482, 493-493, 529-529, 549-550, 553-553, 562-562, 576-576, 601-601, 617-617, 645-645, 666-666, 709-711, 716-716, 735-735, 755-755, 767-767

src/views/document/utils/boxes/IsReachableByPublicTransportsBox.vue (1)

3-3: Scroll target verified
The element with id="public-transport-scroll" is defined in src/views/document/utils/boxes/TransportsBox.vue, so the hardcoded href="#public-transport-scroll" will resolve correctly.

src/components/map/OlMap.vue (5)

863-865: LGTM! Good enhancement for property-based styling.

The addition of document.properties as a parameter to getDocumentLineStyle enables more flexible styling based on document properties, which aligns well with the new transport features.


1095-1118: Well-structured event handling for transport features.

The conditional logic properly handles different document types with appropriate null checks and early returns. The separation of concerns between waypoint clicks and stop clicks is clean.


1283-1294: Good implementation of stop highlighting.

The method properly resets styles before highlighting and includes appropriate error handling.


1297-1317: Well-implemented zoom animation.

Good practices: canceling existing animations, ensuring minimum zoom level for visibility, and proper null checks for geometry.


1394-1411: Clean implementation of stop feature search.

The method properly searches both layers and includes appropriate error handling.

src/views/document/utils/boxes/PlanATripSection.vue (1)

391-391: Remove unused import.

The start import is not used anywhere in the component.

-import start from '@/assets/img/boxes/geoloc-2.svg';

Likely an incorrect or invalid review comment.

Comment thread vue.config.js
prod: {
name: 'prod',
api: 'https://api.camptocamp.org',
api: 'https://preprod.c2c.preprod0.smart-origin.com/api',
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical: Production API URL pointing to preproduction.

The production configuration is now pointing to a preproduction API URL, which could cause serious issues if this code is deployed to production environments.

Verify this change is intentional and ensure proper environment-specific configuration:

#!/bin/bash
# Description: Check build environment handling and deployment configurations
# Expected: Find how BUILD_ENV is used and ensure production builds work correctly

echo "=== Checking BUILD_ENV usage ==="
rg "BUILD_ENV" -A 3 -B 3

echo -e "\n=== Checking deployment configurations ==="
rg "camptocamp\|prod\|demo" --type js --type json -A 2 -B 2

echo -e "\n=== Checking package.json build scripts ==="
cat package.json | jq '.scripts'
🤖 Prompt for AI Agents
In vue.config.js at line 117, the production API URL is incorrectly set to a
preproduction endpoint, which risks deploying the wrong configuration to
production. Review the environment-specific configuration setup to ensure the
production build uses the correct production API URL. Verify how the BUILD_ENV
variable is used to differentiate environments and update the API URL
accordingly so that production builds point to the official production API
endpoint, not the preproduction one.

Comment thread vue.config.js
};

config.urls = config.urlsConfigurations.prod; // default: prod
config.urls = config.urlsConfigurations.localhost; // default: prod
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical: Default configuration changed to localhost.

Changing the default configuration from "prod" to "localhost" will break production deployments unless the BUILD_ENV is properly set.

Ensure this change is reverted or properly handled with environment-specific logic:

-config.urls = config.urlsConfigurations.localhost; // default: prod
+config.urls = config.urlsConfigurations.prod; // default: prod
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
config.urls = config.urlsConfigurations.localhost; // default: prod
config.urls = config.urlsConfigurations.prod; // default: prod
🤖 Prompt for AI Agents
In vue.config.js at line 149, the default assignment of config.urls to
config.urlsConfigurations.localhost changes the default environment from
production to localhost, which can break production deployments. Revert this
line to default to the production configuration or implement conditional logic
that sets config.urls based on the BUILD_ENV environment variable to ensure the
correct configuration is used for each environment.

Comment thread vue.config.js
Comment on lines +137 to +145
localhost: {
name: 'localhost',
api: 'http://localhost:6543',
media: 'https://sos-ch-dk-2.exo.io/c2corg-demov6-active',
imageBackend: 'https://images.demov6.camptocamp.org',
forum: 'https://forum.demov6.camptocamp.org',
modernThumbnailsTimestamp: 0,
modernThumbnailsId: 0,
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove duplicate localhost configuration.

The localhost configuration is defined twice - once here and again at lines 158-166. This duplication should be removed to avoid confusion.

Apply this diff to remove the duplicate:

-    localhost: {
-      name: 'localhost',
-      api: 'http://localhost:6543',
-      media: 'https://sos-ch-dk-2.exo.io/c2corg-demov6-active',
-      imageBackend: 'https://images.demov6.camptocamp.org',
-      forum: 'https://forum.demov6.camptocamp.org',
-      modernThumbnailsTimestamp: 0,
-      modernThumbnailsId: 0,
-    },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
localhost: {
name: 'localhost',
api: 'http://localhost:6543',
media: 'https://sos-ch-dk-2.exo.io/c2corg-demov6-active',
imageBackend: 'https://images.demov6.camptocamp.org',
forum: 'https://forum.demov6.camptocamp.org',
modernThumbnailsTimestamp: 0,
modernThumbnailsId: 0,
},
🤖 Prompt for AI Agents
In vue.config.js between lines 137 and 145, there is a duplicate localhost
configuration also defined at lines 158 to 166. Remove the entire localhost
block from lines 137 to 145 to eliminate the duplication and avoid confusion.

Comment on lines +152 to +154
:global(html) {
scroll-behavior: smooth;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid global style modifications in component.

Setting global styles from a component can have unintended side effects across the entire application. Consider moving this to a global stylesheet or making it more targeted.

Either remove this global style or move it to a more appropriate location like a global CSS file. If you need smooth scrolling only for this component's navigation, consider using JavaScript scrolling with scrollIntoView({ behavior: 'smooth' }) instead.

🤖 Prompt for AI Agents
In src/views/document/utils/boxes/IsReachableByPublicTransportsBox.vue around
lines 152 to 154, avoid setting global styles like :global(html) {
scroll-behavior: smooth; } inside the component as it affects the entire app.
Remove this global style from the component and move it to a global CSS file
instead. If smooth scrolling is only needed within this component, replace the
CSS with JavaScript-based scrolling using scrollIntoView({ behavior: 'smooth' })
for targeted behavior.

Comment on lines +82 to +109
/** Calls the backend service to check if waypoints have associated transports */
checkMultipleWaypointsReachability(waypointIds) {
const checkNextWaypoint = (index) => {
if (index >= waypointIds.length) {
this.showAccessibilityInfo = false;
return;
}

transportService
.isReachable(waypointIds[index])
.then((isReachable) => {
if (isReachable === true) {
this.showAccessibilityInfo = true;
} else {
checkNextWaypoint(index + 1);
}
})
.catch((error) => {
console.error(
`Erreur lors de la vérification de l'accessibilité pour le waypoint ${waypointIds[index]} :`,
error
);
checkNextWaypoint(index + 1);
});
};

checkNextWaypoint(0);
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Optimize performance with parallel API calls.

The current implementation checks waypoints sequentially, which could be slow when there are multiple waypoints. Consider using parallel API calls with Promise.all() to improve performance.

-    checkMultipleWaypointsReachability(waypointIds) {
-      const checkNextWaypoint = (index) => {
-        if (index >= waypointIds.length) {
-          this.showAccessibilityInfo = false;
-          return;
-        }
-
-        transportService
-          .isReachable(waypointIds[index])
-          .then((isReachable) => {
-            if (isReachable === true) {
-              this.showAccessibilityInfo = true;
-            } else {
-              checkNextWaypoint(index + 1);
-            }
-          })
-          .catch((error) => {
-            console.error(
-              `Erreur lors de la vérification de l'accessibilité pour le waypoint ${waypointIds[index]} :`,
-              error
-            );
-            checkNextWaypoint(index + 1);
-          });
-      };
-
-      checkNextWaypoint(0);
+    async checkMultipleWaypointsReachability(waypointIds) {
+      const promises = waypointIds.map(id => 
+        transportService.isReachable(id)
+          .catch(error => {
+            console.error(
+              `Error checking accessibility for waypoint ${id}:`,
+              error
+            );
+            return false;
+          })
+      );
+
+      try {
+        const results = await Promise.all(promises);
+        this.showAccessibilityInfo = results.some(isReachable => isReachable === true);
+      } catch (error) {
+        console.error('Error checking waypoints reachability:', error);
+        this.showAccessibilityInfo = false;
+      }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/views/document/utils/boxes/IsReachableByPublicTransportsBox.vue between
lines 82 and 109, the method checkMultipleWaypointsReachability currently checks
each waypoint's reachability sequentially, causing slow performance. Refactor
this method to perform all isReachable API calls in parallel using Promise.all()
on the array of waypointIds. Then, process the results to set
showAccessibilityInfo to true if any waypoint is reachable, otherwise false.
This will significantly improve the performance by reducing total wait time.

Comment on lines +812 to +813
alert('Unable to get your current location.');
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Replace alert() with proper user notifications.

Using alert() provides poor user experience. Consider using a proper notification system or toast component that's consistent with your application's UI.

Instead of:

alert('Unable to get your current location.');
alert('Geolocation is not supported by your browser.');

Consider emitting events or using a notification service:

this.$emit('show-notification', { 
  type: 'error', 
  message: this.$gettext('Unable to get your current location.')
});

Also applies to: 817-817

🤖 Prompt for AI Agents
In src/views/document/utils/boxes/PlanATripSection.vue around lines 812 to 813
and line 817, replace the use of alert() for error messages with the
application's notification system. Instead of alert(), emit an event or call the
notification service to show an error toast or message consistent with the UI,
for example by using this.$emit('show-notification', { type: 'error', message:
this.$gettext('Your error message') }). This will improve user experience by
integrating with the app's notification framework.

}),
},
properties: {
name: 'Départ',
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use i18n for hardcoded French text.

The text 'Départ' is hardcoded instead of using internationalization.

-name: 'Départ',
+name: this.$gettext('Departure'),
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name: 'Départ',
name: this.$gettext('Departure'),
🤖 Prompt for AI Agents
In src/views/document/utils/boxes/PlanATripSection.vue at line 1054, replace the
hardcoded French text 'Départ' with a call to the i18n translation function to
support internationalization. Use the appropriate i18n key for 'Départ' or add
one if it doesn't exist, and update the code to retrieve the translated string
instead of the hardcoded text.

async mounted() {
// Loads a user's address to put it directly into the 'address' field
await this.loadUserAddressIfLoggedIn();
console.log(this.document);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove console.log statement.

Debug console statements should be removed from production code.

-console.log(this.document);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
console.log(this.document);
🤖 Prompt for AI Agents
In src/views/document/utils/boxes/PlanATripSection.vue at line 485, remove the
console.log statement that outputs this.document to clean up the code and
prevent debug logs from appearing in production.

Comment on lines +98 to +99
placeholder="Entrez une adresse de destination"
/>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix hardcoded French placeholder text.

The placeholder text is hardcoded in French while the rest of the component uses $gettext() for internationalization.

-placeholder="Entrez une adresse de destination"
+:placeholder="$gettext('Enter a destination address')"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
placeholder="Entrez une adresse de destination"
/>
placeholder="$gettext('Enter a destination address')"
/>
🤖 Prompt for AI Agents
In src/views/document/utils/boxes/PlanATripSection.vue around lines 98 to 99,
replace the hardcoded French placeholder text with a call to $gettext() to
ensure the placeholder is internationalized consistently with the rest of the
component. Use $gettext("Entrez une adresse de destination") instead of the raw
string.

Comment on lines +1923 to +1924
.plan-trip-search-button-img {
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove empty CSS block to fix pipeline failure.

The empty .plan-trip-search-button-img block is causing a stylelint error.

-.plan-trip-search-button-img {
-}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.plan-trip-search-button-img {
}
🧰 Tools
🪛 GitHub Actions: Continuous integration

[error] 1923-1923: stylelint: Unexpected empty block (block-no-empty)

🤖 Prompt for AI Agents
In src/views/document/utils/boxes/PlanATripSection.vue at lines 1923 to 1924,
remove the empty CSS block for .plan-trip-search-button-img entirely to resolve
the stylelint error and fix the pipeline failure.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants