diff --git a/src/components/ContentComponents/Konnector/KonnectorForm.tsx b/src/components/ContentComponents/Konnector/KonnectorForm.tsx index c85fece9ab9365970d938a899bc56cb895fb566c..e02336b889dd2542fbf802cfea2a5e30e5a0dbe9 100644 --- a/src/components/ContentComponents/Konnector/KonnectorForm.tsx +++ b/src/components/ContentComponents/Konnector/KonnectorForm.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import React from 'react' import { translate } from 'cozy-ui/react/I18n' import IFluidConfig from 'services/IFluidConfig' @@ -6,46 +6,42 @@ import { Konnector, Trigger } from 'doctypes' import KonnectorLoginForm from 'components/ContentComponents/Konnector/KonnectorLoginForm' import KonnectorOAuthForm from 'components/ContentComponents/Konnector/KonnectorOAuthForm' -import KonnectorLoading from 'components/ContentComponents/Konnector/KonnectorLoading' interface KonnectorFormProps { fluidConfig: IFluidConfig konnector: Konnector - handleConnexion: Function + account: Account | null + trigger: Trigger | null + handleSuccessForm: Function } const KonnectorForm: React.FC<KonnectorFormProps> = ({ fluidConfig, konnector, - handleConnexion, + account, + trigger, + handleSuccessForm, }: KonnectorFormProps) => { const oAuth: boolean = fluidConfig.konnectorConfig.oauth - const [account, setAccount] = useState<Account | null>(null) - const [trigger, setTrigger] = useState<Trigger | null>(null) - const handleForm = (_account: Account, _trigger: Trigger) => { - setAccount(_account) - setTrigger(_trigger) - } - - const handleKonnectorLoading = () => { - handleConnexion(account) + const handleSuccess = (_account: Account, _trigger: Trigger) => { + handleSuccessForm(_account, _trigger) } return ( <> - {account && trigger ? ( - <KonnectorLoading + {!oAuth ? ( + <KonnectorLoginForm + fluidConfig={fluidConfig} + onSuccess={handleSuccess} + account={account} trigger={trigger} - handleKonnectorLoading={handleKonnectorLoading} /> - ) : !oAuth ? ( - <KonnectorLoginForm fluidConfig={fluidConfig} onSuccess={handleForm} /> ) : ( <KonnectorOAuthForm konnector={konnector} siteLink={fluidConfig.siteLink} - onSuccess={handleForm} + onSuccess={handleSuccess} /> )} </> diff --git a/src/components/ContentComponents/Konnector/KonnectorLoading.tsx b/src/components/ContentComponents/Konnector/KonnectorLaunch.tsx similarity index 85% rename from src/components/ContentComponents/Konnector/KonnectorLoading.tsx rename to src/components/ContentComponents/Konnector/KonnectorLaunch.tsx index a0a3ea348aef85e6972a063d2a93116f45ee79e9..9cf2abb7f94d98ecbb22ae6370d65b756420817f 100644 --- a/src/components/ContentComponents/Konnector/KonnectorLoading.tsx +++ b/src/components/ContentComponents/Konnector/KonnectorLaunch.tsx @@ -23,21 +23,21 @@ const loadingOptions = { }, } -interface KonnectorLoadingProps { +interface KonnectorLaunchProps { trigger: Trigger - handleKonnectorLoading: Function + handleKonnectorLaunch: Function client: Client t: Function } -const KonnectorLoading: React.FC<KonnectorLoadingProps> = ({ +const KonnectorLaunch: React.FC<KonnectorLaunchProps> = ({ trigger, - handleKonnectorLoading, + handleKonnectorLaunch, client, t, -}: KonnectorLoadingProps) => { +}: KonnectorLaunchProps) => { const callbackResponse = () => { - handleKonnectorLoading() + handleKonnectorLaunch() } useEffect(() => { @@ -63,6 +63,7 @@ const KonnectorLoading: React.FC<KonnectorLoadingProps> = ({ } }, []) + // TODO - SUCCESS SCREEN return ( <div className="kload-content"> <Lottie options={loadingOptions} height={50} width={50} /> @@ -76,4 +77,4 @@ const KonnectorLoading: React.FC<KonnectorLoadingProps> = ({ ) } -export default translate()(withClient(KonnectorLoading)) +export default translate()(withClient(KonnectorLaunch)) diff --git a/src/components/ContentComponents/Konnector/KonnectorLoginForm.tsx b/src/components/ContentComponents/Konnector/KonnectorLoginForm.tsx index 6726c6af3c09cbda921c660e23289e92b9c24d7e..a4023ac832fd04bb4cdb9f67f9805f8d42b2bb54 100644 --- a/src/components/ContentComponents/Konnector/KonnectorLoginForm.tsx +++ b/src/components/ContentComponents/Konnector/KonnectorLoginForm.tsx @@ -8,10 +8,13 @@ import StyledIconButton from 'components/CommonKit/IconButton/StyledIconButton' import StyledButton from 'components/CommonKit/Button/StyledButton' import TrailingIcon from 'assets/icons/ico/trailing-icon.svg' import { ConnectionService } from 'services/connectionService' +import { Account, Trigger } from 'doctypes' interface KonnectorLoginFormProps { fluidConfig: IFluidConfig onSuccess: Function + account: Account + trigger: Trigger client: Client t: Function } @@ -19,6 +22,8 @@ interface KonnectorLoginFormProps { const KonnectorLoginForm: React.FC<KonnectorLoginFormProps> = ({ fluidConfig, onSuccess, + account, + trigger, client, t, }: KonnectorLoginFormProps) => { @@ -42,6 +47,27 @@ const KonnectorLoginForm: React.FC<KonnectorLoginFormProps> = ({ } } + const connect = async () => { + const connectionService = new ConnectionService( + client, + fluidConfig.konnectorConfig.slug, + login, + password + ) + const { account, trigger } = await connectionService.connectNewUser() + if (!trigger) { + setError(t('KONNECTORCONFIG.ERROR_ACCOUNT_CREATION')) + setLoading(false) + return null + } + onSuccess(account, trigger) + } + + const update = async () => { + // TODO - update account + onSuccess(account, trigger) + } + const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault() try { @@ -52,24 +78,17 @@ const KonnectorLoginForm: React.FC<KonnectorLoginFormProps> = ({ setLoading(false) return null } - const connectionService = new ConnectionService( - client, - fluidConfig.konnectorConfig.slug, - login, - password - ) - const { account, trigger } = await connectionService.connectNewUser() - if (!trigger) { - setError(t('KONNECTORCONFIG.ERROR_ACCOUNT_CREATION')) - setLoading(false) - return null + if (!account) { + await connect() + } else { + await update() } - onSuccess(account, trigger) } catch (error) { setLoading(false) } } + // TODO - if received account from props = display error login failed return ( <form className="form" diff --git a/src/components/ContentComponents/KonnectorViewer/KonnectorViewerCard.tsx b/src/components/ContentComponents/KonnectorViewer/KonnectorViewerCard.tsx index 8074ff68e588fe9b7c60cec725fd6ea813555f06..70b9eeaec329e7191fcf26c9e6a36f411e26e8ff 100644 --- a/src/components/ContentComponents/KonnectorViewer/KonnectorViewerCard.tsx +++ b/src/components/ContentComponents/KonnectorViewer/KonnectorViewerCard.tsx @@ -19,9 +19,11 @@ import IFluidConfig from 'services/IFluidConfig' import KonnectorNotFound from 'components/ContentComponents/Konnector/KonnectorNotFound' import KonnectorForm from 'components/ContentComponents/Konnector/KonnectorForm' import KonnectorResult from 'components/ContentComponents/Konnector/KonnectorResult' +import KonnectorLaunch from 'components/ContentComponents/Konnector/KonnectorLaunch' -import { Konnector } from 'doctypes' +import { Konnector, Trigger, TriggerState } from 'doctypes' import { JobState } from 'services/jobsService' +import { TriggerService } from 'services/triggersService' interface KonnectorViewerCardProps { fluidConfig: IFluidConfig @@ -39,6 +41,9 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ t, }: KonnectorViewerCardProps) => { const [account, setAccount] = useState<Account | null>(null) + const [trigger, setTrigger] = useState<Trigger | null>(null) + const [triggerState, setTriggerState] = useState<TriggerState | null>(null) + const [shouldLaunch, setLaunch] = useState<boolean>(false) const [setActive, setActiveState] = useState('') const [setHeight, setHeightState] = useState('0px') @@ -51,6 +56,10 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ const iconType = getPicto(fluid) const iconAddType = isParam ? getParamPicto(fluid) : getAddPicto(fluid) + const loginFailed: boolean = + triggerState != null && + triggerState.last_error != undefined && + triggerState.last_error === 'LOGIN_FAILED' const toggleAccordion = () => { setActiveState(setActive === '' ? 'active' : '') @@ -72,8 +81,24 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ ) } - const handleConnexion = (_account: Account) => { + const updateState = async (trigger: Trigger) => { + const triggerState = await TriggerService.fetchTriggerState(client, trigger) + if (triggerState) { + setTriggerState(triggerState) + } + } + + const handleSuccessForm = (_account: Account, _trigger: Trigger) => { setAccount(_account) + setTrigger(_trigger) + setLaunch(true) + } + + const handleKonnectorLaunch = () => { + if (trigger) { + updateState(trigger) + } + setLaunch(false) } const handleJobState = (_jobState: JobState) => { @@ -90,6 +115,14 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ ) if (subscribed && _account) { setAccount(_account) + const _trigger = await TriggerService.fetchTriggerFromAccount( + client, + _account + ) + if (subscribed && _trigger) { + setTrigger(_trigger) + await updateState(_trigger) + } } } } @@ -108,18 +141,18 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ onClick={toggleAccordion} > <div className="accordion-icon"> - {!account ? ( - <StyledIcon className="icon" icon={iconAddType} size={49} /> - ) : ( + {account && !loginFailed ? ( <StyledIcon className="icon" icon={iconType} size={49} /> + ) : ( + <StyledIcon className="icon" icon={iconAddType} size={49} /> )} </div> <div className="state-picto">{getKonnectorStateMarkup()}</div> <div className="accordion-info"> <div className="accordion-title text-16-normal"> - {!account - ? t('KONNECTORCONFIG.LABEL_CONNECTTO_' + FluidType[fluid]) - : t('FLUID.' + FluidType[fluid] + '.LABEL')} + {account && !loginFailed + ? t('FLUID.' + FluidType[fluid] + '.LABEL') + : t('KONNECTORCONFIG.LABEL_CONNECTTO_' + FluidType[fluid])} </div> </div> <StyledIconButton icon={setActive ? chevronUp : chevronDown} /> @@ -134,17 +167,22 @@ const KonnectorViewerCard: React.FC<KonnectorViewerCardProps> = ({ <KonnectorNotFound konnectorSlug={fluidConfig.konnectorConfig.slug} /> - ) : !account ? ( - <KonnectorForm - fluidConfig={fluidConfig} - konnector={konnector} - handleConnexion={handleConnexion} + ) : shouldLaunch && trigger ? ( + <KonnectorLaunch + trigger={trigger} + handleKonnectorLaunch={handleKonnectorLaunch} /> - ) : ( + ) : account && !loginFailed ? ( <KonnectorResult account={account} handleJobState={handleJobState} /> + ) : ( + <KonnectorForm + fluidConfig={fluidConfig} + konnector={konnector} + handleSuccessForm={handleSuccessForm} + /> )} </div> </div> diff --git a/src/components/ContentComponents/OAuth/OAuthForm.tsx b/src/components/ContentComponents/OAuth/OAuthForm.tsx index fb8b91c0fde9a58722dd04abcb34d7277793ab24..b0d982ad9e90975a6ce47720f83fbf8551650ead 100644 --- a/src/components/ContentComponents/OAuth/OAuthForm.tsx +++ b/src/components/ContentComponents/OAuth/OAuthForm.tsx @@ -13,6 +13,7 @@ import StyledBlackSpinner from 'components/CommonKit/Spinner/StyledBlackSpinner' interface OAuthFormProps { konnector: Konnector onSuccess: Function + loginFailed: boolean client: Client t: Function } diff --git a/src/doctypes/io-cozy-triggers.ts b/src/doctypes/io-cozy-triggers.ts index 9eb41891215ed36b3da3be7a7621cf074c66aa9b..60e696f4ac1906bd6518670c2e709f1dffac04d1 100644 --- a/src/doctypes/io-cozy-triggers.ts +++ b/src/doctypes/io-cozy-triggers.ts @@ -11,6 +11,18 @@ export type Trigger = { } } +export type TriggerState = { + trigger_id: string + status: string + last_error?: string + last_executed_job_id: string + last_execution: string + last_failed_job_id: string + last_failure: string + last_manual_execution: string + last_manual_job_id: string +} + export function isTrigger(trigger: any): trigger is Trigger { return ( trigger &&