diff --git a/src/Ecotag/ClientApp/public/environment.azure.json b/src/Ecotag/ClientApp/public/environment.azure.json
index cd35fda1..6a205678 100644
--- a/src/Ecotag/ClientApp/public/environment.azure.json
+++ b/src/Ecotag/ClientApp/public/environment.azure.json
@@ -1,6 +1,7 @@
{
"apiUrl": "https://axaguildev-ecotag.azurewebsites.net/api/server/{path}",
"baseUrl": "",
+ "slimfaasBaseUrl": "",
"oidc": {
"mode": "Default",
"configuration": {
diff --git a/src/Ecotag/ClientApp/public/environment.desktop.json b/src/Ecotag/ClientApp/public/environment.desktop.json
index 977da1ed..8e4ea4f9 100644
--- a/src/Ecotag/ClientApp/public/environment.desktop.json
+++ b/src/Ecotag/ClientApp/public/environment.desktop.json
@@ -1,6 +1,7 @@
{
"apiUrl": "https://localhost:5001/api/server/{path}",
"baseUrl": "",
+ "slimfaasBaseUrl": "",
"oidc": {
"mode": "Default",
"configuration": {
diff --git a/src/Ecotag/ClientApp/public/environment.dev.json b/src/Ecotag/ClientApp/public/environment.dev.json
index 87af94f8..28f1f9d9 100644
--- a/src/Ecotag/ClientApp/public/environment.dev.json
+++ b/src/Ecotag/ClientApp/public/environment.dev.json
@@ -1,6 +1,7 @@
{
"apiUrl": "https://localhost:5001/api/server/{path}",
"baseUrl": "",
+ "slimfaasBaseUrl": "",
"oidc": {
"mode": "Default",
"configuration": {
diff --git a/src/Ecotag/ClientApp/public/environment.docker.json b/src/Ecotag/ClientApp/public/environment.docker.json
index 940f6db3..842acc2a 100644
--- a/src/Ecotag/ClientApp/public/environment.docker.json
+++ b/src/Ecotag/ClientApp/public/environment.docker.json
@@ -1,6 +1,7 @@
{
"apiUrl": "http://localhost:5010/api/server/{path}",
"baseUrl": "",
+ "slimfaasBaseUrl": "",
"oidc": {
"mode": "Default",
"configuration": {
diff --git a/src/Ecotag/ClientApp/public/environment.json b/src/Ecotag/ClientApp/public/environment.json
index 1118bcf0..5c60c2f5 100644
--- a/src/Ecotag/ClientApp/public/environment.json
+++ b/src/Ecotag/ClientApp/public/environment.json
@@ -1,6 +1,7 @@
{
"apiUrl": "#{Spa:ApiUrl}#",
"baseUrl": "#{Spa:BaseUrl}#",
+ "slimfaasBaseUrl": "#{Spa:SlimfaasUrl}#",
"oidc": {
"mode": "#{Spa:Oidc:Mode}#",
"configuration": {
diff --git a/src/Ecotag/ClientApp/src/Server/App.js b/src/Ecotag/ClientApp/src/Server/App.js
index 6cdf3f30..22d67fcd 100644
--- a/src/Ecotag/ClientApp/src/Server/App.js
+++ b/src/Ecotag/ClientApp/src/Server/App.js
@@ -16,6 +16,7 @@ import {CallBackSuccess} from "./shared/Oidc/Callback.component";
import AccessToken from "./AccessToken";
import {useHistory} from "react-router";
import {OidcProvider, OidcSecure} from "@axa-fr/react-oidc";
+import PlanetSaver from "./PlanetSaver";
const AppWithOidcProvider = withEnvironment(({environment}) => {
@@ -41,14 +42,30 @@ const AppWithOidcProvider = withEnvironment(({environment}) => {
>
-
-
-
+
});
+const Page = () => (
+ <>
+
+
+
+ >
+);
+
+const SlimFaasSwitch = ({environment}) => {
+ const slimfaasBaseUrl= environment.slimfaasBaseUrl
+ if(slimfaasBaseUrl) {
+ return
+
+
+ }
+ return
+}
+
const Authentification = ({environment}) => (
@@ -63,6 +80,9 @@ const Authentification = ({environment}) => (
);
+
+
+
const AuthentificationWithEnvironment = withEnvironment(Authentification);
const App = () => (
diff --git a/src/Ecotag/ClientApp/src/Server/PlanetSaver.jsx b/src/Ecotag/ClientApp/src/Server/PlanetSaver.jsx
new file mode 100644
index 00000000..b6ce8c11
--- /dev/null
+++ b/src/Ecotag/ClientApp/src/Server/PlanetSaver.jsx
@@ -0,0 +1,42 @@
+import React, { useState, useEffect } from 'react';
+import BaseUrlContext from './BaseUrlContext';
+import SlimFaasPlanetSaver from "./SlimFaasPlanetSaver.js";
+
+const PlanetSaver = ({ children, baseUrl }) => {
+ const [isFirstStart, setIsFirstStart] = useState(true); // État pour le premier démarrage
+
+ useEffect(() => {
+ if (!baseUrl) return;
+
+ const environmentStarter = new SlimFaasPlanetSaver(baseUrl, {
+ updateCallback: (data) => {
+ const allReady = data.every((item) => item.NumberReady >= 1);
+ if (allReady && isFirstStart) {
+ setIsFirstStart(false);
+ }
+ },
+ errorCallback: (error) => {
+ console.error('Erreur détectée :', error);
+ environmentStarter.updateOverlayMessage('An error occured when starting environment. Please contact an administrator.');
+ },
+ overlayMessage: 'Starting the environment...',
+ });
+
+ // Démarrage de la surveillance
+ environmentStarter.startPolling();
+
+ // Nettoyage lors du démontage
+ return () => environmentStarter.cleanup();
+ }, [baseUrl, isFirstStart]);
+
+ // Pendant le premier démarrage, rien n'est affiché
+ if (isFirstStart) {
+ return null;
+ }
+
+ // Une fois le premier démarrage terminé, afficher les enfants
+ return <>{children}>;
+
+};
+
+export default PlanetSaver;
diff --git a/src/Ecotag/ClientApp/src/Server/SlimFaasPlanetSaver.js b/src/Ecotag/ClientApp/src/Server/SlimFaasPlanetSaver.js
new file mode 100644
index 00000000..c1c7d4fa
--- /dev/null
+++ b/src/Ecotag/ClientApp/src/Server/SlimFaasPlanetSaver.js
@@ -0,0 +1,190 @@
+
+export default class SlimFaasPlanetSaver {
+ constructor(baseUrl, options = {}) {
+ this.baseUrl = this.normalizeBaseUrl(baseUrl);
+ this.updateCallback = options.updateCallback || (() => {});
+ this.errorCallback = options.errorCallback || (() => {});
+ this.interval = options.interval || 5000;
+ this.overlayMessage = options.overlayMessage || 'Starting in progress...';
+ this.intervalId = null;
+ this.isDocumentVisible = !document.hidden;
+ this.overlayElement = null;
+ this.styleElement = null;
+ this.isReady = false;
+ this.handleVisibilityChange = this.handleVisibilityChange.bind(this);
+ document.addEventListener('visibilitychange', this.handleVisibilityChange);
+
+ // Initialise le calque et le style
+ this.createOverlay();
+ this.injectStyles();
+
+ // Événements personnalisés
+ this.events = document.createElement('div'); // Utilisé comme bus d'événements
+ }
+
+ // Normalise l'URL de base
+ normalizeBaseUrl(url) {
+ let tempUrl = url;
+ if (tempUrl.endsWith('/')) tempUrl = tempUrl.slice(0, -1);
+ return tempUrl;
+ }
+
+ // Gestion de la visibilité du document
+ handleVisibilityChange() {
+ this.isDocumentVisible = !document.hidden;
+ if (this.isDocumentVisible) {
+ this.startPolling();
+ } else {
+ this.stopPolling();
+ }
+ }
+
+ async wakeUpPods(data) {
+ const wakePromises = data
+ .filter((item) => item.NumberReady === 0)
+ .map((item) =>
+ fetch(`${this.baseUrl}/wake-function/${item.Name}`, {
+ method: 'POST',
+ })
+ );
+
+ try {
+ await Promise.all(wakePromises);
+ } catch (error) {
+ console.error("Erreur lors du réveil des pods:", error);
+ }
+ }
+
+ // Récupère le statut de l'infrastructure
+ async fetchStatus() {
+ if (!this.isDocumentVisible) return;
+
+ try {
+ const response = await fetch(`${this.baseUrl}/status-functions`);
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+ const data = await response.json();
+
+ const allReady = data.every((item) => item.NumberReady >= 1);
+ this.setReadyState(allReady);
+
+ this.updateCallback(data);
+ await this.wakeUpPods(data);
+ } catch (error) {
+ const errorMessage = error.message;
+ this.errorCallback(errorMessage);
+
+ // Déclenche un événement "error"
+ this.triggerEvent('error', { message: errorMessage });
+
+ console.error('Erreur lors de la récupération des données :', errorMessage);
+ }
+ }
+
+ // Définit l'état "ready" et gère le calque
+ setReadyState(isReady) {
+ this.isReady = isReady;
+ if (isReady) {
+ this.hideOverlay();
+ } else {
+ this.showOverlay();
+ }
+ }
+
+ // Démarre la surveillance (polling)
+ startPolling() {
+ if (this.intervalId || !this.baseUrl) return;
+
+ this.fetchStatus();
+
+ this.intervalId = setInterval(() => {
+ this.fetchStatus();
+ }, this.interval);
+ }
+
+ // Arrête la surveillance
+ stopPolling() {
+ if (this.intervalId) {
+ clearInterval(this.intervalId);
+ this.intervalId = null;
+ }
+ }
+
+ // Injecte les styles CSS via un élément