diff --git a/package.json b/package.json
index c706491433ac7e31c08ae506d715918096870261..4faa70aceb1fb67cc7f91d86150fb56cde7f90c2 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,8 @@
     "@material-ui/lab": "^4.0.0-alpha.48",
     "@material-ui/styles": "^4.10.0",
     "downloadjs": "^1.4.7",
+    "i18next": "^23.11.2",
+    "i18next-http-backend": "^2.5.1",
     "moment": "^2.27.0",
     "mui-datatables": "^3.4.0",
     "ol": "^6.3.2-dev.1594217558556",
@@ -20,6 +22,7 @@
     "react-dom": "^16.13.1",
     "react-hanger": "^2.2.1",
     "react-html-parser": "^2.0.2",
+    "react-i18next": "^14.1.1",
     "react-router-dom": "^5.2.0",
     "react-scripts": "^3.3.0"
   },
@@ -45,12 +48,12 @@
     ]
   },
   "devDependencies": {
-    "jscs": "^3.0.7",
+    "eslint-config-prettier": "^9.1.0",
+    "eslint-plugin-prettier": "^5.1.3",
     "husky": "8.0.3",
+    "jscs": "^3.0.7",
     "lint-staged": "14.0.1",
-    "prettier": "^3.2.5",
-    "eslint-config-prettier": "^9.1.0",
-    "eslint-plugin-prettier": "^5.1.3"
+    "prettier": "^3.2.5"
   },
   "husky": {
     "hooks": {
diff --git a/public/index.html b/public/index.html
index 38223fe591121af96fe75b88c0b43242e7ad2dd6..5e6c56481c2b2e5db90e8168d6f8261aab9e9f72 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,17 +1,11 @@
 <!DOCTYPE html>
 <html lang="en">
-
 <head>
   <meta charset="utf-8" />
-  <!-- <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" /> -->
+  <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.png" />
   <meta name="viewport" content="width=device-width, initial-scale=1" />
   <meta name="theme-color" content="#000000" />
-  <!--
-      manifest.json provides metadata used when your web app is installed on a
-      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-    -->
   <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
-
   <!--
       Notice the use of %PUBLIC_URL% in the tags above.
       It will be replaced with the URL of the `public` folder during the build.
@@ -21,23 +15,11 @@
       work correctly both with client-side routing and a non-root public URL.
       Learn how to configure a non-root public URL by running `npm run build`.
     -->
-  <title>IN-SYLVA SEARCH</title>
+  <title>IN-SYLVA Search</title>
   <script src="%PUBLIC_URL%/env-config.js"></script>
 </head>
-
 <body>
   <noscript>You need to enable JavaScript to run this app.</noscript>
   <div id="root"></div>
-  <!--
-      This HTML file is a template.
-      If you open it directly in the browser, you will see an empty page.
-
-      You can add webfonts, meta tags, or analytics to this file.
-      The build step will place the bundled scripts into the <body> tag.
-
-      To begin the development, run `npm start` or `yarn start`.
-      To create a production bundle, use `npm run build` or `yarn build`.
-    -->
 </body>
-
 </html>
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
new file mode 100644
index 0000000000000000000000000000000000000000..506293c381c1ba92b8c840aaea2d59b85ba3c993
--- /dev/null
+++ b/public/locales/en/common.json
@@ -0,0 +1,13 @@
+{
+  "languages": {
+    "en": "English",
+    "fr": "French"
+  },
+  "inSylvaLogoAlt": "In-Sylva logo",
+  "validationActions": {
+    "cancel": "Cancel",
+    "send": "Send",
+    "save": "Save",
+    "validate": "Validate"
+  }
+}
diff --git a/public/locales/en/header.json b/public/locales/en/header.json
new file mode 100644
index 0000000000000000000000000000000000000000..889a13d8020dc576da3ac10b65ed7e7c394204f6
--- /dev/null
+++ b/public/locales/en/header.json
@@ -0,0 +1,11 @@
+{
+  "tabs": {
+    "home": "Home",
+    "search": "Search"
+  },
+  "userMenu": {
+    "title": "User profile",
+    "editProfileButton": "Edit profile",
+    "logOutButton": "Log out"
+  }
+}
diff --git a/public/locales/en/home.json b/public/locales/en/home.json
new file mode 100644
index 0000000000000000000000000000000000000000..d1038e005f2484a8a1e436071e369bfadee70574
--- /dev/null
+++ b/public/locales/en/home.json
@@ -0,0 +1,11 @@
+{
+  "pageTitle": "Welcome on In-Sylva search module's homepage.",
+  "searchToolDescription": {
+    "part1": "As a reminder, it should be remembered that the metadata stored in IN-SYLVA IS are structured around the IN-SYLVA standard.",
+    "part2": "This standard is composed of metadata fields. A metadata record is therefore made up of a series of fields accompanied by their value.",
+    "part3": "With this part of the interface you will be able to search for metadata records (previously loaded via the portal), by defining a certain number of criteria.",
+    "part4": "By default the \"search\" interface opens to a \"plain text\" search, ie the records returned in the result are those which, in one of the field values, contains the supplied character string.",
+    "part5": "A click on the Advanced search button gives access to a more complete form via which you can do more precise searches on one or more targeted fields.",
+    "part6": "Click on the \"Search\" tab to access the search interface."
+  }
+}
diff --git a/public/locales/en/maps.json b/public/locales/en/maps.json
new file mode 100644
index 0000000000000000000000000000000000000000..ca5269d597d32187d9878e055f1cdae7fe0e3002
--- /dev/null
+++ b/public/locales/en/maps.json
@@ -0,0 +1,23 @@
+{
+  "layersChoiceTitle": "Click on layers to toggle display.",
+  "layersTableHeaders": {
+    "cartography": "Cartography",
+    "filters": "Filters",
+    "tools": "Tools"
+  },
+  "layersTable": {
+    "openStreetMap": "Open Street Map",
+    "bingAerial": "Bing Aerial",
+    "IGN": "IGN map",
+    "SylvoEcoRegions": "SylvoEcoRegions",
+    "queryResults": "Query results",
+    "regions": "Regions",
+    "departments": "Departments",
+    "selectFilterOption": "Select a single option",
+    "selectedPointsList": "Selected resources list",
+    "pointSelectionMode": {
+      "select": "Select",
+      "unselect": "Unselect"
+    }
+  }
+}
diff --git a/public/locales/en/profile.json b/public/locales/en/profile.json
new file mode 100644
index 0000000000000000000000000000000000000000..76ab2db9f4c52d0a9f25098cf4c7cc302f038eac
--- /dev/null
+++ b/public/locales/en/profile.json
@@ -0,0 +1,23 @@
+{
+  "pageTitle": "Profile management",
+  "groups": {
+    "groupsList": "Group list",
+    "groupName": "Name",
+    "groupDescription": "Description"
+  },
+  "requestsList": {
+    "requestsList": "Requests list",
+    "requestsMessage": "Message",
+    "processed": "Processed",
+    "cancelRequest": "Cancel this request"
+  },
+  "groupRequests": {
+    "requestGroupAssignment": "Request a group assignment",
+    "currentGroups": "You currently belong to (or have a pending request for) these groups:",
+    "noGroup": "You currently don't belong to any group."
+  },
+  "roleRequests": {
+    "requestRoleAssignment": "Request an application role",
+    "currentRole": "You currently have (or have a pending request for) this role:"
+  }
+}
diff --git a/public/locales/en/results.json b/public/locales/en/results.json
new file mode 100644
index 0000000000000000000000000000000000000000..61cf048cef51645529f6353f5e08fde90b74541a
--- /dev/null
+++ b/public/locales/en/results.json
@@ -0,0 +1,10 @@
+{
+  "yourQuery": "Your query: {{query}}",
+  "clickOnRowTip": "Click on a resource row to display full metadata.",
+  "downloadResultsButton": {
+    "JSON": "Download as JSON"
+  },
+  "table": {
+    "title": "Search results"
+  }
+}
diff --git a/public/locales/en/search.json b/public/locales/en/search.json
new file mode 100644
index 0000000000000000000000000000000000000000..cebc9ebd923a6e84a544c21650da1a833a2c1bea
--- /dev/null
+++ b/public/locales/en/search.json
@@ -0,0 +1,78 @@
+{
+  "pageTitle": "In-Sylva Metadata Search Platform",
+  "tabs": {
+    "composeSearch": "Compose search",
+    "results": "Results",
+    "map": "Map"
+  },
+  "sendSearchButton": "Search",
+  "basicSearch": {
+    "switchSearchMode": "Switch to advanced search",
+    "searchInputPlaceholder": "Search..."
+  },
+  "advancedSearch": {
+    "switchSearchMode": "Switch to basic search",
+    "textQueryPlaceholder": "Add fields...",
+    "countResultsButton": "Count results",
+    "resultsCount_one": "{{count}} result",
+    "resultsCount_other": "{{count}} results",
+    "editableSearchButton": "Editable",
+    "errorInvalidOption": "\"{{value}}\" is not a valid option.",
+    "fields": {
+      "title": "Field search",
+      "loadingFields": "Loading fields...",
+      "removeFieldButton": "Remove field",
+      "clearValues": "Clear values",
+      "addFieldPopover": {
+        "openPopoverButton": "Add field",
+        "title": "Select a field",
+        "button": "Add this field",
+        "selectSection": "Select a section"
+      },
+      "fieldContentPopover": {
+        "addFieldValues": "Add field values",
+        "addValue": "Add value",
+        "firstValue": "1st value",
+        "secondValue": "2nd value",
+        "inputTextValue": "Type value",
+        "betweenDate": "between",
+        "andDate": "and",
+        "selectValues": "Select values"
+      }
+    },
+    "searchHistory": {
+      "placeholder": "Load a previous request",
+      "saveSearch": "Save search",
+      "addSavedSearchName": "Search name",
+      "addSavedSearchDescription": "Description (optional)",
+      "addSavedSearchDescriptionPlaceholder": "Search description..."
+    },
+    "searchOptions": {
+      "title": "Search option",
+      "matchAll": "Match all criterias",
+      "matchAtLeastOne": "Match at least one criteria"
+    },
+    "partnerSources": {
+      "title": "Partner sources",
+      "allSourcesSelected": "By default, all sources are selected",
+      "noSourceAvailable": "No source available."
+    },
+    "policyToast": {
+      "title": "Private field selected",
+      "content": [
+        "You selected a private field.",
+        "Access to this field was granted for specific sources, which means that your search will be restricted to those.",
+        "Please check the sources list before searching."
+      ]
+    },
+    "editableQueryToast": {
+      "title": "Proceed with caution",
+      "content": {
+        "part1": "Manually editing can spoil query results. Syntax must be respected:",
+        "part2": "Fields and their values should be put between brackets: { } - Make sure every opened bracket is closed",
+        "part3": "\"AND\" and \"OR\" should be capitalized between fields and lowercase within a field expression",
+        "part4": "Make sure to check for typing errors"
+      }
+    }
+  }
+}
diff --git a/public/locales/en/validation.json b/public/locales/en/validation.json
new file mode 100644
index 0000000000000000000000000000000000000000..b12bd6a67aead265e9d0262c00b61d58d51137f7
--- /dev/null
+++ b/public/locales/en/validation.json
@@ -0,0 +1,3 @@
+{
+  "requestSent": "Your request has been sent to the administrators."
+}
diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json
new file mode 100644
index 0000000000000000000000000000000000000000..8e9085fbe434c4ceab454e939e90ab0139dbef0e
--- /dev/null
+++ b/public/locales/fr/common.json
@@ -0,0 +1,13 @@
+{
+  "languages": {
+    "en": "Anglais",
+    "fr": "Français"
+  },
+  "inSylvaLogoAlt": "Logo In-Sylva",
+  "validationActions": {
+    "cancel": "Annuler",
+    "send": "Envoyer",
+    "save": "Sauvegarder",
+    "validate": "Valider"
+  }
+}
diff --git a/public/locales/fr/header.json b/public/locales/fr/header.json
new file mode 100644
index 0000000000000000000000000000000000000000..a5e28a5e7bc627ee31d4145c909be2da802a29d4
--- /dev/null
+++ b/public/locales/fr/header.json
@@ -0,0 +1,11 @@
+{
+  "tabs": {
+    "home": "Page d'accueil",
+    "search": "Recherche"
+  },
+  "userMenu": {
+    "title": "Profil utilisateur",
+    "editProfileButton": "Modifier mon profil",
+    "logOutButton": "Déconnexion"
+  }
+}
diff --git a/public/locales/fr/home.json b/public/locales/fr/home.json
new file mode 100644
index 0000000000000000000000000000000000000000..f9bdcd684df9cd4074239e84b369a5a97893ffcc
--- /dev/null
+++ b/public/locales/fr/home.json
@@ -0,0 +1,11 @@
+{
+  "pageTitle": "Bienvenue sur la page d'accueil du module de recherche du Système d'Information In-Sylva",
+  "searchToolDescription": {
+    "part1": "Il est important de rappeler que les métadonnées stockées dans le SI In-Sylva sont structurées autour du standard établi par In-Sylva.",
+    "part2": "Il est composé de champs de métadonnées. Une fiche de métadonnées est donc constituée d'une série de champs accompagnés de leur valeur.",
+    "part3": "Cette interface vous permettra de rechercher des fiches de métadonnées (chargées au préalable par le Portal), en définissant un certain nombre de critères.",
+    "part4": "L'interface \"Recherche\" ouvre une zone de texte de \"Recherche basique\". Les résultats correspondent aux fiches de métadonnées contenant, dans un de leurs champs, la chaîne de caractère renseignée.",
+    "part5": "Un click sur le bouton \"Recherche avancée\" vous permets d'accéder à un formulaire plus complet qui vous permettra des recherches plus précises sur un ou plusieurs champs donnés.",
+    "part6": "Clickez sur l'onglet \"Recherche\" pour accéder à l'interface de recherche."
+  }
+}
diff --git a/public/locales/fr/maps.json b/public/locales/fr/maps.json
new file mode 100644
index 0000000000000000000000000000000000000000..c113605f1b4a4203a817549c7c0c6e5d1c65c33d
--- /dev/null
+++ b/public/locales/fr/maps.json
@@ -0,0 +1,23 @@
+{
+  "layersChoiceTitle": "Cliquez sur les couches pour modifier l'affichage.",
+  "layersTableHeaders": {
+    "cartography": "Cartographie",
+    "filters": "Filtres",
+    "tools": "Outils"
+  },
+  "layersTable": {
+    "openStreetMap": "Open Street Map",
+    "bingAerial": "Bing vue aérienne",
+    "IGN": "Plan IGN",
+    "SylvoEcoRegions": "SylvoEcoRégions",
+    "queryResults": "Résultats de la requête",
+    "regions": "Régions",
+    "departments": "Départements",
+    "selectFilterOption": "Sélectionnez une option",
+    "selectedPointsList": "Liste des resources sélectionnées",
+    "pointSelectionMode": {
+      "select": "Sélection",
+      "unselect": "Désélection"
+    }
+  }
+}
diff --git a/public/locales/fr/profile.json b/public/locales/fr/profile.json
new file mode 100644
index 0000000000000000000000000000000000000000..9f30ddb283a8147bd3dff379de9a808674709736
--- /dev/null
+++ b/public/locales/fr/profile.json
@@ -0,0 +1,23 @@
+{
+  "pageTitle": "Gestion du profil",
+  "groups": {
+    "groupsList": "Liste des groupes",
+    "groupName": "Nom",
+    "groupDescription": "Description"
+  },
+  "requestsList": {
+    "requestsList": "Liste des requêtes",
+    "requestsMessage": "Message",
+    "processed": "Traitée",
+    "cancelRequest": "Annuler cette requête"
+  },
+  "groupRequests": {
+    "requestGroupAssignment": "Demander à faire parti d'un groupe",
+    "currentGroups": "Vous faites actuellement parti (ou avez une demande pour) de ces groupes :",
+    "noGroup": "Vous ne faites actuellement parti d'aucun groupe."
+  },
+  "roleRequests": {
+    "requestRoleAssignment": "Demander un rôle",
+    "currentRole": "Votre rôle actuel (ou demande en cours):"
+  }
+}
diff --git a/public/locales/fr/results.json b/public/locales/fr/results.json
new file mode 100644
index 0000000000000000000000000000000000000000..e611299744c96fb46abb224d811621c4df0bd5e8
--- /dev/null
+++ b/public/locales/fr/results.json
@@ -0,0 +1,10 @@
+{
+  "yourQuery": "Votre requête : {{query}}",
+  "clickOnRowTip": "Clickez sur une ressource (ligne du tableau) pour afficher ses métadonnées.",
+  "downloadResultsButton": {
+    "JSON": "Télécharger en JSON"
+  },
+  "table": {
+    "title": "Résultats de la recherche"
+  }
+}
diff --git a/public/locales/fr/search.json b/public/locales/fr/search.json
new file mode 100644
index 0000000000000000000000000000000000000000..5f6ab3907ccd0c6176b0d8b81d03c3f1d808f28b
--- /dev/null
+++ b/public/locales/fr/search.json
@@ -0,0 +1,78 @@
+{
+  "pageTitle": "Plateforme de recherche de métadonnées In-Sylva",
+  "tabs": {
+    "composeSearch": "Composer une recherche",
+    "results": "Résultats",
+    "map": "Carte"
+  },
+  "sendSearchButton": "Lancer la recherche",
+  "basicSearch": {
+    "switchSearchMode": "Passer en recherche avancée",
+    "searchInputPlaceholder": "Chercher..."
+  },
+  "advancedSearch": {
+    "switchSearchMode": "Passer en recherche basique",
+    "textQueryPlaceholder": "Ajoutez des champs...",
+    "countResultsButton": "Compter les résultats",
+    "resultsCount_one": "{{count}} résultat",
+    "resultsCount_other": "{{count}} résultats",
+    "editableSearchButton": "Modifiable",
+    "errorInvalidOption": "\"{{value}}\" n'est pas une option valide.",
+    "fields": {
+      "title": "Recherche de champ",
+      "loadingFields": "Chargement des champs...",
+      "removeFieldButton": "Supprimer le champ",
+      "clearValues": "Vider les valeurs",
+      "addFieldPopover": {
+        "openPopoverButton": "Selectionnez un champ",
+        "title": "Ajouter ce champ",
+        "button": "Selectionnez une section",
+        "selectSection": "Ajouter un champ"
+      },
+      "fieldContentPopover": {
+        "addValue": "Ajouter une valeur",
+        "addFieldValues": "Ajouter des valeurs de champ",
+        "firstValue": "1ère valeur",
+        "secondValue": "2ème valeur",
+        "inputTextValue": "Entrez une valeur",
+        "betweenDate": "entre",
+        "andDate": "et",
+        "selectValues": "Sélectionnez au moins une valeur"
+      }
+    },
+    "searchHistory": {
+      "placeholder": "Charger une recherche précédente",
+      "saveSearch": "Sauvegarder ma recherche",
+      "addSavedSearchName": "Nom de la recherche",
+      "addSavedSearchDescription": "Description (optionel)",
+      "addSavedSearchDescriptionPlaceholder": "Description de la recherche..."
+    },
+    "searchOptions": {
+      "title": "Option de recherche",
+      "matchAll": "Répondre à tous les critères",
+      "matchAtLeastOne": "Répondre à au moins un critère"
+    },
+    "partnerSources": {
+      "title": "Liste des sources de partenaires",
+      "allSourcesSelected": "Toutes les sources sont sélectionnées par défaut",
+      "noSourceAvailable": "Pas de source disponible."
+    },
+    "policyToast": {
+      "title": "Champ privé sélectionné",
+      "content": [
+        "Vous avez sélectionné un champ privé.",
+        "L'accès à ce champ à été donné par certaines sources, ce qui veut dire que votre recherche va être limitée à celles-ci.",
+        "Veuillez prếter attention à la liste des sources avant de continuer."
+      ]
+    },
+    "editableQueryToast": {
+      "title": "Procéder avec prudence",
+      "content": {
+        "part1": "En éditant manuellement la recherche, vous pouvez facilement gâcher les résultats. Veuillez respecter la syntaxe :",
+        "part2": "Les champs et leurs valeurs doivent être comprises entre accolade: { } - Bien fermer toute accolade ouverte",
+        "part3": "\"AND\" et \"OR\" en majuscule entre les champs et en minuscule à l'intérieur d'une valeur de champ",
+        "part4": "Attention à corriger vos fautes de frappe"
+      }
+    }
+  }
+}
diff --git a/public/locales/fr/validation.json b/public/locales/fr/validation.json
new file mode 100644
index 0000000000000000000000000000000000000000..0f29592894aacffcd6d069a539ed50c510cc7661
--- /dev/null
+++ b/public/locales/fr/validation.json
@@ -0,0 +1,3 @@
+{
+  "requestSent": "Votre requête à bien été envoyée."
+}
diff --git a/src/Map.svg b/src/assets/Map.svg
similarity index 100%
rename from src/Map.svg
rename to src/assets/Map.svg
diff --git a/src/favicon.svg b/src/assets/favicon.svg
similarity index 100%
rename from src/favicon.svg
rename to src/assets/favicon.svg
diff --git a/src/logo.svg b/src/assets/logo.svg
similarity index 100%
rename from src/logo.svg
rename to src/assets/logo.svg
diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js
index f1e74d049f358e01ef1b3056e39b97508da1a37c..d44347a8ca84f3c432f0bff0277ad98eaf33f542 100644
--- a/src/components/Header/Header.js
+++ b/src/components/Header/Header.js
@@ -7,49 +7,58 @@ import {
   EuiHeaderLinks,
   EuiHeaderLink,
 } from '@elastic/eui';
-import HeaderUserMenu from './header_user_menu';
+import HeaderUserMenu from './HeaderUserMenu';
 import style from './styles';
-import logoInSylva from '../../favicon.svg';
+import logoInSylva from '../../assets/favicon.svg';
+import { useTranslation } from 'react-i18next';
+import LanguageSwitcher from '../LanguageSwitcher/LanguageSwitcher';
 
 const structure = [
   {
     id: 0,
-    label: 'Home',
+    label: 'home',
     href: '/app/home',
     icon: '',
   },
   {
     id: 1,
-    label: 'Search',
+    label: 'search',
     href: '/app/search',
     icon: '',
   },
 ];
 
 const Header = () => {
+  const { t } = useTranslation(['header', 'common']);
+
   return (
     <>
       <EuiHeader>
         <EuiHeaderSection grow={true}>
-          <EuiHeaderSectionItem border="right">
+          <EuiHeaderSectionItem>
             <img
-              style={style}
+              style={style.logo}
               src={logoInSylva}
               width="75"
               height="45"
-              alt="Logo INRAE"
+              alt={t('common:inSylvaLogoAlt')}
             />
           </EuiHeaderSectionItem>
-          <EuiHeaderLinks border="right">
+          <EuiHeaderLinks>
             {structure.map((link) => (
               <EuiHeaderLink iconType="empty" key={link.id}>
-                <Link to={link.href}>{link.label}</Link>
+                <Link to={link.href}>{t(`tabs.${link.label}`)}</Link>
               </EuiHeaderLink>
             ))}
           </EuiHeaderLinks>
         </EuiHeaderSection>
         <EuiHeaderSection side="right">
-          <EuiHeaderSectionItem>{HeaderUserMenu()}</EuiHeaderSectionItem>
+          <EuiHeaderSectionItem style={style.languageSwitcherItem} border={'none'}>
+            <LanguageSwitcher />
+          </EuiHeaderSectionItem>
+          <EuiHeaderSectionItem style={style.userMenuItem} border={'none'}>
+            <HeaderUserMenu />
+          </EuiHeaderSectionItem>
         </EuiHeaderSection>
       </EuiHeader>
     </>
diff --git a/src/components/Header/HeaderUserMenu.js b/src/components/Header/HeaderUserMenu.js
new file mode 100644
index 0000000000000000000000000000000000000000..2235573629ac2c2fa85fe3614f5e5b5dca6a43df
--- /dev/null
+++ b/src/components/Header/HeaderUserMenu.js
@@ -0,0 +1,94 @@
+import React, { useEffect, useState } from 'react';
+import {
+  EuiAvatar,
+  EuiFlexGroup,
+  EuiFlexItem,
+  EuiLink,
+  EuiText,
+  EuiSpacer,
+  EuiPopover,
+  EuiButtonIcon,
+} from '@elastic/eui';
+import { signOut } from '../../context/UserContext';
+import { findOneUser } from '../../actions/user';
+import { useTranslation } from 'react-i18next';
+
+const HeaderUserMenu = () => {
+  const { t } = useTranslation('header');
+  const [isOpen, setIsOpen] = useState(false);
+  const [user, setUser] = useState({});
+
+  const onMenuButtonClick = () => {
+    setIsOpen(!isOpen);
+  };
+
+  const closeMenu = () => {
+    setIsOpen(false);
+  };
+
+  useEffect(() => {
+    const loadUser = () => {
+      if (sessionStorage.getItem('user_id')) {
+        findOneUser(sessionStorage.getItem('user_id')).then((user) => {
+          setUser(user);
+        });
+      }
+    };
+
+    loadUser();
+  }, []);
+
+  const HeaderUserButton = (
+    <EuiButtonIcon
+      size="s"
+      onClick={onMenuButtonClick}
+      iconType="user"
+      title={t('userMenu.title')}
+      aria-label={t('userMenu.title')}
+    />
+  );
+
+  return user.username ? (
+    <EuiPopover
+      id="headerUserMenu"
+      ownFocus
+      button={HeaderUserButton}
+      isOpen={isOpen}
+      anchorPosition="downRight"
+      closePopover={closeMenu}
+      panelPaddingSize="none"
+    >
+      <div>
+        <EuiFlexGroup gutterSize="m" className="euiHeaderProfile" responsive={false}>
+          <EuiFlexItem grow={false}>
+            <EuiAvatar name={user.username} size="xl" />
+          </EuiFlexItem>
+          <EuiFlexItem>
+            <EuiText>{user.username}</EuiText>
+            <EuiSpacer size="m" />
+            <EuiFlexGroup>
+              <EuiFlexItem>
+                <EuiFlexGroup justifyContent="spaceBetween">
+                  <EuiFlexItem grow={false}>
+                    <EuiLink href="#/app/profile">
+                      {t('userMenu.editProfileButton')}
+                    </EuiLink>
+                  </EuiFlexItem>
+                  <EuiFlexItem grow={false}>
+                    <EuiLink onClick={() => signOut()}>
+                      {t('userMenu.logOutButton')}
+                    </EuiLink>
+                  </EuiFlexItem>
+                </EuiFlexGroup>
+              </EuiFlexItem>
+            </EuiFlexGroup>
+          </EuiFlexItem>
+        </EuiFlexGroup>
+      </div>
+    </EuiPopover>
+  ) : (
+    <></>
+  );
+};
+
+export default HeaderUserMenu;
diff --git a/src/components/Header/header_user_menu.js b/src/components/Header/header_user_menu.js
deleted file mode 100644
index feb51bb45544c887a679289dab19aa1fa8401652..0000000000000000000000000000000000000000
--- a/src/components/Header/header_user_menu.js
+++ /dev/null
@@ -1,86 +0,0 @@
-import React, { useEffect, useState } from 'react';
-import {
-  EuiAvatar,
-  EuiFlexGroup,
-  EuiFlexItem,
-  EuiLink,
-  EuiText,
-  EuiSpacer,
-  EuiPopover,
-  EuiButtonIcon,
-} from '@elastic/eui';
-import { signOut } from '../../context/UserContext';
-import { findOneUser } from '../../actions/user';
-
-export default function HeaderUserMenu() {
-  const [isOpen, setIsOpen] = useState(false);
-  const [user, setUser] = useState({});
-
-  const onMenuButtonClick = () => {
-    setIsOpen(!isOpen);
-  };
-
-  const closeMenu = () => {
-    setIsOpen(false);
-  };
-
-  const loadUser = () => {
-    if (sessionStorage.getItem('user_id')) {
-      findOneUser(sessionStorage.getItem('user_id')).then((user) => {
-        setUser(user);
-      });
-    }
-  };
-
-  useEffect(() => {
-    loadUser();
-  }, []);
-
-  const HeaderUserButton = (
-    <EuiButtonIcon
-      size="s"
-      onClick={onMenuButtonClick}
-      iconType="user"
-      title="User profile"
-      aria-label="User profile"
-    />
-  );
-
-  return (
-    user.username && (
-      <EuiPopover
-        id="headerUserMenu"
-        ownFocus
-        button={HeaderUserButton}
-        isOpen={isOpen}
-        anchorPosition="downRight"
-        closePopover={closeMenu}
-        panelPaddingSize="none"
-      >
-        <div style={{ width: 320 }}>
-          <EuiFlexGroup gutterSize="m" className="euiHeaderProfile" responsive={false}>
-            <EuiFlexItem grow={false}>
-              <EuiAvatar name={user.username} size="xl" />
-            </EuiFlexItem>
-            <EuiFlexItem>
-              <EuiText>{user.username}</EuiText>
-              <EuiSpacer size="m" />
-              <EuiFlexGroup>
-                <EuiFlexItem>
-                  <EuiFlexGroup justifyContent="spaceBetween">
-                    <EuiFlexItem grow={false}>
-                      <EuiLink href="#/app/profile">Edit profile</EuiLink>
-                    </EuiFlexItem>
-                    <EuiFlexItem grow={false}>
-                      <EuiLink onClick={() => signOut()}>Log out</EuiLink>
-                    </EuiFlexItem>
-                  </EuiFlexGroup>
-                </EuiFlexItem>
-              </EuiFlexGroup>
-            </EuiFlexItem>
-          </EuiFlexGroup>
-        </div>
-      </EuiPopover>
-    )
-  );
-}
diff --git a/src/components/Header/styles.js b/src/components/Header/styles.js
index 2515727ce2391dc110ed0e581dfe850c9968dde9..27b176118e227f03aede6c0cc94d7938e23266af 100644
--- a/src/components/Header/styles.js
+++ b/src/components/Header/styles.js
@@ -1,8 +1,16 @@
 const headerStyle = {
-  paddingTop: '10px',
-  paddingBottom: '-6px',
-  paddingRight: '10px',
-  paddingLeft: '10px',
+  logo: {
+    paddingTop: '10px',
+    paddingBottom: '-6px',
+    paddingRight: '10px',
+    paddingLeft: '10px',
+  },
+  languageSwitcherItem: {
+    margin: '10px',
+  },
+  userMenuItem: {
+    marginRight: '10px',
+  },
 };
 
 export default headerStyle;
diff --git a/src/components/LanguageSwitcher/LanguageSwitcher.js b/src/components/LanguageSwitcher/LanguageSwitcher.js
new file mode 100644
index 0000000000000000000000000000000000000000..7fb068cd82dad00d1b5b180728c1754869c3daf6
--- /dev/null
+++ b/src/components/LanguageSwitcher/LanguageSwitcher.js
@@ -0,0 +1,29 @@
+import React from 'react';
+import { useTranslation } from 'react-i18next';
+import styles from './styles';
+import { EuiSelect } from '@elastic/eui';
+
+const LanguageSwitcher = () => {
+  const { t, i18n } = useTranslation('common');
+
+  const options = [
+    { text: t('languages.en'), value: 'en' },
+    { text: t('languages.fr'), value: 'fr' },
+  ];
+
+  const changeLanguage = (newLng) => {
+    i18n.changeLanguage(newLng).then();
+  };
+
+  return (
+    <EuiSelect
+      style={styles.select}
+      options={options}
+      compressed={true}
+      value={i18n.resolvedLanguage}
+      onChange={(e) => changeLanguage(e.target.value)}
+    />
+  );
+};
+
+export default LanguageSwitcher;
diff --git a/src/components/LanguageSwitcher/styles.js b/src/components/LanguageSwitcher/styles.js
new file mode 100644
index 0000000000000000000000000000000000000000..9c4c4bb7ae6b5014574eb8d32698e75136b9bcae
--- /dev/null
+++ b/src/components/LanguageSwitcher/styles.js
@@ -0,0 +1,7 @@
+const styles = {
+  select: {
+    borderRadius: '6px',
+  },
+};
+
+export default styles;
diff --git a/src/components/Loading/Loading.js b/src/components/Loading/Loading.js
new file mode 100644
index 0000000000000000000000000000000000000000..f5213a7dd183cad47b2cd4f933abd3a36fca42df
--- /dev/null
+++ b/src/components/Loading/Loading.js
@@ -0,0 +1,12 @@
+import React from 'react';
+import styles from './styles';
+
+const Loading = () => {
+  return (
+    <div style={styles.container}>
+      <h1>Loading...</h1>
+    </div>
+  );
+};
+
+export default Loading;
diff --git a/src/components/Loading/package.json b/src/components/Loading/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..b4c70453df6e4755baccb4ff5e3783d092bca4e8
--- /dev/null
+++ b/src/components/Loading/package.json
@@ -0,0 +1,6 @@
+{
+  "name": "Loading",
+  "version": "1.0.0",
+  "private": true,
+  "main": "Loading.js"
+}
diff --git a/src/components/Loading/styles.js b/src/components/Loading/styles.js
new file mode 100644
index 0000000000000000000000000000000000000000..6c4d2706c3230a1d87dde4f06a41bcc1024c802f
--- /dev/null
+++ b/src/components/Loading/styles.js
@@ -0,0 +1,11 @@
+const styles = {
+  container: {
+    width: '100vw',
+    height: '100vh',
+    display: 'flex',
+    justifyContent: 'center',
+    alignItems: 'center',
+  },
+};
+
+export default styles;
diff --git a/src/i18n.js b/src/i18n.js
new file mode 100644
index 0000000000000000000000000000000000000000..236acc5804dc20022e3b4d769204a2cf81f67c06
--- /dev/null
+++ b/src/i18n.js
@@ -0,0 +1,22 @@
+import i18n from 'i18next';
+import { initReactI18next } from 'react-i18next';
+import Backend from 'i18next-http-backend';
+
+i18n
+  .use(Backend)
+  .use(initReactI18next)
+  .init({
+    lng: 'fr',
+    fallbackLng: 'fr',
+    ns: 'common',
+    defaultNS: 'common',
+    debug: true,
+    load: 'languageOnly',
+    loadPath: 'locales/{{lng}}/{{ns}}.json',
+    interpolation: {
+      // not needed for react as it escapes by default
+      escapeValue: false,
+    },
+  });
+
+export default i18n;
diff --git a/src/index.js b/src/index.js
index ab31dbff2807f9889d87325b74923ae2ce76a431..285bd62b697c75b71cb71332d329aa4a2f62f677 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,9 +1,11 @@
-import React from 'react';
+import React, { Suspense } from 'react';
 import ReactDOM from 'react-dom';
 import '@elastic/eui/dist/eui_theme_light.css';
 import { UserProvider, checkUserLogin } from './context/UserContext';
 import App from './App';
 import { getLoginUrl, getUrlParam, redirect } from './Utils.js';
+import './i18n';
+import Loading from './components/Loading';
 
 const userId = getUrlParam('kcId', '');
 const accessToken = getUrlParam('accessToken', '');
@@ -16,7 +18,9 @@ checkUserLogin(userId, accessToken, refreshToken);
 if (sessionStorage.getItem('access_token')) {
   ReactDOM.render(
     <UserProvider>
-      <App userId={userId} accessToken={accessToken} refreshToken={refreshToken} />
+      <Suspense fallback={<Loading />}>
+        <App userId={userId} accessToken={accessToken} refreshToken={refreshToken} />
+      </Suspense>
     </UserProvider>,
     document.getElementById('root')
   );
diff --git a/src/pages/home/Home.js b/src/pages/home/Home.js
index c54f9082634e36a5f12a16691c28c76b8dd5efc5..28040d15303ee4a05db3c9a67c483022dbea0a0f 100644
--- a/src/pages/home/Home.js
+++ b/src/pages/home/Home.js
@@ -3,54 +3,35 @@ import {
   EuiPageContent,
   EuiPageContentHeader,
   EuiPageContentHeaderSection,
-  EuiPageContentBody,
   EuiTitle,
 } from '@elastic/eui';
+import { useTranslation } from 'react-i18next';
 
 const Home = () => {
+  const { t } = useTranslation('home');
+
   return (
     <>
       <EuiPageContent>
         <EuiPageContentHeader>
           <EuiPageContentHeaderSection>
             <EuiTitle>
-              <h2>Welcome to the IN-SYLVA IS application search module</h2>
+              <h2>{t('pageTitle')}</h2>
             </EuiTitle>
             <br />
+            <p>{t('searchToolDescription.part1')}</p>
             <br />
-            <p>
-              As a reminder, it should be remembered that the metadata stored in IN-SYLVA
-              IS are structured around the IN-SYLVA standard.
-            </p>
-            <br />
-            <p>
-              This standard is composed of metadata fields. A metadata record is therefore
-              made up of a series of fields accompanied by their value.
-            </p>
-            <br />
-            <br />
-            <p>
-              With this part of the interface you will be able to search for metadata
-              records (previously loaded via the portal), by defining a certain number of
-              criteria.
-            </p>
+            <p>{t('searchToolDescription.part2')}</p>
             <br />
-            <p>
-              By default the "search" interface opens to a "plain text" search, ie the
-              records returned in the result are those which, in one of the field values,
-              contains the supplied character string.
-            </p>
+            <p>{t('searchToolDescription.part3')}</p>
             <br />
-            <p>
-              A click on the Advanced search button gives access to a more complete form
-              via which you can do more precise searches on one or more targeted fields.
-            </p>
+            <p>{t('searchToolDescription.part4')}</p>
             <br />
+            <p>{t('searchToolDescription.part5')}</p>
             <br />
-            <p>Click on the "Search" tab to access the search interface.</p>
+            <p>{t('searchToolDescription.part6')}</p>
           </EuiPageContentHeaderSection>
         </EuiPageContentHeader>
-        <EuiPageContentBody></EuiPageContentBody>
       </EuiPageContent>
     </>
   );
diff --git a/src/pages/maps/SearchMap.js b/src/pages/maps/SearchMap.js
index 67ebbb5c4c029217aaef9f0932e316c8531afffa..5ba404cfa9dfbc852696dec82dc32fe393093c90 100644
--- a/src/pages/maps/SearchMap.js
+++ b/src/pages/maps/SearchMap.js
@@ -1,19 +1,17 @@
 import React, { useState, useEffect } from 'react';
 import { Map, View } from 'ol';
 import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer';
-import ImageLayer from 'ol/layer/Image';
+import { Fill, Stroke, Style } from 'ol/style';
 import SourceOSM from 'ol/source/OSM';
 import BingMaps from 'ol/source/BingMaps';
 import { Vector as VectorSource } from 'ol/source';
 import WMTS from 'ol/source/WMTS';
 import WMTSTileGrid from 'ol/tilegrid/WMTS';
 import { getWidth } from 'ol/extent';
-import {platformModifierKeyOnly} from 'ol/events/condition.js';
-import ImageWMS from 'ol/source/ImageWMS';
+import { platformModifierKeyOnly } from 'ol/events/condition';
 import GeoJSON from 'ol/format/GeoJSON';
-import {DragBox, Select} from 'ol/interaction.js';
-import { Fill, Stroke, Style, Text, Icon } from 'ol/style';
-import { Circle, Point, Polygon } from 'ol/geom';
+import { DragBox, Select } from 'ol/interaction';
+import { Circle } from 'ol/geom';
 import Feature from 'ol/Feature';
 import * as proj from 'ol/proj';
 import * as olColor from 'ol/color';
@@ -23,463 +21,170 @@ import {
   OverviewMap,
   defaults as defaultControls,
 } from 'ol/control';
-import { toStringXY } from 'ol/coordinate';
 import 'ol/ol.css';
-import { EuiCheckbox, EuiComboBox, EuiPopover, EuiButtonEmpty, EuiText } from '@elastic/eui';
+import {
+  EuiCheckbox,
+  EuiComboBox,
+  EuiPopover,
+  EuiButtonEmpty,
+  EuiText,
+} from '@elastic/eui';
 import { htmlIdGenerator } from '@elastic/eui/lib/services';
 import { updateArrayElement } from '../../Utils.js';
+import { useTranslation } from 'react-i18next';
+import styles from './styles';
 
-const SearchMap = (props) => {
-
-  const onChange = (selectedOptions) => { //selected map as filter
-    const selectedOption = selectedOptions;
-    setSelected(selectedOptions);
-    var selectedMap = selectedOption[0].value;
-    var deselectOption = document.getElementById('deselectCheckboxId');
-    
-    // a DragBox interaction used to select features
-    const dragBox = new DragBox({
-      condition: platformModifierKeyOnly,
-    });
-    
-    var allMyLayers =  map.getLayers();
-    //remove previous selected map used as filter
-    for (let ifilter = 0; ifilter < options.length; ifilter++) {
-      for (let i = 0; i < allMyLayers.getLength(); i++) {
-        if ( options[ifilter].value == map.getLayers().item(i).get('name')){
-          //window.alert('removed map:' + options[ifilter].value);
-          map.removeLayer(map.getLayers().item(i));
-        }
-      }
-    }
-    
-    var pointsSource = map.getLayers().item(getLayerIndex('query_results')).getSource();
-    
-    if(selectedMap == 'ResRequete'){
-      toggleLayer('query_results');
-      var polygonSource = pointsSource;
-    }
-    else{
-      map.addLayer(maps4Filter[selectedMap]);
-      var polygonSource = maps4Filter[selectedMap].get('source');
-    }
-        
-    map.addInteraction(dragBox);
-
-    // clear selection when drawing a new box and when clicking on the map
-    dragBox.on('boxstart', function () {
-      selectedFeatures.clear();
-    });
-          
-    dragBox.on('boxend', function () {
-      const boxExtent = dragBox.getGeometry().getExtent();
-              
-      // if the extent crosses the antimeridian process each world separately
-      const worldExtent = map.getView().getProjection().getExtent();
-      const worldWidth = getWidth(worldExtent);
-      const startWorld = Math.floor((boxExtent[0] - worldExtent[0]) / worldWidth);
-      const endWorld = Math.floor((boxExtent[2] - worldExtent[0]) / worldWidth);
-
-      for (let world = startWorld; world <= endWorld; ++world) {
-        const left = Math.max(boxExtent[0] - world * worldWidth, worldExtent[0]);
-        const right = Math.min(boxExtent[2] - world * worldWidth, worldExtent[2]);
-        const extent = [left, boxExtent[1], right, boxExtent[3]];
-
-        //const boxFeatures = maps4Filter[selectedMap].get('source')
-        const boxFeatures = polygonSource.getFeaturesInExtent(extent)
-        .filter(
-        (feature) =>
-        !selectedFeatures.getArray().includes(feature) &&
-        feature.getGeometry().intersectsExtent(extent),
-        );
-
-        var pointsFeatures = map.getLayers().item(getLayerIndex('query_results')).getSource().getFeatures();
-        var selectedPointsSource = map.getLayers().item(getLayerIndex('selectedPointsSource')).getSource();
-  
-        for (let polygone = 0; polygone < boxFeatures.length; polygone++) {
-          var polygonGeometry = boxFeatures[polygone].getGeometry();
-          if (!deselectOption.checked){
-            for (let point = 0; point < pointsFeatures.length; point++) {
-              var pointGeom = pointsFeatures[point].getGeometry();
-              var pointName = pointsFeatures[point].get('nom');
-              var coords = pointGeom.getCenter();
-              if (polygonGeometry.intersectsCoordinate(coords)){
-                if (!getFeatureNames(selectedPointsSource).includes(pointName)){
-                    var selectedPointFeature = new Feature(new Circle(coords,5000));
-                    selectedPointFeature.set('nom', pointName);
-                    selectedPointsSource.addFeature(selectedPointFeature);
-                }
-              }
-            }
-          }
-          else { //remove selected features
-            var selectedPointsFeatures = selectedPointsSource.getFeatures();
-            if(selectedPointsFeatures.length > 0 ) {
-              for (let point = 0; point < selectedPointsFeatures.length; point++) {
-                var pointGeom = selectedPointsFeatures[point].getGeometry();
-                var coords = pointGeom.getCenter();
-                if (polygonGeometry.intersectsCoordinate(coords)){
-                  selectedPointsSource.removeFeature(selectedPointsFeatures[point]);                                      
-                }
-              }
-            }
-          }
-        }
-        selectedFeatures.extend(boxFeatures);
-      }
-    });
-  };
-
-  const selectedStyle = new Style({
-    fill: new Fill({
-      color: 'rgba(255, 255, 255, 0.6)',
-    }),
-    stroke: new Stroke({
-      color: 'rgba(255, 255, 255, 0.7)',
-      width: 2,
-    }),
-  });
-
-  // a normal select interaction to handle click
-  const select = new Select({
-    style: function (feature) {
-      //const color = feature.get('COLOR_BIO') || '#eeeeee';
-      const color = 'rgba(255, 255, 255, 0.4)';
-      selectedStyle.getFill().setColor(color);
-      return selectedStyle;
-    },
-  });
-
-  const selectedFeatures = select.getFeatures();
-  const selectedPointsFeatures = select.getFeatures();
+const initResolutions = () => {
+  const resolutions = [];
+  const proj3857 = proj.get('EPSG:3857');
 
-  selectedFeatures.on(['add', 'remove'], function () {
-    const names = selectedFeatures.getArray().map((feature) => {
-      //return feature.get('ECO_NAME');
-      return feature.get('nom');
-    });
-    if (names.length > 0) {
-      console.log(names.join(', '));
-    }
-    else {
-    console.log('None');
-    }
-  });
+  const maxResolution = getWidth(proj3857.getExtent()) / 256;
+  for (let i = 0; i < 20; i++) {
+    resolutions[i] = maxResolution / Math.pow(2, i);
+  }
+  return resolutions;
+};
 
-  selectedPointsFeatures.on(['add', 'remove'], function () {
-    const names = getFeatureNames(selectedPointsSource);
-    if (names.length > 0) {
-      //infoBoxPoints.innerHTML = names.join(', ');
-    } else {
-      //infoBoxPoints.innerHTML = 'None';
-    }
-  });
+const initMatrixIds = () => {
+  const matrixIds = [];
 
-  function getFeatureNames(source) {
-    var featureNames = [];
-    source.getFeatures().forEach(function (feature) {
-        var name = feature.get('nom');
-        if (name) {
-            featureNames.push(name);
-        }
-    });
-    return featureNames;
+  for (let i = 0; i < 20; i++) {
+    matrixIds[i] = i.toString();
   }
-  const styles = {
-    tableStyle: {
-      border: '1px solid black',
-    },
-    trStyle: {
-      verticalAlign: 'top'
-    },
-    'Point': new Style({
-      image: new Icon({
-        anchor: [0.5, 46],
-        anchorXUnits: 'fraction',
-        anchorYUnits: 'pixels',
-        src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png',
-      }),
-    }),
-    'MultiPoint': new Style({
-        image: new Icon({
-            anchor: [0.5, 46],
-            anchorXUnits: 'fraction',
-            anchorYUnits: 'pixels',
-            src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png'
-        })
-    }),
-    Circle: new Style({
-      stroke: new Stroke({
-        color: 'black',
-        width: 2,
-      }),
-      //radius: 1000,
-      fill: new Fill({
-        color: 'rgba(0,0,255,0.3)',
-      }),
-    }),
-    /* 'LineString': new Style({
-            stroke: new Stroke({
-                color: 'green',
-                width: 1,
-            }),
-        }),
-        'MultiLineString': new Style({
-            stroke: new Stroke({
-                color: 'green',
-                width: 1,
-            }),
-        }),
-        'MultiPolygon': new Style({
-            stroke: new Stroke({
-                color: 'yellow',
-                width: 1,
-            }),
-            fill: new Fill({
-                color: 'rgba(255, 255, 0, 0.1)',
-            }),
-        }),
-        'Polygon': new Style({
-            stroke: new Stroke({
-                color: 'blue',
-                lineDash: [4],
-                width: 3,
-            }),
-            fill: new Fill({
-                color: 'rgba(0, 0, 255, 0.1)',
-            }),
-        }),
-        'GeometryCollection': new Style({
-            stroke: new Stroke({
-                color: 'magenta',
-                width: 2,
-            }),
-            fill: new Fill({
-                color: 'magenta',
-            }),
-            image: new CircleStyle({
-                radius: 10,
-                fill: null,
-                stroke: new Stroke({
-                    color: 'magenta',
-                }),
-            }),
-        }),*/
-    mapContainer: {
-      height: '80vh',
-      width: '60vw',
-    },
-    layerTree: {
-      cursor: 'pointer',
-    },
-  };
-  const source = new SourceOSM();
-  const overviewMapControl = new OverviewMap({
-    layers: [
-      new TileLayer({
-        source: source,
-      }),
-    ],
-  });
+  return matrixIds;
+};
+
+const SearchMap = ({ searchResults }) => {
+  const { t } = useTranslation('maps');
   const [center, setCenter] = useState(proj.fromLonLat([2.5, 46.5]));
-  //const [center, setCenter] = useState(proj.fromLonLat([3.5, 44.5]));
   const [zoom, setZoom] = useState(6);
-  const styleFunction = function (feature) {
-    return styles[feature.getGeometry().getType()];
-  };
-
-  //maps used to filter results
-  const options = [
-    { label: 'Résultats de la requête', value: 'ResRequete' },
-    //{ label: 'SylvoEcoRégions', value: 'SylvoEcoRegions' },
-    { label: 'Régions', value: 'Regions' },
-    { label: 'Départements', value: 'Departements' },
+  const [isPopoverOpen, setIsPopoverOpen] = useState(false);
+  const [deselectChecked, setDeselectChecked] = useState(false);
+  const filterOptions = [
+    { label: t('maps:layersTable.queryResults'), value: 'ResRequete' },
+    { label: t('maps:layersTable.regions'), value: 'regions' },
+    { label: t('maps:layersTable.departments'), value: 'departements' },
   ];
-  const [selectedOptions, setSelected] = useState([options[0]]);
-
-  const regions_IGN = new VectorSource({
-    url: 'https://data.geopf.fr/wfs/ows?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&typeName=ADMINEXPRESS-COG-CARTO.LATEST:region&outputFormat=application/json',
-    format: new GeoJSON(),
-    });
-
-  const departements_IGN = new VectorSource({
-    url: 'https://data.geopf.fr/wfs/ows?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&typeName=ADMINEXPRESS-COG-CARTO.LATEST:departement&outputFormat=application/json',
-    format: new GeoJSON(),
+  const [selectedOptions, setSelected] = useState([filterOptions[0]]);
+  const resultPointsSource4BG = new VectorSource({});
+  const resultPointsSource = new VectorSource({});
+  let selectedPointsSource = new VectorSource({});
+  const vectorLayersStyle = () => {
+    const style = new Style({
+      fill: new Fill({
+        color: '#eeeeee',
+      }),
     });
-
-  const sylvoecoregions_IGN = new VectorSource({
-    url: 'https://wxs.ign.fr/environnement/geoportail/wmts?VERSION=2.0.0&request=GetFeature&typeName=LANDCOVER.SYLVOECOREGIONS&outputFormat=application/json',
-    format: new GeoJSON(),
+    const stroke = new Stroke({
+      width: 2,
+      lineDash: [4],
+      color: 'black',
     });
-
-  const resultPointsSource = new VectorSource({});
-  const resultPointsSource4BG = new VectorSource({});
-  var selectedPointsSource = new VectorSource({});
-
-  var maps4Filter = {
-    'ResRequete': new VectorLayer({
-       name: 'ResRequete',
-       source: resultPointsSource,
-       style: styleFunction,
+    let colorArray = olColor.asArray('grey').slice();
+    colorArray[3] = 0.5;
+    style.getFill().setColor(colorArray);
+    style.setStroke(stroke);
+    return style;
+  };
+  const mapFilters = {
+    ResRequete: new VectorLayer({
+      name: 'ResRequete',
+      source: resultPointsSource,
+      style: (feature) => {
+        return styles[feature.getGeometry().getType()];
+      },
     }),
-    'selectedPointsLayer': new VectorLayer({
+    selectedPointsLayer: new VectorLayer({
       name: 'selectedPointsSource',
       source: selectedPointsSource,
-      style: styleFunction,
-    }),
-    'Regions': new VectorLayer({
-      name: 'Regions',
-      source: regions_IGN,
-      //background: '#1a2b39',
-      opacity: 0.5,
-      style: function (feature) {
-        ////const color = feature.get('COLOR_BIO') || '#eeeeee';
-        ////const color = '#eeeeee';
-        var stroke = new Stroke({
-          width : 2,
-          lineDash: [4],
-          color : 'black'
-        });
-        var colorArray = olColor.asArray('grey').slice();
-        colorArray[3] = 0.5;
-        style.getFill().setColor(colorArray);
-        style.setStroke(stroke);  
-        return style;
+      style: (feature) => {
+        return styles[feature.getGeometry().getType()];
       },
     }),
-    'Departements': new VectorLayer({
-      name: 'Departements',
-      source: departements_IGN,
-      //background: '#1a2b39',
+    regions: new VectorLayer({
+      name: 'regions',
+      source: new VectorSource({
+        url: 'https://data.geopf.fr/wfs/ows?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&typeName=ADMINEXPRESS-COG-CARTO.LATEST:region&outputFormat=application/json',
+        format: new GeoJSON(),
+      }),
       opacity: 0.5,
-      style: function (feature) {
-        ////const color = feature.get('COLOR_BIO') || '#eeeeee';
-        ////const color = '#eeeeee';
-        var stroke = new Stroke({
-          width : 2,
-          lineDash: [4],
-          color : 'black'
-        });
-        var colorArray = olColor.asArray('grey').slice();
-        colorArray[3] = 0.5;
-        style.getFill().setColor(colorArray);
-        style.setStroke(stroke);  
-        return style;
-      },
+      style: vectorLayersStyle(),
     }),
-  }
-
-  const style = new Style({
-    fill: new Fill({
-      color: '#eeeeee',
+    departements: new VectorLayer({
+      name: 'departements',
+      source: new VectorSource({
+        url: 'https://data.geopf.fr/wfs/ows?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&typeName=ADMINEXPRESS-COG-CARTO.LATEST:departement&outputFormat=application/json',
+        format: new GeoJSON(),
+      }),
+      opacity: 0.5,
+      style: vectorLayersStyle(),
     }),
-  });
- 
-  const resolutions = [];
-  const matrixIds = [];
-  const proj3857 = proj.get('EPSG:3857');
-  const maxResolution = getWidth(proj3857.getExtent()) / 256;
-
-  for (let i = 0; i < 20; i++) {
-    matrixIds[i] = i.toString();
-    resolutions[i] = maxResolution / Math.pow(2, i);
-  }
-
-  const tileGrid = new WMTSTileGrid({
-    origin: [-20037508, 20037508],
-    resolutions: resolutions,
-    matrixIds: matrixIds,
-  });
-
+  };
   const [mapLayers, setMapLayers] = useState([
     new TileLayer({
       name: 'osm-layer',
-      source: source,
+      source: new SourceOSM(),
     }),
-    /* Bing Aerial */
     new TileLayer({
       name: 'Bing Aerial',
+      visible: false,
       preload: Infinity,
       source: new BingMaps({
         key: 'AtdZQap9X-lowJjvdPhTgr1BctJuGGm-ZoVw9wO6dHt1VDURjRKEkssetwOe31Xt',
         imagerySet: 'Aerial',
       }),
-      //visible: false
     }),
     new TileLayer({
       name: 'IGN',
+      visible: false,
       source: new WMTS({
         url: 'https://wxs.ign.fr/choisirgeoportail/geoportail/wmts',
         layer: 'GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2',
         matrixSet: 'PM',
         format: 'image/png',
         projection: 'EPSG:3857',
-        tileGrid: tileGrid,
+        tileGrid: new WMTSTileGrid({
+          origin: [-20037508, 20037508],
+          resolutions: initResolutions(),
+          matrixIds: initMatrixIds(),
+        }),
         style: 'normal',
         attributions:
-          '<a href="https://www.ign.fr/" target="_blank">' + 
-          '<img src="https://www.ign.fr/files/default/styles/thumbnail/public/2020-06/logoIGN_300x200.png?itok=V80_0fm-" title="Institut national de l\'' +
-          //'<img src="https://wxs.ign.fr/static/logos/IGN/IGN.gif" title="Institut national de l\'' +
-          'information géographique et forestière" alt="IGN"></a>',
+          '<a href="https://www.ign.fr/" target="_blank">' +
+          '<img src="https://www.ign.fr/files/default/styles/thumbnail/public/2020-06/logoIGN_300x200.png?itok=V80_0fm-" title="Institut national de l\'information géographique et forestière" alt="IGN"></a>',
       }),
     }),
     new TileLayer({
       name: 'SylvoEcoregions',
+      visible: false,
       source: new WMTS({
         url: 'https://data.geopf.fr/wmts?',
+        crossOrigin: 'anonymous',
         layer: 'LANDCOVER.SYLVOECOREGIONS',
         matrixSet: 'PM',
         format: 'image/png',
         projection: 'EPSG:3857',
-        tileGrid: tileGrid,
+        tileGrid: new WMTSTileGrid({
+          origin: [-20037508, 20037508],
+          resolutions: initResolutions(),
+          matrixIds: initMatrixIds(),
+        }),
         style: 'normal',
         attributions:
-        '<a href="https://www.ign.fr/" target="_blank">' + 
-        '<img src="https://www.ign.fr/files/default/styles/thumbnail/public/2020-06/logoIGN_300x200.png?itok=V80_0fm-" title="Institut national de l\'' +
-        'information géographique et forestière" alt="IGN"></a>',
+          '<a href="https://www.ign.fr/" target="_blank">' +
+          '<img src="https://www.ign.fr/files/default/styles/thumbnail/public/2020-06/logoIGN_300x200.png?itok=V80_0fm-" title="Institut national de l\'' +
+          'information géographique et forestière" alt="IGN"></a>',
       }),
     }),
     new VectorLayer({
-      name: 'query_results',
+      name: 'queryResults',
       source: resultPointsSource4BG,
     }),
-    maps4Filter['selectedPointsLayer'],
+    mapFilters['selectedPointsLayer'],
   ]);
-
   const [mapLayersVisibility, setMapLayersVisibility] = useState(
-    new Array(mapLayers.length).fill(true)
-  );
-
-  const [deselectChecked, setDeselectChecked] = useState();
-  const handleDeselectCheckboxChange = (event) => {
-    setDeselectChecked(!deselectChecked);
-  };
-
-
-  // const posGreenwich = proj.fromLonLat([0, 51.47]);
-  // set initial map objects
-  const view = new View({
-    center: center,
-    zoom: zoom,
-  });
-
-  //list of selected results
-  const [isPopoverOpen, setIsPopoverOpen] = useState(false);
-  const onButtonClick = () =>{
-    setIsPopoverOpen((isPopoverOpen) => !isPopoverOpen);    
-   }
-  const closePopover = () => setIsPopoverOpen(false);
-
-  const button = (
-    <EuiButtonEmpty
-      iconType="documentation"
-      iconSide="right"
-      onClick={onButtonClick}
-    >
-      Liste des résultats sélectionnés
-    </EuiButtonEmpty>
+    new Array(mapLayers.length).fill(false)
   );
-
   const [map] = useState(
     new Map({
       target: null,
@@ -489,26 +194,216 @@ const SearchMap = (props) => {
           projection: 'EPSG:4326',
         }),
         new ScaleLine(),
-        overviewMapControl,
+        new OverviewMap({
+          layers: [
+            new TileLayer({
+              source: new SourceOSM(),
+            }),
+          ],
+        }),
       ]),
-      view: view,
+      view: new View({
+        center: center,
+        zoom: zoom,
+      }),
     })
   );
 
-  const processData = (props) => {
-    if (props.searchResults) {
-      props.searchResults.forEach((result) => {
+  // a DragBox interaction used to select features
+  const dragBox = new DragBox({
+    condition: platformModifierKeyOnly,
+  });
+
+  // set the initial map targets
+  useEffect(() => {
+    setMapLayersVisibility((prev) =>
+      updateArrayElement(prev, getLayerIndex('osm-layer'), true)
+    );
+    setMapLayersVisibility((prev) =>
+      updateArrayElement(prev, getLayerIndex('queryResults'), true)
+    );
+    map.setTarget('map');
+    map.on('moveend', () => {
+      setCenter(map.getView().getCenter());
+      setZoom(map.getView().getZoom());
+    });
+    map.addInteraction(dragBox);
+    map.addInteraction(select);
+    // clear selection when drawing a new box and when clicking on the map
+    dragBox.on('boxstart', function () {
+      selectedFeatures.clear();
+    });
+    dragBox.on('boxend', () => {
+      const boxExtent = dragBox.getGeometry().getExtent();
+      // if the extent crosses the antimeridian process each world separately
+      const worldExtent = map.getView().getProjection().getExtent();
+      const worldWidth = getWidth(worldExtent);
+      const startWorld = Math.floor((boxExtent[0] - worldExtent[0]) / worldWidth);
+      const endWorld = Math.floor((boxExtent[2] - worldExtent[0]) / worldWidth);
+      for (let world = startWorld; world <= endWorld; ++world) {
+        const left = Math.max(boxExtent[0] - world * worldWidth, worldExtent[0]);
+        const right = Math.min(boxExtent[2] - world * worldWidth, worldExtent[2]);
+        const extent = [left, boxExtent[1], right, boxExtent[3]];
+        const pointsSource = map
+          .getLayers()
+          .item(getLayerIndex('queryResults'))
+          .getSource();
+        let polygonSource;
+        if (selectedOptions[0].value === 'queryResults') {
+          polygonSource = pointsSource;
+        } else {
+          polygonSource = mapFilters[selectedOptions[0].value].get('source');
+        }
+        const boxFeatures = polygonSource
+          .getFeaturesInExtent(extent)
+          .filter(
+            (feature) =>
+              !selectedFeatures.getArray().includes(feature) &&
+              feature.getGeometry().intersectsExtent(extent)
+          );
+
+        const pointsFeatures = map
+          .getLayers()
+          .item(getLayerIndex('queryResults'))
+          .getSource()
+          .getFeatures();
+        const selectedPointsSource = map
+          .getLayers()
+          .item(getLayerIndex('selectedPointsSource'))
+          .getSource();
+
+        for (let polygon = 0; polygon < boxFeatures.length; polygon++) {
+          const polygonGeometry = boxFeatures[polygon].getGeometry();
+          if (!deselectChecked) {
+            for (let point = 0; point < pointsFeatures.length; point++) {
+              const pointGeom = pointsFeatures[point].getGeometry();
+              const pointName = pointsFeatures[point].get('nom');
+              const coords = pointGeom.getCenter();
+              if (polygonGeometry.intersectsCoordinate(coords)) {
+                if (!getSelectedPointsNames(selectedPointsSource).includes(pointName)) {
+                  let selectedPointFeature = new Feature(new Circle(coords, 5000));
+                  selectedPointFeature.set('nom', pointName);
+                  selectedPointsSource.addFeature(selectedPointFeature);
+                }
+              }
+            }
+          } else {
+            // remove selected features
+            const selectedPointsFeatures = selectedPointsSource.getFeatures();
+            if (selectedPointsFeatures.length > 0) {
+              for (let point = 0; point < selectedPointsFeatures.length; point++) {
+                const pointGeom = selectedPointsFeatures[point].getGeometry();
+                const coords = pointGeom.getCenter();
+                if (polygonGeometry.intersectsCoordinate(coords)) {
+                  selectedPointsSource.removeFeature(selectedPointsFeatures[point]);
+                }
+              }
+            }
+          }
+        }
+        selectedFeatures.extend(boxFeatures);
+      }
+    });
+    map.getView().animate({ zoom: zoom }, { center: center }, { duration: 2000 });
+    processData();
+  }, [searchResults, map, deselectChecked]);
+
+  const handleDeselectCheckboxChange = () => {
+    setDeselectChecked((prev) => !prev);
+  };
+
+  const onButtonClick = () => {
+    setIsPopoverOpen((isPopoverOpen) => !isPopoverOpen);
+  };
+
+  const closePopover = () => {
+    setIsPopoverOpen(false);
+  };
+
+  const onFilterSelectChange = (newSelectedOptions) => {
+    setSelected(newSelectedOptions);
+    const allMyLayers = map.getLayers();
+    // remove previously selected filter
+    for (let i = 0; i < filterOptions.length; i++) {
+      for (let j = 0; j < allMyLayers.getLength(); j++) {
+        if (filterOptions[i].value === map.getLayers().item(j).get('name')) {
+          map.removeLayer(map.getLayers().item(j));
+          break;
+        }
+      }
+    }
+    if (newSelectedOptions.length === 0) {
+      return;
+    }
+    const selectedMap = newSelectedOptions[0].value;
+    if (selectedMap === 'ResRequete') {
+      toggleLayer('queryResults');
+    } else {
+      map.addLayer(mapFilters[selectedMap]);
+    }
+  };
+
+  // a normal select interaction to handle click
+  const select = new Select({
+    style: () => {
+      const selectedStyle = new Style({
+        fill: new Fill({
+          color: 'rgba(255, 255, 255, 0.6)',
+        }),
+        stroke: new Stroke({
+          color: 'rgba(255, 255, 255, 0.7)',
+          width: 2,
+        }),
+      });
+      const color = 'rgba(255, 255, 255, 0.4)';
+      selectedStyle.getFill().setColor(color);
+      return selectedStyle;
+    },
+  });
+
+  const selectedFeatures = select.getFeatures();
+
+  selectedFeatures.on(['add', 'remove'], () => {
+    const names = selectedFeatures.getArray().map((feature) => {
+      return feature.get('nom');
+    });
+    if (names.length > 0) {
+      console.log(names.join(', '));
+    } else {
+      console.log('None');
+    }
+  });
+
+  const getSelectedPointsNames = (source) => {
+    let featureNames = [];
+    source.getFeatures().forEach(function (feature) {
+      const name = feature.get('nom');
+      if (name) {
+        featureNames.push(name);
+      }
+    });
+    return featureNames;
+  };
+
+  const processData = () => {
+    if (searchResults) {
+      searchResults.forEach((result) => {
         if (
           result.experimental_site.geo_point &&
           result.experimental_site.geo_point.longitude &&
           result.experimental_site.geo_point.latitude
         ) {
-          const coord = [
+          const resourcePointCoordinates = [
             result.experimental_site.geo_point.longitude,
             result.experimental_site.geo_point.latitude,
           ];
-          const pointIdentifier = result.resource.identifier + "--" + result.context.related_experimental_network_title
-          var pointFeature = new Feature(new Circle(proj.fromLonLat(coord),2000));
+          const pointIdentifier =
+            result.resource.identifier +
+            '--' +
+            result.context.related_experimental_network_title;
+          const pointFeature = new Feature(
+            new Circle(proj.fromLonLat(resourcePointCoordinates), 2000)
+          );
           pointFeature.set('nom', pointIdentifier);
           resultPointsSource4BG.addFeature(pointFeature);
         }
@@ -516,24 +411,6 @@ const SearchMap = (props) => {
     }
   };
 
-  // useEffect Hooks
-  // [] = component did mount
-  // set the initial map targets
-  useEffect(() => {
-    map.setTarget('map');
-    map.on('moveend', () => {
-      setCenter(map.getView().getCenter());
-      setZoom(map.getView().getZoom());
-    });
-    map.addInteraction(select);
-    map.getView().animate({ zoom: zoom }, { center: center }, { duration: 2000 });
-    processData(props);
-    // clean up upon component unmount
-    /* return () => {
-            map.setTarget(null);
-        }; */
-  }, [props]);
-
   const getLayerIndex = (name) => {
     let index = 0;
     mapLayers.forEach((layer) => {
@@ -547,7 +424,6 @@ const SearchMap = (props) => {
   const toggleLayer = (name) => {
     let updatedLayers = mapLayers;
     const layerIndex = getLayerIndex(name);
-    // let updatedLayer = updatedLayers[getLayerIndex(name)]
     setMapLayersVisibility(
       updateArrayElement(
         mapLayersVisibility,
@@ -559,43 +435,26 @@ const SearchMap = (props) => {
     setMapLayers(updatedLayers);
   };
 
-  // helpers
-  /* const btnAction = () => {
-        // when button is clicked, recentre map
-        // this does not work :(
-        setCenter(posGreenwich);
-        setZoom(6);
-    }; */
-  // render
   return (
-    <div>
+    <>
       <div id="map" style={styles.mapContainer}></div>
       <div id="layertree">
-        <br />
-        <h5>Couches géographiques</h5>
-        <table style={styles.tableStyle}>
+        <table style={styles.layersTable}>
           <thead>
-            <tr style={styles.trStyle}>
-                <th>Fonds de carte</th>
-                <th>Filtres géo-thématiques</th>
+            <tr>
+              <th>{t('layersTableHeaders.cartography')}</th>
+              <th>{t('layersTableHeaders.filters')}</th>
+              <th>{t('layersTableHeaders.tools')}</th>
             </tr>
           </thead>
           <tbody>
-            <tr style={styles.trStyle}>
-              <td>
+            <tr>
+              <td style={styles.layersTableCells}>
                 <ul>
                   <li>
                     <EuiCheckbox
                       id={htmlIdGenerator()()}
-                      label="Query result"
-                      checked={mapLayersVisibility[getLayerIndex('query_results')]}
-                      onChange={(e) => toggleLayer('query_results')}
-                    />
-                  </li>
-                  <li>
-                    <EuiCheckbox
-                      id={htmlIdGenerator()()}
-                      label="Open Street Map"
+                      label={t('layersTable.openStreetMap')}
                       checked={mapLayersVisibility[getLayerIndex('osm-layer')]}
                       onChange={(e) => toggleLayer('osm-layer')}
                     />
@@ -603,7 +462,7 @@ const SearchMap = (props) => {
                   <li>
                     <EuiCheckbox
                       id={htmlIdGenerator()()}
-                      label="Bing Aerial"
+                      label={t('layersTable.bingAerial')}
                       checked={mapLayersVisibility[getLayerIndex('Bing Aerial')]}
                       onChange={(e) => toggleLayer('Bing Aerial')}
                     />
@@ -611,7 +470,7 @@ const SearchMap = (props) => {
                   <li>
                     <EuiCheckbox
                       id={htmlIdGenerator()()}
-                      label="PLAN IGN"
+                      label={t('maps:layersTable.IGN')}
                       checked={mapLayersVisibility[getLayerIndex('IGN')]}
                       onChange={(e) => toggleLayer('IGN')}
                     />
@@ -626,62 +485,67 @@ const SearchMap = (props) => {
                   </li>
                 </ul>
               </td>
-              <td>
+              <td style={styles.layersTableCells}>
+                <ul>
+                  <EuiCheckbox
+                    id={htmlIdGenerator()()}
+                    label={t('layersTable.queryResults')}
+                    checked={mapLayersVisibility[getLayerIndex('queryResults')]}
+                    onChange={() => toggleLayer('queryResults')}
+                  />
+                  <br />
+                  <EuiComboBox
+                    aria-label={t('maps:layersTable.selectFilterOption')}
+                    placeholder={t('maps:layersTable.selectFilterOption')}
+                    singleSelection={{ asPlainText: true }}
+                    options={filterOptions}
+                    selectedOptions={selectedOptions}
+                    onChange={onFilterSelectChange}
+                  />
+                </ul>
+              </td>
+              <td style={styles.layersTableCells}>
                 <ul>
                   <input
-                    id="deselectCheckboxId"
                     type="checkbox"
                     checked={deselectChecked}
                     onChange={handleDeselectCheckboxChange}
-                    /><i>Délectionner</i>
-                  <EuiComboBox
-                    aria-label="Accessible screen reader label"
-                    placeholder="Select a single option"
-                    singleSelection={{ asPlainText: true }}
-                    options={options}
-                    selectedOptions={selectedOptions}
-                    onChange={onChange}
                   />
-                  <br/>
+                  <i>
+                    {deselectChecked
+                      ? t('maps:layersTable.pointSelectionMode.select')
+                      : t('maps:layersTable.pointSelectionMode.unselect')}
+                  </i>
+                  <br />
                   <EuiPopover
-                    button={button}
+                    button={
+                      <EuiButtonEmpty onClick={onButtonClick}>
+                        {t('maps:layersTable.selectedPointsList')}
+                      </EuiButtonEmpty>
+                    }
                     isOpen={isPopoverOpen}
                     closePopover={closePopover}
                   >
                     <EuiText style={{ width: 300 }}>
-                      <p>{getFeatureNames(map.getLayers().item(getLayerIndex('selectedPointsSource')).getSource()).toString()}</p>
+                      <p>
+                        {map.getLayers().item(getLayerIndex('selectedPointsSource')) &&
+                          getSelectedPointsNames(
+                            map
+                              .getLayers()
+                              .item(getLayerIndex('selectedPointsSource'))
+                              .getSource()
+                          ).toString()}
+                      </p>
                     </EuiText>
                   </EuiPopover>
                 </ul>
               </td>
-              <td>
-                <div id="info">&nbsp;</div>
-              </td>
             </tr>
           </tbody>
         </table>
       </div>
-      {/*<div
-                style={styles.bluecircle}
-                ref={overlayRef}
-                id="overlay"
-                title="overlay"
-            />*/}
-      {/*<button
-                style={{
-                    position: "absolute",
-                    right: 10,
-                    top: 10,
-                    backgroundColor: "white"
-                }}
-                onClick={() => {
-                    btnAction();
-                }}
-            >
-                CLICK
-            </button>*/}
-    </div>
+    </>
   );
 };
 
-export default SearchMap;
\ No newline at end of file
+export default SearchMap;
diff --git a/src/pages/maps/styles.js b/src/pages/maps/styles.js
new file mode 100644
index 0000000000000000000000000000000000000000..72257f8df8e8a461b206e9bd55aa3dfce453c1e9
--- /dev/null
+++ b/src/pages/maps/styles.js
@@ -0,0 +1,44 @@
+import { Fill, Icon, Stroke, Style } from 'ol/style';
+
+const styles = {
+  Point: new Style({
+    image: new Icon({
+      anchor: [0.5, 46],
+      anchorXUnits: 'fraction',
+      anchorYUnits: 'pixels',
+      src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png',
+    }),
+  }),
+  MultiPoint: new Style({
+    image: new Icon({
+      anchor: [0.5, 46],
+      anchorXUnits: 'fraction',
+      anchorYUnits: 'pixels',
+      src: 'https://openlayers.org/en/v3.20.1/examples/data/icon.png',
+    }),
+  }),
+  Circle: new Style({
+    stroke: new Stroke({
+      color: 'black',
+      width: 2,
+    }),
+    fill: new Fill({
+      color: 'rgba(0,0,255,0.3)',
+    }),
+  }),
+  mapContainer: {
+    height: '80vh',
+    width: '60vw',
+  },
+  layerTree: {
+    cursor: 'pointer',
+  },
+  layersTable: {
+    margin: '20px',
+  },
+  layersTableCells: {
+    padding: '10px',
+  },
+};
+
+export default styles;
diff --git a/src/pages/profile/Profile.js b/src/pages/profile/Profile.js
index d6fecd338609b352e8e558aff61e4d54d576bb79..89bd3a7edde33dcf0540186c86bba5aedbae42ff 100644
--- a/src/pages/profile/Profile.js
+++ b/src/pages/profile/Profile.js
@@ -23,20 +23,11 @@ import {
   createUserRequest,
   deleteUserRequest,
 } from '../../actions/user';
-
-/* const fieldsGridOptions = {
-    filter: true,
-    filterType: "dropdown",
-    responsive: "stacked",
-    selectableRows: 'multiple',
-    selectableRowsOnClick: true,
-    onRowsSelect: (rowsSelected, allRows) => {
-    },
-    onRowClick: (rowData, rowState) => {
-    },
-}; */
+import { useTranslation } from 'react-i18next';
+import styles from './styles';
 
 const Profile = () => {
+  const { t } = useTranslation(['profile', 'common', 'validation']);
   const [user, setUser] = useState({});
   const [userRole, setUserRole] = useState('');
   const [groups, setGroups] = useState([]);
@@ -47,15 +38,36 @@ const Profile = () => {
   const [valueError, setValueError] = useState(undefined);
 
   useEffect(() => {
+    const loadUser = () => {
+      if (sessionStorage.getItem('user_id')) {
+        findOneUser(sessionStorage.getItem('user_id')).then((user) => {
+          setUser(user);
+        });
+        findOneUserWithGroupAndRole(sessionStorage.getItem('user_id')).then((result) => {
+          const userGroupList = userGroups;
+          result.forEach((user) => {
+            if (user.groupname) {
+              userGroupList.push({
+                id: user.groupid,
+                label: user.groupname,
+                description: user.groupdescription,
+              });
+            }
+            setUserRole(user.rolename);
+          });
+          setUserGroups(userGroupList);
+        });
+      }
+    };
     loadUser();
     getUserRequests();
     getUserGroups();
     getUserRoles();
-  }, []);
+  }, [userGroups]);
 
   const groupColumns = [
-    { field: 'label', name: 'Group Name', width: '30%' },
-    { field: 'description', name: 'Group description' },
+    { field: 'label', name: t('groups.groupName'), width: '30%' },
+    { field: 'description', name: t('groups.groupDescription') },
   ];
 
   const getUserRoles = () => {
@@ -98,8 +110,8 @@ const Profile = () => {
 
   const requestActions = [
     {
-      name: 'Cancel',
-      description: 'Cancel this request',
+      name: t('common:validationActions.cancel'),
+      description: t('requestsList.cancelRequest'),
       icon: 'trash',
       type: 'icon',
       onClick: onDeleteRequest,
@@ -107,33 +119,15 @@ const Profile = () => {
   ];
 
   const requestsColumns = [
-    { field: 'request_message', name: 'Message', width: '90%' },
-    { field: 'is_processed', name: 'Processed' },
-    { name: 'Delete', actions: requestActions },
+    {
+      field: 'request_message',
+      name: t('requestsList.requestsMessage'),
+      width: '85%',
+    },
+    { field: 'is_processed', name: t('requestsList.processed') },
+    { name: t('common:validationActions.cancel'), actions: requestActions },
   ];
 
-  const loadUser = () => {
-    if (sessionStorage.getItem('user_id')) {
-      findOneUser(sessionStorage.getItem('user_id')).then((user) => {
-        setUser(user);
-      });
-      findOneUserWithGroupAndRole(sessionStorage.getItem('user_id')).then((result) => {
-        const userGroupList = userGroups;
-        result.forEach((user) => {
-          if (user.groupname) {
-            userGroupList.push({
-              id: user.groupid,
-              label: user.groupname,
-              description: user.groupdescription,
-            });
-          }
-          setUserRole(user.rolename);
-        });
-        setUserGroups(userGroupList);
-      });
-    }
-  };
-
   const getUserGroupLabels = () => {
     let labelList = '';
     if (!!userGroups) {
@@ -155,42 +149,65 @@ const Profile = () => {
     );
   };
 
+  const onSendRoleRequest = () => {
+    if (selectedRole) {
+      const message = `The user ${user.username} (${user.email}) has made a request to get the role : ${selectedRole}.`;
+      createUserRequest(user.id, message);
+      sendMail('User role request', message);
+      alert(t('validation:requestSent'));
+    }
+    getUserRequests();
+  };
+
+  const onSendGroupRequest = () => {
+    const groupList = [];
+    if (userGroups) {
+      userGroups.forEach((group) => {
+        groupList.push(group.label);
+      });
+      const message = `The user ${user.username} (${user.email}) has made a request to be part of these groups : ${groupList}.`;
+      createUserRequest(user.id, message);
+      sendMail('User group request', message);
+      alert(t('validation:requestSent'));
+    }
+    getUserRequests();
+  };
+
   return (
     <>
       <EuiPageContent>
         <EuiPageContentHeader>
           <EuiPageContentHeaderSection>
             <EuiTitle>
-              <h2>Profile management</h2>
+              <h2>{t('pageTitle')}</h2>
             </EuiTitle>
           </EuiPageContentHeaderSection>
         </EuiPageContentHeader>
         <EuiPageContentBody>
           <EuiForm component="form">
             <EuiTitle size="s">
-              <h3>Group list</h3>
+              <h3>{t('groups.groupsList')}</h3>
             </EuiTitle>
             <EuiFormRow fullWidth label="">
               <EuiBasicTable items={groups} columns={groupColumns} />
             </EuiFormRow>
             <EuiSpacer size="l" />
             <EuiTitle size="s">
-              <h3>Requests list</h3>
+              <h3>{t('requestsList.requestsList')}</h3>
             </EuiTitle>
             <EuiFormRow fullWidth label="">
               <EuiBasicTable items={userRequests} columns={requestsColumns} />
             </EuiFormRow>
             <EuiSpacer size="l" />
             <EuiTitle size="s">
-              <h3>Request group assignment modifications</h3>
+              <h3>{t('groupRequests.requestGroupAssignment')}</h3>
             </EuiTitle>
             {getUserGroupLabels() ? (
-              <p>
-                You currently belong to (or have a pending demand for) these groups :{' '}
-                {getUserGroupLabels()}{' '}
-              </p>
+              <p
+                style={styles.currentRoleOrGroupText}
+              >{`${t('groupRequests.currentGroups')} ${getUserGroupLabels()}`}</p>
             ) : (
-              <p>You currently belong to no group</p>
+              <p>{t('groupRequests.noGroup')}</p>
             )}
             <EuiFormRow error={valueError} isInvalid={valueError !== undefined}>
               <EuiComboBox
@@ -207,28 +224,20 @@ const Profile = () => {
             <EuiSpacer size="m" />
             <EuiButton
               onClick={() => {
-                if (userGroups) {
-                  const groupList = [];
-                  userGroups.forEach((group) => {
-                    groupList.push(group.label);
-                  });
-                  const message = `The user ${user.username} (${user.email}) has made a request to be part of these groups : ${groupList}.`;
-                  createUserRequest(user.id, message);
-                  sendMail('User group request', message);
-                  alert('Your group request has been sent to the administrators.');
-                }
-                getUserRequests();
+                onSendGroupRequest();
               }}
               fill
             >
-              Send request
+              {t('common:validationActions.send')}
             </EuiButton>
             <EuiSpacer size="l" />
             <EuiTitle size="s">
-              <h3>Request an application role</h3>
+              <h3>{t('roleRequests.requestRoleAssignment')}</h3>
             </EuiTitle>
             {userRole ? (
-              <p>Your current role is (or have a pending demand for) {userRole}</p>
+              <p
+                style={styles.currentRoleOrGroupText}
+              >{`${t('roleRequests.currentRole')} ${userRole}`}</p>
             ) : (
               <></>
             )}
@@ -245,17 +254,11 @@ const Profile = () => {
             <EuiSpacer size="m" />
             <EuiButton
               onClick={() => {
-                if (selectedRole) {
-                  const message = `The user ${user.username} (${user.email}) has made a request to get the role : ${selectedRole}.`;
-                  createUserRequest(user.id, message);
-                  sendMail('User role request', message);
-                  alert('Your role request has been sent to the administrators.');
-                }
-                getUserRequests();
+                onSendRoleRequest();
               }}
               fill
             >
-              Send request
+              {t('common:validationActions.send')}
             </EuiButton>
           </EuiForm>
         </EuiPageContentBody>
diff --git a/src/pages/profile/styles.js b/src/pages/profile/styles.js
new file mode 100644
index 0000000000000000000000000000000000000000..4c2776e98c63a6bf9e919a8f152504dccba201f4
--- /dev/null
+++ b/src/pages/profile/styles.js
@@ -0,0 +1,8 @@
+const style = {
+  currentRoleOrGroupText: {
+    marginTop: '10px',
+    marginBottom: '10px',
+  },
+};
+
+export default style;
diff --git a/src/pages/results/Results.js b/src/pages/results/Results.js
index c54481e0a83b3d9be02a63e6c191c8544493ce56..b647f7738dbe1b6beff02d77d7e6bd933048dc74 100644
--- a/src/pages/results/Results.js
+++ b/src/pages/results/Results.js
@@ -15,8 +15,8 @@ import { createTheme, MuiThemeProvider } from '@material-ui/core/styles';
 import MUIDataTable from 'mui-datatables';
 import JsonView from '@in-sylva/json-view';
 import { updateArrayElement } from '../../Utils.js';
-
-const download = require('downloadjs');
+import download from 'downloadjs';
+import { useTranslation } from 'react-i18next';
 
 const getMuiTheme = () =>
   createTheme({
@@ -38,16 +38,17 @@ const changeFlyoutState = (array, index, value, defaultValue) => {
   return newArray;
 };
 
-const Results = (searchResults, search, basicSearch) => {
+const Results = ({ searchResults, searchQuery }) => {
+  const { t } = useTranslation('results');
   const [resultsCol, setResultsCol] = useState([]);
   const [results, setResults] = useState([]);
   const [isFlyoutOpen, setIsFlyoutOpen] = useState([false]);
-  const [searchQuery, setSearchQuery] = useState('');
+  const [searchQueryText, setSearchQueryText] = useState('');
 
   useEffect(() => {
     processData(searchResults);
-    search.length ? setSearchQuery(search) : setSearchQuery(basicSearch);
-  }, [searchResults, search, basicSearch]);
+    setSearchQueryText(searchQuery);
+  }, [searchResults]);
 
   const updateTableCell = (tableContent, value, colIndex, rowIndex) => {
     const updatedRow = updateArrayElement(tableContent[rowIndex], colIndex, value);
@@ -62,6 +63,55 @@ const Results = (searchResults, search, basicSearch) => {
     return updatedResults;
   };
 
+  const buildColumnName = (name) => {
+    // Replace underscore with spaces
+    name = name.split('_').join(' ');
+    // Uppercase first character
+    name = name.charAt(0).toUpperCase() + name.slice(1);
+    return name;
+  };
+
+  const processData = (metadata) => {
+    if (metadata) {
+      const columns = [];
+      const rows = [];
+      columns.push({
+        name: 'Currently open',
+        options: {
+          display: true,
+          viewColumns: true,
+          filter: true,
+        },
+      });
+      for (let recordIndex = 0; recordIndex < metadata.length; recordIndex++) {
+        const row = [];
+        const displayedFields = metadata[recordIndex].resource;
+        const flyoutCell = recordFlyout(metadata[recordIndex], recordIndex);
+        if (recordIndex >= isFlyoutOpen.length) {
+          setIsFlyoutOpen([...isFlyoutOpen, false]);
+        }
+        row.push(flyoutCell);
+        for (const fieldName in displayedFields) {
+          if (typeof displayedFields[fieldName] === 'string') {
+            if (recordIndex === 0) {
+              const column = {
+                name: buildColumnName(fieldName),
+                options: {
+                  display: true,
+                },
+              };
+              columns.push(column);
+            }
+            row.push(displayedFields[fieldName]);
+          }
+        }
+        rows.push(row);
+      }
+      setResultsCol(columns);
+      setResults(rows);
+    }
+  };
+
   const recordFlyout = (record, recordIndex, isOpen) => {
     if (isOpen) {
       return (
@@ -113,13 +163,11 @@ const Results = (searchResults, search, basicSearch) => {
     filterType: 'dropdown',
     responsive: 'standard',
     selectableRows: 'none',
-    selectableRowsOnClick: false,
+    selectableRowsOnClick: true,
     onRowSelectionChange: (rowsSelected, allRows) => {},
     onRowClick: (rowData, rowState) => {},
     onCellClick: (val, colMeta) => {
-      // if (searchResults.hits.hits && colMeta.colIndex !== 0) {
       if (searchResults && colMeta.colIndex !== 0) {
-        // const updatedTable = updateTableCell(closeAllFlyouts(results), recordFlyout(searchResults.hits.hits[colMeta.rowIndex]._source, colMeta.rowIndex, !isFlyoutOpen[colMeta.rowIndex]), 0, colMeta.rowIndex)
         const updatedTable = updateTableCell(
           closeAllFlyouts(results),
           recordFlyout(
@@ -142,178 +190,13 @@ const Results = (searchResults, search, basicSearch) => {
     },
   };
 
-  /*  const displayRecord = (record) => {
-         let recordDisplay = []
-         if (!!record) {
-             const fields = Object.keys(record)
-             fields.forEach(field => {
-                 if (typeof record[field] != 'string') {
-                     // const rndId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
-                     if (isNaN(field)) {
-                         // const buttonContent = `"${field}"`
-                         let isStrArray = false
-                         if (Array.isArray(record[field])) {
-                             isStrArray = true
-                             record[field].forEach(item => {
-                                 if (typeof item != 'string')
-                                     isStrArray = false
-                             })
-                         }
-                         if (isStrArray) {
-                             recordDisplay.push(
-                                 <>
-                                     <h3>
-                                         &emsp;{field}
-                                     </h3>
-                                     {displayRecord(record[field])}
-                                 </>
-                             )
-                         } else {
-                             recordDisplay.push(
-                                 <>
-                                     <EuiSpacer size="s" />
-                                     <EuiPanel paddingSize="s">
-                                         <EuiAccordion id={Math.random().toString()} buttonContent={field}>
-                                             <EuiText size="s">
-                                                 {displayRecord(record[field])}
-                                             </EuiText>
-                                         </EuiAccordion>
-                                     </EuiPanel>
-                                 </>
-                             )
-                         }
-                     } else {
-                         recordDisplay.push(
-                             <>
-                                 {displayRecord(record[field])}
-                             </>
-                         )
-                         if (fields[fields.indexOf(field) + 1])
-                             recordDisplay.push(
-                                 <>
-                                     <EuiSpacer size="m" />
-                                     <hr />
-                                 </>
-                             )
-                     }
-                 } else {
-                     if (isNaN(field)) {
-                         recordDisplay.push(
-                             <>
-                                 <h3>
-                                     &emsp;{field}
-                                 </h3>
-                                 <EuiTextColor color="secondary">&emsp;&emsp;{record[field]}</EuiTextColor>
-                             </>
-                         )
-                     } else {
-                         recordDisplay.push(
-                             <>
-                                 <EuiSpacer size="s" />
-                                 <EuiTextColor color="secondary">&emsp;&emsp;{record[field]}</EuiTextColor>
-                             </>
-                         )
-                     }
-                 }
-             })
-             return recordDisplay
-         }
-     }
-
-     const recordFlyout = (record, recordIndex, isFlyoutOpen, setIsFlyoutOpen) => {
-         let flyout
-         if (isFlyoutOpen[recordIndex]) {
-             // const flyOutContent = ReactHtmlParser(displayRecord(record, 1))
-             const flyOutStr = displayRecord(record)
-             // const flyOutContent = parse(flyOutStr, { htmlparser2: { lowerCaseTags: false } })
-             const flyout = (
-                 <>
-                     <EuiFlyout
-                         onClose={() => {
-                             // setIsFlyoutOpen(updateArrayElement(isFlyoutOpen, recordIndex, false))
-                             // updateResultsCell(false, 0, recordIndex)
-                             const updatedArray = changeFlyoutState(isFlyoutOpen, recordIndex, !isFlyoutOpen[recordIndex], false)
-                             setIsFlyoutOpen(updatedArray)
-                         }}
-                         aria-labelledby={recordIndex}>
-                         <EuiFlyoutBody>
-                             <EuiText size="s">
-                                 <Fragment>
-                                     {flyOutStr}
-                                 </Fragment>
-                             </EuiText>
-                         </EuiFlyoutBody>
-                     </EuiFlyout>
-                     <EuiIcon type='eye' color='danger' />
-                 </>
-             );
-             return (flyout)
-         }
-     } */
-
-  /* const viewButton = (record, recordIndex, isFlyoutOpenIndex, isFlyoutOpen, setIsFlyoutOpen) => {
-        return (
-            <>
-                <EuiButtonIcon
-                    size="m"
-                    color="success"
-                    onClick={() => {
-                        const flyOutArray = updateArrayElement(isFlyoutOpen, recordIndex, !isFlyoutOpen[recordIndex])
-                        setIsFlyoutOpen(flyOutArray)
-                        updateResultsCell(!isFlyoutOpen[recordIndex], isFlyoutOpenIndex, recordIndex)
-                    }}
-                    iconType="eye"
-                    title="View record"
-                />
-                {recordFlyout(record, recordIndex, isFlyoutOpen, setIsFlyoutOpen)}
-            </>
-        )
-    } */
-
-  const processData = (metadata) => {
-    // if (metadata && metadata.hits) {
-    if (metadata) {
-      const columns = [];
-      const rows = [];
-      // const metadataRecords = metadata.hits.hits
-      columns.push({
-        name: 'currently open',
-        options: {
-          display: true,
-          viewColumns: true,
-          filter: true,
-        },
-      });
-      /* for (let recordIndex = 0; recordIndex < metadataRecords.length; recordIndex++) {
-                const row = []
-                const displayedFields = metadataRecords[recordIndex]._source.resource
-                const flyoutCell = recordFlyout(metadataRecords[recordIndex]._source, recordIndex) */
-      for (let recordIndex = 0; recordIndex < metadata.length; recordIndex++) {
-        const row = [];
-        const displayedFields = metadata[recordIndex].resource;
-        const flyoutCell = recordFlyout(metadata[recordIndex], recordIndex);
-        if (recordIndex >= isFlyoutOpen.length) {
-          setIsFlyoutOpen([...isFlyoutOpen, false]);
-        }
-        row.push(flyoutCell);
-        for (const fieldName in displayedFields) {
-          if (typeof displayedFields[fieldName] === 'string') {
-            if (recordIndex === 0) {
-              const column = {
-                name: fieldName,
-                options: {
-                  display: true,
-                },
-              };
-              columns.push(column);
-            }
-            row.push(displayedFields[fieldName]);
-          }
-        }
-        rows.push(row);
-      }
-      setResultsCol(columns);
-      setResults(rows);
+  const downloadResults = () => {
+    if (searchResults) {
+      download(
+        `{"metadataRecords": ${JSON.stringify(searchResults, null, '\t')}}`,
+        'InSylvaSearchResults.json',
+        'application/json'
+      );
     }
   };
 
@@ -324,39 +207,24 @@ const Results = (searchResults, search, basicSearch) => {
         <EuiSpacer size="s" />
         <EuiFlexItem grow={false}>
           <EuiTitle size="xs">
-            <h2>Your query : {searchQuery}</h2>
+            <h2>{t('results:yourQuery', { query: searchQueryText })}</h2>
           </EuiTitle>
         </EuiFlexItem>
         <EuiSpacer size="s" />
       </EuiFlexGroup>
       <EuiFlexGroup>
         <EuiFlexItem>
-          <EuiCallOut
-            size="s"
-            title="Click on a line of the table to inspect resource metadata (except for the first column)."
-            iconType="search"
-          />
+          <EuiCallOut size="s" title={t('results:clickOnRowTip')} iconType="search" />
         </EuiFlexItem>
         <EuiFlexItem grow={false}>
-          <EuiButton
-            fill
-            onClick={() => {
-              if (searchResults) {
-                download(
-                  `{"metadataRecords": ${JSON.stringify(searchResults, null, '\t')}}`,
-                  'InSylvaSearchResults.json',
-                  'application/json'
-                );
-              }
-            }}
-          >
-            Download as JSON
+          <EuiButton fill onClick={() => downloadResults()}>
+            {t('results:downloadResultsButton.JSON')}
           </EuiButton>
         </EuiFlexItem>
       </EuiFlexGroup>
       <MuiThemeProvider theme={getMuiTheme()}>
         <MUIDataTable
-          title={'Search results'}
+          title={t('results:table.title')}
           data={results}
           columns={resultsCol}
           options={resultsGridOptions}
diff --git a/src/pages/search/AdvancedSearch/AdvancedSearch.js b/src/pages/search/AdvancedSearch/AdvancedSearch.js
new file mode 100644
index 0000000000000000000000000000000000000000..cd4b8a08ae977919cf27a639518b757db83b9dc5
--- /dev/null
+++ b/src/pages/search/AdvancedSearch/AdvancedSearch.js
@@ -0,0 +1,1647 @@
+import {
+  EuiButton,
+  EuiButtonEmpty,
+  EuiButtonIcon,
+  EuiComboBox,
+  EuiFieldText,
+  EuiFlexGroup,
+  EuiFlexItem,
+  EuiForm,
+  EuiFormRow,
+  EuiGlobalToastList,
+  EuiHealth,
+  EuiIcon,
+  EuiModal,
+  EuiModalBody,
+  EuiModalFooter,
+  EuiModalHeader,
+  EuiModalHeaderTitle,
+  EuiOverlayMask,
+  EuiPanel,
+  EuiPopover,
+  EuiPopoverFooter,
+  EuiPopoverTitle,
+  EuiProgress,
+  EuiRadioGroup,
+  EuiSelect,
+  EuiSpacer,
+  EuiSwitch,
+  EuiTextArea,
+  EuiTextColor,
+  EuiTitle,
+} from '@elastic/eui';
+import React, { useEffect, useState } from 'react';
+import {
+  changeNameToLabel,
+  createAdvancedQueriesBySource,
+  getFieldsBySection,
+  getSections,
+  removeArrayElement,
+  SearchField,
+  updateArrayElement,
+  updateSearchFieldValues,
+} from '../../../Utils';
+import { getQueryCount, searchQuery } from '../../../actions/source';
+import { DateOptions, NumericOptions, Operators } from '../Data';
+import TextField from '@material-ui/core/TextField';
+import { addUserHistory, fetchUserHistory } from '../../../actions/user';
+import { useTranslation } from 'react-i18next';
+
+const updateSources = (
+  searchFields,
+  sources,
+  setSelectedSources,
+  setAvailableSources
+) => {
+  let updatedSources = [];
+  let availableSources = [];
+  let noPrivateField = true;
+  //search for policy fields to filter sources
+  searchFields.forEach((field) => {
+    if (field.isValidated) {
+      //if sources haven't already been filtered
+      if (noPrivateField && !updatedSources.length) {
+        availableSources = sources;
+      } else {
+        availableSources = updatedSources;
+      }
+      updatedSources = [];
+      field.sources.forEach((sourceId) => {
+        noPrivateField = false;
+        const source = availableSources.find((src) => src.id === sourceId);
+        if (source && !updatedSources.includes(source)) updatedSources.push(source);
+      });
+    }
+  });
+  setSelectedSources(updatedSources);
+  if (noPrivateField && !updatedSources.length) {
+    setAvailableSources(sources);
+  } else {
+    setAvailableSources(updatedSources);
+  }
+};
+
+const fieldValuesToString = (field) => {
+  let strValues = '';
+  switch (field.type) {
+    case 'Numeric':
+      field.values.forEach((element) => {
+        switch (element.option) {
+          case 'between':
+            strValues = `${strValues} ${element.value1} <= ${field.name} <= ${element.value2} or `;
+            break;
+          default:
+            strValues = `${strValues} ${field.name} ${element.option} ${element.value1} or `;
+        }
+      });
+      if (strValues.endsWith('or '))
+        strValues = strValues.substring(0, strValues.length - 4);
+      break;
+    case 'Date':
+      field.values.forEach((element) => {
+        switch (element.option) {
+          case 'between':
+            strValues = `${strValues} ${element.startDate} <= ${field.name} <= ${element.endDate} or `;
+            break;
+          default:
+            strValues = `${strValues} ${field.name} ${element.option} ${element.startDate} or `;
+        }
+      });
+      if (strValues.endsWith(' or '))
+        strValues = strValues.substring(0, strValues.length - 4);
+      break;
+    case 'List':
+      strValues = `${strValues} ${field.name} = `;
+      field.values.forEach((element) => {
+        strValues = `${strValues} ${element.label}, `;
+      });
+      if (strValues.endsWith(', '))
+        strValues = strValues.substring(0, strValues.length - 2);
+      break;
+    //type : text
+    default:
+      strValues = `${strValues} ${field.name} = ${field.values}`;
+  }
+  return strValues;
+};
+
+const addHistory = (
+  kcID,
+  search,
+  searchName,
+  searchFields,
+  searchDescription,
+  setUserHistory
+) => {
+  addUserHistory(
+    sessionStorage.getItem('user_id'),
+    search,
+    searchName,
+    searchFields,
+    searchDescription
+  ).then(() => {
+    fetchHistory(setUserHistory);
+  });
+};
+
+const fetchHistory = (setUserHistory) => {
+  fetchUserHistory(sessionStorage.getItem('user_id')).then((result) => {
+    if (result[0] && result[0].ui_structure) {
+      result.forEach((item) => {
+        item.ui_structure = JSON.parse(item.ui_structure);
+        item.label = `${item.name} - ${new Date(item.createdat).toLocaleString()}`;
+      });
+    }
+    setUserHistory(result);
+  });
+};
+
+const updateSearch = (setSearch, searchFields, selectedOperatorId, setSearchCount) => {
+  let searchText = '';
+  searchFields.forEach((field) => {
+    if (field.isValidated) {
+      searchText =
+        searchText +
+        `{${fieldValuesToString(field)} } ${Operators[selectedOperatorId].value.toUpperCase()} `;
+    }
+  });
+  if (searchText.endsWith(' AND ')) {
+    searchText = searchText.substring(0, searchText.length - 5);
+  } else if (searchText.endsWith(' OR ')) {
+    searchText = searchText.substring(0, searchText.length - 4);
+  }
+  setSearchCount();
+  setSearch(searchText);
+};
+
+const HistorySelect = ({
+  sources,
+  setAvailableSources,
+  setSelectedSources,
+  setSearch,
+  setSearchFields,
+  setSearchCount,
+  setFieldCount,
+  userHistory,
+  setUserHistory,
+  selectedSavedSearch,
+  setSelectedSavedSearch,
+}) => {
+  const [historySelectError, setHistorySelectError] = useState(undefined);
+  const { t } = useTranslation('search');
+
+  useEffect(() => {
+    fetchHistory(setUserHistory);
+  }, [setUserHistory]);
+
+  const onHistoryChange = (selectedSavedSearch) => {
+    setHistorySelectError(undefined);
+    if (!!selectedSavedSearch[0].query) {
+      setSelectedSavedSearch(selectedSavedSearch);
+      setSearch(selectedSavedSearch[0].query);
+      setSearchCount();
+      setFieldCount([]);
+    }
+    if (!!selectedSavedSearch[0].ui_structure) {
+      updateSources(
+        selectedSavedSearch[0].ui_structure,
+        sources,
+        setSelectedSources,
+        setAvailableSources
+      );
+      setSearchFields(selectedSavedSearch[0].ui_structure);
+    }
+  };
+
+  const onHistorySearchChange = (value, hasMatchingOptions) => {
+    if (value.length === 0 || hasMatchingOptions) {
+      setHistorySelectError(undefined);
+    } else {
+      setHistorySelectError(t('search:advancedSearch.errorInvalidOption', { value }));
+    }
+  };
+
+  return (
+    <>
+      {userHistory && Object.keys(userHistory).length !== 0 && (
+        <EuiFormRow
+          error={historySelectError}
+          isInvalid={historySelectError !== undefined}
+        >
+          <EuiComboBox
+            placeholder={t('search:advancedSearch.searchHistory.placeholder')}
+            singleSelection={{ asPlainText: true }}
+            options={userHistory}
+            selectedOptions={selectedSavedSearch}
+            onChange={onHistoryChange}
+            onSearchChange={onHistorySearchChange}
+          />
+        </EuiFormRow>
+      )}
+    </>
+  );
+};
+
+const SearchBar = ({
+  search,
+  setSearch,
+  setSearchResults,
+  searchFields,
+  setSearchFields,
+  searchName,
+  setSearchName,
+  searchDescription,
+  setSearchDescription,
+  readOnlyQuery,
+  setReadOnlyQuery,
+  selectedSources,
+  setSelectedSources,
+  availableSources,
+  setAvailableSources,
+  standardFields,
+  sources,
+  setSelectedTabNumber,
+  searchCount,
+  setSearchCount,
+  setFieldCount,
+  isSaveSearchModalOpen,
+  setIsSaveSearchModalOpen,
+  selectedSavedSearch,
+  setSelectedSavedSearch,
+  selectedOperatorId,
+  createEditableQueryToast,
+}) => {
+  const { t } = useTranslation(['search', 'common']);
+  const [userHistory, setUserHistory] = useState({});
+  const [isLoading, setIsLoading] = useState(false);
+
+  const closeSaveSearchModal = () => {
+    setIsSaveSearchModalOpen(false);
+  };
+
+  const onClickAdvancedSearch = () => {
+    if (search.trim()) {
+      setIsLoading(true);
+      const queriesWithIndices = createAdvancedQueriesBySource(
+        standardFields,
+        search,
+        selectedSources,
+        availableSources
+      );
+      searchQuery(queriesWithIndices).then((result) => {
+        setSearchResults(result);
+        setSelectedTabNumber(1);
+        if (isLoading) {
+          setIsLoading(false);
+        }
+      });
+    }
+  };
+
+  const onClickCountResults = () => {
+    if (!!search) {
+      const queriesWithIndices = createAdvancedQueriesBySource(
+        standardFields,
+        search,
+        selectedSources,
+        availableSources
+      );
+      getQueryCount(queriesWithIndices).then((result) => {
+        if (result || result === 0) setSearchCount(result);
+      });
+    }
+  };
+
+  const onClickSaveSearch = () => {
+    if (!!searchName) {
+      addHistory(
+        sessionStorage.getItem('user_id'),
+        search,
+        searchName,
+        searchFields,
+        searchDescription,
+        setUserHistory
+      );
+      setSearchName('');
+      setSearchDescription('');
+      closeSaveSearchModal();
+    }
+  };
+
+  const SaveSearchModal = () => {
+    return (
+      <EuiOverlayMask>
+        <EuiModal onClose={closeSaveSearchModal} initialFocus="[name=searchName]">
+          <EuiModalHeader>
+            <EuiModalHeaderTitle>
+              {t('advancedSearch.searchHistory.saveSearch')}
+            </EuiModalHeaderTitle>
+          </EuiModalHeader>
+          <EuiModalBody>
+            <EuiForm>
+              <EuiFormRow label={t('advancedSearch.searchHistory.addSavedSearchName')}>
+                <EuiFieldText
+                  name="searchName"
+                  value={searchName}
+                  onChange={(e) => {
+                    setSearchName(e.target.value);
+                  }}
+                />
+              </EuiFormRow>
+              <EuiFormRow
+                label={t('advancedSearch.searchHistory.addSavedSearchDescription')}
+              >
+                <EuiTextArea
+                  value={searchDescription}
+                  onChange={(e) => setSearchDescription(e.target.value)}
+                  placeholder={t(
+                    'advancedSearch.searchHistory.addSavedSearchDescriptionPlaceholder'
+                  )}
+                  fullWidth
+                  compressed
+                />
+              </EuiFormRow>
+            </EuiForm>
+          </EuiModalBody>
+
+          <EuiModalFooter>
+            <EuiButtonEmpty
+              onClick={() => {
+                closeSaveSearchModal();
+              }}
+            >
+              {t('common:validationActions.cancel')}
+            </EuiButtonEmpty>
+            <EuiButton
+              onClick={() => {
+                onClickSaveSearch();
+              }}
+              fill
+            >
+              {t('common:validationActions.save')}
+            </EuiButton>
+          </EuiModalFooter>
+        </EuiModal>
+      </EuiOverlayMask>
+    );
+  };
+
+  return (
+    <>
+      <EuiFlexGroup>
+        <EuiFlexItem>
+          <EuiTextArea
+            readOnly={readOnlyQuery}
+            value={search}
+            onChange={(e) => setSearch(e.target.value)}
+            placeholder={t('search:advancedSearch.textQueryPlaceholder')}
+            fullWidth
+          />
+        </EuiFlexItem>
+        <EuiFlexItem grow={false}>
+          <EuiButton
+            size="s"
+            fill
+            onClick={() => {
+              onClickAdvancedSearch();
+            }}
+          >
+            {t('search:sendSearchButton')}
+          </EuiButton>
+          <EuiSpacer size="s" />
+          {!isNaN(searchCount) && (
+            <>
+              <EuiTextColor
+                color="secondary"
+                style={{ display: 'flex', justifyContent: 'center' }}
+              >
+                {t('search:advancedSearch.resultsCount', { count: searchCount })}
+              </EuiTextColor>
+              <EuiSpacer size="s" />
+            </>
+          )}
+          <EuiButton
+            size="s"
+            onClick={() => {
+              onClickCountResults();
+            }}
+          >
+            {t('search:advancedSearch.countResultsButton')}
+          </EuiButton>
+          <EuiSpacer size="s" />
+          <EuiButton
+            size="s"
+            onClick={() => {
+              setIsSaveSearchModalOpen(true);
+            }}
+          >
+            {t('search:advancedSearch.searchHistory.saveSearch')}
+          </EuiButton>
+          {isSaveSearchModalOpen && <SaveSearchModal />}
+          <EuiSpacer size="s" />
+          <EuiSwitch
+            compressed
+            label={t('search:advancedSearch.editableSearchButton')}
+            checked={!readOnlyQuery}
+            onChange={() => {
+              setReadOnlyQuery(!readOnlyQuery);
+              if (readOnlyQuery) {
+                createEditableQueryToast();
+              }
+            }}
+          />
+        </EuiFlexItem>
+      </EuiFlexGroup>
+      {isLoading && (
+        <EuiFlexGroup>
+          <EuiFlexItem>
+            <EuiProgress postion="fixed" size="l" color="accent" />
+          </EuiFlexItem>
+        </EuiFlexGroup>
+      )}
+      <EuiSpacer size="s" />
+      <EuiFlexGroup>
+        <EuiFlexItem>
+          <HistorySelect
+            sources={sources}
+            setAvailableSources={setAvailableSources}
+            setSelectedSources={setSelectedSources}
+            setSearch={setSearch}
+            searchFields={searchFields}
+            selectedOperatorId={selectedOperatorId}
+            userHistory={userHistory}
+            setUserHistory={setUserHistory}
+            setSearchFields={setSearchFields}
+            setSearchCount={setSearchCount}
+            setFieldCount={setFieldCount}
+            selectedSavedSearch={selectedSavedSearch}
+            setSelectedSavedSearch={setSelectedSavedSearch}
+          />
+        </EuiFlexItem>
+      </EuiFlexGroup>
+    </>
+  );
+};
+
+const PopoverSelect = ({
+  standardFields,
+  searchFields,
+  setSearchFields,
+  selectedField,
+  setSelectedField,
+  selectedSection,
+  setSelectedSection,
+  isPopoverSelectOpen,
+  setIsPopoverSelectOpen,
+}) => {
+  const { t } = useTranslation('search');
+
+  const handleAddField = () => {
+    if (!!selectedField[0]) {
+      const field = standardFields.find(
+        (item) =>
+          item.field_name.replace(/_|\./g, ' ') ===
+          selectedSection[0].label + ' ' + selectedField[0].label
+      );
+      switch (field.field_type) {
+        case 'Text':
+          setSearchFields([
+            ...searchFields,
+            new SearchField(field.field_name, field.field_type, '', false, field.sources),
+          ]);
+          break;
+        case 'List':
+          setSearchFields([
+            ...searchFields,
+            new SearchField(field.field_name, field.field_type, [], false, field.sources),
+          ]);
+          break;
+        default:
+          setSearchFields([
+            ...searchFields,
+            new SearchField(
+              field.field_name,
+              field.field_type,
+              [{}],
+              false,
+              field.sources
+            ),
+          ]);
+      }
+    }
+  };
+
+  const selectField = () => {
+    const renderOption = (option, searchValue, contentClassName) => {
+      const { label, color } = option;
+      return <EuiHealth color={color}>{label}</EuiHealth>;
+    };
+    if (selectedSection.length) {
+      return (
+        <>
+          <EuiComboBox
+            placeholder={t('search:advancedSearch.fields.addFieldPopover.title')}
+            singleSelection={{ asPlainText: true }}
+            options={getFieldsBySection(standardFields, selectedSection[0])}
+            selectedOptions={selectedField}
+            onChange={(selected) => setSelectedField(selected)}
+            isClearable={true}
+            renderOption={renderOption}
+          />
+          <EuiPopoverFooter>
+            <EuiButton
+              size="s"
+              onClick={() => {
+                handleAddField();
+                setIsPopoverSelectOpen(false);
+                setSelectedSection([]);
+                setSelectedField([]);
+              }}
+            >
+              {t('search:advancedSearch.fields.addFieldPopover.button')}
+            </EuiButton>
+          </EuiPopoverFooter>
+        </>
+      );
+    }
+  };
+
+  return (
+    <EuiPopover
+      panelPaddingSize="s"
+      button={
+        <EuiButton
+          iconType="listAdd"
+          iconSide="left"
+          onClick={() => setIsPopoverSelectOpen(!isPopoverSelectOpen)}
+        >
+          {t('search:advancedSearch.fields.addFieldPopover.openPopoverButton')}
+        </EuiButton>
+      }
+      isOpen={isPopoverSelectOpen}
+      closePopover={() => setIsPopoverSelectOpen(false)}
+    >
+      <div style={{ width: 'intrinsic', minWidth: 240 }}>
+        <EuiPopoverTitle>
+          {t('search:advancedSearch.fields.addFieldPopover.title')}
+        </EuiPopoverTitle>
+        <EuiComboBox
+          placeholder={t('search:advancedSearch.fields.addFieldPopover.selectSection')}
+          singleSelection={{ asPlainText: true }}
+          options={getSections(standardFields)}
+          selectedOptions={selectedSection}
+          onChange={(selected) => {
+            setSelectedSection(selected);
+            setSelectedField([]);
+          }}
+          isClearable={false}
+        />
+      </div>
+      {selectField()}
+    </EuiPopover>
+  );
+};
+
+const PopoverValueContent = ({
+  index,
+  standardFields,
+  searchFields,
+  setSearchFields,
+  valueError,
+  setValueError,
+  setSearch,
+  setSearchCount,
+  fieldCount,
+  setFieldCount,
+  isPopoverValueOpen,
+  setIsPopoverValueOpen,
+  selectedOperatorId,
+  datePickerStyles,
+  createPolicyToast,
+  selectedSources,
+  setSelectedSources,
+  availableSources,
+  setAvailableSources,
+}) => {
+  const { t } = useTranslation(['search', 'common']);
+
+  const onValueSearchChange = (value, hasMatchingOptions) => {
+    if (value.length === 0 || hasMatchingOptions) {
+      setValueError(undefined);
+    } else {
+      setValueError(t('search:advancedSearch.errorInvalidOption', { value }));
+    }
+  };
+
+  const validateFieldValues = () => {
+    let fieldValues;
+    if (Array.isArray(searchFields[index].values)) {
+      fieldValues = [];
+      searchFields[index].values.forEach((value) => {
+        if (!!value) {
+          fieldValues.push(value);
+        }
+      });
+    } else {
+      fieldValues = searchFields[index].values;
+    }
+
+    const updatedSearchFields = updateArrayElement(
+      searchFields,
+      index,
+      new SearchField(
+        searchFields[index].name,
+        searchFields[index].type,
+        fieldValues,
+        true,
+        searchFields[index].sources
+      )
+    );
+    setSearchFields(updatedSearchFields);
+    updateSearch(setSearch, updatedSearchFields, selectedOperatorId, setSearchCount);
+    setFieldCount(updateArrayElement(fieldCount, index));
+    if (searchFields[index].sources.length) {
+      const filteredSources = [];
+      searchFields[index].sources.forEach((sourceId) => {
+        let source;
+        if (selectedSources.length) {
+          source = selectedSources.find((src) => src.id === sourceId);
+        } else {
+          source = availableSources.find((src) => src.id === sourceId);
+        }
+        if (source) {
+          filteredSources.push(source);
+        }
+      });
+      setAvailableSources(filteredSources);
+      setSelectedSources(filteredSources);
+      createPolicyToast();
+    }
+  };
+
+  const invalidateFieldValues = () => {
+    const updatedSearchFields = updateArrayElement(
+      searchFields,
+      index,
+      new SearchField(
+        searchFields[index].name,
+        searchFields[index].type,
+        searchFields[index].values,
+        false,
+        searchFields[index].sources
+      )
+    );
+    setSearchFields(updatedSearchFields);
+    updateSearch(setSearch, updatedSearchFields, selectedOperatorId, setSearchCount);
+  };
+
+  const ValuePopoverFooter = (i) => {
+    if (i === searchFields[index].values.length - 1) {
+      return (
+        <EuiPopoverFooter>
+          <EuiButton
+            size="s"
+            onClick={() => {
+              setSearchFields(
+                updateArrayElement(
+                  searchFields,
+                  index,
+                  new SearchField(
+                    searchFields[index].name,
+                    searchFields[index].type,
+                    [...searchFields[index].values, {}],
+                    false,
+                    searchFields[index].sources
+                  )
+                )
+              );
+            }}
+          >
+            {t('search:advancedSearch.fields.fieldContentPopover.addValue')}
+          </EuiButton>
+          <EuiButton
+            size="s"
+            style={{ float: 'right' }}
+            onClick={() => {
+              validateFieldValues();
+              setIsPopoverValueOpen(updateArrayElement(isPopoverValueOpen, index, false));
+            }}
+          >
+            {t('common:validationActions.validate')}
+          </EuiButton>
+        </EuiPopoverFooter>
+      );
+    }
+  };
+
+  const addFieldValue = (i, selectedOption) => {
+    setSearchFields(
+      updateSearchFieldValues(
+        searchFields,
+        index,
+        updateArrayElement(searchFields[index].values, i, { option: selectedOption })
+      )
+    );
+  };
+
+  const getListFieldValues = () => {
+    const listFieldValues = [];
+    standardFields
+      .find((item) => item.field_name === searchFields[index].name)
+      .values.split(', ')
+      .sort()
+      .forEach((element) => {
+        listFieldValues.push({ label: element });
+      });
+    return listFieldValues;
+  };
+
+  switch (searchFields[index].type) {
+    case 'Text':
+      return (
+        <>
+          <EuiFlexItem>
+            <EuiFieldText
+              placeholder={t(
+                'search:advancedSearch.fields.fieldContentPopover.inputTextValue'
+              )}
+              value={searchFields[index].values}
+              onChange={(e) =>
+                setSearchFields(
+                  updateSearchFieldValues(searchFields, index, e.target.value)
+                )
+              }
+            />
+          </EuiFlexItem>
+          <EuiPopoverFooter>
+            <EuiButton
+              size="s"
+              style={{ float: 'right' }}
+              onClick={() => {
+                validateFieldValues();
+                setIsPopoverValueOpen(
+                  updateArrayElement(isPopoverValueOpen, index, false)
+                );
+              }}
+            >
+              {t('common:validationActions.validate')}
+            </EuiButton>
+          </EuiPopoverFooter>
+        </>
+      );
+    case 'List':
+      return (
+        <>
+          <EuiFormRow error={valueError} isInvalid={valueError !== undefined}>
+            <EuiComboBox
+              placeholder={t(
+                'search:advancedSearch.fields.fieldContentPopover.selectValues'
+              )}
+              options={getListFieldValues()}
+              selectedOptions={searchFields[index].values}
+              onChange={(selectedOptions) => {
+                setValueError(undefined);
+                setSearchFields(
+                  updateSearchFieldValues(searchFields, index, selectedOptions)
+                );
+              }}
+              onSearchChange={onValueSearchChange}
+            />
+          </EuiFormRow>
+          <EuiPopoverFooter>
+            <EuiButton
+              size="s"
+              style={{ float: 'right' }}
+              onClick={() => {
+                validateFieldValues();
+                setIsPopoverValueOpen(
+                  updateArrayElement(isPopoverValueOpen, index, false)
+                );
+              }}
+            >
+              {t('common:validationActions.validate')}
+            </EuiButton>
+          </EuiPopoverFooter>
+        </>
+      );
+    case 'Numeric':
+      const NumericValues = (i) => {
+        if (!!searchFields[index].values[i].option) {
+          switch (searchFields[index].values[i].option) {
+            case 'between':
+              return (
+                <>
+                  <EuiFlexItem>
+                    <EuiFieldText
+                      placeholder={t(
+                        'search:advancedSearch.fields.fieldContentPopover.firstValue'
+                      )}
+                      value={searchFields[index].values[i].value1}
+                      onChange={(e) => {
+                        setSearchFields(
+                          updateSearchFieldValues(
+                            searchFields,
+                            index,
+                            updateArrayElement(searchFields[index].values, i, {
+                              option: searchFields[index].values[i].option,
+                              value1: e.target.value,
+                              value2: searchFields[index].values[i].value2,
+                            })
+                          )
+                        );
+                      }}
+                    />
+                  </EuiFlexItem>
+                  <EuiFlexItem>
+                    <EuiFieldText
+                      placeholder={t(
+                        'search:advancedSearch.fields.fieldContentPopover.secondValue'
+                      )}
+                      value={searchFields[index].values[i].value2}
+                      onChange={(e) =>
+                        setSearchFields(
+                          updateSearchFieldValues(
+                            searchFields,
+                            index,
+                            updateArrayElement(searchFields[index].values, i, {
+                              option: searchFields[index].values[i].option,
+                              value1: searchFields[index].values[i].value1,
+                              value2: e.target.value,
+                            })
+                          )
+                        )
+                      }
+                    />
+                  </EuiFlexItem>
+                  {ValuePopoverFooter(i)}
+                </>
+              );
+
+            default:
+              return (
+                <>
+                  <EuiFlexItem>
+                    <EuiFieldText
+                      placeholder={t(
+                        'search:advancedSearch.fields.fieldContentPopover.inputTextValue'
+                      )}
+                      value={searchFields[index].values[i].value1}
+                      onChange={(e) => {
+                        setSearchFields(
+                          updateSearchFieldValues(
+                            searchFields,
+                            index,
+                            updateArrayElement(searchFields[index].values, i, {
+                              option: searchFields[index].values[i].option,
+                              value1: e.target.value,
+                              value2: searchFields[index].values[i].value2,
+                            })
+                          )
+                        );
+                      }}
+                    />
+                  </EuiFlexItem>
+                  {ValuePopoverFooter(i)}
+                </>
+              );
+          }
+        }
+      };
+
+      return (
+        <>
+          {searchFields[index].values.map((value, i) => (
+            <div key={i}>
+              <EuiSelect
+                hasNoInitialSelection
+                id="Select an option"
+                options={NumericOptions}
+                value={searchFields[index].values[i].option}
+                onChange={(e) => {
+                  addFieldValue(i, e.target.value);
+                  invalidateFieldValues();
+                }}
+              />
+              {NumericValues(i)}
+            </div>
+          ))}
+        </>
+      );
+    case 'Date':
+      const SelectDates = (i) => {
+        if (!!searchFields[index].values[i].option) {
+          switch (searchFields[index].values[i].option) {
+            case 'between':
+              return (
+                <>
+                  <form className={datePickerStyles.container} noValidate>
+                    <TextField
+                      label={t(
+                        'search:advancedSearch.fields.fieldContentPopover.betweenDate'
+                      )}
+                      type="date"
+                      defaultValue={
+                        !!searchFields[index].values[i].startDate
+                          ? searchFields[index].values[i].startDate
+                          : Date.now()
+                      }
+                      className={datePickerStyles.textField}
+                      InputLabelProps={{
+                        shrink: true,
+                      }}
+                      onChange={(e) =>
+                        setSearchFields(
+                          updateSearchFieldValues(
+                            searchFields,
+                            index,
+                            updateArrayElement(searchFields[index].values, i, {
+                              option: searchFields[index].values[i].option,
+                              startDate: e.target.value,
+                              endDate: searchFields[index].values[i].endDate,
+                            })
+                          )
+                        )
+                      }
+                    />
+                  </form>
+                  <form className={datePickerStyles.container} noValidate>
+                    <TextField
+                      label={t(
+                        'search:advancedSearch.fields.fieldContentPopover.andDate'
+                      )}
+                      type="date"
+                      defaultValue={
+                        !!searchFields[index].values[i].endDate
+                          ? searchFields[index].values[i].endDate
+                          : Date.now()
+                      }
+                      className={datePickerStyles.textField}
+                      InputLabelProps={{
+                        shrink: true,
+                      }}
+                      onChange={(e) =>
+                        setSearchFields(
+                          updateSearchFieldValues(
+                            searchFields,
+                            index,
+                            updateArrayElement(searchFields[index].values, i, {
+                              option: searchFields[index].values[i].option,
+                              startDate: searchFields[index].values[i].startDate,
+                              endDate: e.target.value,
+                            })
+                          )
+                        )
+                      }
+                    />
+                  </form>
+                  {ValuePopoverFooter(i)}
+                </>
+              );
+
+            default:
+              return (
+                <>
+                  <form className={datePickerStyles.container} noValidate>
+                    <TextField
+                      type="date"
+                      defaultValue={
+                        !!searchFields[index].values[i].startDate
+                          ? searchFields[index].values[i].startDate
+                          : Date.now()
+                      }
+                      className={datePickerStyles.textField}
+                      InputLabelProps={{
+                        shrink: true,
+                      }}
+                      onChange={(e) =>
+                        setSearchFields(
+                          updateSearchFieldValues(
+                            searchFields,
+                            index,
+                            updateArrayElement(searchFields[index].values, i, {
+                              option: searchFields[index].values[i].option,
+                              startDate: e.target.value,
+                              endDate: Date.now(),
+                            })
+                          )
+                        )
+                      }
+                    />
+                  </form>
+                  {ValuePopoverFooter(i)}
+                </>
+              );
+          }
+        }
+      };
+
+      return (
+        <>
+          {searchFields[index].values.map((value, i) => (
+            <div key={i}>
+              <EuiSelect
+                hasNoInitialSelection
+                id="Select an option"
+                options={DateOptions}
+                value={searchFields[index].values[i].option}
+                onChange={(e) => {
+                  addFieldValue(i, e.target.value);
+                  invalidateFieldValues();
+                }}
+              />
+              {SelectDates(i)}
+            </div>
+          ))}
+        </>
+      );
+    default:
+  }
+};
+
+const PopoverValueButton = ({
+  index,
+  standardFields,
+  searchFields,
+  setSearchFields,
+  isPopoverValueOpen,
+  setIsPopoverValueOpen,
+  valueError,
+  setValueError,
+  setSearch,
+  setSearchCount,
+  fieldCount,
+  setFieldCount,
+  selectedOperatorId,
+  datePickerStyles,
+  createPolicyToast,
+  selectedSources,
+  setSelectedSources,
+  availableSources,
+  setAvailableSources,
+}) => {
+  const { t } = useTranslation('search');
+
+  return (
+    <EuiPopover
+      panelPaddingSize="s"
+      button={
+        <EuiButtonIcon
+          size="s"
+          color="primary"
+          onClick={() =>
+            setIsPopoverValueOpen(
+              updateArrayElement(isPopoverValueOpen, index, !isPopoverValueOpen[index])
+            )
+          }
+          iconType="documentEdit"
+          title={t('search:advancedSearch.fields.fieldContentPopover.addFieldValues')}
+          aria-label={t(
+            'search:advancedSearch.fields.fieldContentPopover.addFieldValues'
+          )}
+        />
+      }
+      isOpen={isPopoverValueOpen[index]}
+      closePopover={() =>
+        setIsPopoverValueOpen(updateArrayElement(isPopoverValueOpen, index, false))
+      }
+    >
+      <div style={{ width: 240 }}>
+        <PopoverValueContent
+          index={index}
+          standardFields={standardFields}
+          searchFields={searchFields}
+          setSearchFields={setSearchFields}
+          valueError={valueError}
+          setValueError={setValueError}
+          setSearch={setSearch}
+          setSearchCount={setSearchCount}
+          fieldCount={fieldCount}
+          setFieldCount={setFieldCount}
+          isPopoverValueOpen={isPopoverValueOpen}
+          setIsPopoverValueOpen={setIsPopoverValueOpen}
+          selectedOperatorId={selectedOperatorId}
+          datePickerStyles={datePickerStyles}
+          createPolicyToast={createPolicyToast}
+          selectedSources={selectedSources}
+          setSelectedSources={setSelectedSources}
+          availableSources={availableSources}
+          setAvailableSources={setAvailableSources}
+        />
+      </div>
+    </EuiPopover>
+  );
+};
+
+const FieldsPanel = ({
+  standardFields,
+  setStandardFields,
+  searchFields,
+  setSearchFields,
+  selectedField,
+  setSelectedField,
+  selectedSection,
+  setSelectedSection,
+  isPopoverSelectOpen,
+  setIsPopoverSelectOpen,
+  isPopoverValueOpen,
+  setIsPopoverValueOpen,
+  valueError,
+  setValueError,
+  search,
+  setSearch,
+  setSearchCount,
+  selectedOperatorId,
+  setSelectedOperatorId,
+  fieldCount,
+  setFieldCount,
+  availableSources,
+  setAvailableSources,
+  selectedSources,
+  setSelectedSources,
+  sources,
+  datePickerStyles,
+  createPolicyToast,
+}) => {
+  const { t } = useTranslation('search');
+
+  const countFieldValues = (field, index) => {
+    const fieldStr = `{${fieldValuesToString(field)}}`;
+    const queriesWithIndices = createAdvancedQueriesBySource(
+      standardFields,
+      fieldStr,
+      selectedSources,
+      availableSources
+    );
+    getQueryCount(queriesWithIndices).then((result) => {
+      if (result || result === 0)
+        setFieldCount(updateArrayElement(fieldCount, index, result));
+    });
+  };
+
+  const handleRemoveField = (index) => {
+    const updatedSearchFields = removeArrayElement(searchFields, index);
+    setSearchFields(updatedSearchFields);
+    updateSources(updatedSearchFields, sources, setSelectedSources, setAvailableSources);
+    updateSearch(setSearch, updatedSearchFields, selectedOperatorId, setSearchCount);
+  };
+
+  const handleClearValues = (index) => {
+    let updatedSearchFields;
+    switch (searchFields[index].type) {
+      case 'Text':
+        updatedSearchFields = updateArrayElement(
+          searchFields,
+          index,
+          new SearchField(
+            searchFields[index].name,
+            searchFields[index].type,
+            '',
+            false,
+            searchFields[index].sources
+          )
+        );
+        break;
+      case 'List':
+        updatedSearchFields = updateArrayElement(
+          searchFields,
+          index,
+          new SearchField(
+            searchFields[index].name,
+            searchFields[index].type,
+            [],
+            false,
+            searchFields[index].sources
+          )
+        );
+        break;
+      default:
+        updatedSearchFields = updateArrayElement(
+          searchFields,
+          index,
+          new SearchField(
+            searchFields[index].name,
+            searchFields[index].type,
+            [{}],
+            false,
+            searchFields[index].sources
+          )
+        );
+    }
+    setSearchFields(updatedSearchFields);
+    updateSources(updatedSearchFields, sources, setSelectedSources, setAvailableSources);
+    setFieldCount(updateArrayElement(fieldCount, index));
+    updateSearch(setSearch, updatedSearchFields, selectedOperatorId, setSearchCount);
+  };
+
+  if (standardFields === []) {
+    return <h2>{t('search:advancedSearch.fields.loadingFields')}</h2>;
+  }
+
+  return (
+    <>
+      <EuiTitle size="xs">
+        <h2>{t('search:advancedSearch.fields.title')}</h2>
+      </EuiTitle>
+      <EuiPanel paddingSize="m">
+        <EuiFlexGroup direction="column">
+          {searchFields.map((field, index) => (
+            <EuiPanel key={'field' + index} paddingSize="s">
+              <EuiFlexItem grow={false}>
+                <EuiFlexGroup direction="row" alignItems="center">
+                  <EuiFlexItem grow={false}>
+                    <EuiButtonIcon
+                      size="s"
+                      color="danger"
+                      onClick={() => handleRemoveField(index)}
+                      iconType="indexClose"
+                      title={t('search:advancedSearch.fields.removeFieldButton')}
+                      aria-label={t('search:advancedSearch.fields.removeFieldButton')}
+                    />
+                  </EuiFlexItem>
+                  <EuiFlexItem>
+                    {field.isValidated ? (
+                      <>
+                        {field.sources.length ? (
+                          <EuiHealth color="danger">
+                            {fieldValuesToString(field).replace(/_|\./g, ' ')}
+                          </EuiHealth>
+                        ) : (
+                          <EuiHealth color="primary">
+                            {fieldValuesToString(field).replace(/_|\./g, ' ')}
+                          </EuiHealth>
+                        )}
+                      </>
+                    ) : (
+                      <>
+                        {field.sources.length ? (
+                          <EuiHealth color="danger">
+                            {field.name.replace(/_|\./g, ' ')}
+                          </EuiHealth>
+                        ) : (
+                          <EuiHealth color="primary">
+                            {field.name.replace(/_|\./g, ' ')}
+                          </EuiHealth>
+                        )}
+                      </>
+                    )}
+                  </EuiFlexItem>
+                  <EuiFlexItem grow={false}>
+                    {!isNaN(fieldCount[index]) && (
+                      <EuiTextColor color="secondary">
+                        {t('search:advancedSearch.resultsCount', {
+                          count: fieldCount[index],
+                        })}
+                      </EuiTextColor>
+                    )}
+                  </EuiFlexItem>
+                  <EuiFlexItem grow={false}>
+                    {field.isValidated && (
+                      <EuiButtonIcon
+                        size="s"
+                        onClick={() => countFieldValues(field, index)}
+                        iconType="number"
+                        title={t('search:advancedSearch.countResultsButton')}
+                        aria-label={t('search:advancedSearch.countResultsButton')}
+                      />
+                    )}
+                  </EuiFlexItem>
+                  <EuiFlexItem grow={false}>
+                    {field.isValidated && (
+                      <EuiButtonIcon
+                        size="s"
+                        color="danger"
+                        onClick={() => handleClearValues(index)}
+                        iconType="trash"
+                        title={t('search:advancedSearch.fields.clearValues')}
+                        aria-label={t('search:advancedSearch.fields.clearValues')}
+                      />
+                    )}
+                  </EuiFlexItem>
+                  <EuiFlexItem grow={false}>
+                    <PopoverValueButton
+                      index={index}
+                      standardFields={standardFields}
+                      setStandardFields={setStandardFields}
+                      searchFields={searchFields}
+                      setSearchFields={setSearchFields}
+                      isPopoverValueOpen={isPopoverValueOpen}
+                      setIsPopoverValueOpen={setIsPopoverValueOpen}
+                      valueError={valueError}
+                      setValueError={setValueError}
+                      search={search}
+                      setSearch={setSearch}
+                      setSearchCount={setSearchCount}
+                      fieldCount={fieldCount}
+                      setFieldCount={setFieldCount}
+                      selectedOperatorId={selectedOperatorId}
+                      datePickerStyles={datePickerStyles}
+                      createPolicyToast={createPolicyToast}
+                      selectedSources={selectedSources}
+                      setSelectedSources={setSelectedSources}
+                      availableSources={availableSources}
+                      setAvailableSources={setAvailableSources}
+                    />
+                  </EuiFlexItem>
+                </EuiFlexGroup>
+              </EuiFlexItem>
+            </EuiPanel>
+          ))}
+        </EuiFlexGroup>
+        <EuiSpacer size="l" />
+        <PopoverSelect
+          standardFields={standardFields}
+          setStandardFields={setStandardFields}
+          searchFields={searchFields}
+          setSearchFields={setSearchFields}
+          selectedField={selectedField}
+          setSelectedField={setSelectedField}
+          selectedSection={selectedSection}
+          setSelectedSection={setSelectedSection}
+          isPopoverSelectOpen={isPopoverSelectOpen}
+          setIsPopoverSelectOpen={setIsPopoverSelectOpen}
+          fieldCount={fieldCount}
+          setFieldCount={setFieldCount}
+          selectedSources={selectedSources}
+          setSelectedSources={setSelectedSources}
+        />
+      </EuiPanel>
+      <EuiSpacer size="s" />
+      <EuiRadioGroup
+        options={Operators.map((operator) => {
+          return { ...operator, label: t(operator.label) };
+        })}
+        idSelected={selectedOperatorId}
+        onChange={(id) => {
+          setSelectedOperatorId(id);
+          updateSearch(setSearch, searchFields, id, setSearchCount);
+        }}
+        name="operators group"
+        legend={{
+          children: <span>{t('search:advancedSearch.searchOptions.title')}</span>,
+        }}
+      />
+    </>
+  );
+};
+
+const SourceSelect = ({
+  availableSources,
+  selectedSources,
+  setSelectedSources,
+  sourceSelectError,
+  setSourceSelectError,
+}) => {
+  const { t } = useTranslation('search');
+
+  if (Object.keys(availableSources).length === 0) {
+    return (
+      <p>
+        <EuiIcon type="alert" color="danger" />
+      </p>
+    );
+  }
+  availableSources.forEach((source) => {
+    if (source.name) {
+      source = changeNameToLabel(source);
+    }
+  });
+
+  const onSourceChange = (selectedOptions) => {
+    setSourceSelectError(undefined);
+    setSelectedSources(selectedOptions);
+  };
+
+  const onSourceSearchChange = (value, hasMatchingOptions) => {
+    if (value.length === 0 || hasMatchingOptions) {
+      setSourceSelectError(undefined);
+    } else {
+      setSourceSelectError(
+        t('search:advancedSearch.errorInvalidOption', { value: value })
+      );
+    }
+  };
+
+  return (
+    <>
+      <EuiTitle size="xs">
+        <h2>{t('search:advancedSearch.partnerSources.title')}</h2>
+      </EuiTitle>
+      <EuiSpacer size="s" />
+      <EuiFlexItem>
+        <EuiFormRow error={sourceSelectError} isInvalid={sourceSelectError !== undefined}>
+          <EuiComboBox
+            placeholder={t('search:advancedSearch.partnerSources.allSourcesSelected')}
+            options={availableSources}
+            selectedOptions={selectedSources}
+            onChange={onSourceChange}
+            onSearchChange={onSourceSearchChange}
+          />
+        </EuiFormRow>
+      </EuiFlexItem>
+    </>
+  );
+};
+
+const AdvancedSearch = ({
+  search,
+  setSearch,
+  searchResults,
+  setSearchResults,
+  searchFields,
+  setSearchFields,
+  searchName,
+  setSearchName,
+  searchDescription,
+  setSearchDescription,
+  readOnlyQuery,
+  setReadOnlyQuery,
+  selectedSources,
+  setSelectedSources,
+  availableSources,
+  setAvailableSources,
+  standardFields,
+  setStandardFields,
+  sources,
+  setSelectedTabNumber,
+  searchCount,
+  setSearchCount,
+  setFieldCount,
+  isReadOnlyModalOpen,
+  setIsReadOnlyModalOpen,
+  isSaveSearchModalOpen,
+  setIsSaveSearchModalOpen,
+  userHistory,
+  setUserHistory,
+  selectedSavedSearch,
+  setSelectedSavedSearch,
+  selectedOperatorId,
+  setIsAdvancedSearch,
+  isAdvancedSearch,
+  selectedField,
+  selectedSection,
+  setSelectedField,
+  setSelectedSection,
+  isPopoverSelectOpen,
+  setIsPopoverSelectOpen,
+  setIsPopoverValueOpen,
+  isPopoverValueOpen,
+  valueError,
+  setValueError,
+  setSelectedOperatorId,
+  fieldCount,
+  sourceSelectError,
+  datePickerStyles,
+  setSourceSelectError,
+}) => {
+  const { t } = useTranslation('search');
+  const [notificationToasts, setNotificationToasts] = useState([]);
+
+  const createPolicyToast = () => {
+    const toast = {
+      title: t('search:advancedSearch.policyToast.title'),
+      color: 'warning',
+      iconType: 'alert',
+      toastLifeTimeMs: 15000,
+      text: (
+        <>
+          <p>{t('search:advancedSearch.policyToast.content.0')}</p>
+          <p>{t('search:advancedSearch.policyToast.content.1')}</p>
+          <p>{t('search:advancedSearch.policyToast.content.2')}</p>
+        </>
+      ),
+    };
+    setNotificationToasts(notificationToasts.concat(toast));
+  };
+
+  const createEditableQueryToast = () => {
+    const toast = {
+      title: t('search:advancedSearch.policyToast.title'),
+      color: 'warning',
+      iconType: 'alert',
+      toastLifeTimeMs: 15000,
+      text: (
+        <>
+          <p>{t('search:advancedSearch.editableQueryToast.content.part1')}</p>
+          <ul>
+            <li>{t('search:advancedSearch.editableQueryToast.content.part2')}</li>
+            <li>{t('search:advancedSearch.editableQueryToast.content.part3')}</li>
+            <li>{t('search:advancedSearch.editableQueryToast.content.part4')}</li>
+          </ul>
+        </>
+      ),
+    };
+    setNotificationToasts(notificationToasts.concat(toast));
+  };
+
+  const removeToast = (removedToast) => {
+    setNotificationToasts(
+      notificationToasts.filter((toast) => toast.id !== removedToast.id)
+    );
+  };
+
+  return (
+    <>
+      <EuiFlexGroup>
+        <EuiFlexItem grow={false}>
+          <EuiSpacer size="s" />
+          <EuiButtonEmpty
+            onClick={() => {
+              setIsAdvancedSearch(!isAdvancedSearch);
+            }}
+          >
+            {t('search:advancedSearch.switchSearchMode')}
+          </EuiButtonEmpty>
+        </EuiFlexItem>
+      </EuiFlexGroup>
+      <EuiFlexGroup>
+        <EuiFlexItem>
+          <EuiSpacer size="s" />
+          <SearchBar
+            search={search}
+            setSearch={setSearch}
+            searchResults={searchResults}
+            setSearchResults={setSearchResults}
+            searchFields={searchFields}
+            setSearchFields={setSearchFields}
+            searchName={searchName}
+            setSearchName={setSearchName}
+            searchDescription={searchDescription}
+            setSearchDescription={setSearchDescription}
+            readOnlyQuery={readOnlyQuery}
+            setReadOnlyQuery={setReadOnlyQuery}
+            selectedSources={selectedSources}
+            setSelectedSources={setSelectedSources}
+            availableSources={availableSources}
+            setAvailableSources={setAvailableSources}
+            standardFields={standardFields}
+            sources={sources}
+            setSelectedTabNumber={setSelectedTabNumber}
+            searchCount={searchCount}
+            setSearchCount={setSearchCount}
+            setFieldCount={setFieldCount}
+            isReadOnlyModalOpen={isReadOnlyModalOpen}
+            setIsReadOnlyModalOpen={setIsReadOnlyModalOpen}
+            isSaveSearchModalOpen={isSaveSearchModalOpen}
+            setIsSaveSearchModalOpen={setIsSaveSearchModalOpen}
+            userHistory={userHistory}
+            setUserHistory={setUserHistory}
+            selectedSavedSearch={selectedSavedSearch}
+            setSelectedSavedSearch={setSelectedSavedSearch}
+            selectedOperatorId={selectedOperatorId}
+            createEditableQueryToast={createEditableQueryToast}
+          />
+        </EuiFlexItem>
+      </EuiFlexGroup>
+      <EuiFlexGroup>
+        <EuiFlexItem>
+          <EuiSpacer size="s" />
+          <FieldsPanel
+            standardFields={standardFields}
+            setStandardFields={setStandardFields}
+            searchFields={searchFields}
+            setSearchFields={setSearchFields}
+            selectedField={selectedField}
+            setSelectedField={setSelectedField}
+            selectedSection={selectedSection}
+            setSelectedSection={setSelectedSection}
+            isPopoverSelectOpen={isPopoverSelectOpen}
+            setIsPopoverSelectOpen={setIsPopoverSelectOpen}
+            isPopoverValueOpen={isPopoverValueOpen}
+            setIsPopoverValueOpen={setIsPopoverValueOpen}
+            valueError={valueError}
+            setValueError={setValueError}
+            search={search}
+            setSearch={setSearch}
+            setSearchCount={setSearchCount}
+            selectedOperatorId={selectedOperatorId}
+            setSelectedOperatorId={setSelectedOperatorId}
+            fieldCount={fieldCount}
+            setFieldCount={setFieldCount}
+            availableSources={availableSources}
+            setAvailableSources={setAvailableSources}
+            selectedSources={selectedSources}
+            setSelectedSources={setSelectedSources}
+            sources={sources}
+            datePickerStyles={datePickerStyles}
+            createPolicyToast={createPolicyToast}
+          />
+          <EuiSpacer size="s" />
+          <SourceSelect
+            availableSources={availableSources}
+            selectedSources={selectedSources}
+            setSelectedSources={setSelectedSources}
+            sourceSelectError={sourceSelectError}
+            setSourceSelectError={setSourceSelectError}
+          />
+        </EuiFlexItem>
+      </EuiFlexGroup>
+      <EuiGlobalToastList
+        toasts={notificationToasts}
+        dismissToast={removeToast}
+        toastLifeTimeMs={2500}
+      />
+    </>
+  );
+};
+
+export default AdvancedSearch;
diff --git a/src/pages/search/BasicSearch/BasicSearch.js b/src/pages/search/BasicSearch/BasicSearch.js
new file mode 100644
index 0000000000000000000000000000000000000000..6f8892dfadc2b06779d33e3ffccd166cadb54361
--- /dev/null
+++ b/src/pages/search/BasicSearch/BasicSearch.js
@@ -0,0 +1,93 @@
+import React, { useState } from 'react';
+import {
+  EuiButton,
+  EuiButtonEmpty,
+  EuiFieldSearch,
+  EuiFlexGroup,
+  EuiFlexItem,
+  EuiProgress,
+  EuiSpacer,
+} from '@elastic/eui';
+import { createBasicQueriesBySource } from '../../../Utils';
+import { searchQuery } from '../../../actions/source';
+import { useTranslation } from 'react-i18next';
+
+const BasicSearch = ({
+  standardFields,
+  availableSources,
+  selectedSources,
+  basicSearch,
+  setBasicSearch,
+  setIsAdvancedSearch,
+  isAdvancedSearch,
+  setSearchResults,
+  setSelectedTabNumber,
+}) => {
+  const { t } = useTranslation('search');
+  const [isLoading, setIsLoading] = useState(false);
+
+  const onFormSubmit = () => {
+    setIsLoading(true);
+    const queriesWithIndices = createBasicQueriesBySource(
+      standardFields,
+      basicSearch,
+      selectedSources,
+      availableSources
+    );
+    searchQuery(queriesWithIndices).then((result) => {
+      setSearchResults(result);
+      setSelectedTabNumber(1);
+      if (isLoading) {
+        setIsLoading(false);
+      }
+    });
+  };
+
+  return (
+    <>
+      <EuiFlexGroup>
+        <EuiFlexItem grow={false}>
+          <EuiSpacer size="s" />
+          <EuiButtonEmpty
+            onClick={() => {
+              setIsAdvancedSearch(!isAdvancedSearch);
+            }}
+          >
+            {t('basicSearch.switchSearchMode')}
+          </EuiButtonEmpty>
+        </EuiFlexItem>
+      </EuiFlexGroup>
+      <EuiFlexGroup>
+        <EuiFlexItem>
+          <EuiSpacer size="s" />
+          <form onSubmit={() => onFormSubmit()}>
+            <EuiFlexGroup>
+              <EuiFlexItem>
+                <EuiFieldSearch
+                  value={basicSearch}
+                  onChange={(e) => setBasicSearch(e.target.value)}
+                  placeholder={t('basicSearch.searchInputPlaceholder')}
+                  fullWidth
+                />
+              </EuiFlexItem>
+              <EuiFlexItem grow={false}>
+                <EuiButton type="submit" fill isDisabled={isAdvancedSearch}>
+                  {t('sendSearchButton')}
+                </EuiButton>
+              </EuiFlexItem>
+            </EuiFlexGroup>
+          </form>
+          {isLoading && (
+            <EuiFlexGroup>
+              <EuiFlexItem>
+                <EuiProgress postion="fixed" size="l" color="accent" />
+              </EuiFlexItem>
+            </EuiFlexGroup>
+          )}
+        </EuiFlexItem>
+      </EuiFlexGroup>
+    </>
+  );
+};
+
+export default BasicSearch;
diff --git a/src/pages/search/Data.js b/src/pages/search/Data.js
index c6577648ea4029f5243b834d71fac2563982fbbb..d0a399a60e2e9dbe10a10c075a207501b35c6130 100644
--- a/src/pages/search/Data.js
+++ b/src/pages/search/Data.js
@@ -2,12 +2,12 @@ export const Operators = [
   {
     id: '0',
     value: 'And',
-    label: 'Match all criterias',
+    label: 'search:advancedSearch.searchOptions.matchAll',
   },
   {
     id: '1',
     value: 'Or',
-    label: 'Match at least one criteria',
+    label: 'search:advancedSearch.searchOptions.matchAtLeastOne',
   },
 ];
 
diff --git a/src/pages/search/Search.js b/src/pages/search/Search.js
index a1c0044118e8373b06e4335e97f36b759329e7ff..61bd93e712548ff2481e0473f84334777f2c7262 100644
--- a/src/pages/search/Search.js
+++ b/src/pages/search/Search.js
@@ -1,1525 +1,34 @@
 import React, { useState, useEffect } from 'react';
 import {
-  EuiProgress,
-  EuiRadioGroup,
-  EuiFieldText,
-  EuiPanel,
-  EuiPopover,
-  EuiPopoverTitle,
-  EuiPopoverFooter,
   EuiTabbedContent,
-  EuiFormRow,
-  EuiComboBox,
   EuiPageContentBody,
   EuiForm,
-  EuiTextArea,
   EuiFlexGroup,
   EuiFlexItem,
-  EuiFieldSearch,
-  EuiButton,
-  EuiButtonEmpty,
-  EuiSwitch,
-  EuiButtonIcon,
-  EuiIcon,
   EuiSpacer,
   EuiPageContent,
   EuiPageContentHeader,
   EuiTitle,
   EuiPageContentHeaderSection,
-  EuiTextColor,
-  EuiOverlayMask,
-  EuiModal,
-  EuiModalHeader,
-  EuiModalHeaderTitle,
-  EuiModalBody,
-  EuiModalFooter,
-  EuiSelect,
-  EuiGlobalToastList,
-  EuiHealth,
 } from '@elastic/eui';
-import { makeStyles } from '@material-ui/core/styles';
-import TextField from '@material-ui/core/TextField';
-import { Operators, NumericOptions, DateOptions } from './Data';
 import Results from '../results/Results';
 import SearchMap from '../maps/SearchMap';
-import {
-  createBasicQueriesBySource,
-  changeNameToLabel,
-  SearchField,
-  removeNullFields,
-  getSections,
-  getFieldsBySection,
-  updateArrayElement,
-  removeArrayElement,
-  updateSearchFieldValues,
-  createAdvancedQueriesBySource,
-} from '../../Utils.js';
+import { removeNullFields } from '../../Utils.js';
 import {
   fetchPublicFields,
   fetchUserPolicyFields,
   fetchSources,
-  searchQuery,
-  getQueryCount,
 } from '../../actions/source';
-import { addUserHistory, fetchUserHistory } from '../../actions/user';
-
-const useStyles = makeStyles((theme) => ({
-  container: {
-    display: 'flex',
-    flexWrap: 'wrap',
-  },
-  textField: {
-    marginLeft: theme.spacing(1),
-    marginRight: theme.spacing(1),
-    width: 240,
-  },
-}));
-
-const fieldValuesToString = (field) => {
-  let strValues = '';
-  switch (field.type) {
-    case 'Numeric':
-      field.values.forEach((element) => {
-        switch (element.option) {
-          case 'between':
-            strValues = `${strValues} ${element.value1} <= ${field.name} <= ${element.value2} or `;
-            break;
-          default:
-            strValues = `${strValues} ${field.name} ${element.option} ${element.value1} or `;
-        }
-      });
-      if (strValues.endsWith('or '))
-        strValues = strValues.substring(0, strValues.length - 4);
-      break;
-    case 'Date':
-      field.values.forEach((element) => {
-        switch (element.option) {
-          case 'between':
-            strValues = `${strValues} ${element.startDate} <= ${field.name} <= ${element.endDate} or `;
-            break;
-          default:
-            strValues = `${strValues} ${field.name} ${element.option} ${element.startDate} or `;
-        }
-      });
-      if (strValues.endsWith(' or '))
-        strValues = strValues.substring(0, strValues.length - 4);
-      break;
-    case 'List':
-      strValues = `${strValues} ${field.name} = `;
-      field.values.forEach((element) => {
-        strValues = `${strValues} ${element.label}, `;
-      });
-      if (strValues.endsWith(', '))
-        strValues = strValues.substring(0, strValues.length - 2);
-      break;
-
-    //type : text
-    default:
-      strValues = `${strValues} ${field.name} = ${field.values}`;
-  }
-  return strValues;
-};
-
-const updateSources = (
-  searchFields,
-  sources,
-  setSelectedSources,
-  setAvailableSources
-) => {
-  let updatedSources = [];
-  let availableSources = [];
-  let noPrivateField = true;
-  //search for policy fields to filter sources
-  searchFields.forEach((field) => {
-    if (field.isValidated) {
-      //if sources haven't already been filtered
-      if (noPrivateField && !updatedSources.length) {
-        availableSources = sources;
-      } else {
-        availableSources = updatedSources;
-      }
-      updatedSources = [];
-      field.sources.forEach((sourceId) => {
-        noPrivateField = false;
-        const source = availableSources.find((src) => src.id === sourceId);
-        if (source && !updatedSources.includes(source)) updatedSources.push(source);
-      });
-    }
-  });
-  setSelectedSources(updatedSources);
-  if (noPrivateField && !updatedSources.length) {
-    setAvailableSources(sources);
-  } else {
-    setAvailableSources(updatedSources);
-  }
-};
-
-const fetchHistory = (setUserHistory) => {
-  fetchUserHistory(sessionStorage.getItem('user_id')).then((result) => {
-    if (result[0] && result[0].ui_structure) {
-      result.forEach((item) => {
-        item.ui_structure = JSON.parse(item.ui_structure);
-        item.label = `${item.name} - ${new Date(item.createdat).toLocaleString()}`;
-      });
-    }
-    setUserHistory(result);
-  });
-};
-
-const addHistory = (
-  kcID,
-  search,
-  searchName,
-  searchFields,
-  searchDescription,
-  setUserHistory
-) => {
-  addUserHistory(
-    sessionStorage.getItem('user_id'),
-    search,
-    searchName,
-    searchFields,
-    searchDescription
-  ).then(() => {
-    fetchHistory(setUserHistory);
-  });
-};
-
-const updateSearch = (setSearch, searchFields, selectedOperatorId, setSearchCount) => {
-  let searchText = '';
-  searchFields.forEach((field) => {
-    if (field.isValidated) {
-      searchText =
-        searchText +
-        `{${fieldValuesToString(field)} } ${Operators[selectedOperatorId].value.toUpperCase()} `;
-    }
-  });
-  if (searchText.endsWith(' AND ')) {
-    searchText = searchText.substring(0, searchText.length - 5);
-  } else if (searchText.endsWith(' OR ')) {
-    searchText = searchText.substring(0, searchText.length - 4);
-  }
-  setSearchCount();
-  setSearch(searchText);
-};
-
-const HistorySelect = (
-  sources,
-  setAvailableSources,
-  setSelectedSources,
-  setSearch,
-  searchFields,
-  selectedOperatorId,
-  userHistory,
-  setUserHistory,
-  setSearchFields,
-  setSearchCount,
-  setFieldCount,
-  selectedSavedSearch,
-  setSelectedSavedSearch,
-  historySelectError,
-  setHistorySelectError
-) => {
-  if (Object.keys(userHistory).length !== 0) {
-    const onHistoryChange = (selectedSavedSearch) => {
-      setHistorySelectError(undefined);
-      if (!!selectedSavedSearch[0].query) {
-        setSelectedSavedSearch(selectedSavedSearch);
-        setSearch(selectedSavedSearch[0].query);
-        setSearchCount();
-        setFieldCount([]);
-      }
-      if (!!selectedSavedSearch[0].ui_structure) {
-        updateSources(
-          selectedSavedSearch[0].ui_structure,
-          sources,
-          setSelectedSources,
-          setAvailableSources
-        );
-        setSearchFields(selectedSavedSearch[0].ui_structure);
-      }
-    };
-
-    const onHistorySearchChange = (value, hasMatchingOptions) => {
-      setHistorySelectError(
-        value.length === 0 || hasMatchingOptions
-          ? undefined
-          : `"${value}" is not a valid option`
-      );
-    };
-
-    return (
-      <>
-        <EuiFormRow
-          error={historySelectError}
-          isInvalid={historySelectError !== undefined}
-        >
-          <EuiComboBox
-            placeholder="Load a previous search"
-            singleSelection={{ asPlainText: true }}
-            options={userHistory}
-            selectedOptions={selectedSavedSearch}
-            onChange={onHistoryChange}
-            onSearchChange={onHistorySearchChange}
-          />
-        </EuiFormRow>
-      </>
-    );
-  }
-};
-
-const SearchBar = (
-  isLoading,
-  setIsLoading,
-  search,
-  setSearch,
-  searchResults,
-  setSearchResults,
-  searchFields,
-  setSearchFields,
-  searchName,
-  setSearchName,
-  searchDescription,
-  setSearchDescription,
-  readOnlyQuery,
-  setReadOnlyQuery,
-  selectedSources,
-  setSelectedSources,
-  availableSources,
-  setAvailableSources,
-  standardFields,
-  sources,
-  setSelectedTabNumber,
-  searchCount,
-  setSearchCount,
-  setFieldCount,
-  isReadOnlyModalOpen,
-  setIsReadOnlyModalOpen,
-  isSaveSearchModalOpen,
-  setIsSaveSearchModalOpen,
-  userHistory,
-  setUserHistory,
-  selectedSavedSearch,
-  setSelectedSavedSearch,
-  historySelectError,
-  setHistorySelectError,
-  selectedOperatorId,
-  createEditableQueryToast
-) => {
-  // const closeReadOnlyModal = () => setIsReadOnlyModalOpen(false)
-
-  /* const switchReadOnly = (readOnlyQuery, isReadOnlyModalOpen) => {
-        if (readOnlyQuery) {
-            setIsReadOnlyModalOpen(true)
-        } else {
-            setReadOnlyQuery(true)
-        } */
-  /* if (!localStorage.getItem("InSylvaReadOnlySearch") && readOnlyQuery) {
-        setIsReadOnlyModalOpen(!isReadOnlyModalOpen)
-    } */
-  // }
-
-  /* let readOnlyModal;
-
-    if (isReadOnlyModalOpen) {
-        readOnlyModal = (
-            <EuiOverlayMask>
-                <EuiConfirmModal
-                    title="Allow query editing"
-                    onCancel={() => closeReadOnlyModal()}
-                    onConfirm={() => {
-                        setReadOnlyQuery(!readOnlyQuery)
-                        closeReadOnlyModal()
-                    }}
-                    cancelButtonText="No"
-                    confirmButtonText="Yes"
-                    buttonColor="danger"
-                    defaultFocusedButton="confirm">
-                    <p>Be aware that manually editing the query can spoil search results.</p>
-                    <p>The syntax needs to be respected :</p>
-                    <ul>Fields and their values must be given between brackets : &#123; &#125;</ul>
-                    <ul>Check eventual typing mistakes</ul>
-                    <ul>Make sure every opened bracket is properly closed</ul>
-                    <p>Are you sure you want to do this?</p>
-                </EuiConfirmModal>
-            </EuiOverlayMask>
-        )
-    }*/
-
-  const closeSaveSearchModal = () => setIsSaveSearchModalOpen(false);
-
-  let saveSearchModal;
-
-  if (isSaveSearchModalOpen) {
-    saveSearchModal = (
-      <EuiOverlayMask>
-        <EuiModal onClose={closeSaveSearchModal} initialFocus="[name=searchName]">
-          <EuiModalHeader>
-            <EuiModalHeaderTitle>Save search</EuiModalHeaderTitle>
-          </EuiModalHeader>
-
-          <EuiModalBody>
-            <EuiForm>
-              <EuiFormRow label="Search name">
-                <EuiFieldText
-                  name="searchName"
-                  value={searchName}
-                  onChange={(e) => {
-                    setSearchName(e.target.value);
-                  }}
-                />
-              </EuiFormRow>
-              <EuiFormRow label="Description (optional)">
-                <EuiTextArea
-                  value={searchDescription}
-                  onChange={(e) => setSearchDescription(e.target.value)}
-                  placeholder="Search description..."
-                  fullWidth
-                  compressed
-                />
-              </EuiFormRow>
-            </EuiForm>
-          </EuiModalBody>
-
-          <EuiModalFooter>
-            <EuiButtonEmpty
-              onClick={() => {
-                closeSaveSearchModal();
-              }}
-            >
-              Cancel
-            </EuiButtonEmpty>
-            <EuiButton
-              onClick={() => {
-                if (!!searchName) {
-                  addHistory(
-                    sessionStorage.getItem('user_id'),
-                    search,
-                    searchName,
-                    searchFields,
-                    searchDescription,
-                    setUserHistory
-                  );
-                  setSearchName('');
-                  setSearchDescription('');
-                  closeSaveSearchModal();
-                }
-              }}
-              fill
-            >
-              Save
-            </EuiButton>
-          </EuiModalFooter>
-        </EuiModal>
-      </EuiOverlayMask>
-    );
-  }
-
-  return (
-    <>
-      {/*!readOnlyQuery ?
-                <>
-                    <EuiCallOut title="Proceed with caution!" color="warning" iconType="alert">
-                        <p>Be aware that manually editing the query can spoil search results. The syntax must be respected :</p>
-                        <ul>Fields and their values should be put between brackets : &#123; &#125;  -  Make sure every opened bracket is properly closed</ul>
-                        <ul>"AND" and "OR" should be capitalized between different fields conditions and lowercased within a field expression</ul>
-                        <ul>Make sure to check eventual typing mistakes</ul>
-
-                    </EuiCallOut>
-                    <EuiSpacer size="s" />
-                </>
-                : <></>
-            */}
-      <EuiFlexGroup>
-        <EuiFlexItem>
-          <EuiTextArea
-            readOnly={readOnlyQuery}
-            value={search}
-            onChange={(e) => setSearch(e.target.value)}
-            placeholder="Add fields..."
-            fullWidth
-          />
-        </EuiFlexItem>
-        <EuiFlexItem grow={false}>
-          <EuiButton
-            size="s"
-            fill
-            onClick={() => {
-              if (search.trim()) {
-                setIsLoading(true);
-                const queriesWithIndices = createAdvancedQueriesBySource(
-                  standardFields,
-                  search,
-                  selectedSources,
-                  availableSources
-                );
-                searchQuery(queriesWithIndices).then((result) => {
-                  // sessionStorage.setItem("searchResults", JSON.stringify(result))
-                  setSearchResults(result);
-                  setSelectedTabNumber(1);
-                  setIsLoading(false);
-                });
-              }
-            }}
-          >
-            Search
-          </EuiButton>
-          <EuiSpacer size="s" />
-          {isNaN(searchCount) ? (
-            <></>
-          ) : (
-            <>
-              <EuiTextColor
-                color="secondary"
-                style={{ display: 'flex', justifyContent: 'center' }}
-              >
-                {searchCount} {searchCount === 1 ? 'result' : 'results'}
-              </EuiTextColor>
-              <EuiSpacer size="s" />
-            </>
-          )}
-          <EuiButton
-            size="s"
-            onClick={() => {
-              if (!!search) {
-                const queriesWithIndices = createAdvancedQueriesBySource(
-                  standardFields,
-                  search,
-                  selectedSources,
-                  availableSources
-                );
-                getQueryCount(queriesWithIndices).then((result) => {
-                  if (result || result === 0) setSearchCount(result);
-                });
-              }
-            }}
-          >
-            Count results
-          </EuiButton>
-          <EuiSpacer size="s" />
-          <EuiButton
-            size="s"
-            onClick={() => {
-              setIsSaveSearchModalOpen(true);
-            }}
-          >
-            Save search
-          </EuiButton>
-          {saveSearchModal}
-          <EuiSpacer size="s" />
-          <EuiSwitch
-            compressed
-            label={'Editable'}
-            checked={!readOnlyQuery}
-            onChange={() => {
-              // switchReadOnly(readOnlyQuery, isReadOnlyModalOpen)
-              setReadOnlyQuery(!readOnlyQuery);
-              if (readOnlyQuery) {
-                createEditableQueryToast();
-              }
-            }}
-          />
-          {/* readOnlyModal */}
-        </EuiFlexItem>
-      </EuiFlexGroup>
-      {isLoading && (
-        <EuiFlexGroup>
-          <EuiFlexItem>
-            <EuiProgress postion="fixed" size="l" color="accent" />
-          </EuiFlexItem>
-        </EuiFlexGroup>
-      )}
-      <EuiSpacer size="s" />
-      <EuiFlexGroup>
-        <EuiFlexItem>
-          {HistorySelect(
-            sources,
-            setAvailableSources,
-            setSelectedSources,
-            setSearch,
-            searchFields,
-            selectedOperatorId,
-            userHistory,
-            setUserHistory,
-            setSearchFields,
-            setSearchCount,
-            setFieldCount,
-            selectedSavedSearch,
-            setSelectedSavedSearch,
-            historySelectError,
-            setHistorySelectError
-          )}
-        </EuiFlexItem>
-      </EuiFlexGroup>
-    </>
-  );
-};
-
-const PopoverSelect = (
-  standardFields,
-  setStandardFields,
-  searchFields,
-  setSearchFields,
-  selectedField,
-  setSelectedField,
-  selectedSection,
-  setSelectedSection,
-  isPopoverSelectOpen,
-  setIsPopoverSelectOpen,
-  fieldCount,
-  setFieldCount,
-  selectedSources,
-  setSelectedSources
-) => {
-  const handleAddfield = () => {
-    if (!!selectedField[0]) {
-      const field = standardFields.find(
-        (item) =>
-          item.field_name.replace(/_|\./g, ' ') ===
-          selectedSection[0].label + ' ' + selectedField[0].label
-      );
-      switch (field.field_type) {
-        case 'Text':
-          setSearchFields([
-            ...searchFields,
-            new SearchField(field.field_name, field.field_type, '', false, field.sources),
-          ]);
-          break;
-        case 'List':
-          setSearchFields([
-            ...searchFields,
-            new SearchField(field.field_name, field.field_type, [], false, field.sources),
-          ]);
-          break;
-        default:
-          setSearchFields([
-            ...searchFields,
-            new SearchField(
-              field.field_name,
-              field.field_type,
-              [{}],
-              false,
-              field.sources
-            ),
-          ]);
-      }
-    }
-  };
-
-  const selectField = () => {
-    const renderOption = (option, searchValue, contentClassName) => {
-      const { label, color } = option;
-      return <EuiHealth color={color}>{label}</EuiHealth>;
-    };
-    if (selectedSection.length) {
-      return (
-        <>
-          <EuiComboBox
-            placeholder="Select a field"
-            singleSelection={{ asPlainText: true }}
-            options={getFieldsBySection(standardFields, selectedSection[0])}
-            selectedOptions={selectedField}
-            onChange={(selected) => setSelectedField(selected)}
-            isClearable={true}
-            renderOption={renderOption}
-          />
-          <EuiPopoverFooter>
-            <EuiButton
-              size="s"
-              onClick={() => {
-                handleAddfield();
-                setIsPopoverSelectOpen(false);
-                setSelectedSection([]);
-                setSelectedField([]);
-              }}
-            >
-              Add this field
-            </EuiButton>
-          </EuiPopoverFooter>
-        </>
-      );
-    }
-  };
-
-  return (
-    <EuiPopover
-      panelPaddingSize="s"
-      button={
-        <EuiButton
-          iconType="listAdd"
-          iconSide="left"
-          onClick={() => setIsPopoverSelectOpen(!isPopoverSelectOpen)}
-        >
-          Add field
-        </EuiButton>
-      }
-      isOpen={isPopoverSelectOpen}
-      closePopover={() => setIsPopoverSelectOpen(false)}
-    >
-      <div style={{ width: 'intrinsic', minWidth: 240 }}>
-        <EuiPopoverTitle>Select a field</EuiPopoverTitle>
-        <EuiComboBox
-          placeholder="Select a section"
-          singleSelection={{ asPlainText: true }}
-          options={getSections(standardFields)}
-          selectedOptions={selectedSection}
-          onChange={(selected) => {
-            setSelectedSection(selected);
-            setSelectedField([]);
-          }}
-          isClearable={false}
-        />
-      </div>
-      {selectField()}
-    </EuiPopover>
-  );
-};
-
-const PopoverValueContent = (
-  index,
-  standardFields,
-  setStandardFields,
-  searchFields,
-  setSearchFields,
-  valueError,
-  setValueError,
-  search,
-  setSearch,
-  setSearchCount,
-  fieldCount,
-  setFieldCount,
-  isPopoverValueOpen,
-  setIsPopoverValueOpen,
-  selectedOperatorId,
-  datePickerStyles,
-  createPolicyToast,
-  selectedSources,
-  setSelectedSources,
-  availableSources,
-  setAvailableSources
-) => {
-  const onValueSearchChange = (value, hasMatchingOptions) => {
-    setValueError(
-      value.length === 0 || hasMatchingOptions
-        ? undefined
-        : `"${value}" is not a valid option`
-    );
-  };
-
-  const validateFieldValues = () => {
-    let fieldValues;
-    if (Array.isArray(searchFields[index].values)) {
-      fieldValues = [];
-      searchFields[index].values.forEach((value) => {
-        if (!!value) {
-          fieldValues.push(value);
-        }
-      });
-    } else {
-      fieldValues = searchFields[index].values;
-    }
-
-    const updatedSearchFields = updateArrayElement(
-      searchFields,
-      index,
-      new SearchField(
-        searchFields[index].name,
-        searchFields[index].type,
-        fieldValues,
-        true,
-        searchFields[index].sources
-      )
-    );
-    setSearchFields(updatedSearchFields);
-    updateSearch(setSearch, updatedSearchFields, selectedOperatorId, setSearchCount);
-    setFieldCount(updateArrayElement(fieldCount, index));
-    if (searchFields[index].sources.length) {
-      const filteredSources = [];
-      searchFields[index].sources.forEach((sourceId) => {
-        let source;
-        if (selectedSources.length) {
-          source = selectedSources.find((src) => src.id === sourceId);
-        } else {
-          source = availableSources.find((src) => src.id === sourceId);
-        }
-        if (source) {
-          filteredSources.push(source);
-        }
-      });
-      setAvailableSources(filteredSources);
-      setSelectedSources(filteredSources);
-      createPolicyToast();
-    }
-  };
-
-  const invalidateFieldValues = () => {
-    const updatedSearchFields = updateArrayElement(
-      searchFields,
-      index,
-      new SearchField(
-        searchFields[index].name,
-        searchFields[index].type,
-        searchFields[index].values,
-        false,
-        searchFields[index].sources
-      )
-    );
-    setSearchFields(updatedSearchFields);
-    updateSearch(setSearch, updatedSearchFields, selectedOperatorId, setSearchCount);
-  };
-
-  const ValuePopoverFooter = (i) => {
-    if (i === searchFields[index].values.length - 1) {
-      return (
-        <EuiPopoverFooter>
-          <EuiButton
-            size="s"
-            onClick={() => {
-              setSearchFields(
-                updateArrayElement(
-                  searchFields,
-                  index,
-                  new SearchField(
-                    searchFields[index].name,
-                    searchFields[index].type,
-                    [...searchFields[index].values, {}],
-                    false,
-                    searchFields[index].sources
-                  )
-                )
-              );
-            }}
-          >
-            Add value
-          </EuiButton>
-          <EuiButton
-            size="s"
-            style={{ float: 'right' }}
-            onClick={() => {
-              validateFieldValues();
-              setIsPopoverValueOpen(updateArrayElement(isPopoverValueOpen, index, false));
-            }}
-          >
-            Validate
-          </EuiButton>
-        </EuiPopoverFooter>
-      );
-    }
-  };
-
-  const addFieldValue = (i, selectedOption) => {
-    setSearchFields(
-      updateSearchFieldValues(
-        searchFields,
-        index,
-        updateArrayElement(searchFields[index].values, i, { option: selectedOption })
-      )
-    );
-  };
-
-  const getListFieldValues = () => {
-    const listFieldValues = [];
-    standardFields
-      .find((item) => item.field_name === searchFields[index].name)
-      .values.split(', ')
-      .sort()
-      .forEach((element) => {
-        listFieldValues.push({ label: element });
-      });
-    return listFieldValues;
-  };
-
-  switch (searchFields[index].type) {
-    case 'Text':
-      return (
-        <>
-          <EuiFlexItem>
-            <EuiFieldText
-              placeholder={'Type values'}
-              value={searchFields[index].values}
-              onChange={(e) =>
-                setSearchFields(
-                  updateSearchFieldValues(searchFields, index, e.target.value)
-                )
-              }
-            />
-          </EuiFlexItem>
-          <EuiPopoverFooter>
-            <EuiButton
-              size="s"
-              style={{ float: 'right' }}
-              onClick={() => {
-                validateFieldValues();
-                setIsPopoverValueOpen(
-                  updateArrayElement(isPopoverValueOpen, index, false)
-                );
-              }}
-            >
-              Validate
-            </EuiButton>
-          </EuiPopoverFooter>
-        </>
-      );
-    case 'List':
-      return (
-        <>
-          <EuiFormRow error={valueError} isInvalid={valueError !== undefined}>
-            <EuiComboBox
-              placeholder={'Select values'}
-              options={getListFieldValues()}
-              selectedOptions={searchFields[index].values}
-              onChange={(selectedOptions) => {
-                setValueError(undefined);
-                setSearchFields(
-                  updateSearchFieldValues(searchFields, index, selectedOptions)
-                );
-              }}
-              onSearchChange={onValueSearchChange}
-            />
-          </EuiFormRow>
-          <EuiPopoverFooter>
-            <EuiButton
-              size="s"
-              style={{ float: 'right' }}
-              onClick={() => {
-                validateFieldValues();
-                setIsPopoverValueOpen(
-                  updateArrayElement(isPopoverValueOpen, index, false)
-                );
-              }}
-            >
-              Validate
-            </EuiButton>
-          </EuiPopoverFooter>
-        </>
-      );
-
-    case 'Numeric':
-      const NumericValues = (i) => {
-        if (!!searchFields[index].values[i].option) {
-          switch (searchFields[index].values[i].option) {
-            case 'between':
-              return (
-                <>
-                  <EuiFlexItem>
-                    <EuiFieldText
-                      placeholder={'1st value'}
-                      value={searchFields[index].values[i].value1}
-                      onChange={(e) => {
-                        setSearchFields(
-                          updateSearchFieldValues(
-                            searchFields,
-                            index,
-                            updateArrayElement(searchFields[index].values, i, {
-                              option: searchFields[index].values[i].option,
-                              value1: e.target.value,
-                              value2: searchFields[index].values[i].value2,
-                            })
-                          )
-                        );
-                      }}
-                    />
-                  </EuiFlexItem>
-                  <EuiFlexItem>
-                    <EuiFieldText
-                      placeholder={'2nd value'}
-                      value={searchFields[index].values[i].value2}
-                      onChange={(e) =>
-                        setSearchFields(
-                          updateSearchFieldValues(
-                            searchFields,
-                            index,
-                            updateArrayElement(searchFields[index].values, i, {
-                              option: searchFields[index].values[i].option,
-                              value1: searchFields[index].values[i].value1,
-                              value2: e.target.value,
-                            })
-                          )
-                        )
-                      }
-                    />
-                  </EuiFlexItem>
-                  {ValuePopoverFooter(i)}
-                </>
-              );
-
-            default:
-              return (
-                <>
-                  <EuiFlexItem>
-                    <EuiFieldText
-                      placeholder={'Type value'}
-                      value={searchFields[index].values[i].value1}
-                      onChange={(e) => {
-                        setSearchFields(
-                          updateSearchFieldValues(
-                            searchFields,
-                            index,
-                            updateArrayElement(searchFields[index].values, i, {
-                              option: searchFields[index].values[i].option,
-                              value1: e.target.value,
-                              value2: searchFields[index].values[i].value2,
-                            })
-                          )
-                        );
-                      }}
-                    />
-                  </EuiFlexItem>
-                  {ValuePopoverFooter(i)}
-                </>
-              );
-          }
-        }
-      };
-
-      return (
-        <>
-          {searchFields[index].values.map((value, i) => (
-            <div key={i}>
-              <EuiSelect
-                hasNoInitialSelection
-                id="Select an option"
-                options={NumericOptions}
-                value={searchFields[index].values[i].option}
-                onChange={(e) => {
-                  addFieldValue(i, e.target.value);
-                  invalidateFieldValues();
-                }}
-              />
-              {NumericValues(i)}
-            </div>
-          ))}
-        </>
-      );
-
-    case 'Date':
-      const SelectDates = (i) => {
-        if (!!searchFields[index].values[i].option) {
-          switch (searchFields[index].values[i].option) {
-            case 'between':
-              return (
-                <>
-                  <form className={datePickerStyles.container} noValidate>
-                    <TextField
-                      label="between"
-                      type="date"
-                      defaultValue={
-                        !!searchFields[index].values[i].startDate
-                          ? searchFields[index].values[i].startDate
-                          : Date.now()
-                      }
-                      className={datePickerStyles.textField}
-                      InputLabelProps={{
-                        shrink: true,
-                      }}
-                      onChange={(e) =>
-                        setSearchFields(
-                          updateSearchFieldValues(
-                            searchFields,
-                            index,
-                            updateArrayElement(searchFields[index].values, i, {
-                              option: searchFields[index].values[i].option,
-                              startDate: e.target.value,
-                              endDate: searchFields[index].values[i].endDate,
-                            })
-                          )
-                        )
-                      }
-                    />
-                  </form>
-                  <form className={datePickerStyles.container} noValidate>
-                    <TextField
-                      label="and"
-                      type="date"
-                      defaultValue={
-                        !!searchFields[index].values[i].endDate
-                          ? searchFields[index].values[i].endDate
-                          : Date.now()
-                      }
-                      className={datePickerStyles.textField}
-                      InputLabelProps={{
-                        shrink: true,
-                      }}
-                      onChange={(e) =>
-                        setSearchFields(
-                          updateSearchFieldValues(
-                            searchFields,
-                            index,
-                            updateArrayElement(searchFields[index].values, i, {
-                              option: searchFields[index].values[i].option,
-                              startDate: searchFields[index].values[i].startDate,
-                              endDate: e.target.value,
-                            })
-                          )
-                        )
-                      }
-                    />
-                  </form>
-                  {ValuePopoverFooter(i)}
-                </>
-              );
-
-            default:
-              return (
-                <>
-                  <form className={datePickerStyles.container} noValidate>
-                    <TextField
-                      type="date"
-                      defaultValue={
-                        !!searchFields[index].values[i].startDate
-                          ? searchFields[index].values[i].startDate
-                          : Date.now()
-                      }
-                      className={datePickerStyles.textField}
-                      InputLabelProps={{
-                        shrink: true,
-                      }}
-                      onChange={(e) =>
-                        setSearchFields(
-                          updateSearchFieldValues(
-                            searchFields,
-                            index,
-                            updateArrayElement(searchFields[index].values, i, {
-                              option: searchFields[index].values[i].option,
-                              startDate: e.target.value,
-                              endDate: Date.now(),
-                            })
-                          )
-                        )
-                      }
-                    />
-                  </form>
-                  {ValuePopoverFooter(i)}
-                </>
-              );
-          }
-        }
-      };
-
-      return (
-        <>
-          {searchFields[index].values.map((value, i) => (
-            <div key={i}>
-              <EuiSelect
-                hasNoInitialSelection
-                id="Select an option"
-                options={DateOptions}
-                value={searchFields[index].values[i].option}
-                onChange={(e) => {
-                  addFieldValue(i, e.target.value);
-                  invalidateFieldValues();
-                }}
-              />
-              {SelectDates(i)}
-            </div>
-          ))}
-        </>
-      );
-    default:
-  }
-};
-
-const PopoverValueButton = (
-  index,
-  standardFields,
-  setStandardFields,
-  searchFields,
-  setSearchFields,
-  isPopoverValueOpen,
-  setIsPopoverValueOpen,
-  valueError,
-  setValueError,
-  search,
-  setSearch,
-  setSearchCount,
-  fieldCount,
-  setFieldCount,
-  selectedOperatorId,
-  datePickerStyles,
-  createPolicyToast,
-  selectedSources,
-  setSelectedSources,
-  availableSources,
-  setAvailableSources
-) => {
-  return (
-    <EuiPopover
-      panelPaddingSize="s"
-      button={
-        <EuiButtonIcon
-          size="s"
-          color="primary"
-          onClick={() =>
-            setIsPopoverValueOpen(
-              updateArrayElement(isPopoverValueOpen, index, !isPopoverValueOpen[index])
-            )
-          }
-          iconType="documentEdit"
-          title="Give field values"
-        />
-      }
-      isOpen={isPopoverValueOpen[index]}
-      closePopover={() =>
-        setIsPopoverValueOpen(updateArrayElement(isPopoverValueOpen, index, false))
-      }
-    >
-      {/*<div style={{ width: 240 }}>
-                <EuiButtonIcon
-                    size="s"
-                    style={{ float: 'right' }}
-                    color="danger"
-                    onClick={() => setIsPopoverValueOpen(updateArrayElement(isPopoverValueOpen, index, false))}
-                    iconType="crossInACircleFilled"
-                    title="Close popover"
-                />
-            </div>*/}
-      <div style={{ width: 240 }}>
-        {PopoverValueContent(
-          index,
-          standardFields,
-          setStandardFields,
-          searchFields,
-          setSearchFields,
-          valueError,
-          setValueError,
-          search,
-          setSearch,
-          setSearchCount,
-          fieldCount,
-          setFieldCount,
-          isPopoverValueOpen,
-          setIsPopoverValueOpen,
-          selectedOperatorId,
-          datePickerStyles,
-          createPolicyToast,
-          selectedSources,
-          setSelectedSources,
-          availableSources,
-          setAvailableSources
-        )}
-      </div>
-    </EuiPopover>
-  );
-};
-
-const FieldsPanel = (
-  standardFields,
-  setStandardFields,
-  searchFields,
-  setSearchFields,
-  selectedField,
-  setSelectedField,
-  selectedSection,
-  setSelectedSection,
-  isPopoverSelectOpen,
-  setIsPopoverSelectOpen,
-  isPopoverValueOpen,
-  setIsPopoverValueOpen,
-  valueError,
-  setValueError,
-  search,
-  setSearch,
-  setSearchCount,
-  selectedOperatorId,
-  setSelectedOperatorId,
-  fieldCount,
-  setFieldCount,
-  availableSources,
-  setAvailableSources,
-  selectedSources,
-  setSelectedSources,
-  sources,
-  datePickerStyles,
-  createPolicyToast
-) => {
-  const countFieldValues = (field, index) => {
-    const fieldStr = `{${fieldValuesToString(field)}}`;
-    const queriesWithIndices = createAdvancedQueriesBySource(
-      standardFields,
-      fieldStr,
-      selectedSources,
-      availableSources
-    );
-    getQueryCount(queriesWithIndices).then((result) => {
-      if (result || result === 0)
-        setFieldCount(updateArrayElement(fieldCount, index, result));
-    });
-  };
-
-  const handleRemoveField = (index) => {
-    const updatedSearchFields = removeArrayElement(searchFields, index);
-    setSearchFields(updatedSearchFields);
-    updateSources(updatedSearchFields, sources, setSelectedSources, setAvailableSources);
-    updateSearch(setSearch, updatedSearchFields, selectedOperatorId, setSearchCount);
-  };
-
-  const handleClearValues = (index) => {
-    let updatedSearchFields = [];
-    switch (searchFields[index].type) {
-      case 'Text':
-        updatedSearchFields = updateArrayElement(
-          searchFields,
-          index,
-          new SearchField(
-            searchFields[index].name,
-            searchFields[index].type,
-            '',
-            false,
-            searchFields[index].sources
-          )
-        );
-        break;
-      case 'List':
-        updatedSearchFields = updateArrayElement(
-          searchFields,
-          index,
-          new SearchField(
-            searchFields[index].name,
-            searchFields[index].type,
-            [],
-            false,
-            searchFields[index].sources
-          )
-        );
-        break;
-      default:
-        updatedSearchFields = updateArrayElement(
-          searchFields,
-          index,
-          new SearchField(
-            searchFields[index].name,
-            searchFields[index].type,
-            [{}],
-            false,
-            searchFields[index].sources
-          )
-        );
-    }
-    setSearchFields(updatedSearchFields);
-    updateSources(updatedSearchFields, sources, setSelectedSources, setAvailableSources);
-    setFieldCount(updateArrayElement(fieldCount, index));
-    updateSearch(setSearch, updatedSearchFields, selectedOperatorId, setSearchCount);
-  };
-
-  if (standardFields === []) {
-    return <h2>Loading user fields...</h2>;
-  }
-
-  return (
-    <>
-      <EuiTitle size="xs">
-        <h2>Field search</h2>
-      </EuiTitle>
-      <EuiPanel paddingSize="m">
-        <EuiFlexGroup direction="column">
-          {searchFields.map((field, index) => (
-            <EuiPanel key={'field' + index} paddingSize="s">
-              <EuiFlexItem grow={false}>
-                <EuiFlexGroup direction="row" alignItems="center">
-                  <EuiFlexItem grow={false}>
-                    <EuiButtonIcon
-                      size="s"
-                      color="danger"
-                      onClick={() => handleRemoveField(index)}
-                      iconType="indexClose"
-                      title="Remove field"
-                    />
-                  </EuiFlexItem>
-                  <EuiFlexItem>
-                    {field.isValidated ? (
-                      <>
-                        {field.sources.length ? (
-                          <EuiHealth color="danger">
-                            {fieldValuesToString(field).replace(/_|\./g, ' ')}
-                          </EuiHealth>
-                        ) : (
-                          <EuiHealth color="primary">
-                            {fieldValuesToString(field).replace(/_|\./g, ' ')}
-                          </EuiHealth>
-                        )}
-                      </>
-                    ) : (
-                      <>
-                        {field.sources.length ? (
-                          <EuiHealth color="danger">
-                            {field.name.replace(/_|\./g, ' ')}
-                          </EuiHealth>
-                        ) : (
-                          <EuiHealth color="primary">
-                            {field.name.replace(/_|\./g, ' ')}
-                          </EuiHealth>
-                        )}
-                      </>
-                    )}
-                  </EuiFlexItem>
-                  <EuiFlexItem grow={false}>
-                    {isNaN(fieldCount[index]) ? (
-                      <></>
-                    ) : (
-                      <>
-                        <EuiTextColor color="secondary">
-                          {fieldCount[index]}{' '}
-                          {fieldCount[index] === 1 ? 'result' : 'results'}
-                        </EuiTextColor>
-                      </>
-                    )}
-                  </EuiFlexItem>
-                  <EuiFlexItem grow={false}>
-                    {field.isValidated ? (
-                      <>
-                        <EuiButtonIcon
-                          size="s"
-                          onClick={() => countFieldValues(field, index)}
-                          iconType="number"
-                          title="Count results"
-                        />
-                      </>
-                    ) : (
-                      <></>
-                    )}
-                  </EuiFlexItem>
-                  <EuiFlexItem grow={false}>
-                    {field.isValidated ? (
-                      <>
-                        <EuiButtonIcon
-                          size="s"
-                          color="danger"
-                          onClick={() => handleClearValues(index)}
-                          iconType="trash"
-                          title="Clear values"
-                        />
-                      </>
-                    ) : (
-                      <></>
-                    )}
-                  </EuiFlexItem>
-                  <EuiFlexItem grow={false}>
-                    {PopoverValueButton(
-                      index,
-                      standardFields,
-                      setStandardFields,
-                      searchFields,
-                      setSearchFields,
-                      isPopoverValueOpen,
-                      setIsPopoverValueOpen,
-                      valueError,
-                      setValueError,
-                      search,
-                      setSearch,
-                      setSearchCount,
-                      fieldCount,
-                      setFieldCount,
-                      selectedOperatorId,
-                      datePickerStyles,
-                      createPolicyToast,
-                      selectedSources,
-                      setSelectedSources,
-                      availableSources,
-                      setAvailableSources
-                    )}
-                  </EuiFlexItem>
-                </EuiFlexGroup>
-              </EuiFlexItem>
-            </EuiPanel>
-          ))}
-        </EuiFlexGroup>
-        <EuiSpacer size="l" />
-        {PopoverSelect(
-          standardFields,
-          setStandardFields,
-          searchFields,
-          setSearchFields,
-          selectedField,
-          setSelectedField,
-          selectedSection,
-          setSelectedSection,
-          isPopoverSelectOpen,
-          setIsPopoverSelectOpen,
-          fieldCount,
-          setFieldCount,
-          selectedSources,
-          setSelectedSources
-        )}
-      </EuiPanel>
-      <EuiSpacer size="s" />
-      <EuiRadioGroup
-        options={Operators}
-        idSelected={selectedOperatorId}
-        onChange={(id) => {
-          setSelectedOperatorId(id);
-          updateSearch(setSearch, searchFields, id, setSearchCount);
-        }}
-        name="operators group"
-        legend={{
-          children: <span>Search option</span>,
-        }}
-      />
-    </>
-  );
-};
-
-const SourceSelect = (
-  availableSources,
-  selectedSources,
-  setSelectedSources,
-  sourceSelectError,
-  setSourceSelectError
-) => {
-  if (Object.keys(availableSources).length !== 0) {
-    availableSources.forEach((source) => {
-      if (source.name) {
-        source = changeNameToLabel(source);
-      }
-    });
-
-    const onSourceChange = (selectedOptions) => {
-      setSourceSelectError(undefined);
-      setSelectedSources(selectedOptions);
-    };
-
-    const onSourceSearchChange = (value, hasMatchingOptions) => {
-      setSourceSelectError(
-        value.length === 0 || hasMatchingOptions
-          ? undefined
-          : `"${value}" is not a valid option`
-      );
-    };
-    return (
-      <>
-        <EuiTitle size="xs">
-          <h2>Partner sources</h2>
-        </EuiTitle>
-        <EuiSpacer size="s" />
-        <EuiFlexItem>
-          <EuiFormRow
-            error={sourceSelectError}
-            isInvalid={sourceSelectError !== undefined}
-          >
-            <EuiComboBox
-              placeholder="By default, all sources are selected"
-              options={availableSources}
-              selectedOptions={selectedSources}
-              onChange={onSourceChange}
-              onSearchChange={onSourceSearchChange}
-            />
-          </EuiFormRow>
-        </EuiFlexItem>
-      </>
-    );
-  } else {
-    return (
-      <p>
-        <EuiIcon type="alert" color="danger" /> No source available !
-      </p>
-    );
-  }
-};
+import { useTranslation } from 'react-i18next';
+import AdvancedSearch from './AdvancedSearch/AdvancedSearch';
+import BasicSearch from './BasicSearch/BasicSearch';
+import styles from './styles';
 
 const Search = () => {
-  const [isLoading, setIsLoading] = useState(false);
+  const { t } = useTranslation('search');
+  const datePickerStyles = styles();
   const [selectedTabNumber, setSelectedTabNumber] = useState(0);
-  const [userHistory, setUserHistory] = useState({});
-  const [advancedSearch, setAdvancedSearch] = useState(false);
+  const [isAdvancedSearch, setIsAdvancedSearch] = useState(false);
   const [readOnlyQuery, setReadOnlyQuery] = useState(true);
   const [selectedField, setSelectedField] = useState([]);
   const [selectedSection, setSelectedSection] = useState([]);
@@ -1543,9 +52,6 @@ const Search = () => {
   const [isReadOnlyModalOpen, setIsReadOnlyModalOpen] = useState(false);
   const [isSaveSearchModalOpen, setIsSaveSearchModalOpen] = useState(false);
   const [selectedSavedSearch, setSelectedSavedSearch] = useState();
-  const [historySelectError, setHistorySelectError] = useState(undefined);
-  const [notificationToasts, setNotificationToasts] = useState([]);
-  const datePickerStyles = useStyles();
 
   useEffect(() => {
     fetchPublicFields().then((resultStdFields) => {
@@ -1576,262 +82,106 @@ const Search = () => {
           setStandardFields(removeNullFields(userFields));
         }
       );
-
-      // policyField => {
-      //     policyField.forEach(
     });
     fetchSources(sessionStorage.getItem('user_id')).then((result) => {
       setSources(result);
       setAvailableSources(result);
     });
-    fetchHistory(setUserHistory);
   }, []);
 
-  const createPolicyToast = () => {
-    const toast = {
-      title: 'Policy field selected',
-      color: 'warning',
-      iconType: 'alert',
-      toastLifeTimeMs: 15000,
-      text: (
-        <>
-          <p>You selected a private field.</p>
-          <p>
-            Access to this field was granted for specific sources, which means that your
-            search will be restricted to those.
-          </p>
-          <p>Please check the sources list before searching.</p>
-        </>
-      ),
-    };
-    setNotificationToasts(notificationToasts.concat(toast));
-  };
-
-  const createEditableQueryToast = () => {
-    const toast = {
-      title: 'Proceed with caution',
-      color: 'warning',
-      iconType: 'alert',
-      toastLifeTimeMs: 15000,
-      text: (
-        <>
-          <p>
-            Be aware that manually editing the query can spoil search results. The syntax
-            must be respected :
-          </p>
-          <ul>
-            Fields and their values should be put between brackets : &#123; &#125; - Make
-            sure every opened bracket is properly closed
-          </ul>
-          <ul>
-            "AND" and "OR" should be capitalized between different fields conditions and
-            lowercased within a field expression
-          </ul>
-          <ul>Make sure to check eventual typing mistakes</ul>
-        </>
-      ),
-    };
-    setNotificationToasts(notificationToasts.concat(toast));
-  };
-
-  const removeToast = (removedToast) => {
-    setNotificationToasts(
-      notificationToasts.filter((toast) => toast.id !== removedToast.id)
-    );
-  };
-
-  const onFormSubmit = () => {
-    setIsLoading(true);
-    const queriesWithIndices = createBasicQueriesBySource(
-      standardFields,
-      basicSearch,
-      selectedSources,
-      availableSources
-    );
-    searchQuery(queriesWithIndices).then((result) => {
-      setSearchResults(result);
-      setSelectedTabNumber(1);
-      setIsLoading(false);
-    });
-  };
-
   const tabsContent = [
     {
       id: 'tab1',
-      name: 'Compose search',
+      name: t('tabs.composeSearch'),
       content: (
         <>
-          {advancedSearch ? (
-            <>
-              <EuiFlexGroup>
-                <EuiFlexItem grow={false}>
-                  <EuiSpacer size="s" />
-                  <EuiButtonEmpty
-                    onClick={() => {
-                      setAdvancedSearch(!advancedSearch);
-                    }}
-                  >
-                    Switch to basic search
-                  </EuiButtonEmpty>
-                </EuiFlexItem>
-              </EuiFlexGroup>
-              <EuiFlexGroup>
-                <EuiFlexItem>
-                  <EuiSpacer size="s" />
-                  {SearchBar(
-                    isLoading,
-                    setIsLoading,
-                    search,
-                    setSearch,
-                    searchResults,
-                    setSearchResults,
-                    searchFields,
-                    setSearchFields,
-                    searchName,
-                    setSearchName,
-                    searchDescription,
-                    setSearchDescription,
-                    readOnlyQuery,
-                    setReadOnlyQuery,
-                    selectedSources,
-                    setSelectedSources,
-                    availableSources,
-                    setAvailableSources,
-                    standardFields,
-                    sources,
-                    setSelectedTabNumber,
-                    searchCount,
-                    setSearchCount,
-                    setFieldCount,
-                    isReadOnlyModalOpen,
-                    setIsReadOnlyModalOpen,
-                    isSaveSearchModalOpen,
-                    setIsSaveSearchModalOpen,
-                    userHistory,
-                    setUserHistory,
-                    selectedSavedSearch,
-                    setSelectedSavedSearch,
-                    historySelectError,
-                    setHistorySelectError,
-                    selectedOperatorId,
-                    createEditableQueryToast
-                  )}
-                </EuiFlexItem>
-              </EuiFlexGroup>
-              <EuiFlexGroup>
-                <EuiFlexItem>
-                  <EuiSpacer size="s" />
-                  {FieldsPanel(
-                    standardFields,
-                    setStandardFields,
-                    searchFields,
-                    setSearchFields,
-                    selectedField,
-                    setSelectedField,
-                    selectedSection,
-                    setSelectedSection,
-                    isPopoverSelectOpen,
-                    setIsPopoverSelectOpen,
-                    isPopoverValueOpen,
-                    setIsPopoverValueOpen,
-                    valueError,
-                    setValueError,
-                    search,
-                    setSearch,
-                    setSearchCount,
-                    selectedOperatorId,
-                    setSelectedOperatorId,
-                    fieldCount,
-                    setFieldCount,
-                    availableSources,
-                    setAvailableSources,
-                    selectedSources,
-                    setSelectedSources,
-                    sources,
-                    datePickerStyles,
-                    createPolicyToast
-                  )}
-                  <EuiSpacer size="s" />
-                  {SourceSelect(
-                    availableSources,
-                    selectedSources,
-                    setSelectedSources,
-                    sourceSelectError,
-                    setSourceSelectError
-                  )}
-                </EuiFlexItem>
-              </EuiFlexGroup>
-              <EuiGlobalToastList
-                toasts={notificationToasts}
-                dismissToast={removeToast}
-                toastLifeTimeMs={2500}
-              />
-            </>
+          {isAdvancedSearch ? (
+            <AdvancedSearch
+              search={search}
+              setSearch={setSearch}
+              searchResults={searchResults}
+              setSearchResults={setSearchResults}
+              searchFields={searchFields}
+              setSearchFields={setSearchFields}
+              searchName={searchName}
+              setSearchName={setSearchName}
+              searchDescription={searchDescription}
+              setSearchDescription={setSearchDescription}
+              readOnlyQuery={readOnlyQuery}
+              setReadOnlyQuery={setReadOnlyQuery}
+              selectedSources={selectedSources}
+              setSelectedSources={setSelectedSources}
+              availableSources={availableSources}
+              setAvailableSources={setAvailableSources}
+              standardFields={standardFields}
+              setStandardFields={setStandardFields}
+              sources={sources}
+              setSelectedTabNumber={setSelectedTabNumber}
+              searchCount={searchCount}
+              setSearchCount={setSearchCount}
+              setFieldCount={setFieldCount}
+              isReadOnlyModalOpen={isReadOnlyModalOpen}
+              setIsReadOnlyModalOpen={setIsReadOnlyModalOpen}
+              isSaveSearchModalOpen={isSaveSearchModalOpen}
+              setIsSaveSearchModalOpen={setIsSaveSearchModalOpen}
+              selectedSavedSearch={selectedSavedSearch}
+              setSelectedSavedSearch={setSelectedSavedSearch}
+              selectedOperatorId={selectedOperatorId}
+              setIsAdvancedSearch={setIsAdvancedSearch}
+              isAdvancedSearch={isAdvancedSearch}
+              selectedField={selectedField}
+              selectedSection={selectedSection}
+              setSelectedField={setSelectedField}
+              setSelectedSection={setSelectedSection}
+              isPopoverSelectOpen={isPopoverSelectOpen}
+              setIsPopoverSelectOpen={setIsPopoverSelectOpen}
+              setIsPopoverValueOpen={setIsPopoverValueOpen}
+              isPopoverValueOpen={isPopoverValueOpen}
+              valueError={valueError}
+              setValueError={setValueError}
+              setSelectedOperatorId={setSelectedOperatorId}
+              fieldCount={fieldCount}
+              sourceSelectError={sourceSelectError}
+              datePickerStyles={datePickerStyles}
+              setSourceSelectError={setSourceSelectError}
+            />
           ) : (
-            <>
-              <EuiFlexGroup>
-                <EuiFlexItem grow={false}>
-                  <EuiSpacer size="s" />
-                  <EuiButtonEmpty
-                    onClick={() => {
-                      setAdvancedSearch(!advancedSearch);
-                    }}
-                  >
-                    Switch to advanced search
-                  </EuiButtonEmpty>
-                </EuiFlexItem>
-              </EuiFlexGroup>
-              <EuiFlexGroup>
-                <EuiFlexItem>
-                  <EuiSpacer size="s" />
-                  <form onSubmit={onFormSubmit}>
-                    <EuiFlexGroup>
-                      <EuiFlexItem>
-                        <EuiFieldSearch
-                          value={basicSearch}
-                          onChange={(e) => setBasicSearch(e.target.value)}
-                          placeholder="Search..."
-                          fullWidth
-                        />
-                      </EuiFlexItem>
-                      <EuiFlexItem grow={false}>
-                        <EuiButton type="submit" fill isDisabled={advancedSearch}>
-                          Search
-                        </EuiButton>
-                      </EuiFlexItem>
-                    </EuiFlexGroup>
-                  </form>
-                  {isLoading && (
-                    <EuiFlexGroup>
-                      <EuiFlexItem>
-                        <EuiProgress postion="fixed" size="l" color="accent" />
-                      </EuiFlexItem>
-                    </EuiFlexGroup>
-                  )}
-                </EuiFlexItem>
-              </EuiFlexGroup>
-            </>
+            <BasicSearch
+              isAdvancedSearch={isAdvancedSearch}
+              setIsAdvancedSearch={setIsAdvancedSearch}
+              standardFields={standardFields}
+              availableSources={availableSources}
+              selectedSources={selectedSources}
+              basicSearch={basicSearch}
+              setBasicSearch={setBasicSearch}
+              setSearchResults={setSearchResults}
+              setSelectedTabNumber={setSelectedTabNumber}
+            />
           )}
         </>
       ),
     },
     {
       id: 'tab3',
-      name: 'Results',
+      name: t('tabs.results'),
       content: (
         <EuiFlexGroup>
-          <EuiFlexItem>{Results(searchResults, search, basicSearch)}</EuiFlexItem>
+          <EuiFlexItem>
+            <Results
+              searchResults={searchResults}
+              searchQuery={isAdvancedSearch ? search : basicSearch}
+            />
+          </EuiFlexItem>
         </EuiFlexGroup>
       ),
     },
     {
       id: 'tab2',
-      name: 'Map',
+      name: t('tabs.map'),
       content: (
         <EuiFlexGroup>
           <EuiFlexItem>
             <EuiSpacer size="l" />
-            {/*<a href="https://agroenvgeo.data.inra.fr/mapfishapp/"><img src={map} width="460" height="400" alt='Map' /></a>*/}
             <SearchMap searchResults={searchResults} />
           </EuiFlexItem>
         </EuiFlexGroup>
@@ -1842,12 +192,10 @@ const Search = () => {
   return (
     <>
       <EuiPageContent>
-        {' '}
-        {/*style={{ backgroundColor: "#fafafa" }}*/}
         <EuiPageContentHeader>
           <EuiPageContentHeaderSection>
             <EuiTitle>
-              <h2>In-Sylva Metadata Search Platform</h2>
+              <h2>{t('pageTitle')}</h2>
             </EuiTitle>
           </EuiPageContentHeaderSection>
         </EuiPageContentHeader>
diff --git a/src/pages/search/styles.js b/src/pages/search/styles.js
new file mode 100644
index 0000000000000000000000000000000000000000..66022dc748fea12084c48d6a7c6fc471b22dce14
--- /dev/null
+++ b/src/pages/search/styles.js
@@ -0,0 +1,15 @@
+import { makeStyles } from '@material-ui/core/styles';
+
+const style = makeStyles((theme) => ({
+  container: {
+    display: 'flex',
+    flexWrap: 'wrap',
+  },
+  textField: {
+    marginLeft: theme.spacing(1),
+    marginRight: theme.spacing(1),
+    width: 240,
+  },
+}));
+
+export default style;