From 51c4b0b60d52dd074d8558e1384ce0db31c32d17 Mon Sep 17 00:00:00 2001 From: Vijay Kumar S <94220135+vijay151096@users.noreply.github.com> Date: Mon, 29 Apr 2024 14:18:19 +0530 Subject: [PATCH] InjiWeb refactoring for PDF Download (#45) * injiweb-refactoring with pdf download Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> * injiweb-refactoring with pdf download Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> * injiweb-refactoring with pdf download Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> * injiweb-refactoring with pdf download Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> * injiweb-refactoring with optimization Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> --------- Signed-off-by: Vijay <94220135+vijay151096@users.noreply.github.com> --- .github/workflows/push-trigger.yml | 5 +++-- inji-web/src/components/Common/ItemBox.tsx | 2 +- .../src/components/Common/SpinningLoader.tsx | 9 ++++---- .../components/Credentials/CredentialList.tsx | 4 +--- .../src/components/Help/HelpAccordionItem.tsx | 4 ++-- .../src/components/Issuers/IssuersList.tsx | 4 +--- .../src/components/PageTemplate/Header.tsx | 3 ++- .../components/Redirection/DownloadResult.tsx | 13 +++++++---- inji-web/src/hooks/useFetch.tsx | 12 +++++----- inji-web/src/locales/en.json | 4 ++++ inji-web/src/pages/RedirectionPage.tsx | 22 +++++++++++++------ inji-web/src/types/components.d.ts | 9 +++++++- inji-web/src/utils/misc.ts | 6 ++--- inji-web/tailwind.config.js | 8 +++++++ 14 files changed, 68 insertions(+), 37 deletions(-) diff --git a/.github/workflows/push-trigger.yml b/.github/workflows/push-trigger.yml index 224d755..02a50e5 100644 --- a/.github/workflows/push-trigger.yml +++ b/.github/workflows/push-trigger.yml @@ -2,9 +2,9 @@ name: inji-web build upon a push on: release: - types: [published] + types: [ published ] pull_request: - types: [opened, reopened, synchronize] + types: [ opened, reopened, synchronize ] push: branches: - '!release-branch' @@ -13,6 +13,7 @@ on: - 1.* - develop - MOSIP* + - injiweb* jobs: build-dockers-inji-web: diff --git a/inji-web/src/components/Common/ItemBox.tsx b/inji-web/src/components/Common/ItemBox.tsx index 27d80b4..9032ee8 100644 --- a/inji-web/src/components/Common/ItemBox.tsx +++ b/inji-web/src/components/Common/ItemBox.tsx @@ -5,7 +5,7 @@ export const ItemBox: React.FC = (props) => { return
Issuer Logo diff --git a/inji-web/src/components/Common/SpinningLoader.tsx b/inji-web/src/components/Common/SpinningLoader.tsx index 62e1581..8d53625 100644 --- a/inji-web/src/components/Common/SpinningLoader.tsx +++ b/inji-web/src/components/Common/SpinningLoader.tsx @@ -1,18 +1,19 @@ import React from "react"; -import {TailSpin} from "react-loader-spinner"; +import {Oval} from "react-loader-spinner"; export const SpinningLoader: React.FC = () => { return
-
diff --git a/inji-web/src/components/Credentials/CredentialList.tsx b/inji-web/src/components/Credentials/CredentialList.tsx index 3471799..01d530f 100644 --- a/inji-web/src/components/Credentials/CredentialList.tsx +++ b/inji-web/src/components/Credentials/CredentialList.tsx @@ -7,6 +7,7 @@ import {EmptyListContainer} from "../Common/EmptyListContainer"; import {useTranslation} from "react-i18next"; import {RequestStatus} from "../../hooks/useFetch"; import {SpinningLoader} from "../Common/SpinningLoader"; +import {CredentialListProps} from "../../types/components"; export const CredentialList: React.FC = ({state}) => { @@ -33,6 +34,3 @@ export const CredentialList: React.FC = ({state}) => { } -type CredentialListProps = { - state: RequestStatus; -} diff --git a/inji-web/src/components/Help/HelpAccordionItem.tsx b/inji-web/src/components/Help/HelpAccordionItem.tsx index 87afc83..360091f 100644 --- a/inji-web/src/components/Help/HelpAccordionItem.tsx +++ b/inji-web/src/components/Help/HelpAccordionItem.tsx @@ -10,7 +10,7 @@ export const HelpAccordionItem: React.FC = (props) => { data-testid="Help-Item-Container"> {(props.id === props.open) && ( -
{props.content.map(content =>

{content}

)} diff --git a/inji-web/src/components/Issuers/IssuersList.tsx b/inji-web/src/components/Issuers/IssuersList.tsx index df7316f..17798a4 100644 --- a/inji-web/src/components/Issuers/IssuersList.tsx +++ b/inji-web/src/components/Issuers/IssuersList.tsx @@ -7,6 +7,7 @@ import {useTranslation} from "react-i18next"; import {EmptyListContainer} from "../Common/EmptyListContainer"; import {RequestStatus} from "../../hooks/useFetch"; import {SpinningLoader} from "../Common/SpinningLoader"; +import {IssuersListProps} from "../../types/components"; export const IssuersList: React.FC = ({state}) => { const issuers = useSelector((state: RootState) => state.issuers); @@ -31,6 +32,3 @@ export const IssuersList: React.FC = ({state}) => { } -type IssuersListProps = { - state: RequestStatus; -} diff --git a/inji-web/src/components/PageTemplate/Header.tsx b/inji-web/src/components/PageTemplate/Header.tsx index c646f8d..9a08938 100644 --- a/inji-web/src/components/PageTemplate/Header.tsx +++ b/inji-web/src/components/PageTemplate/Header.tsx @@ -25,7 +25,8 @@ export const Header: React.FC = () => {
navigate("/help")} className="text-light-title dark:text-dark-title font-bold cursor-pointer">{t("Header.help")}
-
  • {t("Header.aboutInji")}
  • diff --git a/inji-web/src/components/Redirection/DownloadResult.tsx b/inji-web/src/components/Redirection/DownloadResult.tsx index 2b0af00..6158fad 100644 --- a/inji-web/src/components/Redirection/DownloadResult.tsx +++ b/inji-web/src/components/Redirection/DownloadResult.tsx @@ -1,7 +1,8 @@ import React from "react"; import {useNavigate} from "react-router-dom"; -import {BsShieldFillCheck, BsShieldFillX} from "react-icons/bs"; +import {BsShieldFillCheck, BsShieldFillExclamation, BsShieldFillX} from "react-icons/bs"; import {DownloadResultProps} from "../../types/components"; +import {RequestStatus} from "../../hooks/useFetch"; export const DownloadResult: React.FC = (props) => { @@ -9,14 +10,18 @@ export const DownloadResult: React.FC = (props) => { return
    - {props.success ? + {props.state === RequestStatus.DONE &&
    -
    : + data-testid="DownloadResult-Success-SheildIcon" size={40} color={"green"}/>
    } + {props.state === RequestStatus.ERROR &&
    } + {props.state === RequestStatus.LOADING && +
    +
    }

    {props.title}

    diff --git a/inji-web/src/hooks/useFetch.tsx b/inji-web/src/hooks/useFetch.tsx index db6dd2e..57757ef 100644 --- a/inji-web/src/hooks/useFetch.tsx +++ b/inji-web/src/hooks/useFetch.tsx @@ -1,6 +1,5 @@ import {useState} from "react"; import {api, MethodType} from "../utils/api"; -import {ResponseTypeObject} from "../types/data"; export enum RequestStatus { LOADING, @@ -15,21 +14,22 @@ export const useFetch = () => { const fetchRequest = async (uri: string, method: MethodType, header: any, body?: any) => { try { setState(RequestStatus.LOADING); - let responseJson: (ResponseTypeObject) = {}; const response = await fetch(`${api.mimotoHost}${uri}`, { method: MethodType[method], headers: header, body: body, }); - responseJson = response; - if (response.ok && uri.indexOf("download") === -1) { - responseJson = await response.json(); + + if (uri.indexOf("download") !== -1) { setState(RequestStatus.DONE); + return await response.blob(); } if (!response.ok) { setState(RequestStatus.ERROR); + return response; } - return responseJson; + setState(RequestStatus.DONE); + return await response.json(); } catch (e) { setState(RequestStatus.ERROR); setError("Error Happened"); diff --git a/inji-web/src/locales/en.json b/inji-web/src/locales/en.json index b055e1b..b362388 100644 --- a/inji-web/src/locales/en.json +++ b/inji-web/src/locales/en.json @@ -25,6 +25,10 @@ "errorContent": "The service is currently unavailable now. Please try again later." }, "RedirectionPage": { + "loading": { + "title": "Download InProgress...", + "subTitle": "please wait while your pdf gets downloaded." + }, "success": { "title": "Download Success", "subTitle": "PDF is generated" diff --git a/inji-web/src/pages/RedirectionPage.tsx b/inji-web/src/pages/RedirectionPage.tsx index 27aacc4..db161d3 100644 --- a/inji-web/src/pages/RedirectionPage.tsx +++ b/inji-web/src/pages/RedirectionPage.tsx @@ -42,7 +42,7 @@ export const RedirectionPage: React.FC = () => { let apiRequest: ApiRequest = api.fetchToken; let response = await fetchRequest( - apiRequest.url(issuerId) + `?code=${code}&clientId=${clientId}&codeVerifier=${codeVerifier}`, + apiRequest.url(issuerId), apiRequest.methodType, apiRequest.headers(), requestBody @@ -50,12 +50,11 @@ export const RedirectionPage: React.FC = () => { apiRequest = api.downloadVc; response = await fetchRequest( - apiRequest.url(issuerId, certificateId) + `?token=${response?.access_token}`, + apiRequest.url(issuerId, certificateId), apiRequest.methodType, apiRequest.headers(response?.access_token) ); - await downloadCredentialPDF(response, certificateId); - if (state === RequestStatus.DONE) { + if (state !== RequestStatus.ERROR) { await downloadCredentialPDF(response, certificateId); } if (urlState != null) { @@ -74,7 +73,16 @@ export const RedirectionPage: React.FC = () => { + state={RequestStatus.ERROR}/> +
    + } + + if (state === RequestStatus.LOADING) { + return
    + +
    } @@ -83,7 +91,7 @@ export const RedirectionPage: React.FC = () => { + state={RequestStatus.ERROR}/>
    } @@ -91,6 +99,6 @@ export const RedirectionPage: React.FC = () => { + state={RequestStatus.DONE}/>
    } diff --git a/inji-web/src/types/components.d.ts b/inji-web/src/types/components.d.ts index 31b2b53..5544273 100644 --- a/inji-web/src/types/components.d.ts +++ b/inji-web/src/types/components.d.ts @@ -1,5 +1,6 @@ import {CredentialWellknownObject, IssuerObject, ResponseTypeObject} from "./data"; import React from "react"; +import {RequestStatus} from "../hooks/useFetch"; export type ItemBoxProps = { index: number; @@ -29,7 +30,7 @@ export type IssuerProps = { issuer: IssuerObject; } export type DownloadResultProps = { - success: boolean; + state: RequestStatus; title: string; subTitle: string; } @@ -44,3 +45,9 @@ export type HeaderTileProps = { export type SearchIssuerProps = { fetchRequest: (...arg: any) => ResponseTypeObject } +export type IssuersListProps = { + state: RequestStatus; +} +export type CredentialListProps = { + state: RequestStatus; +} diff --git a/inji-web/src/utils/misc.ts b/inji-web/src/utils/misc.ts index 3ece559..b639f95 100644 --- a/inji-web/src/utils/misc.ts +++ b/inji-web/src/utils/misc.ts @@ -34,11 +34,11 @@ export const getFileName = (contentDispositionHeader: any) => { export const downloadCredentialPDF = async (response: any, certificateId: string) => { - const blob: Blob = new Blob([response.data], {type: response.headers['content-type']}); + // const blob: Blob = new Blob([response], {type: 'application/pdf'}); - let fileName = getFileName(response.headers['content-disposition']) ?? `${certificateId}.pdf`; + let fileName = `${certificateId}.pdf`; // Create a temporary URL for the Blob - const url = window.URL.createObjectURL(blob); + const url = window.URL.createObjectURL(response); // Create a temporary link element const link = document.createElement('a'); diff --git a/inji-web/tailwind.config.js b/inji-web/tailwind.config.js index 74aa9bf..73d415a 100644 --- a/inji-web/tailwind.config.js +++ b/inji-web/tailwind.config.js @@ -14,15 +14,19 @@ module.exports = { subTitle: '#717171', searchTitle: '#3E3E3E', primary: '#EB6F2D', + helpAccordionHover: '#e0e0e0', shadow: '#18479329', navigationBar: '#F2FBFF', languageIcon: '#EB6F2D', closeIcon: '#8E8E8E', searchIcon: '#8E8E8E', + tileBackground: '#FFFFFF', shieldSuccessIcon: '#4b9d1f', shieldErrorIcon: '#EF4444', + shieldLoadingIcon: '#ff914b', shieldSuccessShadow: '#f1f7ee', shieldErrorShadow: '#FEF2F2', + shieldLoadingShadow: '#f6dfbe', }, dark: { background: '#9DB2BF', @@ -31,15 +35,19 @@ module.exports = { subTitle: '#717171', searchTitle: '#3E3E3E', primary: '#EB6F2D', + helpAccordionHover: '#e0e0e0', shadow: '#526D82', navigationBar: '#DDE6ED', languageIcon: '#EB6F2D', closeIcon: '#8E8E8E', searchIcon: '#8E8E8E', + tileBackground: '#DDE6ED', shieldSuccessIcon: '#4b9d1f', shieldErrorIcon: '#EF4444', + shieldLoadingIcon: '#EF4444', shieldSuccessShadow: '#f1f7ee', shieldErrorShadow: '#FEF2F2', + shieldLoadingShadow: '#FEF2F2', } } },