@geotrekce/geotrek-rando-widget 0.0.3 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/dist/cjs/geotrek-rando-widget.cjs.js +2 -2
  2. package/dist/cjs/grw-app.cjs.entry.js +111 -0
  3. package/dist/cjs/{grw-app_10.cjs.entry.js → grw-filter_6.cjs.entry.js} +284 -446
  4. package/dist/cjs/grw-information-desk-detail_3.cjs.entry.js +52 -0
  5. package/dist/cjs/grw-trek-card.cjs.entry.js +47 -0
  6. package/dist/cjs/{index-c6f73e30.js → index-c2c4531d.js} +46 -1
  7. package/dist/cjs/length-d315d156.js +34 -0
  8. package/dist/cjs/loader.cjs.js +2 -2
  9. package/dist/cjs/store-fd04a216.js +211 -0
  10. package/dist/collection/collection-manifest.json +1 -0
  11. package/dist/collection/components/grw-app/grw-app.css +69 -5
  12. package/dist/collection/components/grw-app/grw-app.js +76 -28
  13. package/dist/collection/components/grw-filter/grw-filter.css +29 -0
  14. package/dist/collection/components/grw-filter/grw-filter.js +132 -0
  15. package/dist/collection/components/grw-information-desk-detail/grw-information-desk-detail.css +5 -4
  16. package/dist/collection/components/grw-information-desk-detail/grw-information-desk-detail.js +1 -1
  17. package/dist/collection/components/grw-map/grw-map.css +19 -1
  18. package/dist/collection/components/grw-map/grw-map.js +101 -40
  19. package/dist/collection/components/grw-poi-detail/grw-poi-detail.css +5 -4
  20. package/dist/collection/components/grw-poi-detail/grw-poi-detail.js +1 -1
  21. package/dist/collection/components/grw-sensitive-area-detail/grw-sensitive-area-detail.css +27 -3
  22. package/dist/collection/components/grw-sensitive-area-detail/grw-sensitive-area-detail.js +17 -3
  23. package/dist/collection/components/grw-trek-card/grw-trek-card.css +66 -32
  24. package/dist/collection/components/grw-trek-card/grw-trek-card.js +34 -10
  25. package/dist/collection/components/grw-trek-detail/grw-trek-detail.css +134 -4
  26. package/dist/collection/components/grw-trek-detail/grw-trek-detail.js +95 -6
  27. package/dist/collection/components/grw-treks-list/grw-treks-list.css +16 -3
  28. package/dist/collection/components/grw-treks-list/grw-treks-list.js +33 -6
  29. package/dist/collection/store/grw-trek-provider.js +32 -10
  30. package/dist/collection/store/grw-treks-provider.js +14 -4
  31. package/dist/collection/store/store.js +10 -1
  32. package/dist/collection/stories/App.js +8 -10
  33. package/dist/collection/stories/App.stories.js +4 -3
  34. package/dist/collection/stories/TrekMap.stories.js +3 -2
  35. package/dist/collection/stories/TreksList.js +8 -8
  36. package/dist/collection/stories/TreksMap.stories.js +3 -2
  37. package/dist/components/grw-app.js +66 -9
  38. package/dist/components/grw-filter.d.ts +11 -0
  39. package/dist/components/grw-filter.js +6 -0
  40. package/dist/components/grw-filter2.js +95 -0
  41. package/dist/components/grw-information-desk-detail2.js +2 -2
  42. package/dist/components/grw-map2.js +102 -41
  43. package/dist/components/grw-poi-detail2.js +2 -2
  44. package/dist/components/grw-sensitive-area-detail2.js +7 -2
  45. package/dist/components/grw-trek-card2.js +10 -5
  46. package/dist/components/grw-trek-detail2.js +25 -4
  47. package/dist/components/grw-trek-provider2.js +32 -10
  48. package/dist/components/grw-treks-list2.js +15 -7
  49. package/dist/components/grw-treks-provider2.js +14 -4
  50. package/dist/components/store.js +10 -1
  51. package/dist/esm/geotrek-rando-widget.js +2 -2
  52. package/dist/esm/grw-app.entry.js +107 -0
  53. package/dist/esm/{grw-app_10.entry.js → grw-filter_6.entry.js} +246 -404
  54. package/dist/esm/grw-information-desk-detail_3.entry.js +46 -0
  55. package/dist/esm/grw-trek-card.entry.js +43 -0
  56. package/dist/esm/{index-7aa9e822.js → index-192d910f.js} +47 -2
  57. package/dist/esm/length-d82189db.js +27 -0
  58. package/dist/esm/loader.js +2 -2
  59. package/dist/esm/store-b2c76c0c.js +208 -0
  60. package/dist/geotrek-rando-widget/geotrek-rando-widget.esm.js +1 -1
  61. package/dist/geotrek-rando-widget/p-1b2ba86d.entry.js +1 -0
  62. package/dist/geotrek-rando-widget/p-5f17d340.entry.js +1 -0
  63. package/dist/geotrek-rando-widget/p-6716c635.entry.js +1 -0
  64. package/dist/geotrek-rando-widget/p-6dce5e6c.js +2 -0
  65. package/dist/geotrek-rando-widget/p-7715153d.entry.js +1 -0
  66. package/dist/geotrek-rando-widget/p-e6710c64.js +1 -0
  67. package/dist/geotrek-rando-widget/p-f3f7d6be.js +1 -0
  68. package/dist/types/components/grw-app/grw-app.d.ts +9 -2
  69. package/dist/types/components/grw-filter/grw-filter.d.ts +9 -0
  70. package/dist/types/components/grw-map/grw-map.d.ts +3 -1
  71. package/dist/types/components/grw-trek-card/grw-trek-card.d.ts +6 -4
  72. package/dist/types/components/grw-trek-detail/grw-trek-detail.d.ts +9 -4
  73. package/dist/types/components/grw-treks-list/grw-treks-list.d.ts +1 -0
  74. package/dist/types/components.d.ts +23 -2
  75. package/dist/types/store/store.d.ts +22 -3
  76. package/dist/types/types/types.d.ts +74 -1
  77. package/package.json +5 -4
  78. package/readme.md +4 -5
  79. package/dist/geotrek-rando-widget/p-332ba9ab.js +0 -2
  80. package/dist/geotrek-rando-widget/p-73bc92fe.entry.js +0 -1
@@ -4,10 +4,11 @@ import arrowBackImage from '../../assets/arrow-back.svg';
4
4
  export class GrwApp {
5
5
  constructor() {
6
6
  this.showTrek = false;
7
- this.showMap = false;
7
+ this.showTreksMap = false;
8
+ this.showTrekMap = false;
9
+ this.showFilters = false;
8
10
  this.isLargeView = false;
9
11
  this.language = 'fr';
10
- this.appName = 'Geotrek Rando Widget';
11
12
  this.colorPrimary = '#6b0030';
12
13
  this.colorPrimaryShade = '#4a0021';
13
14
  this.colorPrimaryTint = '#974c6e';
@@ -16,11 +17,15 @@ export class GrwApp {
16
17
  this.colorArrivalIcon = '#85003b';
17
18
  this.colorSensitiveArea = '#4974a5';
18
19
  this.colorPoiIcon = '#974c6e';
19
- this.largeViewSize = 664;
20
+ this.handlePopStateBind = this.handlePopState.bind(this);
21
+ this.largeViewSize = 1024;
20
22
  }
21
23
  onTrekCardPress(event) {
22
24
  this.currentTrekId = event.detail;
23
25
  this.showTrek = !this.showTrek;
26
+ const url = new URL(window.location.toString());
27
+ url.searchParams.set('trek', this.currentTrekId.toString());
28
+ window.history.pushState({}, '', url);
24
29
  }
25
30
  onWindowResize() {
26
31
  this.handleView();
@@ -30,6 +35,14 @@ export class GrwApp {
30
35
  }
31
36
  componentDidLoad() {
32
37
  this.handleView();
38
+ window.addEventListener('popstate', this.handlePopStateBind, false);
39
+ const url = new URL(window.location.toString());
40
+ const trekParam = url.searchParams.get('trek');
41
+ if (trekParam) {
42
+ window.history.replaceState({ isInitialHistoryWithTrek: true }, '', url);
43
+ this.currentTrekId = Number(trekParam);
44
+ this.showTrek = !this.showTrek;
45
+ }
33
46
  }
34
47
  onTrekDetailsClose() {
35
48
  this.currentTrekId = null;
@@ -37,24 +50,75 @@ export class GrwApp {
37
50
  }
38
51
  handleView() {
39
52
  this.isLargeView = this.element.getBoundingClientRect().width >= this.largeViewSize;
40
- this.showMap = this.isLargeView;
53
+ this.showTreksMap = this.isLargeView;
54
+ this.showTrekMap = this.isLargeView;
55
+ }
56
+ handleFilters() {
57
+ this.showFilters = !this.showFilters;
58
+ }
59
+ handleBackButton() {
60
+ if (window.history.state.isInitialHistoryWithTrek) {
61
+ this.onTrekDetailsClose();
62
+ const url = new URL(window.location.toString());
63
+ url.searchParams.delete('trek');
64
+ window.history.pushState({}, '', url);
65
+ }
66
+ else {
67
+ window.history.back();
68
+ }
69
+ }
70
+ handlePopState() {
71
+ const url = new URL(window.location.toString());
72
+ const trekParam = url.searchParams.get('trek');
73
+ if (trekParam) {
74
+ this.currentTrekId = Number(trekParam);
75
+ this.showTrek = !this.showTrek;
76
+ }
77
+ else {
78
+ this.onTrekDetailsClose();
79
+ }
80
+ }
81
+ handleShowMap() {
82
+ if (this.currentTrekId) {
83
+ this.showTrekMap = !this.showTrekMap;
84
+ }
85
+ else {
86
+ this.showTreksMap = !this.showTreksMap;
87
+ }
88
+ }
89
+ disconnectedCallback() {
90
+ window.removeEventListener('popstate', this.handlePopStateBind);
41
91
  }
42
92
  render() {
43
- return (h(Host, { style: { '--color-primary': this.colorPrimary, '--color-primary-tint': this.colorPrimaryTint } },
93
+ return (h(Host, { style: { '--color-primary': this.colorPrimary, '--color-primary-tint': this.colorPrimaryTint, '--color-primary-shade': this.colorPrimaryShade } },
44
94
  h("grw-treks-provider", { api: this.api, language: this.language, "in-bbox": this.inBbox, cities: this.cities, districts: this.districts, structures: this.structures, themes: this.themes, portals: this.portals, routes: this.routes, practices: this.practices }),
45
95
  this.showTrek && this.currentTrekId && h("grw-trek-provider", { api: state.api, language: this.language, "trek-id": this.currentTrekId }),
46
96
  h("div", { class: "app-container" },
47
- h("div", { class: this.isLargeView ? 'large-view-header-container' : 'header-container' }, this.showTrek ? h("div", { onClick: () => this.onTrekDetailsClose(), class: "arrow-back-icon", innerHTML: arrowBackImage }) : h("div", { class: "title" }, this.appName)),
97
+ h("div", { class: this.isLargeView ? 'large-view-header-container' : 'header-container' },
98
+ this.showTrek ? (h("div", { onClick: () => this.handleBackButton(), class: "arrow-back-icon", innerHTML: arrowBackImage })) : (h("div", { onClick: () => this.handleFilters(), class: "handle-filters-button" }, "FILTRER")),
99
+ !this.showTrek && this.showFilters && (h("div", { class: "options-container" },
100
+ h("div", { class: "filters-container" },
101
+ h("div", { class: "current-treks-length" }, `${state.currentTreks.length} résultat${state.currentTreks.length > 1 ? 's' : ''}`),
102
+ h("div", { onClick: () => this.handleFilters(), class: "close-filters-button" }, "X"),
103
+ h("div", null,
104
+ h("grw-filter", { filterName: "Pratique", filterType: "practices", filterNameProperty: "name" })),
105
+ h("div", { class: "filter-margin-top" },
106
+ h("grw-filter", { filterName: "Difficult\u00E9", filterType: "difficulties", filterNameProperty: "label" })),
107
+ h("div", { class: "filter-margin-top" },
108
+ h("grw-filter", { filterName: "Dur\u00E9e", filterType: "durations", filterNameProperty: "name" }))),
109
+ h("div", { onClick: () => this.handleFilters(), class: "back-filters-container" }))),
110
+ h("div", { class: "attribution-container" },
111
+ h("a", { target: "_blank", href: "https://geotrek.fr" }, "GEOTREK"))),
48
112
  h("div", { class: "content-container" },
49
113
  h("div", { class: this.isLargeView ? 'large-view-app-treks-list-container' : 'app-treks-list-container', style: { display: this.showTrek ? 'none' : 'flex', position: this.showTrek ? 'absolute' : 'relative' } },
50
- h("grw-treks-list", { "color-primary": this.colorPrimary, "color-primary-tint": this.colorPrimaryTint })),
114
+ h("grw-treks-list", { "is-large-view": this.isLargeView, "color-primary": this.colorPrimary, "color-primary-tint": this.colorPrimaryTint })),
51
115
  this.showTrek && !state.currentTrek && (h("div", { class: this.isLargeView ? 'large-view-loader-container' : 'loader-container' },
52
116
  h("span", { class: "loader" }))),
53
117
  state.currentTrek && (h("div", { class: this.isLargeView ? 'large-view-app-trek-detail-container' : 'app-trek-detail-container' },
54
118
  h("grw-trek-detail", { "color-primary": this.colorPrimary, "color-primary-shade": this.colorPrimaryShade, "color-primary-tint": this.colorPrimaryTint }))),
55
- h("grw-map", { class: this.isLargeView ? 'large-view-app-map-container' : 'app-map-container', style: { visibility: this.showMap ? 'visible' : 'hidden' }, "url-layer": this.urlLayer, center: this.center, zoom: this.zoom, attribution: this.attribution, "color-trek-line": this.colorTrekLine, "color-departure-icon": this.colorDepartureIcon, "color-arrival-icon": this.colorArrivalIcon, "color-sensitive-area": this.colorSensitiveArea, "color-poi-icon": this.colorPoiIcon })),
119
+ h("grw-map", { class: this.isLargeView ? 'large-view-app-map-container' : 'app-map-container', style: { visibility: (this.showTreksMap && !this.showTrek) || (this.showTrekMap && this.showTrek) ? 'visible' : 'hidden' }, "url-layer": this.urlLayer, center: this.center, zoom: this.zoom, attribution: this.attribution, "color-primary": this.colorPrimary, "color-primary-tint": this.colorPrimaryTint, "color-trek-line": this.colorTrekLine, "color-departure-icon": this.colorDepartureIcon, "color-arrival-icon": this.colorArrivalIcon, "color-sensitive-area": this.colorSensitiveArea, "color-poi-icon": this.colorPoiIcon })),
56
120
  h("div", { class: "map-visibility-button", style: { display: this.isLargeView ? 'none' : 'flex' } },
57
- h("div", { onClick: () => (this.showMap = !this.showMap) }, this.showMap ? (this.showTrek ? 'Voir la fiche' : 'Voir la liste') : 'Voir la carte')))));
121
+ h("div", { onClick: () => this.handleShowMap() }, this.showTreksMap || this.showTrekMap ? (this.showTrek ? 'Voir la fiche' : 'Voir la liste') : 'Voir la carte')))));
58
122
  }
59
123
  static get is() { return "grw-app"; }
60
124
  static get encapsulation() { return "shadow"; }
@@ -236,24 +300,6 @@ export class GrwApp {
236
300
  "attribute": "practices",
237
301
  "reflect": false
238
302
  },
239
- "appName": {
240
- "type": "string",
241
- "mutable": false,
242
- "complexType": {
243
- "original": "string",
244
- "resolved": "string",
245
- "references": {}
246
- },
247
- "required": false,
248
- "optional": false,
249
- "docs": {
250
- "tags": [],
251
- "text": ""
252
- },
253
- "attribute": "app-name",
254
- "reflect": false,
255
- "defaultValue": "'Geotrek Rando Widget'"
256
- },
257
303
  "urlLayer": {
258
304
  "type": "string",
259
305
  "mutable": false,
@@ -469,7 +515,9 @@ export class GrwApp {
469
515
  }; }
470
516
  static get states() { return {
471
517
  "showTrek": {},
472
- "showMap": {},
518
+ "showTreksMap": {},
519
+ "showTrekMap": {},
520
+ "showFilters": {},
473
521
  "isLargeView": {},
474
522
  "currentTrekId": {}
475
523
  }; }
@@ -0,0 +1,29 @@
1
+ .filter-name {
2
+ margin-left: 8px;
3
+ color: var(--color-primary);
4
+ font-size: 24px;
5
+ font-weight: bold;
6
+ }
7
+
8
+ .filter-button-container {
9
+ display: flex;
10
+ flex-direction: row;
11
+ flex-wrap: wrap;
12
+ }
13
+ .filter-button-container .filter-button,
14
+ .filter-button-container .selected-filter-button {
15
+ user-select: none;
16
+ cursor: pointer;
17
+ border: 1px var(--color-primary) solid;
18
+ border-radius: 8px;
19
+ margin: 8px 0px 0px 8px;
20
+ padding: 8px;
21
+ }
22
+ .filter-button-container .filter-button {
23
+ color: var(--color-primary);
24
+ background-color: #ffffff;
25
+ }
26
+ .filter-button-container .selected-filter-button {
27
+ color: #ffffff;
28
+ background-color: var(--color-primary);
29
+ }
@@ -0,0 +1,132 @@
1
+ import { Component, Host, h, Prop } from '@stencil/core';
2
+ import state from 'store/store';
3
+ export class GrwFilter {
4
+ constructor() {
5
+ this.filters = [
6
+ { property: 'practices', trekProperty: 'practice', type: 'include' },
7
+ { property: 'difficulties', trekProperty: 'difficulty', type: 'include' },
8
+ { property: 'durations', trekProperty: 'duration', type: 'interval' },
9
+ ];
10
+ }
11
+ handleFilter(_event, filterToHandle) {
12
+ const filterFromState = [...state[this.filterType]];
13
+ filterFromState.find(currentFilter => currentFilter.id === filterToHandle.id).selected = !filterFromState.find(currentFilter => currentFilter.id === filterToHandle.id)
14
+ .selected;
15
+ state[this.filterType] = filterFromState;
16
+ let isUsingFilter = false;
17
+ let filtersTreks = [];
18
+ for (const filter of this.filters) {
19
+ const currentFiltersId = state[filter.property].filter(currentFilter => currentFilter.selected).map(currentFilter => currentFilter.id);
20
+ if (currentFiltersId.length > 0) {
21
+ if (filtersTreks.length > 0) {
22
+ if (filter.type === 'include') {
23
+ filtersTreks = [...filtersTreks.filter(trek => currentFiltersId.includes(trek[filter.trekProperty]))];
24
+ }
25
+ else if (filter.type === 'interval') {
26
+ let minValue;
27
+ let maxValue;
28
+ for (const currentFilterId of currentFiltersId) {
29
+ const currentFilter = state[filter.property].find(property => property.id === currentFilterId);
30
+ if (isNaN(minValue) || currentFilter.minValue < minValue) {
31
+ minValue = currentFilter.minValue;
32
+ }
33
+ if (isNaN(maxValue) || currentFilter.maxValue > maxValue) {
34
+ maxValue = currentFilter.maxValue;
35
+ }
36
+ }
37
+ filtersTreks = [...filtersTreks.filter(trek => trek[filter.trekProperty] >= minValue && trek[filter.trekProperty] <= maxValue)];
38
+ }
39
+ }
40
+ else {
41
+ if (!isUsingFilter) {
42
+ isUsingFilter = true;
43
+ }
44
+ if (filter.type === 'include') {
45
+ filtersTreks = [...state.treks.filter(trek => currentFiltersId.includes(trek[filter.trekProperty]))];
46
+ }
47
+ else if (filter.type === 'interval') {
48
+ let minValue;
49
+ let maxValue;
50
+ for (const currentFilterId of currentFiltersId) {
51
+ const currentFilter = state[filter.property].find(property => property.id === currentFilterId);
52
+ if (isNaN(minValue) || currentFilter.minValue < minValue) {
53
+ minValue = currentFilter.minValue;
54
+ }
55
+ if (isNaN(maxValue) || currentFilter.maxValue > maxValue) {
56
+ maxValue = currentFilter.maxValue;
57
+ }
58
+ }
59
+ filtersTreks = [...state.treks.filter(trek => trek[filter.trekProperty] >= minValue && trek[filter.trekProperty] <= maxValue)];
60
+ }
61
+ }
62
+ }
63
+ }
64
+ state.currentTreks = isUsingFilter ? filtersTreks : state.treks;
65
+ }
66
+ render() {
67
+ return (h(Host, null,
68
+ h("div", { class: "filter-name" }, this.filterName),
69
+ h("div", { class: "filter-button-container" }, state[this.filterType].map(currentFilter => (h("div", { onClick: event => this.handleFilter(event, currentFilter), class: currentFilter.selected ? 'selected-filter-button' : 'filter-button' }, currentFilter[this.filterNameProperty]))))));
70
+ }
71
+ static get is() { return "grw-filter"; }
72
+ static get encapsulation() { return "shadow"; }
73
+ static get originalStyleUrls() { return {
74
+ "$": ["grw-filter.scss"]
75
+ }; }
76
+ static get styleUrls() { return {
77
+ "$": ["grw-filter.css"]
78
+ }; }
79
+ static get properties() { return {
80
+ "filterType": {
81
+ "type": "string",
82
+ "mutable": false,
83
+ "complexType": {
84
+ "original": "string",
85
+ "resolved": "string",
86
+ "references": {}
87
+ },
88
+ "required": false,
89
+ "optional": false,
90
+ "docs": {
91
+ "tags": [],
92
+ "text": ""
93
+ },
94
+ "attribute": "filter-type",
95
+ "reflect": false
96
+ },
97
+ "filterName": {
98
+ "type": "string",
99
+ "mutable": false,
100
+ "complexType": {
101
+ "original": "string",
102
+ "resolved": "string",
103
+ "references": {}
104
+ },
105
+ "required": false,
106
+ "optional": false,
107
+ "docs": {
108
+ "tags": [],
109
+ "text": ""
110
+ },
111
+ "attribute": "filter-name",
112
+ "reflect": false
113
+ },
114
+ "filterNameProperty": {
115
+ "type": "string",
116
+ "mutable": false,
117
+ "complexType": {
118
+ "original": "string",
119
+ "resolved": "string",
120
+ "references": {}
121
+ },
122
+ "required": false,
123
+ "optional": false,
124
+ "docs": {
125
+ "tags": [],
126
+ "text": ""
127
+ },
128
+ "attribute": "filter-name-property",
129
+ "reflect": false
130
+ }
131
+ }; }
132
+ }
@@ -1,7 +1,9 @@
1
1
  :host {
2
2
  display: flex;
3
3
  flex-direction: column;
4
- padding: 0px 8px 8px 8px;
4
+ }
5
+ :host a {
6
+ color: var(--color-primary);
5
7
  }
6
8
 
7
9
  .information-desk-img {
@@ -12,17 +14,16 @@
12
14
  border-radius: 8px;
13
15
  }
14
16
 
15
- .information-desk-right-container {
17
+ .information-desk-sub-container {
16
18
  display: flex;
17
19
  flex-direction: column;
18
- padding: 8px;
19
20
  }
20
21
 
21
22
  .information-desk-name {
22
23
  color: var(--color-primary);
23
24
  font-size: 24px;
24
25
  font-weight: bold;
25
- padding: 0px 0px 8px 0px;
26
+ padding: 12px 0px;
26
27
  }
27
28
 
28
29
  .information-desk-description {
@@ -4,7 +4,7 @@ export class GrwInformationDeskDetail {
4
4
  return (h(Host, null,
5
5
  this.informationDesk.photo_url && (h("div", { class: "information-desk-img" },
6
6
  h("img", { src: this.informationDesk.photo_url, loading: "lazy" }))),
7
- h("div", { class: "information-desk-right-container" },
7
+ h("div", { class: "information-desk-sub-container" },
8
8
  this.informationDesk.name && h("div", { class: "information-desk-name" }, this.informationDesk.name),
9
9
  this.informationDesk.description && h("div", { class: "information-desk-description", innerHTML: this.informationDesk.description }),
10
10
  this.informationDesk.postal_code ||
@@ -750,8 +750,13 @@ grw-map {
750
750
 
751
751
  .poi-tooltip .poi-name,
752
752
  .poi-tooltip .information-desks-name,
753
+ .poi-tooltip .sensitive-area-name,
753
754
  .information-desks-tooltip .poi-name,
754
- .information-desks-tooltip .information-desks-name {
755
+ .information-desks-tooltip .information-desks-name,
756
+ .information-desks-tooltip .sensitive-area-name,
757
+ .sensitive-area-tooltip .poi-name,
758
+ .sensitive-area-tooltip .information-desks-name,
759
+ .sensitive-area-tooltip .sensitive-area-name {
755
760
  color: var(--color-primary);
756
761
  font-weight: bold;
757
762
  font-size: 12px;
@@ -800,4 +805,17 @@ grw-map {
800
805
  height: 48px;
801
806
  font-size: 24px;
802
807
  color: #ffffff;
808
+ }
809
+
810
+ .point-reference-icon {
811
+ background-color: #ff0000;
812
+ border: 1px solid #ffffff;
813
+ border-radius: 50%;
814
+ display: flex;
815
+ justify-content: center;
816
+ align-items: center;
817
+ width: 24px;
818
+ height: 24px;
819
+ font-size: 18px;
820
+ color: #ffffff;
803
821
  }
@@ -14,6 +14,7 @@ export class GrwMap {
14
14
  this.colorArrivalIcon = '#85003b';
15
15
  this.colorSensitiveArea = ' #4974a5';
16
16
  this.colorPoiIcon = '#974c6e';
17
+ this.handleTreksWithinBoundsBind = this.handleTreksWithinBounds.bind(this);
17
18
  }
18
19
  componentDidLoad() {
19
20
  this.map = L.map(this.element, {
@@ -31,11 +32,11 @@ export class GrwMap {
31
32
  else if (state.currentTrek) {
32
33
  this.addTreks();
33
34
  }
34
- onChange('treks', () => {
35
+ onChange('currentTreks', () => {
35
36
  if (state.currentTrek) {
36
37
  this.addTrek();
37
38
  }
38
- else if (state.treks) {
39
+ else if (state.currentTreks) {
39
40
  this.addTreks();
40
41
  }
41
42
  });
@@ -57,7 +58,7 @@ export class GrwMap {
57
58
  type: 'FeatureCollection',
58
59
  features: [],
59
60
  };
60
- for (const trek of state.treks) {
61
+ for (const trek of state.currentTreks) {
61
62
  trekscurrentDepartureCoordinates.push(trek.departure_geom);
62
63
  treksFeatureCollection.features.push({
63
64
  type: 'Feature',
@@ -66,51 +67,69 @@ export class GrwMap {
66
67
  id: trek.id,
67
68
  name: trek.name,
68
69
  practice: (_a = state.practices.find(practice => practice.id === trek.practice)) === null || _a === void 0 ? void 0 : _a.pictogram,
69
- imgSrc: trek.attachments && trek.attachments.length > 0 && trek.attachments[0].url,
70
+ imgSrc: trek.attachments && trek.attachments.length > 0 && trek.attachments[0].thumbnail,
70
71
  },
71
72
  });
72
73
  }
73
- if (trekscurrentDepartureCoordinates.length > 0) {
74
- const bounds = L.latLngBounds(trekscurrentDepartureCoordinates.map(coordinate => [coordinate[1], coordinate[0]]));
75
- this.currentBounds = bounds;
76
- this.map.fitBounds(this.currentBounds);
77
- }
78
- this.treksLayer = L.geoJSON(treksFeatureCollection, {
79
- pointToLayer: (geoJsonPoint, latlng) => L.marker(latlng, {
80
- icon: L.divIcon({
81
- html: geoJsonPoint.properties.practice && `<img src=${geoJsonPoint.properties.practice} />`,
82
- className: 'trek-marker',
83
- iconSize: 48,
74
+ if (!this.treksLayer) {
75
+ if (trekscurrentDepartureCoordinates.length > 0 && !state.currentMapTreksBounds) {
76
+ const bounds = L.latLngBounds(trekscurrentDepartureCoordinates.map(coordinate => [coordinate[1], coordinate[0]]));
77
+ this.map.fitBounds(bounds);
78
+ }
79
+ else {
80
+ this.map.fitBounds(state.currentMapTreksBounds);
81
+ }
82
+ this.treksLayer = L.geoJSON(treksFeatureCollection, {
83
+ pointToLayer: (geoJsonPoint, latlng) => L.marker(latlng, {
84
+ icon: L.divIcon({
85
+ html: geoJsonPoint.properties.practice ? `<img src=${geoJsonPoint.properties.practice} />` : `<img />`,
86
+ className: 'trek-marker',
87
+ iconSize: 48,
88
+ }),
89
+ autoPanOnFocus: false,
84
90
  }),
85
- autoPanOnFocus: false,
86
- }),
87
- onEachFeature: (geoJsonPoint, layer) => {
88
- layer.once('click', () => {
89
- const trekDeparturePopup = L.DomUtil.create('div');
90
- trekDeparturePopup.className = 'trek-departure-popup';
91
- trekDeparturePopup.onclick = () => this.trekCardPress.emit(geoJsonPoint.properties.id);
92
- const trekName = L.DomUtil.create('div');
93
- trekName.innerHTML = geoJsonPoint.properties.name;
94
- trekName.className = 'trek-name';
95
- if (geoJsonPoint.properties.imgSrc) {
96
- trekName.className += ' trek-name-margin-top';
97
- const trekImg = L.DomUtil.create('img');
98
- trekImg.src = geoJsonPoint.properties.imgSrc;
99
- trekDeparturePopup.appendChild(trekImg);
100
- }
101
- trekDeparturePopup.appendChild(trekName);
102
- layer.bindPopup(trekDeparturePopup, { interactive: true, autoPan: false, closeButton: false }).openPopup();
103
- });
104
- },
105
- }).addTo(this.map);
91
+ onEachFeature: (geoJsonPoint, layer) => {
92
+ layer.once('click', () => {
93
+ const trekDeparturePopup = L.DomUtil.create('div');
94
+ trekDeparturePopup.className = 'trek-departure-popup';
95
+ trekDeparturePopup.onclick = () => this.trekCardPress.emit(geoJsonPoint.properties.id);
96
+ const trekName = L.DomUtil.create('div');
97
+ trekName.innerHTML = geoJsonPoint.properties.name;
98
+ trekName.className = 'trek-name';
99
+ if (geoJsonPoint.properties.imgSrc) {
100
+ trekName.className += ' trek-name-margin-top';
101
+ const trekImg = L.DomUtil.create('img');
102
+ trekImg.src = geoJsonPoint.properties.imgSrc;
103
+ trekDeparturePopup.appendChild(trekImg);
104
+ }
105
+ trekDeparturePopup.appendChild(trekName);
106
+ layer.bindPopup(trekDeparturePopup, { interactive: true, autoPan: false, closeButton: false }).openPopup();
107
+ });
108
+ },
109
+ }).addTo(this.map);
110
+ }
111
+ else {
112
+ if (trekscurrentDepartureCoordinates.length > 0) {
113
+ const bounds = L.latLngBounds(trekscurrentDepartureCoordinates.map(coordinate => [coordinate[1], coordinate[0]]));
114
+ this.map.fitBounds(bounds);
115
+ }
116
+ this.treksLayer.clearLayers();
117
+ this.treksLayer.addData(treksFeatureCollection);
118
+ }
106
119
  !this.mapIsReady && (this.mapIsReady = !this.mapIsReady);
120
+ this.map.on('moveend', this.handleTreksWithinBoundsBind);
107
121
  }
108
122
  removeTreks() {
109
123
  if (this.treksLayer) {
124
+ state.currentMapTreksBounds = this.map.getBounds();
110
125
  this.map.removeLayer(this.treksLayer);
111
126
  this.treksLayer = null;
127
+ this.map.off('moveend', this.handleTreksWithinBoundsBind);
112
128
  }
113
129
  }
130
+ handleTreksWithinBounds() {
131
+ state.treksWithinBounds = state.currentTreks.filter(trek => this.map.getBounds().contains(L.latLng(trek.departure_geom[1], trek.departure_geom[0])));
132
+ }
114
133
  addTrek() {
115
134
  const currentTrekFeature = {
116
135
  type: 'Feature',
@@ -124,8 +143,7 @@ export class GrwMap {
124
143
  interactive: false,
125
144
  }).addTo(this.map);
126
145
  const bounds = L.latLngBounds(state.currentTrek.geometry.coordinates.map(coordinate => [coordinate[1], coordinate[0]]));
127
- this.currentBounds = bounds;
128
- this.map.fitBounds(this.currentBounds);
146
+ this.map.fitBounds(bounds);
129
147
  const currentDepartureCoordinates = [state.currentTrek.geometry.coordinates.at(0)[0], state.currentTrek.geometry.coordinates.at(0)[1]];
130
148
  const currentArrivalCoordinates = [state.currentTrek.geometry.coordinates.at(-1)[0], state.currentTrek.geometry.coordinates.at(-1)[1]];
131
149
  const currentDepartureArrivalFeatureCollection = {
@@ -184,11 +202,24 @@ export class GrwMap {
184
202
  for (const sensitiveArea of state.currentSensitiveAreas) {
185
203
  currentSensitiveAreasFeatureCollection.features.push({
186
204
  type: 'Feature',
187
- properties: {},
205
+ properties: { name: sensitiveArea.name },
188
206
  geometry: sensitiveArea.geometry,
189
207
  });
190
208
  }
191
- this.currentSensitiveAreasLayer = L.geoJSON(currentSensitiveAreasFeatureCollection, { style: () => ({ color: this.colorSensitiveArea }) }).addTo(this.map);
209
+ this.currentSensitiveAreasLayer = L.geoJSON(currentSensitiveAreasFeatureCollection, {
210
+ onEachFeature: (geoJsonPoint, layer) => {
211
+ layer.once('mouseover', () => {
212
+ const sensitiveAreaTooltip = L.DomUtil.create('div');
213
+ sensitiveAreaTooltip.className = 'sensitive-area-tooltip';
214
+ const sensitiveAreaName = L.DomUtil.create('div');
215
+ sensitiveAreaName.innerHTML = geoJsonPoint.properties.name;
216
+ sensitiveAreaName.className = 'sensitive-area-name';
217
+ sensitiveAreaTooltip.appendChild(sensitiveAreaName);
218
+ layer.bindTooltip(sensitiveAreaTooltip).openTooltip();
219
+ });
220
+ },
221
+ style: () => ({ color: this.colorSensitiveArea }),
222
+ }).addTo(this.map);
192
223
  L.Control.SensitiveAreasCheckboxContainer = L.Control.extend({
193
224
  onAdd: () => {
194
225
  const sensitiveAreasCheckboxContainer = L.DomUtil.create('div');
@@ -282,6 +313,32 @@ export class GrwMap {
282
313
  },
283
314
  }).addTo(this.map);
284
315
  }
316
+ if (state.currentTrek.points_reference) {
317
+ const currentPointsReferenceFeatureCollection = {
318
+ type: 'FeatureCollection',
319
+ features: [],
320
+ };
321
+ currentPointsReferenceFeatureCollection.features.push({
322
+ type: 'Feature',
323
+ properties: {},
324
+ geometry: state.currentTrek.points_reference,
325
+ });
326
+ let index = 0;
327
+ this.currentPointsReferenceLayer = L.geoJSON(currentPointsReferenceFeatureCollection, {
328
+ pointToLayer: (_geoJsonPoint, latlng) => {
329
+ index += 1;
330
+ return L.marker(latlng, {
331
+ icon: L.divIcon({
332
+ html: index,
333
+ className: 'point-reference-icon',
334
+ iconSize: 24,
335
+ }),
336
+ autoPanOnFocus: false,
337
+ interactive: false,
338
+ });
339
+ },
340
+ }).addTo(this.map);
341
+ }
285
342
  !this.mapIsReady && (this.mapIsReady = !this.mapIsReady);
286
343
  }
287
344
  removeTrek() {
@@ -311,6 +368,10 @@ export class GrwMap {
311
368
  this.map.removeLayer(this.currentInformationDesksLayer);
312
369
  this.currentInformationDesksLayer = null;
313
370
  }
371
+ if (this.currentPointsReferenceLayer) {
372
+ this.map.removeLayer(this.currentPointsReferenceLayer);
373
+ this.currentPointsReferenceLayer = null;
374
+ }
314
375
  }
315
376
  render() {
316
377
  return (h(Host, { style: {
@@ -1,7 +1,9 @@
1
1
  :host {
2
2
  display: flex;
3
3
  flex-direction: column;
4
- padding: 0px 8px 8px 8px;
4
+ }
5
+ :host a {
6
+ color: var(--color-primary);
5
7
  }
6
8
 
7
9
  .poi-img {
@@ -12,17 +14,16 @@
12
14
  border-radius: 8px;
13
15
  }
14
16
 
15
- .poi-right-container {
17
+ .poi-sub-container {
16
18
  display: flex;
17
19
  flex-direction: column;
18
- padding: 8px;
19
20
  }
20
21
 
21
22
  .poi-name {
22
23
  color: var(--color-primary);
23
24
  font-size: 24px;
24
25
  font-weight: bold;
25
- padding: 0px 0px 8px 0px;
26
+ padding: 12px 0px;
26
27
  }
27
28
 
28
29
  .poi-description {
@@ -4,7 +4,7 @@ export class GrwPoiDetail {
4
4
  return (h(Host, null,
5
5
  this.poi.attachments && this.poi.attachments[0] && this.poi.attachments[0].thumbnail && (h("div", { class: "poi-img" },
6
6
  h("img", { src: this.poi.attachments[0].thumbnail, loading: "lazy" }))),
7
- h("div", { class: "poi-right-container" },
7
+ h("div", { class: "poi-sub-container" },
8
8
  h("div", { class: "poi-name" }, this.poi.name),
9
9
  h("div", { class: "poi-description", innerHTML: this.poi.description }))));
10
10
  }