From 542410f0ba394bcdec93e8e7c1f25f92c5db6c3a Mon Sep 17 00:00:00 2001 From: sanjay-k1910 Date: Wed, 22 Nov 2023 21:45:30 +0530 Subject: [PATCH 1/4] refactor: bulk issuance Signed-off-by: sanjay-k1910 --- src/api/BulkIssuance.ts | 6 +- src/common/global.css | 7 + src/components/Issuance/BulkIssuance.tsx | 768 +++++++++--------- src/components/Issuance/Connections.tsx | 11 +- src/components/Issuance/IssuancePopup.tsx | 1 + src/components/Issuance/IssuedCrdentials.tsx | 34 +- src/components/RoleViewButton/index.tsx | 25 +- src/config/pathRoutes.ts | 1 + .../credentials/bulk-issuance.astro | 16 + 9 files changed, 465 insertions(+), 404 deletions(-) create mode 100644 src/pages/organizations/credentials/bulk-issuance.astro diff --git a/src/api/BulkIssuance.ts b/src/api/BulkIssuance.ts index 4b087365a..e8904673d 100644 --- a/src/api/BulkIssuance.ts +++ b/src/api/BulkIssuance.ts @@ -24,9 +24,8 @@ export const getSchemaCredDef = async () => { } }; -export const DownloadCsvTemplate = async () => { +export const DownloadCsvTemplate = async (credDefId: string) => { const orgId = await getFromLocalStorage(storageKeys.ORG_ID); - const credDefId = await getFromLocalStorage(storageKeys.CRED_DEF_ID); const url = `${apiRoutes.organizations.root}/${orgId}/${credDefId}${apiRoutes.Issuance.download}`; const axiosPayload = { @@ -46,9 +45,8 @@ export const DownloadCsvTemplate = async () => { // upload file -export const uploadCsvFile = async (payload: any) => { +export const uploadCsvFile = async (payload: any, credefId: string) => { const orgId = await getFromLocalStorage(storageKeys.ORG_ID); - const credefId = await getFromLocalStorage(storageKeys.CRED_DEF_ID); const url = `${apiRoutes.organizations.root}/${orgId}${apiRoutes.Issuance.bulk.uploadCsv}?credDefId=${credefId}`; diff --git a/src/common/global.css b/src/common/global.css index e590fde14..de61c66fc 100644 --- a/src/common/global.css +++ b/src/common/global.css @@ -17,6 +17,13 @@ ul[role="tablist"] li[role="presentation"] button[aria-selected="true"] { @apply text-primary-700 border-primary-700; } +button.role-btn span { + @apply overflow-hidden; + border-radius: 8px; + padding-top: 6.5px; + padding-bottom: 6.5px; +} + .word-break-word{ word-break: break-word !important; } diff --git a/src/components/Issuance/BulkIssuance.tsx b/src/components/Issuance/BulkIssuance.tsx index c0e873beb..7b2d79971 100644 --- a/src/components/Issuance/BulkIssuance.tsx +++ b/src/components/Issuance/BulkIssuance.tsx @@ -14,6 +14,8 @@ import { pathRoutes } from '../../config/pathRoutes'; import IssuancePopup from './IssuancePopup'; import SOCKET from '../../config/SocketConfig'; import { ToastContainer, toast } from 'react-toastify'; +import BreadCrumbs from '../BreadCrumbs'; +import BackButton from '../../commonComponents/backbutton' interface IValues { value: string; @@ -111,13 +113,13 @@ const BulkIssuance = () => { const DownloadSchemaTemplate = async () => { setProcess(true); - const credDefId = await getFromLocalStorage(storageKeys.CRED_DEF_ID); - - if (credDefId) { + // const credDefId = await getFromLocalStorage(storageKeys.CRED_DEF_ID); +console.log(65658, credentialSelected) + if (credentialSelected) { try { setProcess(true); - const response = await DownloadCsvTemplate(); + const response = await DownloadCsvTemplate(credentialSelected); const { data } = response as AxiosResponse; if (data) { @@ -221,8 +223,7 @@ const BulkIssuance = () => { await wait(500); - - const response = await uploadCsvFile(payload); + const response = await uploadCsvFile(payload, credentialSelected); const { data } = response as AxiosResponse; if (data?.statusCode === apiStatusCodes?.API_STATUS_CREATED) { @@ -342,6 +343,7 @@ const BulkIssuance = () => { const response = await issueBulkCredential(requestId, SOCKET.id); const { data } = response as AxiosResponse; if (data?.statusCode === apiStatusCodes.API_STATUS_CREATED) { + if (data?.data) { setLoading(false); setOpenModal(false); @@ -372,227 +374,254 @@ const BulkIssuance = () => { ); return ( -
- - {(success || failure) && ( - { - setSuccess(null); - setFailure(null); - }} - viewButton={Boolean((success && success === "Issuance process completed") || (error && error === "Issuance process failed, please retry"))} - path={pathRoutes.organizations.Issuance.history} - /> - )} -
-
-

- Bulk Issuance -

- Bulk issuance by .csv +
+
+
+ +
-
-
- +
+ + {(success || failure) && ( + { + setSuccess(null); + setFailure(null); + }} + viewButton={Boolean((success && success === "Issuance process completed") || (error && error === "Issuance process failed, please retry"))} + path={pathRoutes.organizations.Issuance.history} + /> + )} +
-
-
-
- { + setCredentialSelected(value?.value ?? ""); + }} + /> +
+
+ {credentialSelected && ( + +
+

+ Schema: + {selectedCred?.schemaName || ""}{' '} + [{selectedCred?.schemaVersion}] +

+

+ {' '} + + Credential Definition: + {' '} + {selectedCred?.credentialDefinition} +

+ Attributes: +
+ {selectedCred?.schemaAttributes.map( + (element: IAttributes) => ( +
+ + {element.attributeName} + +
+ ), + )} +
-
- - )} -
-
- -
-
- {/* ---------------- */} -
-
-
-
+
+ +
+
+ {/* ---------------- */} +
+
+
+ -
-
- + {' '} + {' '} + {' '} + + +

+ Drag file here +

+
+ +
+
+ +
-
-
- {uploadedFileName && ( -
-

- {uploadedFileName} -

- +
+ )} + {error && ( +
+

{error}

{ d="M6 18L18 6M6 6l12 12" /> - -
- )} - {error && ( -
-

{error}

- - - -
- )} +
+ )} +
-
-
- - {csvData && csvData.length > 0 && ( - -
-
-
- {csvData && csvData.length > 0 && ( -
- - - - - {csvData.length > 0 && - Object.keys(csvData[0]).map((header, index) => ( - - ))} - - - - {csvData && - csvData.length > 0 && - csvData.map((row, rowIndex) => ( - - {Object.values(row).map((cell, cellIndex) => ( - + + + {csvData && + csvData.length > 0 && + csvData.map((row, rowIndex) => ( + + {Object.values(row).map((cell, cellIndex) => ( + + ))} + + ))} + +
- {header} -
+ + {csvData && csvData.length > 0 && ( + +
+
+
+ {csvData && csvData.length > 0 && ( +
+ + + + + {csvData.length > 0 && + Object.keys(csvData[0]).map((header, index) => ( + ))} - - ))} - -
- {cell} - + {header} +
-
- )} +
+ {cell} +
+
+ )} +
-
- {currentPage.total > 1 && ( -
- -
- )} - - )} -
- {!isCredSelected && ( - <> -

Steps

-
    -
  • -

    - Select and Download -

    -

    - Select credential definition and download .CSV file -

    -
  • -
  • -

    - Fill the data -

    -

    - Fill issuance data in the downloaded .CSV file -

    -
  • -
  • -

    - Upload and Issue -

    -

    - Upload .CSV file and click on issue -

    -
  • -
- + {currentPage.total > 1 && ( +
+ +
+ )} + )} +
+ {!isCredSelected && ( + <> +

Steps

+
    +
  • +

    + Select and Download +

    +

    + Select credential definition and download .CSV file +

    +
  • +
  • +

    + Fill the data +

    +

    + Fill issuance data in the downloaded .CSV file +

    +
  • +
  • +

    + Upload and Issue +

    +

    + Upload .CSV file and click on issue +

    +
  • +
+ + )} - + -
- - + + + + + Reset + +
@@ -793,4 +803,4 @@ const BulkIssuance = () => { ); }; -export default BulkIssuance; +export default BulkIssuance; \ No newline at end of file diff --git a/src/components/Issuance/Connections.tsx b/src/components/Issuance/Connections.tsx index dfc204ef3..fffdc7e5f 100644 --- a/src/components/Issuance/Connections.tsx +++ b/src/components/Issuance/Connections.tsx @@ -10,7 +10,6 @@ import { pathRoutes } from '../../config/pathRoutes'; import BreadCrumbs from '../BreadCrumbs'; import ConnectionList from './ConnectionList'; import BackButton from '../../commonComponents/backbutton'; -import BulkIssuance from './BulkIssuance'; const Connections = () => { const [selectedConnectionList, setSelectedConnectionList] = useState< @@ -63,7 +62,8 @@ const Connections = () => { Connection -
  • + {/* Keep this code as it is, this is required in future use. */} + {/*
  • -
  • + */}
    @@ -129,14 +129,15 @@ const Connections = () => { )}
    -
    -
    +
    */} ); diff --git a/src/components/Issuance/IssuancePopup.tsx b/src/components/Issuance/IssuancePopup.tsx index fe874fde5..9fbe2d97b 100644 --- a/src/components/Issuance/IssuancePopup.tsx +++ b/src/components/Issuance/IssuancePopup.tsx @@ -90,6 +90,7 @@ const IssuancePopup = (props: IProps) => { disabled={props.isProcessing} onClick={() => { props.onSuccess(true); + window.scrollTo({top: 0, left: 0, behavior: 'smooth'}); }} className="bg-primary-700 hover:!bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800 font-medium rounded-lg inline-flex items-center text-center ml-2" > diff --git a/src/components/Issuance/IssuedCrdentials.tsx b/src/components/Issuance/IssuedCrdentials.tsx index 657c68979..db311429e 100644 --- a/src/components/Issuance/IssuedCrdentials.tsx +++ b/src/components/Issuance/IssuedCrdentials.tsx @@ -150,25 +150,49 @@ const CredentialList = () => {
    -
    +

    Credentials

    -
    +
    + { walletCreated && - - + + } onClickEvent={schemeSelection} /> } + { + walletCreated && + + + + + + + + + + + + + + } + onClickEvent={() => window.location.href = pathRoutes.organizations.Issuance.bulkIssuance} + /> + }
    diff --git a/src/components/RoleViewButton/index.tsx b/src/components/RoleViewButton/index.tsx index 1c2f0616b..1023fd678 100644 --- a/src/components/RoleViewButton/index.tsx +++ b/src/components/RoleViewButton/index.tsx @@ -11,10 +11,11 @@ interface RoleViewButtonProps { svgComponent?: ReactElement, onClickEvent?: () => void, feature: string + isOutline?: boolean } -const RoleViewButton = ({ buttonTitle, svgComponent, onClickEvent, feature }: RoleViewButtonProps) => { +const RoleViewButton = ({ buttonTitle, svgComponent, onClickEvent, feature, isOutline }: RoleViewButtonProps) => { const [userRoles, setUserRoles] = useState([]) @@ -30,25 +31,25 @@ const RoleViewButton = ({ buttonTitle, svgComponent, onClickEvent, feature }: Ro const isRoleAccess = (): boolean => { - if(feature === Features.CRETAE_ORG){ + if (feature === Features.CRETAE_ORG) { return true } else if (feature === Features.ISSUENCE) { - if (userRoles.includes(Roles.OWNER) - || userRoles.includes(Roles.ADMIN) - || userRoles.includes(Roles.ISSUER) + if (userRoles.includes(Roles.OWNER) + || userRoles.includes(Roles.ADMIN) + || userRoles.includes(Roles.ISSUER) ) { return true } return false - }else if (feature === Features.VERIFICATION) { - if (userRoles.includes(Roles.OWNER) - || userRoles.includes(Roles.ADMIN) - || userRoles.includes(Roles.VERIFIER) + } else if (feature === Features.VERIFICATION) { + if (userRoles.includes(Roles.OWNER) + || userRoles.includes(Roles.ADMIN) + || userRoles.includes(Roles.VERIFIER) ) { return true } return false - }else if (userRoles.includes(Roles.OWNER) || userRoles.includes(Roles.ADMIN)) { + } else if (userRoles.includes(Roles.OWNER) || userRoles.includes(Roles.ADMIN)) { return true } else { return false @@ -61,8 +62,10 @@ const RoleViewButton = ({ buttonTitle, svgComponent, onClickEvent, feature }: Ro { isRoleAccess() &&