summaryrefslogtreecommitdiff
path: root/ab_openstreetmap/static/src/js/googlemap_widget.js
blob: 2c639bc3ddc56aca28117f122a20b1abc240790e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
odoo.define("ab_openstreetmap.googlemap_widget", function (require) {
  "use strict";

  const AbstractField = require("web.AbstractField");
  const fieldRegistry = require("web.field_registry");
  const rpc = require("web.rpc");

  const GoogleMapWidget = AbstractField.extend({
    template: "googlemap_template",

    start: async function () {
      await this._super(...arguments);

      const apiKey = await rpc.query({
        model: "ir.config_parameter",
        method: "get_param",
        args: ["google.maps.api_key"],
      });

      this._waitForMapReady(apiKey);
    },

    _waitForMapReady(apiKey) {
      const checkReady = () => {
        const el = document.getElementById("mapid");
        if (el && el.offsetHeight > 0 && el.offsetWidth > 0) {
          this._loadGoogleMaps(apiKey);
        } else {
          setTimeout(checkReady, 150);
        }
      };
      checkReady();
    },

    _loadGoogleMaps(apiKey) {
      if (!window.google || !window.google.maps) {
        const script = document.createElement("script");
        script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=marker`;
        script.async = true;
        script.defer = true;
        script.onload = this._initMap.bind(this);
        document.head.appendChild(script);
      } else {
        this._initMap();
      }
    },

    _initMap() {
      const lat = parseFloat(this.recordData.latitude) || -6.2;
      const lng = parseFloat(this.recordData.longtitude) || 106.816666;
      const isEditable = this.mode === "edit";

      const map = new google.maps.Map(document.getElementById("mapid"), {
        center: { lat, lng },
        zoom: 15,
      });

      // Use AdvancedMarkerElement if available
      if (google.maps.marker && google.maps.marker.AdvancedMarkerElement) {
        const { AdvancedMarkerElement } = google.maps.marker;

        const marker = new AdvancedMarkerElement({
          position: { lat, lng },
          map: map,
          gmpDraggable: isEditable,
        });

        if (isEditable) {
          marker.addListener("dragend", (e) => {
            const newLat = e.latLng.lat();
            const newLng = e.latLng.lng();
            this._saveCoords(newLat, newLng);
          });
        }
      } else {
        const marker = new google.maps.Marker({
          position: { lat, lng },
          map: map,
          draggable: isEditable,
        });

        if (isEditable) {
          marker.addListener("dragend", (e) => {
            const newLat = e.latLng.lat();
            const newLng = e.latLng.lng();
            this._saveCoords(newLat, newLng);
          });
        }
      }

      // Handle resize if tab is hidden initially
      setTimeout(() => {
        google.maps.event.trigger(map, "resize");
        map.setCenter({ lat, lng });
      }, 500);
    },

    _saveCoords(lat, lng) {
      this.trigger_up("field_changed", {
        dataPointID: this.dataPointID,
        changes: {
          latitude: lat.toString(),
          longtitude: lng.toString(),
        },
        viewType: this.viewType,
      });
    },

    isSet() {
      return true;
    },
  });

  fieldRegistry.add("googlemap", GoogleMapWidget);
});