From b770fef9d0d8fa319b8924b7f08580c9c4cc7609 Mon Sep 17 00:00:00 2001
From: Yoan Vallet <yoan.vallet@gmail.com>
Date: Tue, 26 May 2020 01:48:29 +0200
Subject: [PATCH] WIP: handle OAuth konnector

---
 config.json                                   |  12 +-
 .../Konnector/KonnectorForm.tsx               | 101 ++++++++
 .../Konnector/KonnectorLoading.tsx            |  12 +
 .../Konnector/KonnectorOAuthForm.tsx          |  28 +++
 .../Konnector/KonnectorResult.tsx             |  55 +++++
 .../KonnectorViewer/KonnectorViewer.tsx       |  90 +++----
 .../KonnectorViewer/KonnectorViewerCard.tsx   | 219 ++++++------------
 .../ContentComponents/OAuth/OAuthForm.tsx     |  71 ++++++
 .../OAuthKonnector/OAuthKonnector.tsx         |  99 --------
 src/locales/en.json                           |   3 +-
 src/services/accountService.ts                |   2 +-
 11 files changed, 395 insertions(+), 297 deletions(-)
 create mode 100644 src/components/ContentComponents/Konnector/KonnectorForm.tsx
 create mode 100644 src/components/ContentComponents/Konnector/KonnectorLoading.tsx
 create mode 100644 src/components/ContentComponents/Konnector/KonnectorOAuthForm.tsx
 create mode 100644 src/components/ContentComponents/Konnector/KonnectorResult.tsx
 create mode 100644 src/components/ContentComponents/OAuth/OAuthForm.tsx
 delete mode 100644 src/components/ContentComponents/OAuthKonnector/OAuthKonnector.tsx

diff --git a/config.json b/config.json
index 4a2b8bb71..dba7af10a 100644
--- a/config.json
+++ b/config.json
@@ -9,8 +9,8 @@
         "name": "enedis",
         "type": "ELECTRICITY",
         "oauth": true,
-        "slug": "enedis-konnector",
-        "id": "io.cozy.konnectors/enedis-konnector"
+        "slug": "enedis",
+        "id": "io.cozy.konnectors/enedis"
       }
     },
     {
@@ -22,8 +22,8 @@
         "name": "eau du grand lyon",
         "type": "WATER",
         "oauth": false,
-        "slug": "egl-api-connector",
-        "id": "io.cozy.konnectors/egl-api-connector"
+        "slug": "egl",
+        "id": "io.cozy.konnectors/egl"
       }
     },
     {
@@ -35,8 +35,8 @@
         "name": "grdf",
         "type": "GAS",
         "oauth": false,
-        "slug": "grdf-scraping-connector",
-        "id": "io.cozy.konnectors/grdf-scraping-connector"
+        "slug": "grdf",
+        "id": "io.cozy.konnectors/grdf"
       }
     }
   ]
diff --git a/src/components/ContentComponents/Konnector/KonnectorForm.tsx b/src/components/ContentComponents/Konnector/KonnectorForm.tsx
new file mode 100644
index 000000000..ac3455632
--- /dev/null
+++ b/src/components/ContentComponents/Konnector/KonnectorForm.tsx
@@ -0,0 +1,101 @@
+import React from 'react'
+import { translate } from 'cozy-ui/react/I18n'
+
+import IFluidConfig from 'services/IFluidConfig'
+
+import StyledIconButton from 'components/CommonKit/IconButton/StyledIconButton'
+import StyledButton from 'components/CommonKit/Button/StyledButton'
+import TrailingIcon from 'assets/icons/ico/trailing-icon.svg'
+
+interface KonnectorFormProps {
+  fluidConfig: IFluidConfig
+  login: string
+  setLogin: Function
+  password: string
+  setPassword: Function
+  loading: boolean
+  error: string
+  handleSubmit: Function
+  t: Function
+}
+
+const KonnectorForm: React.FC<KonnectorFormProps> = ({
+  fluidConfig,
+  login,
+  setLogin,
+  password,
+  setPassword,
+  loading,
+  error,
+  handleSubmit,
+  t,
+}: KonnectorFormProps) => {
+  const konnectorName: string = fluidConfig.konnectorConfig.name
+  const konnectorType: string = fluidConfig.konnectorConfig.type
+
+  function revealPassword(idInput: string) {
+    const input = document.getElementById(idInput)
+    if (input) {
+      if (input.getAttribute('type') === 'password') {
+        input.setAttribute('type', 'text')
+      } else {
+        input.setAttribute('type', 'password')
+      }
+    }
+  }
+
+  return (
+    <form
+      className="form"
+      onSubmit={(e: React.FormEvent<HTMLFormElement>) => handleSubmit(e)}
+    >
+      {t('KONNECTORCONFIG.LABEL_FILLIN')} {konnectorName}
+      <div className="form-group">
+        <div className="form-message">{error}</div>
+        <input
+          id={'idFieldLogin' + konnectorType}
+          type="text"
+          className="form-control form-input"
+          aria-describedby="emailHelp"
+          placeholder="Adresse e-mail"
+          name="login"
+          onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
+            setLogin(e.target.value)
+          }
+          value={login}
+        ></input>
+      </div>
+      <div className="form-group">
+        <div className="form-message">{error}</div>
+        <input
+          id={'idFieldPassword' + konnectorType}
+          type="password"
+          className="form-control form-input"
+          aria-describedby="PasswordHelp"
+          placeholder="Mot de passe"
+          name="password"
+          onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
+            setPassword(e.target.value)
+          }
+          value={password}
+        />
+        <span>
+          <StyledIconButton
+            icon={TrailingIcon}
+            className="form-trailing-icon"
+            size={22}
+            onClick={() => revealPassword('idFieldPassword' + konnectorType)}
+          />
+        </span>
+      </div>
+      <StyledButton type="submit" color="primary" disabled={loading}>
+        {t('KONNECTORCONFIG.BTN_CONNECTION')}
+      </StyledButton>
+      <StyledButton type="button" color="secondary" disabled={loading}>
+        {t('KONNECTORCONFIG.BTN_NOACCOUNT')}
+      </StyledButton>
+    </form>
+  )
+}
+
+export default translate()(KonnectorForm)
diff --git a/src/components/ContentComponents/Konnector/KonnectorLoading.tsx b/src/components/ContentComponents/Konnector/KonnectorLoading.tsx
new file mode 100644
index 000000000..54aca4baa
--- /dev/null
+++ b/src/components/ContentComponents/Konnector/KonnectorLoading.tsx
@@ -0,0 +1,12 @@
+import React from 'react'
+
+const KonnectorLoading = () => {
+  return (
+    <div>
+      Vos données sont en cours de rappatriement. Ce traitement peut prendre
+      plusieurs minutes, merci de patienter.
+    </div>
+  )
+}
+
+export default KonnectorLoading
diff --git a/src/components/ContentComponents/Konnector/KonnectorOAuthForm.tsx b/src/components/ContentComponents/Konnector/KonnectorOAuthForm.tsx
new file mode 100644
index 000000000..2f028ec8f
--- /dev/null
+++ b/src/components/ContentComponents/Konnector/KonnectorOAuthForm.tsx
@@ -0,0 +1,28 @@
+import React from 'react'
+import { translate } from 'cozy-ui/react/I18n'
+
+import OAuthForm from 'components/ContentComponents/OAuth/OAuthForm'
+import { Konnector } from 'doctypes'
+
+interface KonnectorOAuthFormProps {
+  konnector: Konnector
+  onSuccess: Function
+  loading: boolean
+  t: Function
+}
+
+const KonnectorOAuthForm: React.FC<KonnectorOAuthFormProps> = ({
+  konnector,
+  onSuccess,
+  loading,
+  t,
+}: KonnectorOAuthFormProps) => {
+  return (
+    <div>
+      {t('oauth.connect.' + konnector.slug)}
+      <OAuthForm konnector={konnector} onSuccess={onSuccess} />
+    </div>
+  )
+}
+
+export default translate()(KonnectorOAuthForm)
diff --git a/src/components/ContentComponents/Konnector/KonnectorResult.tsx b/src/components/ContentComponents/Konnector/KonnectorResult.tsx
new file mode 100644
index 000000000..53971d5c1
--- /dev/null
+++ b/src/components/ContentComponents/Konnector/KonnectorResult.tsx
@@ -0,0 +1,55 @@
+import React from 'react'
+import { translate } from 'cozy-ui/react/I18n'
+
+import StyledButton from 'components/CommonKit/Button/StyledButton'
+import Spinner from 'components/CommonKit/Spinner/Spinner'
+
+interface KonnectorResultProps {
+  date: string
+  updating: boolean
+  errored: boolean
+  updateKonnector: (event: any) => void
+  deleteAccount: (event: any) => void
+  t: Function
+}
+
+const KonnectorResult: React.FC<KonnectorResultProps> = ({
+  date,
+  updating,
+  errored,
+  updateKonnector,
+  deleteAccount,
+  t,
+}) => {
+  return (
+    <div>
+      <div className="accordion-update">
+        <div
+          className={errored ? 'accordion-caption-red' : 'accordion-caption'}
+        >
+          {t('KONNECTORCONFIG.LABEL_UPDATEDAT')}
+        </div>
+        <div>{date}</div>
+      </div>
+      <div className="inline-buttons">
+        <StyledButton type="button" color="primary" onClick={updateKonnector}>
+          {updating ? (
+            <Spinner size="2em" />
+          ) : (
+            <div>{t('KONNECTORCONFIG.BTN_UPDATE')}</div>
+          )}
+        </StyledButton>
+        <StyledButton
+          type="button"
+          color="secondary"
+          onClick={deleteAccount}
+          disabled={updating}
+        >
+          {t('KONNECTORCONFIG.BTN_DELETE')}
+        </StyledButton>
+      </div>
+    </div>
+  )
+}
+
+export default translate()(KonnectorResult)
diff --git a/src/components/ContentComponents/KonnectorViewer/KonnectorViewer.tsx b/src/components/ContentComponents/KonnectorViewer/KonnectorViewer.tsx
index 1d6089592..25c75055b 100644
--- a/src/components/ContentComponents/KonnectorViewer/KonnectorViewer.tsx
+++ b/src/components/ContentComponents/KonnectorViewer/KonnectorViewer.tsx
@@ -1,6 +1,10 @@
 import React, { useState, useEffect } from 'react'
 import { withClient, Client } from 'cozy-client'
+
+import { Konnector } from 'doctypes'
+import KonnectorService from 'services/konnectorService'
 import KonnectorStatusService from 'services/konnectorStatusService'
+
 import KonnectorViewerCard from 'components/ContentComponents/KonnectorViewer/KonnectorViewerCard'
 import IFluidConfig from 'services/IFluidConfig'
 
@@ -15,55 +19,61 @@ const KonnectorViewer: React.FC<KonnectorViewerProps> = ({
   client,
   isParam = false,
 }: KonnectorViewerProps) => {
-  const [Konnectors, setKonnectors] = useState(null)
-  const [Triggers, setTriggers] = useState(null)
+  const [konnector, setKonnector] = useState<Konnector | null>(null)
+  const [lastTrigger, setLastTrigger] = useState<any>(null)
 
-  const setAllKonnectors = async () => {
+  useEffect(() => {
+    let subscribed = true
+    const konnectorService = new KonnectorService(
+      client,
+      fluidConfig.konnectorConfig.slug
+    )
     const kss = new KonnectorStatusService(client)
-    const allKonnectors = await kss.getAllKonnectors()
-    setKonnectors(allKonnectors)
-    //console.log('All Konnectors',allKonnectors);
-  }
 
-  const setAllTriggers = async () => {
-    const kss = new KonnectorStatusService(client)
-    const allTriggers = await kss.getAllTriggers()
-    setTriggers(allTriggers)
-    //console.log('All Triggers',allTriggers)
-  }
+    async function getData() {
+      const _konnector: Konnector = await konnectorService.fetchKonnector()
+      if (!_konnector || !_konnector.slug) {
+        throw new Error(
+          `Could not find konnector for ${fluidConfig.konnectorConfig.slug}`
+        )
+      }
+      if (subscribed && _konnector) {
+        setKonnector(_konnector)
+      }
 
-  const fetchKonnectorFromTrigger = trigger => {
-    let konnectorName = ''
-    try {
-      konnectorName = trigger.message.konnector
-    } catch (error) {
-      return konnectorName
+      const allTriggers = await kss.getAllTriggers()
+      if (allTriggers) {
+        const lastTrigger = allTriggers
+          .filter(
+            trigger =>
+              trigger.worker === 'konnector' &&
+              trigger.message.konnector === fluidConfig.konnectorConfig.slug
+          )
+          .sort((a, b) => (new Date(a) > new Date(b) ? 1 : -1))
+          .shift()
+        if (subscribed && lastTrigger) {
+          setLastTrigger(lastTrigger)
+        }
+      }
     }
-    return konnectorName
-  }
 
-  const getLastTrigger = konnector => {
-    if (!Triggers) return null
-    const lastTrigger = Triggers.filter(
-      trigger =>
-        fetchKonnectorFromTrigger(trigger) === konnector.id.split('/').pop()
-    )
-      .sort((a, b) => (new Date(a) > new Date(b) ? 1 : -1))
-      .shift()
-    return lastTrigger
-  }
-
-  useEffect(() => {
-    setAllKonnectors()
-    setAllTriggers()
+    getData()
+    return () => {
+      subscribed = false
+    }
   }, [])
 
   return (
-    <KonnectorViewerCard
-      fluidConfig={fluidConfig}
-      trigger={getLastTrigger(fluidConfig.konnectorConfig)}
-      isParam={isParam}
-    />
+    <>
+      {!konnector ? null : (
+        <KonnectorViewerCard
+          fluidConfig={fluidConfig}
+          konnector={konnector}
+          trigger={lastTrigger}
+          isParam={isParam}
+        />
+      )}
+    </>
   )
 }
 
diff --git a/src/components/ContentComponents/KonnectorViewer/KonnectorViewerCard.tsx b/src/components/ContentComponents/KonnectorViewer/KonnectorViewerCard.tsx
index d2b0a0bf6..a79e63b48 100644
--- a/src/components/ContentComponents/KonnectorViewer/KonnectorViewerCard.tsx
+++ b/src/components/ContentComponents/KonnectorViewer/KonnectorViewerCard.tsx
@@ -14,43 +14,36 @@ import { translate } from 'cozy-ui/react/I18n'
 import { getPicto, getAddPicto, getFuildType, getParamPicto } from 'utils/utils'
 import chevronDown from 'assets/icons/ico/chevron-down.svg'
 import chevronUp from 'assets/icons/ico/chevron-up.svg'
-import TrailingIcon from 'assets/icons/ico/trailing-icon.svg'
 
 import StyledIcon from 'components/CommonKit/Icon/StyledIcon'
 import StyledIconButton from 'components/CommonKit/IconButton/StyledIconButton'
-import StyledButton from 'components/CommonKit/Button/StyledButton'
 
 import failurePicto from '../KonnectorViewer/picto-failure.png'
 import successPicto from '../KonnectorViewer/picto-success.png'
 import pendingPicto from '../KonnectorViewer/picto-pending.png'
 import KonnectorService from 'services/konnectorService'
 import KonnectorStatusService from 'services/konnectorStatusService'
-import Spinner from 'components/CommonKit/Spinner/Spinner'
 import IFluidConfig from 'services/IFluidConfig'
-import OAuthKonnector from '../OAuthKonnector/OAuthKonnector'
+
+import KonnectorForm from 'components/ContentComponents/Konnector/KonnectorForm'
+import KonnectorOAuthForm from 'components/ContentComponents/Konnector/KonnectorOAuthForm'
+import KonnectorLoading from 'components/ContentComponents/Konnector/KonnectorLoading'
+import KonnectorResult from 'components/ContentComponents/Konnector/KonnectorResult'
+
 import { Account, Konnector, Trigger } from 'doctypes'
 
 interface KonnectorViewerCardProps {
   fluidConfig: IFluidConfig
+  konnector: Konnector
   trigger: any | null
   client: Client
   isParam: boolean
   t: Function
 }
 
-function revealPassword(idInput: string) {
-  const input = document.getElementById(idInput)
-  if (input) {
-    if (input.getAttribute('type') === 'password') {
-      input.setAttribute('type', 'text')
-    } else {
-      input.setAttribute('type', 'password')
-    }
-  }
-}
-
 const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({
   fluidConfig,
+  konnector,
   trigger,
   client,
   isParam,
@@ -59,6 +52,7 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({
   const [login, setLogin] = useState<string>('')
   const [password, setPassword] = useState<string>('')
   const [loading, setLoading] = useState<boolean>(false)
+  const [updating, setUpdating] = useState<boolean>(false)
   const [konnectorAccountId, setAccountId] = useState<string>('')
   const [isKonnectorAcc, setAccount] = useState<boolean>(false)
   const [setActive, setActiveState] = useState('')
@@ -104,7 +98,7 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({
       setJobState(JobState.Running)
       const connectionService = new ConnectionService(
         client,
-        fluidConfig.konnectorConfig.id,
+        fluidConfig.konnectorConfig.slug,
         login,
         password
       )
@@ -126,7 +120,7 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({
       setAccountId(data.message.account)
       setError('Connected')
       setAccount(true)
-      await context.refreshFluidTypes()
+      // await context.refreshFluidTypes()
       return data
     } catch (error) {
       setLoading(false)
@@ -154,7 +148,7 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({
       toggleAccordion()
       trigger = null
       setAccount(false)
-      context.refreshFluidTypes()
+      await context.refreshFluidTypes()
     } catch (error) {
       setLoading(false)
       setError(error.message)
@@ -164,17 +158,17 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({
   const updateKonnector = async () => {
     setError('')
     setJobState('')
-    setLoading(true)
+    setUpdating(true)
     try {
       const account = await AccountService.getAccount(
         client,
         konnectorAccountId
       )
-      const konnectorService = new KonnectorService(
-        client,
-        fluidConfig.konnectorConfig.slug
-      )
-      const konnector = await konnectorService.fetchKonnector()
+      // const konnectorService = new KonnectorService(
+      //   client,
+      //   fluidConfig.konnectorConfig.slug
+      // )
+      // const konnector = await konnectorService.fetchKonnector()
       const triggersServices = new TriggerService(client, account, konnector)
       if (updateTrigger !== null) {
         triggersServices.setTrigger(updateTrigger)
@@ -186,27 +180,27 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({
         throw new Error(`Error during trigger launching`)
       }
       setlaunchedJob(job)
-      setLoading(false)
+      // setUpdating(false)
       setUpdateDate(new Date(job.queued_at).toDateString())
     } catch (error) {
-      setLoading(false)
+      setUpdating(false)
       setError(error.message)
     }
   }
 
-  const initOauthAccount = async oauthAccountId => {
+  const initOauthAccount = async (oauthAccountId: string) => {
     console.log('initOauthAccount', oauthAccountId)
     setError('')
     setJobState('')
     setLoading(true)
     try {
       const account = await AccountService.getAccount(client, oauthAccountId)
-      const konnectorService = new KonnectorService(
-        client,
-        fluidConfig.konnectorConfig.slug
-      )
-      console.log(account)
-      const konnector: Konnector = await konnectorService.fetchKonnector()
+      // const konnectorService = new KonnectorService(
+      //   client,
+      //   fluidConfig.konnectorConfig.slug
+      // )
+      // console.log(account)
+      // const konnector: Konnector = await konnectorService.fetchKonnector()
       console.log(konnector)
       const triggersServices = new TriggerService(client, account, konnector)
       const trigger: Trigger = await triggersServices.createTrigger()
@@ -226,7 +220,7 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({
       setAccountId(job.message.account)
       setError('Connected')
       setAccount(true)
-      await context.refreshFluidTypes()
+      // await context.refreshFluidTypes()
     } catch (error) {
       setLoading(false)
       setError(error.message)
@@ -260,7 +254,14 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({
   }
 
   const jobStateCallBack = async (state: string) => {
+    console.log('JobCallBack', state)
     setJobState(state)
+    if (state !== JobState.Running) {
+      setLoading(false)
+      setUpdating(false)
+      setJobState(state)
+      context.refreshFluidTypes()
+    }
   }
 
   useEffect(() => {
@@ -271,13 +272,12 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({
         let runningJob = null
 
         if (trigger) {
-          let triggerState = ''
+          let triggerState = null
           triggerState = TriggerService.fetchStateFromTrigger(trigger)
           const konnectorAcc = TriggerService.fetchKonnectorAccountFromTrigger(
             trigger
           )
-          const konnectorId = fluidConfig.konnectorConfig.id.split('/')
-          if (subscribed && konnectorAcc.konnector === konnectorId[1]) {
+          if (subscribed && konnectorAcc.konnector === konnector.slug) {
             setAccountId(konnectorAcc.account)
             setAccount(true)
           }
@@ -286,7 +286,7 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({
             runningJob = jobService.fetchJob(triggerState.last_executed_job_id)
         }
         if (launchedJob) runningJob = launchedJob
-        if (runningJob) jobService.watch(runningJob, setJobStateAfterTimer)
+        if (runningJob) jobService.watch(runningJob, jobStateCallBack)
       }
     }
     getTriggerData()
@@ -328,119 +328,38 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({
             className={`accordion-content ${setActive}`}
           >
             {!isKonnectorAcc ? (
-              <div>
-                {!fluidConfig.konnectorConfig.oauth ? (
-                  <form
-                    className="form"
-                    onSubmit={(e: React.FormEvent<HTMLFormElement>) =>
-                      handleSubmit(e)
-                    }
-                  >
-                    {t('KONNECTORCONFIG.LABEL_FILLIN')}{' '}
-                    {fluidConfig.konnectorConfig.name}
-                    <div className="form-group">
-                      <div className="form-message">{error}</div>
-                      <input
-                        id={'idFieldLogin' + type}
-                        type="text"
-                        className="form-control form-input"
-                        aria-describedby="emailHelp"
-                        placeholder="Adresse e-mail"
-                        name="login"
-                        onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
-                          setLogin(e.target.value)
-                        }
-                        value={login}
-                      ></input>
-                    </div>
-                    <div className="form-group">
-                      <div className="form-message">{error}</div>
-                      <input
-                        id={'idFieldPassword' + type}
-                        type="password"
-                        className="form-control form-input"
-                        aria-describedby="PasswordHelp"
-                        placeholder="Mot de passe"
-                        name="password"
-                        onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
-                          setPassword(e.target.value)
-                        }
-                        value={password}
-                      />
-                      <span>
-                        <StyledIconButton
-                          icon={TrailingIcon}
-                          className="form-trailing-icon"
-                          size={22}
-                          onClick={() =>
-                            revealPassword('idFieldPassword' + type)
-                          }
-                        />
-                      </span>
-                    </div>
-                    <StyledButton
-                      type="submit"
-                      color="primary"
-                      disabled={loading}
-                    >
-                      {t('KONNECTORCONFIG.BTN_CONNECTION')}
-                    </StyledButton>
-                    <StyledButton
-                      type="button"
-                      color="secondary"
-                      disabled={loading}
-                    >
-                      {t('KONNECTORCONFIG.BTN_NOACCOUNT')}
-                    </StyledButton>
-                  </form>
-                ) : (
-                  <div>
-                    <OAuthKonnector setKonnectorAccount={initOauthAccount} />
-                  </div>
-                )}
-              </div>
+              !fluidConfig.konnectorConfig.oauth ? (
+                <KonnectorForm
+                  fluidConfig={fluidConfig}
+                  login={login}
+                  setLogin={setLogin}
+                  password={password}
+                  setPassword={setPassword}
+                  loading={loading}
+                  error={error}
+                  handleSubmit={handleSubmit}
+                />
+              ) : (
+                <KonnectorOAuthForm
+                  konnector={konnector}
+                  onSuccess={initOauthAccount}
+                  loading={loading}
+                />
+              )
+            ) : loading ? (
+              <KonnectorLoading />
             ) : (
-              <div>
-                <div>
-                  <div className="accordion-update">
-                    <div
-                      className={
-                        JobState.Errored
-                          ? 'accordion-caption-red'
-                          : 'accordion-caption'
-                      }
-                    >
-                      {t('KONNECTORCONFIG.LABEL_UPDATEDAT')}
-                    </div>
-                    {trigger ? (
-                      <div>{TriggerService.fetchDateFromTrigger(trigger)}</div>
-                    ) : (
-                      <div>{updateDate}</div>
-                    )}
-                  </div>
-                  <div className="inline-buttons">
-                    <StyledButton
-                      type="button"
-                      color="primary"
-                      onClick={updateKonnector}
-                    >
-                      {loading ? (
-                        <Spinner size="2em" />
-                      ) : (
-                        <div>{t('KONNECTORCONFIG.BTN_UPDATE')}</div>
-                      )}
-                    </StyledButton>
-                    <StyledButton
-                      type="button"
-                      color="secondary"
-                      onClick={deleteAccount}
-                      disabled={loading}
-                    >
-                      {t('KONNECTORCONFIG.BTN_DELETE')}
-                    </StyledButton>
-                  </div>
-                </div>
-              </div>
+              <KonnectorResult
+                date={
+                  trigger
+                    ? TriggerService.fetchDateFromTrigger(trigger)
+                    : updateDate
+                }
+                updating={updating}
+                errored={jobState === JobState.Errored}
+                updateKonnector={updateKonnector}
+                deleteAccount={deleteAccount}
+              />
             )}
           </div>
         </div>
diff --git a/src/components/ContentComponents/OAuth/OAuthForm.tsx b/src/components/ContentComponents/OAuth/OAuthForm.tsx
new file mode 100644
index 000000000..10e743b5b
--- /dev/null
+++ b/src/components/ContentComponents/OAuth/OAuthForm.tsx
@@ -0,0 +1,71 @@
+import React, { useState, useEffect } from 'react'
+import { Client, withClient } from 'cozy-client'
+import { translate } from 'cozy-ui/react/I18n'
+
+import { Konnector } from 'doctypes'
+import KonnectorService from 'services/konnectorService'
+
+import { OAuthWindow } from 'cozy-harvest-lib/dist/components/OAuthWindow'
+
+import StyledButton from 'components/CommonKit/Button/StyledButton'
+
+interface OAuthFormProps {
+  konnector: Konnector
+  onSuccess: Function
+  client: Client
+  t: Function
+}
+
+const OAuthForm: React.FC<OAuthFormProps> = ({
+  konnector,
+  onSuccess,
+  client,
+  t,
+}: OAuthFormProps) => {
+  const IDLE = 'idle'
+  const WAITING = 'waiting'
+
+  const [status, setStatus] = useState<string>(IDLE)
+
+  function endOAuth() {
+    setStatus(IDLE)
+  }
+  function startOAuth() {
+    setStatus(WAITING)
+  }
+  function handleAccountId(accountId: string) {
+    endOAuth()
+    onSuccess(accountId)
+  }
+  function handleSubmit() {
+    startOAuth()
+  }
+  function handleOAuthCancel() {
+    endOAuth()
+  }
+
+  const isWaiting = status === WAITING
+  return !konnector ? null : (
+    <>
+      <StyledButton
+        type="button"
+        color="primary"
+        onClick={handleSubmit}
+        disabled={isWaiting}
+      >
+        {t('oauth.connect.label')}
+      </StyledButton>
+      {isWaiting && (
+        <OAuthWindow
+          client={client}
+          konnector={konnector}
+          onSuccess={handleAccountId}
+          onCancel={handleOAuthCancel}
+          t={t}
+        />
+      )}
+    </>
+  )
+}
+
+export default translate()(withClient(OAuthForm))
diff --git a/src/components/ContentComponents/OAuthKonnector/OAuthKonnector.tsx b/src/components/ContentComponents/OAuthKonnector/OAuthKonnector.tsx
deleted file mode 100644
index 609b6968f..000000000
--- a/src/components/ContentComponents/OAuthKonnector/OAuthKonnector.tsx
+++ /dev/null
@@ -1,99 +0,0 @@
-import React, { useState, useEffect } from 'react'
-import { Client, withClient } from 'cozy-client'
-import { translate } from 'cozy-ui/react/I18n'
-
-import { Konnector } from 'doctypes'
-
-import KonnectorService from 'services/konnectorService'
-
-import { OAuthForm } from 'cozy-harvest-lib/dist/components/OAuthForm'
-import { OAuthWindow } from 'cozy-harvest-lib/dist/components/OAuthWindow'
-
-import triggersMutations from 'cozy-harvest-lib/dist/connections/triggers'
-import StyledButton from 'components/CommonKit/Button/StyledButton'
-
-interface OAuthKonnectorProps {
-  // account: any
-  // konnector: any
-  setKonnectorAccount: any
-  client: Client
-  t: Function
-}
-
-const OAuthKonnector: React.FC<OAuthKonnectorProps> = ({
-  client,
-  setKonnectorAccount,
-  t,
-}: OAuthKonnectorProps) => {
-  const konnectorId = 'enedis-konnector'
-  const IDLE = 'idle'
-  const WAITING = 'waiting'
-
-  const [konnector, setKonnector] = useState<any>(null)
-  const [initialValues, setInitialValues] = useState<any>(null)
-  const [status, setStatus] = useState<string>(IDLE)
-
-  function endOAuth() {
-    setStatus(IDLE)
-  }
-  function startOAuth() {
-    setStatus(WAITING)
-  }
-  function handleAccountId(accountId) {
-    // const { onSuccess } = this.props
-    console.log('handleaccountid', accountId)
-    setKonnectorAccount(accountId)
-    endOAuth()
-    // if (typeof onSuccess === 'function') onSuccess(accountId)
-  }
-  function handleSubmit() {
-    startOAuth()
-  }
-  function handleOAuthCancel() {
-    endOAuth()
-  }
-
-  useEffect(() => {
-    let subscribed = true
-    const konnectorService = new KonnectorService(client, konnectorId)
-
-    async function getKonnector() {
-      const _konnector: Konnector = await konnectorService.fetchKonnector()
-      if (!_konnector || !_konnector.slug) {
-        throw new Error(`Could not find konnector for ${konnectorId}`)
-      }
-      if (subscribed && _konnector) {
-        setKonnector(_konnector)
-      }
-    }
-    getKonnector()
-    return () => {
-      subscribed = false
-    }
-  }, [])
-
-  const isWaiting = status === WAITING
-  return !konnector ? null : (
-    <>
-      <StyledButton
-        type="button"
-        color="primary"
-        onClick={handleSubmit}
-        disabled={isWaiting}
-      >
-        {t('oauth.connect.label')}
-      </StyledButton>
-      {isWaiting && (
-        <OAuthWindow
-          client={client}
-          konnector={konnector}
-          onSuccess={handleAccountId}
-          onCancel={handleOAuthCancel}
-          t={t}
-        />
-      )}
-    </>
-  )
-}
-
-export default translate()(withClient(OAuthKonnector))
diff --git a/src/locales/en.json b/src/locales/en.json
index d009fd664..73c80f3d7 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -172,7 +172,8 @@
   },
   "oauth": {
     "connect": {
-      "label": "Connect"
+      "enedis": "En cliquant sur ce bouton, vous allez accéder à votre compte personnel Enedis où vous pourrez donner votre accord pour qu’Enedis nous transmette vos données.",
+      "label": "Connexion"
     },
     "window": {
       "title": "OAuth"
diff --git a/src/services/accountService.ts b/src/services/accountService.ts
index 77795c9e3..09dd90174 100644
--- a/src/services/accountService.ts
+++ b/src/services/accountService.ts
@@ -105,7 +105,7 @@ export class AccountService {
         .find('io.cozy.accounts')
         // eslint-disable-next-line @typescript-eslint/camelcase
         .where({ account_type: type })
-        .sortBy([{ 'cozyMetadata.updatedAt': 'desc' }])
+        // .sortBy([{ 'cozyMetadata.updatedAt': 'desc' }])
         .limitBy(1)
       return await client.query(query)
     } catch (error) {
-- 
GitLab