diff --git a/.github/workflows/kaban.yml b/.github/workflows/kaban.yml
index e5a13cb7..bc805954 100644
--- a/.github/workflows/kaban.yml
+++ b/.github/workflows/kaban.yml
@@ -17,4 +17,4 @@ jobs:
uses: srggrs/assign-one-project-github-action@1.2.1
if: github.event.action == 'opened'
with:
- project: "https://github.com/12rambau/sepal_ui/projects/4"
+ project: "https://github.com/12rambau/sepal_ui/projects/5"
diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml
index d7e9d8cf..5b3a0b12 100644
--- a/.github/workflows/unit.yml
+++ b/.github/workflows/unit.yml
@@ -9,7 +9,9 @@ on:
env:
PLANET_API_CREDENTIALS: ${{ secrets.PLANET_API_CREDENTIALS }}
PLANET_API_KEY: ${{ secrets.PLANET_API_KEY }}
- EARTHENGINE_TOKEN: ${{ secrets.EARTHENGINE_TOKEN }}
+ EARTHENGINE_TOKEN: ${{ secrets.EARTHENGINE_SERVICE_ACCOUNT }}
+ EARTHENGINE_SERVICE_ACCOUNT: ${{ secrets.EARTHENGINE_SERVICE_ACCOUNT }}
+ EARTHENGINE_PROJECT: ${{ secrets.EARTHENGINE_PROJECT }}
jobs:
lint:
diff --git a/sepal_ui/frontend/css/custom.css b/sepal_ui/frontend/css/custom.css
index 4da5c3df..6dbda56f 100644
--- a/sepal_ui/frontend/css/custom.css
+++ b/sepal_ui/frontend/css/custom.css
@@ -112,3 +112,12 @@ nav.v-navigation-drawer {
contain: revert !important;
background-color: revert !important;
}
+
+.full-screen-map > .leaflet-container {
+ position: fixed !important;
+ width: 100vw;
+ height: calc(100vh - 48px);
+ z-index: 800;
+ bottom: 0;
+ left: 0;
+}
diff --git a/sepal_ui/frontend/js/jupyter_embed.js b/sepal_ui/frontend/js/jupyter_embed.js
deleted file mode 100644
index 15e83ea1..00000000
--- a/sepal_ui/frontend/js/jupyter_embed.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/* set a selected map to embed mode (i.e. default display) */
-var i = 0;
-const wait_unitl_element_appear = setInterval(() => {
- var element = document.querySelector(".%s .leaflet-container");
- if (element != null) {
- element.style.position = "";
- element.style.width = "";
- element.style.height = "";
- element.style.zIndex = "";
- element.style.bottom = "";
- element.style.left = "";
- window.dispatchEvent(new Event("resize"));
- clearInterval(wait_unitl_element_appear);
- } else if (i > 50) {
- clearInterval(wait_unitl_element_appear);
- console.log("cannot find the map element");
- } else {
- i++;
- }
-}, 100);
diff --git a/sepal_ui/frontend/js/jupyter_fullscreen.js b/sepal_ui/frontend/js/jupyter_fullscreen.js
deleted file mode 100644
index 1a22651c..00000000
--- a/sepal_ui/frontend/js/jupyter_fullscreen.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/* set a selected map to fullscreen */
-var i = 0;
-const wait_unitl_element_appear = setInterval(() => {
- var element = document.querySelector(".%s .leaflet-container");
- if (element != null) {
- element.style.position = "fixed";
- element.style.width = "100vw";
- element.style.height = "calc(100vh - %s)";
- element.style.zIndex = 800;
- element.style.bottom = 0;
- element.style.left = 0;
- window.dispatchEvent(new Event("resize"));
- clearInterval(wait_unitl_element_appear);
- } else if (i > 50) {
- clearInterval(wait_unitl_element_appear);
- console.log("cannot find the map element");
- } else {
- i++;
- }
-}, 100);
diff --git a/sepal_ui/mapping/fullscreen_control.py b/sepal_ui/mapping/fullscreen_control.py
index 2c4ff28a..80020418 100644
--- a/sepal_ui/mapping/fullscreen_control.py
+++ b/sepal_ui/mapping/fullscreen_control.py
@@ -1,12 +1,11 @@
"""Customized control to toggle the fullscreen state of the map."""
-from pathlib import Path
from typing import List, Optional
import ipyvuetify as v
from ipyleaflet import Map, WidgetControl
-from IPython.display import Javascript, display
+from sepal_ui.frontend.resize_trigger import rt
from sepal_ui.mapping.map_btn import MapBtn
@@ -43,11 +42,9 @@ def __init__(
fullapp: either or not the map will be used as the sole widget/tile of an application
kwargs: any available arguments from a ipyleaflet WidgetControl
"""
- # set the offset
- offset = "48px" if fullapp else "0px"
-
# register the required zoom value
self.zoomed = fullscreen
+ self.m = m
# create a btn
self.w_btn = MapBtn(self.ICONS[self.zoomed])
@@ -63,41 +60,10 @@ def __init__(
# add javascrip behaviour
self.w_btn.on_event("click", self.toggle_fullscreen)
- # save the 2 fullscrenn js code in a table 0 for embedded and 1 for fullscreen
- js_dir = Path(__file__).parents[1] / "frontend/js"
- embed = (js_dir / "jupyter_embed.js").read_text() % m._id
- full = (js_dir / "jupyter_fullscreen.js").read_text() % (m._id, offset)
-
- # template with js behaviour
- # "jupyter_fullscreen" place the "leaflet-container element on the front screen
- # and expand it's display to the full screen
- # "jupyter_embed" reset all the changed parameter
- # both trigger the resize event to force the reload of the Tilelayers
-
- default = "fullscreen" if self.zoomed else "embed"
-
- self.template = v.VuetifyTemplate(
- template=f"""
-
-
- """
- )
- display(self.template)
+ if fullapp:
+ self.m.add_class("full-screen-map")
+ else:
+ self.m.remove_class("full-screen-map")
def toggle_fullscreen(self, *args) -> None:
"""Toggle fullscreen state.
@@ -111,7 +77,11 @@ def toggle_fullscreen(self, *args) -> None:
# change button icon
self.w_btn.children[0].children = [self.ICONS[self.zoomed]]
- # zoom
- self.template.send({"method": self.METHODS[self.zoomed], "args": []})
+ if self.zoomed:
+ self.m.add_class("full-screen-map")
+ else:
+ self.m.remove_class("full-screen-map")
+
+ rt.resize()
return
diff --git a/sepal_ui/mapping/sepal_map.py b/sepal_ui/mapping/sepal_map.py
index 7ff2d770..32052571 100644
--- a/sepal_ui/mapping/sepal_map.py
+++ b/sepal_ui/mapping/sepal_map.py
@@ -3,6 +3,8 @@
# known bug of rasterio
import os
+from sepal_ui.mapping.fullscreen_control import FullScreenControl
+
if "GDAL_DATA" in list(os.environ.keys()):
del os.environ["GDAL_DATA"]
if "PROJ_LIB" in list(os.environ.keys()):
@@ -130,6 +132,9 @@ def __init__(
self.add(ipl.AttributionControl(position="bottomleft", prefix="SEPAL"))
self.add(ipl.ScaleControl(position="bottomleft", imperial=False))
+ if kwargs.get("fullscreen_control", False):
+ self.add(FullScreenControl(self))
+
# specific drawing control
self.dc = DrawControl(self)
not dc or self.add(self.dc)
diff --git a/sepal_ui/scripts/decorator.py b/sepal_ui/scripts/decorator.py
index 10458eb4..98de3b84 100644
--- a/sepal_ui/scripts/decorator.py
+++ b/sepal_ui/scripts/decorator.py
@@ -59,18 +59,24 @@ def init_ee() -> None:
# Extract the project name from credentials
_credentials = json.loads(credential_file_path.read_text())
- project_id = os.environ.get(
- "EARTHENGINE_PROJECT",
- _credentials.get("project_id", _credentials.get("project", None)),
- )
+ project_id = _credentials.get("project_id", _credentials.get("project", None))
if not project_id:
raise NameError(
"The project name cannot be detected. "
- "Please set the EARTHENGINE_PROJECT environment variable. "
- "Or authenticate using `earthengine set_project project_name`."
+ "Please set it using `earthengine set_project project_name`."
)
+ # Check if we are using a google service account
+ if _credentials.get("type") == "service_account":
+ ee_user = _credentials.get("client_email")
+ credentials = ee.ServiceAccountCredentials(
+ ee_user, str(credential_file_path)
+ )
+ ee.Initialize(credentials=credentials)
+ ee.data._cloud_api_user_project = project_id
+ return
+
# if the user is in local development the authentication should
# already be available
ee.Initialize(project=project_id)
diff --git a/sepal_ui/scripts/utils.py b/sepal_ui/scripts/utils.py
index b32bd894..d59e62f4 100644
--- a/sepal_ui/scripts/utils.py
+++ b/sepal_ui/scripts/utils.py
@@ -140,7 +140,6 @@ def init_ee() -> None:
As all init method of pytest-gee, this method will fallback to a regular ``ee.Initialize()`` if the environment variable is not found e.g. on your local computer.
"""
if not ee.data._credentials:
- print("initializing earth engine")
credential_folder_path = Path.home() / ".config" / "earthengine"
credential_file_path = credential_folder_path / "credentials"
@@ -153,17 +152,23 @@ def init_ee() -> None:
# Extract the project name from credentials
_credentials = json.loads(credential_file_path.read_text())
- project_id = os.environ.get(
- "EARTHENGINE_PROJECT",
- _credentials.get("project_id", _credentials.get("project", None)),
- )
+ project_id = _credentials.get("project_id", _credentials.get("project", None))
if not project_id:
raise NameError(
"The project name cannot be detected. "
- "Please set the EARTHENGINE_PROJECT environment variable. "
- "Or authenticate using `earthengine set_project project_name`."
+ "Please set it using `earthengine set_project project_name`."
+ )
+
+ # Check if we are using a google service account
+ if _credentials.get("type") == "service_account":
+ ee_user = _credentials.get("client_email")
+ credentials = ee.ServiceAccountCredentials(
+ ee_user, str(credential_file_path)
)
+ ee.Initialize(credentials=credentials)
+ ee.data._cloud_api_user_project = project_id
+ return
# if the user is in local development the authentication should
# already be available
diff --git a/tests/test_scripts/test_decorator.py b/tests/test_scripts/test_decorator.py
index f48519bd..1ca0f432 100644
--- a/tests/test_scripts/test_decorator.py
+++ b/tests/test_scripts/test_decorator.py
@@ -43,6 +43,7 @@ def test_init_ee() -> None:
## 2. Assert when there's no a project associated
# remove the project_id key if it exists
+ ee.data._credentials = None
credentials.pop("project_id", None)
credentials.pop("project", None)
if "EARTHENGINE_PROJECT" in os.environ:
diff --git a/tests/test_scripts/test_utils.py b/tests/test_scripts/test_utils.py
index abecbdee..33cdd646 100644
--- a/tests/test_scripts/test_utils.py
+++ b/tests/test_scripts/test_utils.py
@@ -137,6 +137,7 @@ def test_init_ee() -> None:
## 2. Assert when there's no a project associated
# remove the project_id key if it exists
+ ee.data._credentials = None
credentials.pop("project_id", None)
credentials.pop("project", None)
if "EARTHENGINE_PROJECT" in os.environ: