diff --git a/src/api/Agent.ts b/src/api/Agent.ts index b4a38eb61..ac6c1d14b 100644 --- a/src/api/Agent.ts +++ b/src/api/Agent.ts @@ -3,7 +3,7 @@ import { apiRoutes } from "../config/apiRoutes"; import { getFromLocalStorage } from "./Auth"; import { storageKeys } from "../config/CommonConstant"; -export const getAgentHealth = async (orgId:number) => { +export const getAgentHealth = async (orgId:string) => { const token = await getFromLocalStorage(storageKeys.TOKEN) const details = { url: `${apiRoutes.organizations.root}/${orgId}${apiRoutes.Agent.checkAgentHealth}`, diff --git a/src/api/BulkIssuance.ts b/src/api/BulkIssuance.ts index 4b087365a..64f18a7dd 100644 --- a/src/api/BulkIssuance.ts +++ b/src/api/BulkIssuance.ts @@ -1,4 +1,3 @@ -import type download from 'downloadjs'; import { apiRoutes } from '../config/apiRoutes'; import { storageKeys } from '../config/CommonConstant'; import { @@ -24,9 +23,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 = { @@ -42,14 +40,8 @@ export const DownloadCsvTemplate = async () => { } }; -// bulk issuance - -// upload file - -export const uploadCsvFile = async (payload: any) => { +export const uploadCsvFile = async (payload: {file: Uint8Array | Blob, fileName:string}, 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}`; const axiosPayload = { @@ -66,8 +58,6 @@ export const uploadCsvFile = async (payload: any) => { } }; -//get file data - export const getCsvFileData = async ( requestId: any, pageNumber: number, @@ -110,15 +100,13 @@ export const issueBulkCredential = async (requestId: string, clientId: string) = } }; -export const retryBulkIssuance = async (fileId:string) => { - const socketId= await getFromLocalStorage(storageKeys.SOCKET_ID) - +export const retryBulkIssuance = async (fileId:string, clientId:string) => { const orgId = await getFromLocalStorage(storageKeys.ORG_ID); const url = `${apiRoutes.organizations.root}/${orgId}/${fileId}${apiRoutes.Issuance.bulk.retry}`; const axiosPayload = { url, - payload:{clientId:socketId}, + payload:{clientId:clientId}, config: await getHeaderConfigs(), }; diff --git a/src/api/Schema.ts b/src/api/Schema.ts index a86d4b49a..1372d2f48 100644 --- a/src/api/Schema.ts +++ b/src/api/Schema.ts @@ -49,7 +49,7 @@ export const getAllSchemasByOrgId = async ({ search, itemPerPage, page }: GetAll } } -export const addSchema = async (payload: createSchema, orgId: number) => { +export const addSchema = async (payload: createSchema, orgId: string) => { const token = await getFromLocalStorage(storageKeys.TOKEN) const details = { url: `${apiRoutes.organizations.root}/${orgId}${apiRoutes.schema.create}`, @@ -72,7 +72,7 @@ export const addSchema = async (payload: createSchema, orgId: number) => { } } -export const getSchemaById = async (schemaId: string, orgId: number) => { +export const getSchemaById = async (schemaId: string, orgId: string) => { const token = await getFromLocalStorage(storageKeys.TOKEN) const details = { url: `${apiRoutes.organizations.root}/${orgId}${apiRoutes.schema.getSchemaById}/${schemaId}`, @@ -94,7 +94,7 @@ export const getSchemaById = async (schemaId: string, orgId: number) => { } } -export const createCredentialDefinition = async (payload: createCredDeffFieldName, orgId:number) => { +export const createCredentialDefinition = async (payload: createCredDeffFieldName, orgId:string) => { const token = await getFromLocalStorage(storageKeys.TOKEN) const details = { url: `${apiRoutes.organizations.root}/${orgId}${apiRoutes.schema.createCredentialDefinition}`, @@ -118,7 +118,7 @@ export const createCredentialDefinition = async (payload: createCredDeffFieldNam } } -export const getCredDeffById = async (schemaId: string, orgId: number) => { +export const getCredDeffById = async (schemaId: string, orgId: string) => { const token = await getFromLocalStorage(storageKeys.TOKEN) const details = { url: `${apiRoutes.organizations.root}/${orgId}${apiRoutes.schema.getCredDefBySchemaId}/${schemaId}/cred-defs`, diff --git a/src/api/ecosystem.ts b/src/api/ecosystem.ts index 770edd9c9..e72275f56 100644 --- a/src/api/ecosystem.ts +++ b/src/api/ecosystem.ts @@ -10,7 +10,7 @@ interface CreateEcosystemPayload { description: string; logo: string; tags?: string; - userId: number; + userId: string; autoEndorsement: boolean; } @@ -105,7 +105,7 @@ export const getEndorsementList = async ( export const createSchemaRequest = async ( data: object, endorsementId: string, - orgId: number, + orgId: string, ) => { const url = `${apiRoutes.Ecosystem.root}/${endorsementId}/${orgId}${apiRoutes.Ecosystem.endorsements.createSchemaRequest}`; const payload = data; @@ -126,7 +126,7 @@ export const createSchemaRequest = async ( export const createCredDefRequest = async ( data: object, ecosystemId: string, - orgId: number, + orgId: string, ) => { const url = `${apiRoutes.Ecosystem.root}/${ecosystemId}/${orgId}${apiRoutes.Ecosystem.endorsements.createCredDefRequest}`; const payload = data; diff --git a/src/api/invitations.ts b/src/api/invitations.ts index 47bfbd2d5..c687945e0 100644 --- a/src/api/invitations.ts +++ b/src/api/invitations.ts @@ -43,7 +43,7 @@ export const createInvitations = async (invitationList: Array) => { const url = `${apiRoutes.organizations.root}/${orgId}${apiRoutes.organizations.invitations}` const payload = { invitations: invitationList, - orgId: Number(orgId) + orgId: orgId } const token = await getFromLocalStorage(storageKeys.TOKEN) @@ -233,7 +233,7 @@ export const getEcosystemInvitations = async (pageNumber: number, pageSize: numb } // Accept/ Reject Invitations -export const acceptRejectEcosystemInvitations = async (invitationId: string, orgId: number, status: string, orgName: string, orgDid: string) => { +export const acceptRejectEcosystemInvitations = async (invitationId: string, orgId: string, status: string, orgName: string, orgDid: string) => { const url = `${apiRoutes.Ecosystem.root}/${orgId}${apiRoutes.Ecosystem.invitations}/${invitationId}` @@ -265,12 +265,12 @@ export const acceptRejectEcosystemInvitations = async (invitationId: string, org } } -export const acceptRejectInvitations = async (invitationId: number, orgId: number, status: string) => { +export const acceptRejectInvitations = async (invitationId: string, orgId: string, status: string) => { const url = `${apiRoutes.users.invitations}/${invitationId}` const payload = { - orgId: Number(orgId), + orgId: orgId, status } const token = await getFromLocalStorage(storageKeys.TOKEN) @@ -296,7 +296,7 @@ export const acceptRejectInvitations = async (invitationId: number, orgId: numbe } } -export const deleteEcosystemInvitations = async (invitationId: number) => { +export const deleteEcosystemInvitations = async (invitationId: string) => { const ecosystemId = await getFromLocalStorage(storageKeys.ECOSYSTEM_ID); const orgId = await getFromLocalStorage(storageKeys.ORG_ID) diff --git a/src/api/organization.ts b/src/api/organization.ts index 236e7450e..818be26e5 100644 --- a/src/api/organization.ts +++ b/src/api/organization.ts @@ -138,7 +138,7 @@ export const getOrgDashboard = async (orgId: string) => { } } -export const spinupDedicatedAgent = async (data: object, orgId:number) => { +export const spinupDedicatedAgent = async (data: object, orgId:string) => { const url = `${apiRoutes.organizations.root}/${orgId}${apiRoutes.Agent.agentDedicatedSpinup}` const payload = data @@ -166,7 +166,7 @@ export const spinupDedicatedAgent = async (data: object, orgId:number) => { } } -export const spinupSharedAgent = async (data: object, orgId:number) => { +export const spinupSharedAgent = async (data: object, orgId:string) => { const url = `${apiRoutes.organizations.root}/${orgId}${apiRoutes.Agent.agentSharedSpinup}` const payload = data @@ -247,7 +247,7 @@ export const getOrganizationUsers = async (pageNumber: number, pageSize: number, } // Edit user roles -export const editOrganizationUserRole = async (userId: number, roles: number[]) => { +export const editOrganizationUserRole = async (userId: string, roles: string[]) => { const orgId = await getFromLocalStorage(storageKeys.ORG_ID) @@ -284,7 +284,7 @@ export const createConnection = async (orgName: string) => { label: orgName, multiUseInvitation: true, autoAcceptConnection: true, - orgId: Number(orgId) + orgId: orgId } const payload = data diff --git a/src/common/enums.ts b/src/common/enums.ts index 7283a230b..f4f869552 100644 --- a/src/common/enums.ts +++ b/src/common/enums.ts @@ -57,3 +57,25 @@ export enum EcosystemRoles { export enum PlatformRoles { platformAdmin = "platform_admin" } + +export enum BulkIssuanceHistory { + started = 'PROCESS_STARTED', + completed = 'PROCESS_COMPLETED', + interrupted= 'PROCESS_INTERRUPTED', + retry= 'PROCESS_REINITIATED', + partially_completed= 'PARTIALLY_COMPLETED' + +} + +export enum BulkIssuanceHistoryData { + started = 'Process Started', + completed = 'Process Completed', + interrupted= 'Process Interrupted', + retry= 'Process Reinitiated', + partially_completed= "Process Failed" +} + +export enum BulkIssuanceStatus { + successful= 'Successful', + failed= 'Failed' +} diff --git a/src/common/global.css b/src/common/global.css index e590fde14..f3db9b26a 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; } @@ -103,7 +110,7 @@ ul.timelinestatic { } .search-dropdown .select__control .select__placeholder { - @apply absolute flex items-start; + @apply absolute flex items-start ml-2; } .search-dropdown .select__control .select__value-container{ @@ -112,8 +119,11 @@ ul.timelinestatic { } .select__single-value{ - @apply !text-primary-700; - width: calc(100% - 5px); + @apply dark:!text-white !text-primary-700 w-fit; +} + +.select__value-container .select__value-container--has-value .select__single-value { + @apply w-fit; } .search-dropdown{ diff --git a/src/commonComponents/AgentHealth.tsx b/src/commonComponents/AgentHealth.tsx index fc3bb9b39..58a135ccf 100644 --- a/src/commonComponents/AgentHealth.tsx +++ b/src/commonComponents/AgentHealth.tsx @@ -29,7 +29,7 @@ const AgentHealth = () => { const organizationId = await getFromLocalStorage(storageKeys.ORG_ID); setCheckOrgExist(Number(organizationId)) if (Number(organizationId) !== 0) { - const agentData = await getAgentHealth(Number(organizationId)); + const agentData = await getAgentHealth(organizationId); const { data } = agentData as AxiosResponse; if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { setAgentHealthDetails(data?.data); diff --git a/src/components/CreateEcosystemOrgModal/index.tsx b/src/components/CreateEcosystemOrgModal/index.tsx index b06b3f8b5..a3840d1ef 100644 --- a/src/components/CreateEcosystemOrgModal/index.tsx +++ b/src/components/CreateEcosystemOrgModal/index.tsx @@ -10,7 +10,7 @@ import { storageKeys, } from '../../config/CommonConstant'; import { calculateSize, dataURItoBlob } from '../../utils/CompressImage'; -import { useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { AlertComponent } from '../AlertComponent'; import type { AxiosResponse } from 'axios'; import { asset } from '../../lib/data.js'; @@ -186,7 +186,7 @@ const CreateEcosystemOrgModal = (props: IProps) => { description: values.description, logo: (logoImage?.imagePreviewUrl as string) || '', tags: '', - userId: Number(user_data?.id), + userId: user_data?.id, orgName: orgDetails?.orgName, orgDid: orgDetails?.orgDid, autoEndorsement: autoEndorse, @@ -516,4 +516,4 @@ const CreateEcosystemOrgModal = (props: IProps) => { return <>{renderEcosystemModal()}; }; -export default CreateEcosystemOrgModal; +export default CreateEcosystemOrgModal; \ No newline at end of file diff --git a/src/components/Ecosystem/Endorsement/index.tsx b/src/components/Ecosystem/Endorsement/index.tsx index 4dfe76fce..05fc2cead 100644 --- a/src/components/Ecosystem/Endorsement/index.tsx +++ b/src/components/Ecosystem/Endorsement/index.tsx @@ -42,7 +42,7 @@ interface IEndorsementList { status: string; type: string; ecosystemOrgs: { - orgId: number; + orgId: string; }; requestPayload: string; responsePayload: string; diff --git a/src/components/Ecosystem/interfaces/index.ts b/src/components/Ecosystem/interfaces/index.ts index cdf99b631..479f2f950 100644 --- a/src/components/Ecosystem/interfaces/index.ts +++ b/src/components/Ecosystem/interfaces/index.ts @@ -14,12 +14,12 @@ export interface IEcosystem { } export interface Ecosystem { - id: number + id: string createDateTime: string - createdBy: number + createdBy: string lastChangedDateTime: string + lastChangedBy: string autoEndorsement:boolean - lastChangedBy: number name: string description: string logoUrl: string diff --git a/src/components/EcosystemInvite/EcoSystemReceivedInvitations.tsx b/src/components/EcosystemInvite/EcoSystemReceivedInvitations.tsx index 41e68e165..5f1da3f67 100644 --- a/src/components/EcosystemInvite/EcoSystemReceivedInvitations.tsx +++ b/src/components/EcosystemInvite/EcoSystemReceivedInvitations.tsx @@ -40,9 +40,9 @@ export interface EcosystemInvitation { ecosystem: { name: string; logoUrl: string; }; id: string createDateTime: string - createdBy: number + createdBy: string lastChangedDateTime: string - lastChangedBy: number + lastChangedBy: string deletedAt: any userId: string orgId: string @@ -60,7 +60,7 @@ const ReceivedInvitations = () => { const [error, setError] = useState(null); const [organizationsList, setOrganizationsList] = useState | null>(null); const [currentPage, setCurrentPage] = useState(initialPageState); - const [selectedId, setSelectedId] = useState(); + const [selectedId, setSelectedId] = useState(''); const [searchText, setSearchText] = useState(''); const [invitationsData, setInvitationsData] = useState | null>(null); const [getOrgError, setGetOrgError] = useState(null); @@ -154,7 +154,7 @@ const ReceivedInvitations = () => { if (orgDid) { const response = await acceptRejectEcosystemInvitations( invite.id, - Number(selectedId), + selectedId, status, orgName, orgDid @@ -222,7 +222,7 @@ const ReceivedInvitations = () => { const getOrgId = async () => { const orgId = await getFromLocalStorage(storageKeys.ORG_ID); if (orgId) { - setSelectedId(Number(orgId)); + setSelectedId(orgId); } }; diff --git a/src/components/EcosystemInvite/SentInvitations.tsx b/src/components/EcosystemInvite/SentInvitations.tsx index eecbb3069..ccd2c3179 100644 --- a/src/components/EcosystemInvite/SentInvitations.tsx +++ b/src/components/EcosystemInvite/SentInvitations.tsx @@ -66,7 +66,7 @@ const SentInvitations = () => { setLoading(false); }; - const deletInvitations = async (invitationId: number) => { + const deletInvitations = async (invitationId: string) => { const response = await deleteEcosystemInvitations(invitationId); const { data } = response as AxiosResponse; diff --git a/src/components/Issuance/BulkIssuance.tsx b/src/components/Issuance/BulkIssuance.tsx index c0e873beb..043cab0ef 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; @@ -33,20 +35,26 @@ interface ICredentials { schemaAttributes: IAttributes | boolean; credentialDefinition: string; } + +interface IUploadMessage { + message: string + type : "success" | "failure" +} + const BulkIssuance = () => { const [csvData, setCsvData] = useState([]); const [requestId, setRequestId] = useState(""); const [process, setProcess] = useState(false); const [loading, setLoading] = useState(true); const [credentialOptions, setCredentialOptions] = useState([]); - const [credentialSelected, setCredentialSelected] = useState(""); + const [credentialSelected, setCredentialSelected] = useState(""); const [isFileUploaded, setIsFileUploaded] = useState(false); const [uploadedFileName, setUploadedFileName] = useState(''); const [uploadedFile, setUploadedFile] = useState(null); const [openModal, setOpenModal] = useState(false); const [message, setMessage] = useState(''); const [searchText, setSearchText] = useState(''); - const [error, setError] = useState(null); + const [uploadMessage, setUploadMessage] = useState(null) const [success, setSuccess] = useState(null); const [failure, setFailure] = useState(null); @@ -86,12 +94,16 @@ const BulkIssuance = () => { ); setCredentialOptions(options); } else { - setError(response as string); + setUploadMessage({message: response as string, type: "failure"}); + setSuccess(null) + setFailure(null) } setLoading(false); } } catch (error) { - setError(error as string); + setUploadMessage({message: error as string, type: "failure"}); + setSuccess(null) + setFailure(null) } }; @@ -111,32 +123,33 @@ const BulkIssuance = () => { const DownloadSchemaTemplate = async () => { setProcess(true); - const credDefId = await getFromLocalStorage(storageKeys.CRED_DEF_ID); - - if (credDefId) { + if (credentialSelected) { try { setProcess(true); - const response = await DownloadCsvTemplate(); + const response = await DownloadCsvTemplate(credentialSelected); const { data } = response as AxiosResponse; if (data) { const fileUrl = data; - // Adjust this based on the response structure if (fileUrl) { - // Open the file in a new tab - // window.open(data); downloadFile(fileUrl, 'downloadedFile.csv'); setSuccess('File downloaded successfully'); setProcess(false); } else { - setError('File URL is missing in the response'); + setUploadMessage({message: 'File URL is missing in the response', type: "failure"}); + setSuccess(null) + setFailure(null) } } else { - setError('API request was not successful'); + setUploadMessage({message: 'API request was not successful', type: "failure"}); + setSuccess(null) + setFailure(null) } } catch (error) { - setError(error as string); + setUploadMessage({message: error as string, type: "failure"}); + setSuccess(null) + setFailure(null) } } @@ -186,7 +199,7 @@ const BulkIssuance = () => { SOCKET.on('error-in-bulk-issuance-process', () => { console.log(`error-in-bulk-issuance-process-initiated`); - toast.error('Issuance process failed, please retry', { + toast.error('Issuance process failed. Please retry', { position: 'top-right', autoClose: 3000, hideProgressBar: false, @@ -196,7 +209,7 @@ const BulkIssuance = () => { progress: undefined, theme: 'colored', }); - setError("Issuance process failed, please retry") + setFailure("Issuance process failed, please retry") }); }, []) @@ -205,7 +218,9 @@ const BulkIssuance = () => { setLoading(true); if (file.type !== 'text/csv') { - setError('Invalid file type. Please select only CSV files.'); + setUploadMessage({message:'Invalid file type. Please select only CSV files.', type: "failure"}); + setSuccess(null) + setFailure(null) return; } try { @@ -217,25 +232,27 @@ const BulkIssuance = () => { await setToLocalStorage(storageKeys.SOCKET_ID, clientId) const payload = { file: binaryData, + fileName: file?.name || "Not available" }; await wait(500); + setUploadedFileName(file?.name); + setUploadedFile(file); - const response = await uploadCsvFile(payload); + const response = await uploadCsvFile(payload, credentialSelected); const { data } = response as AxiosResponse; if (data?.statusCode === apiStatusCodes?.API_STATUS_CREATED) { setLoading(false); setRequestId(data?.data); - setSuccess(data?.message); setIsFileUploaded(true); - setUploadedFileName(file?.name); - setUploadedFile(file); - setError(null); + setUploadMessage({message: data?.message, type: "success"}); await handleCsvFileData(data?.data); } else { - setError(response as string); + setUploadMessage({message: response as string, type: "failure"}); + setSuccess(null) + setFailure(null) } setLoading(false); } catch (err) { @@ -289,6 +306,7 @@ const BulkIssuance = () => { setIsFileUploaded(false); setUploadedFileName(''); setUploadedFile(null); + setUploadMessage(null) }; const handleDrop = (e: { @@ -316,7 +334,7 @@ const BulkIssuance = () => { } }; const clearError = () => { - setError(null); + setUploadMessage(null); }; const handleOpenConfirmation = () => { @@ -342,14 +360,13 @@ 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); setSuccess(data.message); + setUploadMessage(null) handleResetForConfirm() - // setTimeout(() => { - // window.location.href = pathRoutes.organizations.Issuance.connections; - // }, 2000); } else { setFailure(response as string); setLoading(false); @@ -372,420 +389,417 @@ 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") || (failure && failure === "Issuance process failed, please retry"))} + path={pathRoutes.organizations.Issuance.history} + /> + )} +
-
-
-
- { + setCredentialSelected(value?.value ?? ""); + }} + /> +
+
+ {credentialSelected && selectedCred && ( + +
+

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

+

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

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

{error}

- +
+ {uploadedFileName && ( +
- - -
- )} +

+ {uploadedFileName} +

+ +
+ )} + {uploadMessage !== null && ( + + )} +
-
- - - {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 +807,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/History.tsx b/src/components/Issuance/History.tsx index 072124742..bbd4f5ed5 100644 --- a/src/components/Issuance/History.tsx +++ b/src/components/Issuance/History.tsx @@ -1,8 +1,7 @@ 'use client'; - +import 'react-toastify/dist/ReactToastify.css'; import type { AxiosResponse } from 'axios'; import { ChangeEvent, useEffect, useState } from 'react'; -import { getConnectionsByOrg } from '../../api/connection'; import DataTable from '../../commonComponents/datatable'; import type { TableData } from '../../commonComponents/datatable/interface'; import { apiStatusCodes } from '../../config/CommonConstant'; @@ -18,6 +17,11 @@ import SearchInput from '../SearchInput'; import { Button, Pagination } from 'flowbite-react'; import { getFilesHistory, retryBulkIssuance } from '../../api/BulkIssuance'; import SOCKET from '../../config/SocketConfig'; +import { + BulkIssuanceHistory, + BulkIssuanceHistoryData, +} from '../../common/enums'; +import { ToastContainer, toast } from 'react-toastify'; const HistoryBulkIssuance = () => { const initialPageState = { @@ -46,17 +50,15 @@ const HistoryBulkIssuance = () => { }; const handleRetry = async (fileId: string) => { + setSuccess('Issuance process reinitiated. Please wait a moment.'); setLoading(true); - const retryIssunace = await retryBulkIssuance(fileId); + const retryIssunace = await retryBulkIssuance(fileId, SOCKET.id); const { data } = retryIssunace as AxiosResponse; if (data?.statusCode === apiStatusCodes.API_STATUS_CREATED) { if (data?.data) { setLoading(false); - setSuccess(data?.message); - setTimeout(()=>{ - getConnections(); - },500) + getConnections(); } else { setLoading(false); } @@ -69,20 +71,38 @@ const HistoryBulkIssuance = () => { } }; - SOCKET.on('bulk-issuance-process-completed', () => { - console.log(`bulk-issuance-process-completed`); - // toast.success('Bulk issuance process completed.', { - // position: 'top-right', - // autoClose: 5000, - // hideProgressBar: false, - // closeOnClick: true, - // pauseOnHover: true, - // draggable: true, - // progress: undefined, - // theme: 'colored', - // }); - }); useEffect(() => { + SOCKET.emit('bulk-connection'); + SOCKET.on('bulk-issuance-process-retry-completed', () => { + console.log(`bulk-issuance-process-retry-completed`); + toast.success('Issuance process completed', { + position: 'top-right', + autoClose: 3000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + theme: 'colored', + }); + setSuccess('Issuance process completed'); + }); + + SOCKET.on('error-in-bulk-issuance-retry-process', () => { + console.log(`error-in-bulk-issuance-retry-process-initiated`); + toast.error('Issuance process failed. Please retry', { + position: 'top-right', + autoClose: 3000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + theme: 'colored', + }); + setError('Issuance process failed, please retry'); + }); + let getData: NodeJS.Timeout; if (searchText.length >= 1) { @@ -149,21 +169,37 @@ const HistoryBulkIssuance = () => { { data: failedRecords }, { - data: - status === 'PROCESS_STARTED' ? ( -

    - Process Started -

    - ) : ( -

    - Process Completed -

    - ), + data: ( +

    + {status === BulkIssuanceHistory.started + ? BulkIssuanceHistoryData.started + : status === BulkIssuanceHistory.completed + ? BulkIssuanceHistoryData.completed + : status === BulkIssuanceHistory.interrupted + ? BulkIssuanceHistoryData.interrupted + : status === BulkIssuanceHistory.partially_completed + ? BulkIssuanceHistoryData.partially_completed + : BulkIssuanceHistoryData.retry} +

    + ), }, { data: (
    + + +
    { }, { data: ( - - {history?.isError === false ? 'Successful' : 'Failed'} - + {history?.isError === false ? BulkIssuanceStatus.successful : BulkIssuanceStatus.failed} +

    ), }, { data: history?.error - ? history?.error.replace(/[[\]"]/g, '') + ? history?.error.replace(/[[\]"{},]/g, ' ') : '-', }, ], diff --git a/src/components/Issuance/Issuance.tsx b/src/components/Issuance/Issuance.tsx index 1e37378cd..256ae3e68 100644 --- a/src/components/Issuance/Issuance.tsx +++ b/src/components/Issuance/Issuance.tsx @@ -36,7 +36,7 @@ interface IssuanceFormPayload { connectionId: string; attributes: Attributes[]; credentialDefinitionId: string; - orgId: number; + orgId: string; } interface DataTypeAttributes { @@ -81,7 +81,7 @@ const IssueCred = () => { const selectedUsers = await getSelectedUsers(); const attributes = await getSchemaDetails(); if (attributes && attributes.length) { - createIssuanceForm(selectedUsers, attributes, credDefId, Number(orgId)); + createIssuanceForm(selectedUsers, attributes, credDefId, orgId); } else { setFailure('Attributes are not available'); } @@ -91,7 +91,7 @@ const IssueCred = () => { selectedUsers: SelectedUsers[], attributes: DataTypeAttributes[], credDefId: string, - orgId: number, + orgId: string, ) => { const attrObj = attributes.map((attr) => ({ name: attr?.attributeName, diff --git a/src/components/Issuance/IssuancePopup.tsx b/src/components/Issuance/IssuancePopup.tsx index fe874fde5..9ab2bc772 100644 --- a/src/components/Issuance/IssuancePopup.tsx +++ b/src/components/Issuance/IssuancePopup.tsx @@ -4,7 +4,6 @@ interface IProps { openModal: boolean; closeModal: (flag: boolean) => void; onSuccess: (flag: boolean) => void; - message: string; isProcessing: boolean; } @@ -40,74 +39,88 @@ const IssuancePopup = (props: IProps) => {
    -

    Confirmation

    +

    Confirmation

    - {props.message} + Are you sure you want to Offer Credentials ?

    - -
    - - +

    Yes, I'm sure

    +
    @@ -116,4 +129,4 @@ const IssuancePopup = (props: IProps) => { ); }; -export default IssuancePopup; +export default IssuancePopup; \ No newline at end of file diff --git a/src/components/Issuance/IssuedCrdentials.tsx b/src/components/Issuance/IssuedCrdentials.tsx index 657c68979..2e5261250 100644 --- a/src/components/Issuance/IssuedCrdentials.tsx +++ b/src/components/Issuance/IssuedCrdentials.tsx @@ -150,25 +150,41 @@ const CredentialList = () => {
    -
    +

    Credentials

    -
    +
    + { walletCreated && - - + + } onClickEvent={schemeSelection} /> } + { + walletCreated && + + + + + + } + onClickEvent={() => window.location.href = pathRoutes.organizations.Issuance.bulkIssuance} + /> + }
    diff --git a/src/components/Profile/interfaces/index.ts b/src/components/Profile/interfaces/index.ts index 6ed2fa620..249fda505 100644 --- a/src/components/Profile/interfaces/index.ts +++ b/src/components/Profile/interfaces/index.ts @@ -39,7 +39,7 @@ export interface UserEmail { } export interface UserProfile { - id: number + id: string profileImg?: string username?: string email: string diff --git a/src/components/Resources/Schema/Create.tsx b/src/components/Resources/Schema/Create.tsx index a6379de5c..3a7adeaa0 100644 --- a/src/components/Resources/Schema/Create.tsx +++ b/src/components/Resources/Schema/Create.tsx @@ -16,6 +16,7 @@ import { ICheckEcosystem, checkEcosystem, getEcosystemId } from '../../../config import { createSchemaRequest } from '../../../api/ecosystem'; import ConfirmModal from '../../../commonComponents/ConfirmPopup'; import EcosystemProfileCard from '../../../commonComponents/EcosystemProfileCard' +import React from 'react'; const options = [ { value: 'string', label: 'String' }, @@ -39,7 +40,7 @@ interface IFormData { const CreateSchema = () => { const [failure, setFailure] = useState(null); - const [orgId, setOrgId] = useState(0); + const [orgId, setOrgId] = useState(''); const [createLoader, setCreateLoader] = useState(false); const [showPopup, setShowPopup] = useState(false) const [isEcosystemData, setIsEcosystemData] = useState(); @@ -60,7 +61,7 @@ const CreateSchema = () => { const fetchData = async () => { const organizationId = await getFromLocalStorage( storageKeys.ORG_ID); - setOrgId(Number(organizationId)); + setOrgId(organizationId); }; fetchData(); diff --git a/src/components/Resources/Schema/ViewSchema.tsx b/src/components/Resources/Schema/ViewSchema.tsx index f4bc29293..1e0488222 100644 --- a/src/components/Resources/Schema/ViewSchema.tsx +++ b/src/components/Resources/Schema/ViewSchema.tsx @@ -59,7 +59,7 @@ const ViewSchemas = () => { const [credDefListErr, setCredDefListErr] = useState(null) const [schemaDetailErr, setSchemaDetailErr] = useState(null) const [failure, setFailure] = useState(null) - const [orgId, setOrgId] = useState(0) + const [orgId, setOrgId] = useState('') const [credDefAuto, setCredDefAuto] = useState('') const [isEcosystemData, setIsEcosystemData] = useState(); @@ -67,7 +67,7 @@ const ViewSchemas = () => { const [userRoles, setUserRoles] = useState([]) - const getSchemaDetails = async (SchemaId: string, organizationId: number) => { + const getSchemaDetails = async (SchemaId: string, organizationId: string) => { try { setLoading(true); const SchemaDetails = await getSchemaById(SchemaId, organizationId); @@ -88,7 +88,7 @@ const ViewSchemas = () => { } }; - const getCredentialDefinitionList = async (id: string, orgId: number) => { + const getCredentialDefinitionList = async (id: string, orgId: string) => { try { setCredDeffloader(true); const credentialDefinitions = await getCredDeffById(id, orgId); @@ -113,12 +113,12 @@ const ViewSchemas = () => { useEffect(() => { const fetchData = async () => { const organizationId = await getFromLocalStorage(storageKeys.ORG_ID); - setOrgId(Number(organizationId)); + setOrgId(String(organizationId)); if (window?.location?.search) { const str = window?.location?.search; const schemaId = str.substring(str.indexOf('=') + 1); - await getSchemaDetails(schemaId, Number(organizationId)); - await getCredentialDefinitionList(schemaId, Number(organizationId)); + await getSchemaDetails(schemaId, String(organizationId)); + await getCredentialDefinitionList(schemaId, String(organizationId)); } }; diff --git a/src/components/Resources/Schema/interfaces/index.ts b/src/components/Resources/Schema/interfaces/index.ts index d4dd1d444..f65ed2149 100644 --- a/src/components/Resources/Schema/interfaces/index.ts +++ b/src/components/Resources/Schema/interfaces/index.ts @@ -1,4 +1,3 @@ -import { Pagination } from 'flowbite-react'; export interface GetAllSchemaListParameter { itemPerPage: number, page: number, @@ -25,9 +24,9 @@ type DataItem = { version: string; attributes: string[]; schemaLedgerId: string; - createdBy: number; + createdBy: string; publisherDid: string; - orgId: number; + orgId: string; issuerId: string; }; @@ -53,7 +52,7 @@ export type PaginationData = { export interface CredDeffFieldNameType { tag: string; revocable: boolean; - orgId: number; + orgId: string; schemaLedgerId: string; } @@ -61,7 +60,7 @@ export interface FieldName { schemaName: string; schemaVersion: string; attributes: IAttributes[] - orgId: number; + orgId: string; } @@ -69,13 +68,13 @@ export interface createSchema { schemaName: string; schemaVersion: string; attributes: IAttributes[] - orgId: number; + orgId: string; } export interface createCredDeffFieldName { tag: string; revocable: boolean; - orgId: number; + orgId: string; schemaLedgerId: string; } 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() &&