From 2ab5d72d1745627c20bc5782597fef67dff5bd60 Mon Sep 17 00:00:00 2001 From: Yogesh Pawar Date: Fri, 4 Aug 2023 13:45:23 +0530 Subject: [PATCH 1/9] feat: Created date conversion function. Signed-off-by: Yogesh Pawar --- src/utils/DateConversion.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/utils/DateConversion.ts diff --git a/src/utils/DateConversion.ts b/src/utils/DateConversion.ts new file mode 100644 index 000000000..27dd10304 --- /dev/null +++ b/src/utils/DateConversion.ts @@ -0,0 +1,23 @@ +export const dateConversion = (date: string): string => { + + const newDate = new Date(date); + const now = new Date(); + + const timeDifferenceInMilliseconds = now.getTime() - newDate.getTime(); + const timeDifferenceInSeconds = Math.floor(timeDifferenceInMilliseconds / 1000); + + if (timeDifferenceInSeconds < 60) { + return `${timeDifferenceInSeconds} sec ago`; + } else if (timeDifferenceInSeconds < 3600) { + const minutes = Math.floor(timeDifferenceInSeconds / 60); + return `${minutes} mins ago`; + } else if (timeDifferenceInSeconds < 86400) { + const hours = Math.floor(timeDifferenceInSeconds / 3600); + return `${hours} hrs ago`; + } else { + const year = newDate.getFullYear(); + const month = String(newDate.getMonth() + 1).padStart(2, '0'); + const day = String(newDate.getDate()).padStart(2, '0'); + return `${year}-${month}-${day}`; + } +}; From fc04f0fb330a4d3be4de73bf77f812b3ff2be5ab Mon Sep 17 00:00:00 2001 From: Yogesh Pawar Date: Fri, 4 Aug 2023 13:48:27 +0530 Subject: [PATCH 2/9] feat: Created custom datatable component to display list of records Signed-off-by: Yogesh Pawar --- src/commonComponents/datatable/index.tsx | 58 +++++++++++++++++++++ src/commonComponents/datatable/interface.ts | 10 ++++ 2 files changed, 68 insertions(+) create mode 100644 src/commonComponents/datatable/index.tsx create mode 100644 src/commonComponents/datatable/interface.ts diff --git a/src/commonComponents/datatable/index.tsx b/src/commonComponents/datatable/index.tsx new file mode 100644 index 000000000..0556580d7 --- /dev/null +++ b/src/commonComponents/datatable/index.tsx @@ -0,0 +1,58 @@ +import CopyIcon from '../../assets/icons/copy-icon.svg'; +import { Spinner } from "flowbite-react"; +import type { TableData, TableHeader } from './interface'; + +const DataTable = (props: { header: TableHeader[], data: TableData[][], loading: boolean }) => { + const { header, data, loading } = props; + return ( +
+ {loading + ?
+ +
+ :
+
+
+ + + + {header && header.length > 0 && + header.map(ele => ( + + ))} + + + + {data.length ? data.map((ele, index) => ( + + {ele.map(subEle => ( + + ))} + + )) : } + +
+
{ele.columnName}
+ {ele.subColumnName &&
{ele.subColumnName}
} + +
+
{subEle.data}
+ {subEle.subData &&
{subEle.subData}   {subEle.copySubData && Copy}
} +
No Data Found
+
+
+
+ } +
+ ) +} + + +export default DataTable diff --git a/src/commonComponents/datatable/interface.ts b/src/commonComponents/datatable/interface.ts new file mode 100644 index 000000000..df914ede0 --- /dev/null +++ b/src/commonComponents/datatable/interface.ts @@ -0,0 +1,10 @@ +export interface TableHeader { + columnName: string; + subColumnName?: string; +} + +export interface TableData { + data: string | JSX.Element; + subData?: string; + copySubData?: boolean; +} From 863fd6d4fe42eeb6c26b726a6270e6c6568fc34a Mon Sep 17 00:00:00 2001 From: Yogesh Pawar Date: Fri, 4 Aug 2023 13:49:27 +0530 Subject: [PATCH 3/9] feat: Displayed issued credential list Signed-off-by: Yogesh Pawar --- src/api/issuance.ts | 23 ++++ src/app/SideBar.astro | 2 +- src/assets/icons/copy-icon.svg | 3 + src/common/enums.ts | 13 ++ .../organization/IssuedCrdentials.tsx | 128 ++++++++++++++++++ src/config/apiRoutes.ts | 7 +- src/config/pathRoutes.ts | 4 +- .../organizations/issued-credentials.astro | 8 ++ 8 files changed, 183 insertions(+), 5 deletions(-) create mode 100644 src/api/issuance.ts create mode 100644 src/assets/icons/copy-icon.svg create mode 100644 src/common/enums.ts create mode 100644 src/components/organization/IssuedCrdentials.tsx create mode 100644 src/pages/organizations/issued-credentials.astro diff --git a/src/api/issuance.ts b/src/api/issuance.ts new file mode 100644 index 000000000..fdb51c82b --- /dev/null +++ b/src/api/issuance.ts @@ -0,0 +1,23 @@ +import type { IssueCredential } from '../common/enums'; +import { apiRoutes } from '../config/apiRoutes'; +import { storageKeys } from '../config/CommonConstant'; +import { getHeaderConfigs } from '../config/GetHeaderConfigs'; +import { axiosGet } from '../services/apiRequests'; +import { getFromLocalStorage } from './Auth'; + +export const getIssuedCredentials = async (state: IssueCredential) => { + const orgId = await getFromLocalStorage(storageKeys.ORG_ID); + const url = `${apiRoutes.Issuance.getIssuedCredentials}?orgId=${orgId}&state=${state}`; + + const axiosPayload = { + url, + config: await getHeaderConfigs(), + }; + + try { + return await axiosGet(axiosPayload); + } catch (error) { + const err = error as Error; + return err?.message; + } +}; diff --git a/src/app/SideBar.astro b/src/app/SideBar.astro index c7e45729b..8d870bea0 100644 --- a/src/app/SideBar.astro +++ b/src/app/SideBar.astro @@ -140,7 +140,7 @@ import { pathRoutes } from "../config/pathRoutes"; CredentialsIssued Credentials diff --git a/src/assets/icons/copy-icon.svg b/src/assets/icons/copy-icon.svg new file mode 100644 index 000000000..2b6b264de --- /dev/null +++ b/src/assets/icons/copy-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/common/enums.ts b/src/common/enums.ts new file mode 100644 index 000000000..8bb6e09d3 --- /dev/null +++ b/src/common/enums.ts @@ -0,0 +1,13 @@ +export enum IssueCredential { + proposalSent = 'proposal-sent', + proposalReceived = 'proposal-received', + offerSent = 'offer-sent', + offerReceived = 'offer-received', + declined = 'decliend', + requestSent = 'request-sent', + requestReceived = 'request-received', + credentialIssued = 'credential-issued', + credentialReceived = 'credential-received', + done = 'done', + abandoned = 'abandoned', +} diff --git a/src/components/organization/IssuedCrdentials.tsx b/src/components/organization/IssuedCrdentials.tsx new file mode 100644 index 000000000..41ff4c247 --- /dev/null +++ b/src/components/organization/IssuedCrdentials.tsx @@ -0,0 +1,128 @@ +'use client'; + +import { Button, Pagination } from 'flowbite-react'; +import { ChangeEvent, useEffect, useState } from 'react'; +import { apiStatusCodes, storageKeys } from '../../config/CommonConstant'; +import type { AxiosResponse } from 'axios'; +import BreadCrumbs from '../BreadCrumbs'; +import SearchInput from '../SearchInput'; +import { getIssuedCredentials } from '../../api/issuance'; +import { IssueCredential } from '../../common/enums'; +import { AlertComponent } from '../AlertComponent'; +import DataTable from '../../commonComponents/datatable'; +import type { TableData } from '../../commonComponents/datatable/interface'; +import { dateConversion } from '../../utils/DateConversion'; + +interface IssuedCredential { + metadata: { [x: string]: { schemaId: string; }; }; + connectionId: string; + updatedAt: string; + state: string; + isRevocable: boolean; +} +const CredentialList = () => { + const [loading, setLoading] = useState(true) + const [error, setError] = useState(null) + const [searchText, setSearchText] = useState(""); + const [organizationsList, setOrganizationList] = useState([]) + + //Fetch all issued credential list + const getIssuedCredDefs = async () => { + setLoading(true) + const response = await getIssuedCredentials(IssueCredential.done); + const { data } = response as AxiosResponse + + if (data?.statusCode === apiStatusCodes.API_STATUS_CREATED) { + const credentialList = data?.data?.map((issuedCredential: IssuedCredential) => { + const schemaName = issuedCredential.metadata["_anoncreds/credential"].schemaId ? issuedCredential.metadata["_anoncreds/credential"].schemaId.split(':').slice(2).join(':') : 'Not available' + return [{ data: issuedCredential.connectionId ? issuedCredential.connectionId : 'Not available' }, { data: schemaName }, { data: dateConversion(issuedCredential.updatedAt) }, + { + data: + {issuedCredential.state.replace(/_/g, ' ').replace(/\w\S*/g, (word: string) => word.charAt(0).toUpperCase() + word.substring(1).toLowerCase())} + + }, { + data: issuedCredential?.isRevocable ? + : Non revocable + }]; + }) + + setOrganizationList(credentialList) + } else { + setError(response as string) + } + + setLoading(false) + } + + + //This useEffect is called when the searchText changes + useEffect(() => { + let getData: NodeJS.Timeout + + if (searchText.length >= 1) { + getData = setTimeout(() => { + getIssuedCredDefs() + + }, 1000) + } else { + getIssuedCredDefs() + } + + return () => clearTimeout(getData) + }, [searchText]) + + //onCHnage of Search input text + const searchInputChange = (e: ChangeEvent) => { + setSearchText(e.target.value); + } + + const header = [ + { columnName: 'Connection Id' }, + { columnName: 'Schema Name' }, + { columnName: 'Date' }, + { columnName: 'Status' }, + { columnName: 'Action' } + ] + + return ( +
+
+ + +

+ Issued Credentials +

+
+
+
+
+ + +
+ { + setError(null) + }} + /> + +
+
+
+ ) +} + +export default CredentialList; diff --git a/src/config/apiRoutes.ts b/src/config/apiRoutes.ts index 0e8affcaa..aea844098 100644 --- a/src/config/apiRoutes.ts +++ b/src/config/apiRoutes.ts @@ -43,5 +43,8 @@ export const apiRoutes = { fidoAuthentication: 'Fido/generate-authentication-options', fidoVerifyAuthentication: 'Fido/verify-authentication/' - } -} \ No newline at end of file + }, + Issuance:{ + getIssuedCredentials:'/issue-credentials' + } +} diff --git a/src/config/pathRoutes.ts b/src/config/pathRoutes.ts index e8076b5f9..fce935715 100644 --- a/src/config/pathRoutes.ts +++ b/src/config/pathRoutes.ts @@ -14,7 +14,7 @@ export const pathRoutes = { root: '/organizations', invitations: '/organizations/invitations', users: '/organizations/users', - credentials: '/organizations/credentials', + credentials: '/organizations/issued-credentials', schemas: `/organizations/schemas`, dashboard: '/organizations/dashboard', createSchema: '/organizations/schemas/create', @@ -39,4 +39,4 @@ export const pathRoutes = { createCredentialDefinition: '/credential-definitions', getCredDeffBySchemaId: '/schemas/credential-definitions' } -} \ No newline at end of file +} diff --git a/src/pages/organizations/issued-credentials.astro b/src/pages/organizations/issued-credentials.astro new file mode 100644 index 000000000..ecbd9a43c --- /dev/null +++ b/src/pages/organizations/issued-credentials.astro @@ -0,0 +1,8 @@ +--- +import LayoutSidebar from '../../app/LayoutSidebar.astro'; +import CredentialList from '../../components/organization/IssuedCrdentials'; +--- + + + + From 21c86afff51f9cd733ca40ab116c77581639a0cc Mon Sep 17 00:00:00 2001 From: Yogesh Pawar Date: Fri, 4 Aug 2023 15:04:15 +0530 Subject: [PATCH 4/9] feat: Implemented Schema selection functionality in Issuance flow --- src/app/SideBar.astro | 2 +- src/commonComponents/SchemaCard.tsx | 16 +- src/commonComponents/datatable/index.tsx | 30 +-- src/commonComponents/datatable/interface.ts | 7 +- src/components/Issuance/SchemaSelection.tsx | 17 ++ src/components/Resources/Schema/Schemas.tsx | 183 +----------------- .../Resources/Schema/SchemasList.tsx | 143 ++++++++++++++ .../organization/IssuedCrdentials.tsx | 16 +- src/config/pathRoutes.ts | 10 +- .../organizations/issued-credentials.astro | 8 - .../issued-credentials/index.astro | 9 + .../issued-credentials/schemas/index.astro | 7 + src/pages/organizations/schemas/index.astro | 7 +- src/utils/TextTransform.ts | 12 +- 14 files changed, 244 insertions(+), 223 deletions(-) create mode 100644 src/components/Issuance/SchemaSelection.tsx create mode 100644 src/components/Resources/Schema/SchemasList.tsx delete mode 100644 src/pages/organizations/issued-credentials.astro create mode 100644 src/pages/organizations/issued-credentials/index.astro create mode 100644 src/pages/organizations/issued-credentials/schemas/index.astro diff --git a/src/app/SideBar.astro b/src/app/SideBar.astro index 8d870bea0..67695d8d6 100644 --- a/src/app/SideBar.astro +++ b/src/app/SideBar.astro @@ -138,7 +138,7 @@ import { pathRoutes } from "../config/pathRoutes";
  • Issued Credentials diff --git a/src/commonComponents/SchemaCard.tsx b/src/commonComponents/SchemaCard.tsx index d72bb1d59..f81730369 100644 --- a/src/commonComponents/SchemaCard.tsx +++ b/src/commonComponents/SchemaCard.tsx @@ -1,23 +1,23 @@ import { Card } from 'flowbite-react'; -import { pathRoutes } from '../config/pathRoutes'; +import { dateConversion } from '../utils/DateConversion'; -const SchemaCard = (props: { schemaName: string, version: string, schemaId: string, issuerDid: string, attributes: string[], created: string },) => { +const SchemaCard = (props: { schemaName: string, version: string, schemaId: string, issuerDid: string, attributes: string[], created: string, onClickCallback: (schemaId: string) => void; },) => { return ( { - window.location.href = `${pathRoutes.organizations.viewSchema}?schemaId=${props.schemaId}` + props.onClickCallback(props.schemaId) }} className='transform transition duration-500 hover:scale-105 hover:bg-gray-50 cursor-pointer' style={{ width: '470px', height: '240px', maxWidth: '100%', maxHeight: '100%', overflow: 'auto' }}>
    {props.schemaName}
    -

    +

    Version: {props.version}

    -

    - {new Date(props.created).toLocaleDateString('en-GB')} +

    + {dateConversion(props.created)}

    @@ -29,7 +29,7 @@ const SchemaCard = (props: { schemaName: string, version: string, schemaId: stri Issuer DID: {props.issuerDid}

    - Ledger: {props.issuerDid.split(':')[2]} + Ledger: {props.issuerDid?.split(':')[2]}

    @@ -66,5 +66,3 @@ const SchemaCard = (props: { schemaName: string, version: string, schemaId: stri export default SchemaCard - - diff --git a/src/commonComponents/datatable/index.tsx b/src/commonComponents/datatable/index.tsx index 0556580d7..a2ae742e3 100644 --- a/src/commonComponents/datatable/index.tsx +++ b/src/commonComponents/datatable/index.tsx @@ -1,11 +1,17 @@ -import CopyIcon from '../../assets/icons/copy-icon.svg'; -import { Spinner } from "flowbite-react"; -import type { TableData, TableHeader } from './interface'; +import type { TableData, TableHeader } from "./interface" +import { Spinner, Tooltip } from "flowbite-react"; + +interface DataTableProps { + header: TableHeader[]; + data: TableData[]; + loading: boolean; + callback?: (clickId: string | null | undefined) => void; +} + +const DataTable: React.FC = ({ header, data, loading, callback }) => { -const DataTable = (props: { header: TableHeader[], data: TableData[][], loading: boolean }) => { - const { header, data, loading } = props; return ( -
    +
    {loading ?
    (
    {ele.columnName}
    {ele.subColumnName &&
    {ele.subColumnName}
    } @@ -35,11 +41,11 @@ const DataTable = (props: { header: TableHeader[], data: TableData[][], loading: {data.length ? data.map((ele, index) => ( - - {ele.map(subEle => ( - + callback ? callback(ele?.clickId) : ''}> + {ele.data.map(subEle => ( +
    {subEle.data}
    - {subEle.subData &&
    {subEle.subData}   {subEle.copySubData && Copy}
    } + {subEle.subData && subEle.subData} ))} @@ -50,7 +56,7 @@ const DataTable = (props: { header: TableHeader[], data: TableData[][], loading:
    } -
    + ) } diff --git a/src/commonComponents/datatable/interface.ts b/src/commonComponents/datatable/interface.ts index df914ede0..ab0a23849 100644 --- a/src/commonComponents/datatable/interface.ts +++ b/src/commonComponents/datatable/interface.ts @@ -1,10 +1,15 @@ export interface TableHeader { columnName: string; subColumnName?: string; + width?: string; } export interface TableData { + clickId?: string | null; + data: Data[]; +} + +interface Data { data: string | JSX.Element; subData?: string; - copySubData?: boolean; } diff --git a/src/components/Issuance/SchemaSelection.tsx b/src/components/Issuance/SchemaSelection.tsx new file mode 100644 index 000000000..1ec4c759d --- /dev/null +++ b/src/components/Issuance/SchemaSelection.tsx @@ -0,0 +1,17 @@ +'use client'; + +import { pathRoutes } from "../../config/pathRoutes"; +import SchemaList from "../Resources/Schema/SchemasList"; + +const SchemaSelection = () => { + + const schemaSelectionCallback = (schemaId: string) => { + window.location.href = `${pathRoutes.organizations.Issuance.credDef}?schemaId=${schemaId}` + } + + return ( + + ) +} + +export default SchemaSelection diff --git a/src/components/Resources/Schema/Schemas.tsx b/src/components/Resources/Schema/Schemas.tsx index b547659dc..336b7635d 100644 --- a/src/components/Resources/Schema/Schemas.tsx +++ b/src/components/Resources/Schema/Schemas.tsx @@ -1,178 +1,13 @@ -'use client'; +import { pathRoutes } from "../../../config/pathRoutes" +import SchemaList from "./SchemasList" -import { Alert, Button, Card, Pagination, Spinner, Table, } from 'flowbite-react'; -import { ChangeEvent, useEffect, useState } from 'react'; -import type { GetAllSchemaListParameter, PaginationData } from './interfaces'; -import { apiStatusCodes, storageKeys } from '../../../config/CommonConstant'; - -import type { AxiosResponse } from 'axios'; -import BreadCrumbs from '../../BreadCrumbs'; -import SchemaCard from '../../../commonComponents/SchemaCard'; -import SearchInput from '../../SearchInput'; -import { getAllSchemas } from '../../../api/Schema'; -import { getFromLocalStorage } from '../../../api/Auth'; -import { pathRoutes } from '../../../config/pathRoutes'; -import { EmptyListMessage } from '../../EmptyListComponent'; - -const SchemaList = () => { - const [schemaList, setSchemaList] = useState([]) - const [schemaListErr, setSchemaListErr] = useState('') - const [loading, setLoading] = useState(true) - const [orgId, setOrgId] = useState('') - const [schemaListAPIParameter, setSchemaListAPIParameter] = useState({ - itemPerPage: 9, - page: 1, - search: "", - sortBy: "id", - sortingOrder: "DESC" - }) - - const getSchemaList = async (schemaListAPIParameter: GetAllSchemaListParameter) => { - try { - const organizationId = await getFromLocalStorage(storageKeys.ORG_ID); - setOrgId(organizationId); - setLoading(true); - - const schemaList = await getAllSchemas(schemaListAPIParameter, organizationId); - const { data } = schemaList as AxiosResponse; - - if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { - if (data?.data?.data?.length === 0) { - setSchemaListErr('No Data Found'); - } - if (data?.data?.data) { - setSchemaList(data?.data?.data); - setLoading(false); - } else { - setLoading(false); - setSchemaListErr(schemaList as string) - } - } else { - setLoading(false); - setSchemaListErr(schemaList as string) - } - } catch (error) { - console.error('Error while fetching schema list:', error); - setLoading(false); - +const Schemas = () => { + const schemaSelectionCallback = (schemaId: string) => { + window.location.href = `${pathRoutes.organizations.viewSchema}?schemaId=${schemaId}` } - }; - - const createSchema = () => { - window.location.href = `${pathRoutes.organizations.createSchema}?OrgId=${orgId}` - } - - useEffect(() => { - getSchemaList(schemaListAPIParameter) - }, []); - - useEffect(() => { - getSchemaList(schemaListAPIParameter) - - }, [schemaListAPIParameter]) - - const onSearch = async (event: ChangeEvent): Promise => { - event.preventDefault() - setSchemaListAPIParameter({ - ...schemaListAPIParameter, - search: event.target.value - }) - - getSchemaList({ - ...schemaListAPIParameter, - search: event.target.value - }) - - } - - return ( -
    -
    - -

    - Schemas -

    -
    -
    -
    -
    -
    - -
    - -
    - { - schemaListErr && - setSchemaListErr(null)} - > - -

    - {schemaListErr} -

    -
    -
    - } - {loading - ? (
    - -
    ) - : - schemaList && schemaList.length > 0 ? ( - -
    -
    - { schemaList.map((element, key) => ( -
    - -
    - ))} -
    -
    - - { - setSchemaListAPIParameter(prevState => ({ - ...prevState, - page: page - })); - }} - totalPages={0} - /> -
    -
    ) : ( - - } - onClick={createSchema} - />) - } -
    -
    -
    - - ) + return ( + + ) } - -export default SchemaList \ No newline at end of file +export default Schemas diff --git a/src/components/Resources/Schema/SchemasList.tsx b/src/components/Resources/Schema/SchemasList.tsx new file mode 100644 index 000000000..782d3228d --- /dev/null +++ b/src/components/Resources/Schema/SchemasList.tsx @@ -0,0 +1,143 @@ +'use client'; + +import { Button, Card, Pagination, Spinner, Table, } from 'flowbite-react'; +import { ChangeEvent, useEffect, useState } from 'react'; +import type { GetAllSchemaListParameter, PaginationData } from './interfaces'; +import { apiStatusCodes, storageKeys } from '../../../config/CommonConstant'; +import type { AxiosResponse } from 'axios'; +import BreadCrumbs from '../../BreadCrumbs'; +import SchemaCard from '../../../commonComponents/SchemaCard'; +import SearchInput from '../../SearchInput'; +import { getAllSchemas } from '../../../api/Schema'; +import { getFromLocalStorage } from '../../../api/Auth'; +import { pathRoutes } from '../../../config/pathRoutes'; + +const SchemaList = (props: { schemaSelectionCallback: (schemaId: string) => void; }) => { + const [schemaList, setSchemaList] = useState([]) + const [loading, setLoading] = useState(true) + const [orgId, setOrgId] = useState('') + const [schemaListAPIParameter, setSchemaListAPIParameter] = useState({ + itemPerPage: 9, + page: 1, + search: "", + sortBy: "id", + sortingOrder: "DESC" + }) + + const getSchemaList = async (schemaListAPIParameter: GetAllSchemaListParameter) => { + const organizationId = await getFromLocalStorage(storageKeys.ORG_ID) + setOrgId(organizationId) + setLoading(true) + + const schemaList = await getAllSchemas(schemaListAPIParameter, organizationId); + const { data } = schemaList as AxiosResponse + + if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { + if (data?.data?.data) { + setSchemaList(data?.data?.data) + setLoading(false) + } else { + setLoading(false) + } + } else { + setLoading(false) + } + } + + + useEffect(() => { + getSchemaList(schemaListAPIParameter) + }, []); + + useEffect(() => { + getSchemaList(schemaListAPIParameter) + + }, [schemaListAPIParameter]) + + const onSearch = async (event: ChangeEvent): Promise => { + event.preventDefault() + setSchemaListAPIParameter({ + ...schemaListAPIParameter, + search: event.target.value + }) + + getSchemaList({ + ...schemaListAPIParameter, + search: event.target.value + }) + + } + + const schemaSelectionCallback = (schemaId: string) => { + props.schemaSelectionCallback(schemaId) + } + + return ( +
    +
    + +

    + Schemas +

    +
    +
    +
    +
    +
    + +
    + +
    + {loading + ?
    + +
    + : +
    +
    + {schemaList && schemaList.length > 0 && + schemaList.map((element, key) => ( +
    + +
    + ))} +
    +
    + + { + setSchemaListAPIParameter(prevState => ({ + ...prevState, + page: page + })); + }} + totalPages={0} + /> +
    +
    + } +
    +
    +
    + + ) +} + + +export default SchemaList diff --git a/src/components/organization/IssuedCrdentials.tsx b/src/components/organization/IssuedCrdentials.tsx index 41ff4c247..8b8273f7e 100644 --- a/src/components/organization/IssuedCrdentials.tsx +++ b/src/components/organization/IssuedCrdentials.tsx @@ -6,12 +6,13 @@ import { apiStatusCodes, storageKeys } from '../../config/CommonConstant'; import type { AxiosResponse } from 'axios'; import BreadCrumbs from '../BreadCrumbs'; import SearchInput from '../SearchInput'; +import { dateConversion } from '../../utils/DateConversion'; import { getIssuedCredentials } from '../../api/issuance'; import { IssueCredential } from '../../common/enums'; import { AlertComponent } from '../AlertComponent'; +import { pathRoutes } from '../../config/pathRoutes'; import DataTable from '../../commonComponents/datatable'; import type { TableData } from '../../commonComponents/datatable/interface'; -import { dateConversion } from '../../utils/DateConversion'; interface IssuedCredential { metadata: { [x: string]: { schemaId: string; }; }; @@ -24,7 +25,7 @@ const CredentialList = () => { const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [searchText, setSearchText] = useState(""); - const [organizationsList, setOrganizationList] = useState([]) + const [issuedCredList, setIssuedCredList] = useState([]) //Fetch all issued credential list const getIssuedCredDefs = async () => { @@ -51,7 +52,7 @@ const CredentialList = () => { }]; }) - setOrganizationList(credentialList) + setIssuedCredList(credentialList) } else { setError(response as string) } @@ -81,6 +82,10 @@ const CredentialList = () => { setSearchText(e.target.value); } + const schemeSelection = () => { + window.location.href = pathRoutes.organizations.Issuance.schema + } + const header = [ { columnName: 'Connection Id' }, { columnName: 'Schema Name' }, @@ -92,7 +97,6 @@ const CredentialList = () => { return (
    -

    Issued Credentials @@ -105,7 +109,7 @@ const CredentialList = () => { -

    diff --git a/src/config/pathRoutes.ts b/src/config/pathRoutes.ts index fce935715..c8fed3a19 100644 --- a/src/config/pathRoutes.ts +++ b/src/config/pathRoutes.ts @@ -14,12 +14,16 @@ export const pathRoutes = { root: '/organizations', invitations: '/organizations/invitations', users: '/organizations/users', - credentials: '/organizations/issued-credentials', + issuedCredentials: '/organizations/issued-credentials', schemas: `/organizations/schemas`, dashboard: '/organizations/dashboard', createSchema: '/organizations/schemas/create', - viewSchema: '/organizations/schemas/view-schema' - + viewSchema: '/organizations/schemas/view-schema', + Issuance: { + schema: '/organizations/issued-credentials/schemas', + credDef:'/organizations/issued-credentials/schemas/cred-defs', + connections:'/organizations/issued-credentials/schemas/cred-defs/connections' + }, }, ecosystems: { root: '/ecosystems', diff --git a/src/pages/organizations/issued-credentials.astro b/src/pages/organizations/issued-credentials.astro deleted file mode 100644 index ecbd9a43c..000000000 --- a/src/pages/organizations/issued-credentials.astro +++ /dev/null @@ -1,8 +0,0 @@ ---- -import LayoutSidebar from '../../app/LayoutSidebar.astro'; -import CredentialList from '../../components/organization/IssuedCrdentials'; ---- - - - - diff --git a/src/pages/organizations/issued-credentials/index.astro b/src/pages/organizations/issued-credentials/index.astro new file mode 100644 index 000000000..01c43aed7 --- /dev/null +++ b/src/pages/organizations/issued-credentials/index.astro @@ -0,0 +1,9 @@ +--- +import LayoutSidebar from "../../../app/LayoutSidebar.astro"; +import CredentialList from "../../../components/organization/IssuedCrdentials"; + +--- + + + + diff --git a/src/pages/organizations/issued-credentials/schemas/index.astro b/src/pages/organizations/issued-credentials/schemas/index.astro new file mode 100644 index 000000000..b87087217 --- /dev/null +++ b/src/pages/organizations/issued-credentials/schemas/index.astro @@ -0,0 +1,7 @@ +--- +import LayoutSidebar from '../../../../app/LayoutSidebar.astro'; +import SchemaSelection from '../../../../components/Issuance/SchemaSelection' +--- + + + diff --git a/src/pages/organizations/schemas/index.astro b/src/pages/organizations/schemas/index.astro index 05a6c09bd..b8e40d12e 100644 --- a/src/pages/organizations/schemas/index.astro +++ b/src/pages/organizations/schemas/index.astro @@ -1,10 +1,7 @@ --- -import LayoutStacked from '../../../app/LayoutStacked.astro'; -import LayoutCommon from '../../../app/LayoutCommon.astro'; -import SideBar from '../../../app/SideBar.astro'; import LayoutSidebar from '../../../app/LayoutSidebar.astro'; -import SchemaList from '../../../components/Resources/Schema/Schemas' +import Schemas from '../../../components/Resources/Schema/Schemas'; --- - + diff --git a/src/utils/TextTransform.ts b/src/utils/TextTransform.ts index 6d75473c3..8ea0d04e5 100644 --- a/src/utils/TextTransform.ts +++ b/src/utils/TextTransform.ts @@ -1,5 +1,9 @@ - - export const TextTittlecase = (text: string): string => { - return text.charAt(0).toUpperCase() + text.slice(1) -} \ No newline at end of file + return text.charAt(0).toUpperCase() + text.slice(1); +}; + +export const copyText = (copiedText: string | undefined) => { + if (copiedText) { + navigator.clipboard.writeText(copiedText); + } +}; From 3f6c682c866825efbc439993f72b6f9d0f550257 Mon Sep 17 00:00:00 2001 From: Yogesh Pawar Date: Fri, 4 Aug 2023 16:44:20 +0530 Subject: [PATCH 5/9] feat: Implemented Credential Definitions selection functionality in issuance flow --- src/api/issuance.ts | 16 ++ src/components/Issuance/CredDefSelection.tsx | 144 ++++++++++++++++++ src/config/apiRoutes.ts | 3 +- .../schemas/cred-defs/index.astro | 7 + 4 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 src/components/Issuance/CredDefSelection.tsx create mode 100644 src/pages/organizations/issued-credentials/schemas/cred-defs/index.astro diff --git a/src/api/issuance.ts b/src/api/issuance.ts index fdb51c82b..fe0e63a8b 100644 --- a/src/api/issuance.ts +++ b/src/api/issuance.ts @@ -21,3 +21,19 @@ export const getIssuedCredentials = async (state: IssueCredential) => { return err?.message; } }; + +export const getCredentialDefinitions = async (schemaId: string) => { + const orgId = await getFromLocalStorage(storageKeys.ORG_ID); + const url = `${apiRoutes.Issuance.getCredDefBySchemaId}?schemaId=${schemaId}&orgId=${orgId}`; + const axiosPayload = { + url, + config: await getHeaderConfigs(), + }; + + try { + return await axiosGet(axiosPayload); + } catch (error) { + const err = error as Error; + return err?.message; + } +}; diff --git a/src/components/Issuance/CredDefSelection.tsx b/src/components/Issuance/CredDefSelection.tsx new file mode 100644 index 000000000..aca8d0ad0 --- /dev/null +++ b/src/components/Issuance/CredDefSelection.tsx @@ -0,0 +1,144 @@ +'use client'; + +import type { AxiosResponse } from "axios"; +import { Spinner } from "flowbite-react"; +import { useEffect, useState } from "react"; +import { getFromLocalStorage } from "../../api/Auth"; +import { getCredentialDefinitions } from "../../api/issuance"; +import { getSchemaById } from "../../api/Schema"; +import DataTable from "../../commonComponents/datatable"; +import type { TableData } from "../../commonComponents/datatable/interface"; +import SchemaCard from "../../commonComponents/SchemaCard"; +import { apiStatusCodes, storageKeys } from "../../config/CommonConstant"; +import { pathRoutes } from "../../config/pathRoutes"; +import BreadCrumbs from "../BreadCrumbs"; + + +interface SchemaState { + schemaId: string; + issuerDid: string; + attributes: string[]; + createdDateTime: string; +} + +interface CredDefData { + credentialDefinitionId: string; + revocable: boolean; + schemaLedgerId: string; + tag: string; +} + +const CredDefSelection = () => { + const [schemaState, setSchemaState] = useState({ schemaName: '', version: '' }) + const [loading, setLoading] = useState(true) + const [schemaLoader, setSchemaLoader] = useState(true) + const [error, setError] = useState(null) + const [credDefList, setCredDefList] = useState([]) + const [schemaDetailsState, setSchemaDetailsState] = useState({ schemaId: '', issuerDid: '', attributes: [], createdDateTime: '' }) + + useEffect(() => { + if (window?.location?.search) { + const urlParams = new URLSearchParams(window.location.search); + const schemaIdParam = urlParams.get('schemaId'); + if (schemaIdParam) { + getSchemaDetails(schemaIdParam) + getCredDefs(schemaIdParam) + const parts = schemaIdParam.split(":"); + const schemaName = parts[2]; + const version = parts[3]; + setSchemaState({ schemaName, version }) + } else { + setSchemaState({ schemaName: '', version: '' }) + } + } + }, []); + + const getSchemaDetails = async (schemaId: string) => { + setSchemaLoader(true) + const orgId = await getFromLocalStorage(storageKeys.ORG_ID) + const schemaDetails = await getSchemaById(schemaId, Number(orgId)) + const { data } = schemaDetails as AxiosResponse + + if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { + if (data.data.response) { + const { response } = data.data + setSchemaDetailsState({ schemaId: response?.schemaId, issuerDid: response?.schema?.issuerId, attributes: response.schema.attrNames, createdDateTime: 'string' }) + + } + } + setSchemaLoader(false) + } + + const header = [ + { columnName: 'Name' }, + { columnName: 'Created on' }, + { columnName: 'Revocable?' } + ] + + //Fetch all issued credential list + const getCredDefs = async (schemaId: string) => { + setLoading(true) + const response = await getCredentialDefinitions(schemaId); + const { data } = response as AxiosResponse + + if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { + const credDefs = data?.data?.data.map((ele: CredDefData) => { + return { + clickId: ele.credentialDefinitionId, data: [{ data: ele.tag ? ele.tag : 'Not available' }, { data: ele.tag ? ele.tag : 'Not available' }, + { data: ele.revocable === true ? Yes : No } + ] + } + }) + + if (credDefs.length === 0) { + setError('No Data Found') + } + + setCredDefList(credDefs) + } else { + setError(response as string) + } + + setLoading(false) + } + const schemaSelectionCallback = () => { + + } + + const selectCredDef = (credDefId: string | null | undefined) => { + if (credDefId) { + window.location.href = `${pathRoutes.organizations.Issuance.connections}` + } + } + + return ( +
    +
    + +

    + Schema +

    +
    +
    + {schemaLoader ? +
    + +
    + : } +
    + +
    +

    + Credential definitions +

    +
    + + +
    + ) +} + +export default CredDefSelection diff --git a/src/config/apiRoutes.ts b/src/config/apiRoutes.ts index aea844098..388885cb0 100644 --- a/src/config/apiRoutes.ts +++ b/src/config/apiRoutes.ts @@ -45,6 +45,7 @@ export const apiRoutes = { }, Issuance:{ - getIssuedCredentials:'/issue-credentials' + getIssuedCredentials:'/issue-credentials', + getCredDefBySchemaId :'/schemas/credential-definitions' } } diff --git a/src/pages/organizations/issued-credentials/schemas/cred-defs/index.astro b/src/pages/organizations/issued-credentials/schemas/cred-defs/index.astro new file mode 100644 index 000000000..cb145a134 --- /dev/null +++ b/src/pages/organizations/issued-credentials/schemas/cred-defs/index.astro @@ -0,0 +1,7 @@ +--- +import LayoutSidebar from '../../../../../app/LayoutSidebar.astro'; +import CredDefSelection from '../../../../../components/Issuance/CredDefSelection'; +--- + + + From 9ca8ce92468a5f1e95f23d1d44648dbd31403a2c Mon Sep 17 00:00:00 2001 From: Yogesh Pawar Date: Fri, 4 Aug 2023 18:26:47 +0530 Subject: [PATCH 6/9] feat: Implemented connection selection functionality in issuance flow --- src/api/connection.ts | 21 +++ src/assets/coming-soon.svg | 4 + src/components/Issuance/ConnectionList.tsx | 124 ++++++++++++++++++ src/components/Issuance/Connections.tsx | 39 ++++++ src/components/Issuance/CredDefSelection.tsx | 27 ++-- src/components/Issuance/EmailList.tsx | 13 ++ src/components/Issuance/interface.ts | 13 ++ src/config/apiRoutes.ts | 3 +- .../schemas/cred-defs/connections/index.astro | 8 ++ 9 files changed, 234 insertions(+), 18 deletions(-) create mode 100644 src/api/connection.ts create mode 100644 src/assets/coming-soon.svg create mode 100644 src/components/Issuance/ConnectionList.tsx create mode 100644 src/components/Issuance/Connections.tsx create mode 100644 src/components/Issuance/EmailList.tsx create mode 100644 src/components/Issuance/interface.ts create mode 100644 src/pages/organizations/issued-credentials/schemas/cred-defs/connections/index.astro diff --git a/src/api/connection.ts b/src/api/connection.ts new file mode 100644 index 000000000..678cd3046 --- /dev/null +++ b/src/api/connection.ts @@ -0,0 +1,21 @@ +import { apiRoutes } from '../config/apiRoutes'; +import { storageKeys } from '../config/CommonConstant'; +import { getHeaderConfigs } from '../config/GetHeaderConfigs'; +import { axiosGet } from '../services/apiRequests'; +import { getFromLocalStorage } from './Auth'; + +export const getConnectionsByOrg = async () => { + const orgId = await getFromLocalStorage(storageKeys.ORG_ID); + const url = `${apiRoutes.Issuance.getAllConnections}?orgId=${orgId}`; + const axiosPayload = { + url, + config: await getHeaderConfigs(), + }; + + try { + return await axiosGet(axiosPayload); + } catch (error) { + const err = error as Error; + return err?.message; + } +}; diff --git a/src/assets/coming-soon.svg b/src/assets/coming-soon.svg new file mode 100644 index 000000000..b0708043d --- /dev/null +++ b/src/assets/coming-soon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/components/Issuance/ConnectionList.tsx b/src/components/Issuance/ConnectionList.tsx new file mode 100644 index 000000000..7212a2410 --- /dev/null +++ b/src/components/Issuance/ConnectionList.tsx @@ -0,0 +1,124 @@ +'use client'; + +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"; +import { AlertComponent } from "../AlertComponent"; + + +const ConnectionList = () => { + const [connectionList, setConnectionList] = useState([]) + const [selectedConnectionList, setSelectedConnectionList] = useState([]) + + const [loading, setLoading] = useState(false) + const [searchText, setSearchText] = useState(""); + const [error, setError] = useState(null) + + //This useEffect is called when the searchText changes + useEffect(() => { + getConnections() + }, []) + + + //Fetch the connection list against organization id + const getConnections = async () => { + setLoading(true) + const response = await getConnectionsByOrg(); + const { data } = response as AxiosResponse + + if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { + const connections = data?.data?.map((ele) => { + const userName = ele?.theirLabel ? ele.theirLabel : 'Not available'; + const connectionId = ele.id ? ele.id : 'Not available' + return { + data: [{ + data:
    + ) => { + const inputElement = event.target as HTMLInputElement; + selectConnection(userName, connectionId, inputElement.checked) + }} + value="" className="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600 cursor-pointer" /> +
    + }, + { data: userName }, { data: connectionId }, + ] + } + }) + + setConnectionList(connections) + } else { + setError(response as string) + } + + setLoading(false) + } + + + const header = [ + { columnName: '', width: 'w-0.5' }, + { columnName: 'User' }, + { columnName: 'Connection ID' } + ] + + const selectedConnectionHeader = [ + { columnName: 'User' }, + { columnName: 'Connection ID' } + ] + + const selectConnection = (user: string, connectionId: string, checked: boolean) => { + + if (checked) { + setSelectedConnectionList((prevList) => [...prevList, { + data: [ + { + data: user, + }, { + data: connectionId, + }] + }] + ) + } else { + setSelectedConnectionList((prevList) => + prevList.filter((connection) => connection.data[1].data !== connectionId) + ); + } + } + + return ( +
    + +
    +

    + Connection List +

    +
    + { + setError(null) + }} + /> +
    + + +
    +
    +

    + Selected Users +

    +
    +
    + +
    + +
    + ) +} + +export default ConnectionList diff --git a/src/components/Issuance/Connections.tsx b/src/components/Issuance/Connections.tsx new file mode 100644 index 000000000..98597e9f8 --- /dev/null +++ b/src/components/Issuance/Connections.tsx @@ -0,0 +1,39 @@ +'use client'; + +import BreadCrumbs from "../BreadCrumbs"; +import ConnectionList from "./ConnectionList"; +import EmailList from "./EmailList"; + +const Connections = () => { + + return ( +
    +
    + +
    + +
    +
      +
    • + +
    • +
    • + +
    • +
    +
    +
    +
    + +
    +
    + +
    +
    + + +
    + ) +} + +export default Connections diff --git a/src/components/Issuance/CredDefSelection.tsx b/src/components/Issuance/CredDefSelection.tsx index aca8d0ad0..f92cb7d24 100644 --- a/src/components/Issuance/CredDefSelection.tsx +++ b/src/components/Issuance/CredDefSelection.tsx @@ -11,22 +11,9 @@ import type { TableData } from "../../commonComponents/datatable/interface"; import SchemaCard from "../../commonComponents/SchemaCard"; import { apiStatusCodes, storageKeys } from "../../config/CommonConstant"; import { pathRoutes } from "../../config/pathRoutes"; +import { AlertComponent } from "../AlertComponent"; import BreadCrumbs from "../BreadCrumbs"; - - -interface SchemaState { - schemaId: string; - issuerDid: string; - attributes: string[]; - createdDateTime: string; -} - -interface CredDefData { - credentialDefinitionId: string; - revocable: boolean; - schemaLedgerId: string; - tag: string; -} +import type { SchemaState, CredDefData } from "./interface"; const CredDefSelection = () => { const [schemaState, setSchemaState] = useState({ schemaName: '', version: '' }) @@ -75,7 +62,7 @@ const CredDefSelection = () => { { columnName: 'Revocable?' } ] - //Fetch all issued credential list + //Fetch credential definitions against schemaId const getCredDefs = async (schemaId: string) => { setLoading(true) const response = await getCredentialDefinitions(schemaId); @@ -135,7 +122,13 @@ const CredDefSelection = () => { Credential definitions - + { + setError(null) + }} + /> ) diff --git a/src/components/Issuance/EmailList.tsx b/src/components/Issuance/EmailList.tsx new file mode 100644 index 000000000..0f068787f --- /dev/null +++ b/src/components/Issuance/EmailList.tsx @@ -0,0 +1,13 @@ +'use client'; + +import ComingSoonImage from '../../assets/coming-soon.svg' +const EmailList = () => { + + return ( +
    + Centered Image +
    + ) +} + +export default EmailList diff --git a/src/components/Issuance/interface.ts b/src/components/Issuance/interface.ts new file mode 100644 index 000000000..33a937b31 --- /dev/null +++ b/src/components/Issuance/interface.ts @@ -0,0 +1,13 @@ +export interface SchemaState { + schemaId: string; + issuerDid: string; + attributes: string[]; + createdDateTime: string; +} + +export interface CredDefData { + credentialDefinitionId: string; + revocable: boolean; + schemaLedgerId: string; + tag: string; +} diff --git a/src/config/apiRoutes.ts b/src/config/apiRoutes.ts index 388885cb0..8fd63d15a 100644 --- a/src/config/apiRoutes.ts +++ b/src/config/apiRoutes.ts @@ -46,6 +46,7 @@ export const apiRoutes = { }, Issuance:{ getIssuedCredentials:'/issue-credentials', - getCredDefBySchemaId :'/schemas/credential-definitions' + getCredDefBySchemaId :'/schemas/credential-definitions', + getAllConnections:'/connections' } } diff --git a/src/pages/organizations/issued-credentials/schemas/cred-defs/connections/index.astro b/src/pages/organizations/issued-credentials/schemas/cred-defs/connections/index.astro new file mode 100644 index 000000000..1da4d2c0a --- /dev/null +++ b/src/pages/organizations/issued-credentials/schemas/cred-defs/connections/index.astro @@ -0,0 +1,8 @@ +--- +import LayoutSidebar from "../../../../../../app/LayoutSidebar.astro"; +import Connections from "../../../../../../components/Issuance/Connections"; +--- + + + + From f1a26d6a09f9d624e10836e26e452945fa24b5f4 Mon Sep 17 00:00:00 2001 From: "@nishad.shirsat" Date: Fri, 4 Aug 2023 19:46:13 +0530 Subject: [PATCH 7/9] Worked on the deno env deploy changes Signed-off-by: @nishad.shirsat --- .github/workflows/deploy.yml | 4 ++-- astro.config.mjs | 7 +++++++ src/api/Auth.ts | 7 ++++--- src/app/LayoutCommon.astro | 8 +++++++- src/config/SocketConfig.ts | 3 ++- src/config/envConfig.ts | 6 ++++++ src/env.d.ts | 7 +++++++ src/pages/authentication/sign-up.astro | 1 - src/pages/index.astro | 5 ++--- src/pages/server.ts | 1 + src/services/axiosIntercepter.ts | 9 ++++++++- 11 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 src/config/envConfig.ts create mode 100644 src/pages/server.ts diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 1f877cc6f..c3081c76d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: push: - branches: main + branches: deno-env-deploy pull_request: - branches: main + branches: deno-env-deploy jobs: deploy: diff --git a/astro.config.mjs b/astro.config.mjs index f16c5acef..063d3cff9 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -3,6 +3,7 @@ import { defineConfig } from 'astro/config'; import react from "@astrojs/react"; import sitemap from '@astrojs/sitemap'; import tailwind from '@astrojs/tailwind'; + const DEV_PORT = 3000; // https://astro.build/config @@ -31,3 +32,9 @@ export default defineConfig({ sitemap(), tailwind(), react()], adapter: Deno() }); + +if (typeof globalThis !== 'undefined' && typeof Deno !== 'undefined') { + globalThis.process ||= { + env: Deno.env.toObject() + } +} diff --git a/src/api/Auth.ts b/src/api/Auth.ts index 67a6e0162..574f0e281 100644 --- a/src/api/Auth.ts +++ b/src/api/Auth.ts @@ -4,6 +4,7 @@ import { number, string } from 'yup' import type { AxiosError } from 'axios' import CryptoJS from "crypto-js" import { apiRoutes } from '../config/apiRoutes' +import { envConfig } from '../config/envConfig' import { storageKeys } from '../config/CommonConstant' export interface UserSignUpData { @@ -125,7 +126,7 @@ export const addPasswordDetails = async(payload: AddPasswordDetails, email:strin } export const passwordEncryption = (password: string): string => { - const CRYPTO_PRIVATE_KEY: string = `${import.meta.env.PUBLIC_CRYPTO_PRIVATE_KEY}` + const CRYPTO_PRIVATE_KEY: string = `${envConfig.PUBLIC_CRYPTO_PRIVATE_KEY}` const encryptedPassword: string = CryptoJS.AES.encrypt(JSON.stringify(password), CRYPTO_PRIVATE_KEY).toString() return encryptedPassword } @@ -134,13 +135,13 @@ export const encryptData = (value: any): string => { if(typeof(value) !== 'string'){ value = JSON.stringify(value) } - const CRYPTO_PRIVATE_KEY: string = `${import.meta.env.PUBLIC_CRYPTO_PRIVATE_KEY}` + const CRYPTO_PRIVATE_KEY: string = `${envConfig.PUBLIC_CRYPTO_PRIVATE_KEY}` const convrtedValue: string = CryptoJS.AES.encrypt(value, CRYPTO_PRIVATE_KEY).toString() return convrtedValue } export const decryptData = (value: any): string => { - const CRYPTO_PRIVATE_KEY: string = `${import.meta.env.PUBLIC_CRYPTO_PRIVATE_KEY}` + const CRYPTO_PRIVATE_KEY: string = `${envConfig.PUBLIC_CRYPTO_PRIVATE_KEY}` const bytes = CryptoJS.AES.decrypt(value, CRYPTO_PRIVATE_KEY) var originalValue: string = bytes.toString(CryptoJS.enc.Utf8); return originalValue diff --git a/src/app/LayoutCommon.astro b/src/app/LayoutCommon.astro index 3e15b5556..d3b5654ad 100644 --- a/src/app/LayoutCommon.astro +++ b/src/app/LayoutCommon.astro @@ -6,7 +6,8 @@ import { SITE_TITLE } from './constants.js'; const { class: clazz } = Astro.props; -// import { ViewTransitions } from 'astro:transitions'; +const baseUrl = process.env.PUBLIC_BASE_URL || import.meta.env.PUBLIC_BASE_URL +const encryptKey = process.env.PUBLIC_CRYPTO_PRIVATE_KEY || import.meta.env.PUBLIC_CRYPTO_PRIVATE_KEY --- @@ -65,6 +66,11 @@ const { class: clazz } = Astro.props; import 'flowbite/dist/datepicker.js'; + + diff --git a/src/config/SocketConfig.ts b/src/config/SocketConfig.ts index f235a6469..2a5eef880 100644 --- a/src/config/SocketConfig.ts +++ b/src/config/SocketConfig.ts @@ -1,6 +1,7 @@ +import { envConfig } from "./envConfig" import io from "socket.io-client" -const SOCKET = io(`${import.meta.env.PUBLIC_BASE_URL}`, { +const SOCKET = io(`${envConfig.PUBLIC_BASE_URL}`, { reconnection: true, reconnectionDelay: 500, reconnectionAttempts: Infinity, diff --git a/src/config/envConfig.ts b/src/config/envConfig.ts new file mode 100644 index 000000000..6dadbbca4 --- /dev/null +++ b/src/config/envConfig.ts @@ -0,0 +1,6 @@ + +export const envConfig = { + PUBLIC_BASE_URL: globalThis.baseUrl, + PUBLIC_CRYPTO_PRIVATE_KEY: globalThis.encryptKey + +} \ No newline at end of file diff --git a/src/env.d.ts b/src/env.d.ts index 0703c7fec..4d7c87866 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -9,3 +9,10 @@ interface ImportMetaEnv { interface ImportMeta { readonly env: ImportMetaEnv; } + +declare global { + var baseUrl: string; + var encryptKey: string; +} + +export { }; \ No newline at end of file diff --git a/src/pages/authentication/sign-up.astro b/src/pages/authentication/sign-up.astro index 20f982792..8b74d92b8 100644 --- a/src/pages/authentication/sign-up.astro +++ b/src/pages/authentication/sign-up.astro @@ -6,4 +6,3 @@ import SignUpUser from '../../components/Authentication/SignUpUser' -../../components/Authentication/SignUpUser \ No newline at end of file diff --git a/src/pages/index.astro b/src/pages/index.astro index e646a3a46..464384a40 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,7 +1,6 @@ --- -import { asset, url } from '../lib/data.js'; -import { ViewTransitions } from 'astro:transitions'; -import { pathRoutes } from '../config/pathRoutes.js'; +// import { ViewTransitions } from 'astro:transitions'; +import { pathRoutes } from '../config/pathRoutes'; --- diff --git a/src/pages/server.ts b/src/pages/server.ts new file mode 100644 index 000000000..847573e6b --- /dev/null +++ b/src/pages/server.ts @@ -0,0 +1 @@ +import "https://deno.land/std@0.197.0/dotenv/load.ts"; diff --git a/src/services/axiosIntercepter.ts b/src/services/axiosIntercepter.ts index 9bf10662c..519db0ebf 100644 --- a/src/services/axiosIntercepter.ts +++ b/src/services/axiosIntercepter.ts @@ -1,9 +1,16 @@ import axios from 'axios' +import { envConfig } from '../config/envConfig'; import { pathRoutes } from '../config/pathRoutes'; + const instance = axios.create({ - baseURL: import.meta.env.PUBLIC_BASE_URL + baseURL: envConfig.PUBLIC_BASE_URL }) +instance.interceptors.request.use(async config => { + config.baseURL = globalThis.baseUrl; + return config; +}, error => Promise.reject(error)); + // Add a response interceptor instance.interceptors.response.use(function (response) { From 07cc8a61a97346e91c45a0e57c1a29fa146adeb5 Mon Sep 17 00:00:00 2001 From: Yogesh Pawar Date: Fri, 4 Aug 2023 19:58:00 +0530 Subject: [PATCH 8/9] feat: Implemented issue credential functionality --- src/api/Auth.ts | 9 +- src/api/issuance.ts | 20 +- src/components/Issuance/ConnectionList.tsx | 47 +-- src/components/Issuance/Connections.tsx | 58 +++- src/components/Issuance/CredDefSelection.tsx | 42 +-- src/components/Issuance/EmailList.tsx | 2 +- src/components/Issuance/Issuance.tsx | 267 ++++++++++++++++++ .../IssuedCrdentials.tsx | 34 +-- src/components/Issuance/SchemaSelection.tsx | 7 +- src/config/CommonConstant.ts | 7 +- src/config/apiRoutes.ts | 3 +- src/config/pathRoutes.ts | 3 +- .../issued-credentials/index.astro | 7 +- .../cred-defs/connections/issuance.astro | 8 + 14 files changed, 437 insertions(+), 77 deletions(-) create mode 100644 src/components/Issuance/Issuance.tsx rename src/components/{organization => Issuance}/IssuedCrdentials.tsx (75%) create mode 100644 src/pages/organizations/issued-credentials/schemas/cred-defs/connections/issuance.astro diff --git a/src/api/Auth.ts b/src/api/Auth.ts index 67a6e0162..2b5e12de1 100644 --- a/src/api/Auth.ts +++ b/src/api/Auth.ts @@ -147,8 +147,8 @@ export const decryptData = (value: any): string => { } export const setToLocalStorage = async (key: string, value: any) =>{ - const convrtedValue = await encryptData(value) - const setValue = await localStorage.setItem(key, convrtedValue as string) + const convertedValue = await encryptData(value) + const setValue = await localStorage.setItem(key, convertedValue as string) return true } @@ -157,3 +157,8 @@ export const getFromLocalStorage = async (key: string) =>{ const convertedValue = value ? await decryptData(value) : '' return convertedValue } + +export const removeFromLocalStorage = async (key: string) => { + await localStorage.removeItem(key); + return true; +}; diff --git a/src/api/issuance.ts b/src/api/issuance.ts index fe0e63a8b..4157b0fa4 100644 --- a/src/api/issuance.ts +++ b/src/api/issuance.ts @@ -2,7 +2,7 @@ import type { IssueCredential } from '../common/enums'; import { apiRoutes } from '../config/apiRoutes'; import { storageKeys } from '../config/CommonConstant'; import { getHeaderConfigs } from '../config/GetHeaderConfigs'; -import { axiosGet } from '../services/apiRequests'; +import { axiosGet, axiosPost } from '../services/apiRequests'; import { getFromLocalStorage } from './Auth'; export const getIssuedCredentials = async (state: IssueCredential) => { @@ -37,3 +37,21 @@ export const getCredentialDefinitions = async (schemaId: string) => { return err?.message; } }; + + +export const issueCredential = async (data: object) => { + const url = apiRoutes.Issuance.issueCredential; + const payload = data; + const axiosPayload = { + url, + payload, + config: await getHeaderConfigs(), + }; + + try { + return await axiosPost(axiosPayload); + } catch (error) { + const err = error as Error; + return err?.message; + } +}; diff --git a/src/components/Issuance/ConnectionList.tsx b/src/components/Issuance/ConnectionList.tsx index 7212a2410..4014e97d0 100644 --- a/src/components/Issuance/ConnectionList.tsx +++ b/src/components/Issuance/ConnectionList.tsx @@ -1,15 +1,16 @@ 'use client'; import type { AxiosResponse } from "axios"; -import { ChangeEvent, useEffect, useState } from "react"; +import { 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"; import { AlertComponent } from "../AlertComponent"; +const ConnectionList = (props: { selectConnection: (connections: TableData[]) => void; }) => { + -const ConnectionList = () => { const [connectionList, setConnectionList] = useState([]) const [selectedConnectionList, setSelectedConnectionList] = useState([]) @@ -36,7 +37,7 @@ const ConnectionList = () => { return { data: [{ data:
    - ) => { + ) => { const inputElement = event.target as HTMLInputElement; selectConnection(userName, connectionId, inputElement.checked) }} @@ -63,23 +64,30 @@ const ConnectionList = () => { { columnName: 'Connection ID' } ] - const selectedConnectionHeader = [ - { columnName: 'User' }, - { columnName: 'Connection ID' } - ] const selectConnection = (user: string, connectionId: string, checked: boolean) => { - if (checked) { - setSelectedConnectionList((prevList) => [...prevList, { + + // Needed for multiple connection selection + // setSelectedConnectionList((prevList) => [...prevList, { + // data: [ + // { + // data: user, + // }, { + // data: connectionId, + // }] + // }] + // ) + + // It is for single connection selection + setSelectedConnectionList([{ data: [ { data: user, }, { data: connectionId, }] - }] - ) + }]) } else { setSelectedConnectionList((prevList) => prevList.filter((connection) => connection.data[1].data !== connectionId) @@ -87,9 +95,13 @@ const ConnectionList = () => { } } + useEffect(() => { + props.selectConnection(selectedConnectionList); + + }, [selectedConnectionList]) + return (
    -

    Connection List @@ -104,19 +116,8 @@ const ConnectionList = () => { />
    -
    -
    -

    - Selected Users -

    -
    -
    - -
    -

    ) } diff --git a/src/components/Issuance/Connections.tsx b/src/components/Issuance/Connections.tsx index 98597e9f8..d99586731 100644 --- a/src/components/Issuance/Connections.tsx +++ b/src/components/Issuance/Connections.tsx @@ -1,10 +1,35 @@ 'use client'; +import { Button } from "flowbite-react"; +import { useState } from "react"; +import { setToLocalStorage } from "../../api/Auth"; +import DataTable from "../../commonComponents/datatable"; +import type { TableData } from "../../commonComponents/datatable/interface"; +import { storageKeys } from "../../config/CommonConstant"; +import { pathRoutes } from "../../config/pathRoutes"; import BreadCrumbs from "../BreadCrumbs"; import ConnectionList from "./ConnectionList"; import EmailList from "./EmailList"; const Connections = () => { + const [selectedConnectionList, setSelectedConnectionList] = useState([]) + + const selectedConnectionHeader = [ + { columnName: 'User' }, + { columnName: 'Connection ID' } + ] + + const selectConnection = (connections: TableData[]) => { + setSelectedConnectionList(connections) + } + + const continueToIssue = async () => { + const selectedConnections = selectedConnectionList.map(ele =>{ + return {userName: ele.data[0].data, connectionId:ele.data[1].data} + }) + await setToLocalStorage(storageKeys.SELECTED_USER, selectedConnections) + window.location.href = `${pathRoutes.organizations.Issuance.issuance}` + } return (
    @@ -23,14 +48,37 @@ const Connections = () => {
    -
    - +
    +
    -
    - +
    +
    - +
    +

    + Selected Users +

    +
    +
    + + {selectedConnectionList.length ?
    + +
    + : ''} +
    ) diff --git a/src/components/Issuance/CredDefSelection.tsx b/src/components/Issuance/CredDefSelection.tsx index f92cb7d24..126bf6986 100644 --- a/src/components/Issuance/CredDefSelection.tsx +++ b/src/components/Issuance/CredDefSelection.tsx @@ -3,17 +3,18 @@ import type { AxiosResponse } from "axios"; import { Spinner } from "flowbite-react"; import { useEffect, useState } from "react"; -import { getFromLocalStorage } from "../../api/Auth"; +import { getFromLocalStorage, setToLocalStorage } from "../../api/Auth"; import { getCredentialDefinitions } from "../../api/issuance"; import { getSchemaById } from "../../api/Schema"; -import DataTable from "../../commonComponents/datatable"; -import type { TableData } from "../../commonComponents/datatable/interface"; import SchemaCard from "../../commonComponents/SchemaCard"; import { apiStatusCodes, storageKeys } from "../../config/CommonConstant"; import { pathRoutes } from "../../config/pathRoutes"; -import { AlertComponent } from "../AlertComponent"; +import { dateConversion } from "../../utils/DateConversion"; import BreadCrumbs from "../BreadCrumbs"; +import { AlertComponent } from "../AlertComponent"; import type { SchemaState, CredDefData } from "./interface"; +import type { TableData } from "../../commonComponents/datatable/interface"; +import DataTable from "../../commonComponents/datatable"; const CredDefSelection = () => { const [schemaState, setSchemaState] = useState({ schemaName: '', version: '' }) @@ -24,22 +25,23 @@ const CredDefSelection = () => { const [schemaDetailsState, setSchemaDetailsState] = useState({ schemaId: '', issuerDid: '', attributes: [], createdDateTime: '' }) useEffect(() => { - if (window?.location?.search) { - const urlParams = new URLSearchParams(window.location.search); - const schemaIdParam = urlParams.get('schemaId'); - if (schemaIdParam) { - getSchemaDetails(schemaIdParam) - getCredDefs(schemaIdParam) - const parts = schemaIdParam.split(":"); - const schemaName = parts[2]; - const version = parts[3]; - setSchemaState({ schemaName, version }) - } else { - setSchemaState({ schemaName: '', version: '' }) - } - } + getSchemaAndCredDef() }, []); + const getSchemaAndCredDef = async () => { + const schemaId = await getFromLocalStorage(storageKeys.SCHEMA_ID) + if (schemaId) { + getSchemaDetails(schemaId) + getCredDefs(schemaId) + const parts = schemaId.split(":"); + const schemaName = parts[2]; + const version = parts[3]; + setSchemaState({ schemaName, version }) + } else { + setSchemaState({ schemaName: '', version: '' }) + } + } + const getSchemaDetails = async (schemaId: string) => { setSchemaLoader(true) const orgId = await getFromLocalStorage(storageKeys.ORG_ID) @@ -88,12 +90,14 @@ const CredDefSelection = () => { setLoading(false) } + const schemaSelectionCallback = () => { } - const selectCredDef = (credDefId: string | null | undefined) => { + const selectCredDef = async(credDefId: string | null | undefined) => { if (credDefId) { + await setToLocalStorage(storageKeys.CRED_DEF_ID, credDefId) window.location.href = `${pathRoutes.organizations.Issuance.connections}` } } diff --git a/src/components/Issuance/EmailList.tsx b/src/components/Issuance/EmailList.tsx index 0f068787f..66cb5ac28 100644 --- a/src/components/Issuance/EmailList.tsx +++ b/src/components/Issuance/EmailList.tsx @@ -5,7 +5,7 @@ const EmailList = () => { return (
    - Centered Image + Coming soon
    ) } diff --git a/src/components/Issuance/Issuance.tsx b/src/components/Issuance/Issuance.tsx new file mode 100644 index 000000000..cda2d01b6 --- /dev/null +++ b/src/components/Issuance/Issuance.tsx @@ -0,0 +1,267 @@ +'use client'; + +import type { AxiosResponse } from "axios"; +import { Alert, Button, Card, Spinner } from "flowbite-react"; +import { useEffect, useState } from "react"; +import { getFromLocalStorage, removeFromLocalStorage } from "../../api/Auth"; +import { getCredDeffById, getSchemaById } from "../../api/Schema"; +import { apiStatusCodes, storageKeys } from "../../config/CommonConstant"; +import BreadCrumbs from "../BreadCrumbs"; +import { Formik, Form, Field, ErrorMessage } from "formik"; +import * as Yup from 'yup'; +import { issueCredential } from "../../api/issuance"; +import { pathRoutes } from "../../config/pathRoutes"; + +interface SchemaDetails { + schemaName: string, + version: string, + schemaId: string, + credDefId: string +} + +interface SelectedUsers { + userName: string, + connectionId: string +} + +interface Attributes { + name: string, + value: string +} +interface IssuanceFormPayload { + userName: string, + connectionId: string, + attributes: Attributes[], + credentialDefinitionId: string, + orgId: number +} + +const IssueCred = () => { + const [schemaLoader, setSchemaLoader] = useState(true) + const [userLoader, setUserLoader] = useState(true) + const [schemaDetails, setSchemaDetails] = useState({ + schemaName: '', version: '', schemaId: '', credDefId: '' + }) + const [issuanceFormPayload, setIssuanceFormPayload] = useState([]) + const [issuanceLoader, setIssuanceLoader] = useState(false) + const [failure, setFailure] = useState(null) + + useEffect(() => { + getSchemaAndUsers() + }, []) + + const getSchemaAndUsers = async () => { + const credDefId = await getFromLocalStorage(storageKeys.CRED_DEF_ID) + const schemaId = await getFromLocalStorage(storageKeys.SCHEMA_ID) + const orgId = await getFromLocalStorage(storageKeys.ORG_ID) + + createSchemaPayload(schemaId, credDefId) + setUserLoader(true) + const selectedUsers = await getSelectedUsers() + const attributes = await getSchemaDetails(schemaId, Number(orgId)) + if (attributes && attributes.length) { + createIssuanceForm(selectedUsers, attributes, credDefId, Number(orgId)) + } else { + setFailure('Attributes are not available') + } + + } + + const createIssuanceForm = (selectedUsers: SelectedUsers[], attributes: string[], credDefId: string, orgId: number) => { + const attrObj = attributes.map(attr => ({ name: attr, value: '' })) + const issuancePayload = selectedUsers.map(user => { + return { + userName: user.userName, connectionId: user.connectionId, + attributes: attrObj, credentialDefinitionId: credDefId, orgId + } + }) + setIssuanceFormPayload(issuancePayload) + setUserLoader(false) + } + + const getSchemaDetails = async (schemaId: string, orgId: number): Promise => { + const schemaDetails = await getSchemaById(schemaId, orgId) + const { data } = schemaDetails as AxiosResponse + + if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { + if (data.data.response) { + const { response } = data.data + return response?.schema?.attrNames + } + } + return null; + + } + + const createSchemaPayload = async (schemaId: string, credDefId: string) => { + if (schemaId) { + setSchemaLoader(true) + const parts = schemaId.split(":"); + const schemaName = parts[2]; + const version = parts[3]; + setSchemaDetails({ schemaName, version, schemaId, credDefId }) + setSchemaLoader(false) + } + } + + const getSelectedUsers = async (): Promise => { + const selectedUsers = await getFromLocalStorage(storageKeys.SELECTED_USER) + return JSON.parse(selectedUsers) + } + + + const validationSchema = Yup.object().shape({ + attributes: Yup.array().of( + Yup.object().shape({ + value: Yup.string().required(`This field is required`), + }) + ), + }); + + const handleSubmit = async (values: IssuanceFormPayload) => { + setIssuanceLoader(true) + const issueCredRes = await issueCredential(values) + const { data } = issueCredRes as AxiosResponse + setIssuanceLoader(false) + + if (data?.statusCode === apiStatusCodes.API_STATUS_CREATED) { + goToIssueCredList() + } else { + setFailure(issueCredRes as string) + } + }; + + const goToIssueCredList = () => { + removeFromLocalStorage(storageKeys.SELECTED_USER) + removeFromLocalStorage(storageKeys.SCHEMA_ID) + removeFromLocalStorage(storageKeys.CRED_DEF_ID) + window.location.href = `${pathRoutes.organizations.issuedCredentials}` + } + + return ( +
    +
    + +

    + Issuance +

    +
    + {!schemaLoader ? + +
    +
    +
    + {schemaDetails.schemaName} +
    +

    + Version: {schemaDetails.version} +

    +
    +
    +
    +

    + Schema ID: {schemaDetails.schemaId} +

    +

    + Credential Definition: {schemaDetails.credDefId} +

    +
    +
    + : ''} + {userLoader ? +
    + +
    + : <>{ + issuanceFormPayload.length ? + issuanceFormPayload.map(user => + + {({ values }) => ( +
    + +
    +
    + {user.userName} +
    + {/* Needed for multiple users issuance */} + {/*
    + +
    */} +
    +
    +
    + Connection Id: +
    + {user.connectionId} +
    +

    Attributes

    +
    +
    + + {values.attributes.map((attr, index) => ( +
    +
    + + +
    +
    +
    + +
    +
    + ))} +
    +
    +
    + { + failure && +
    + setFailure(null)} + > + +

    + {failure} +

    +
    +
    +
    + } +
    + +
    +
    + )} +
    ) + : '' + } + } +
    + ) +} + +export default IssueCred diff --git a/src/components/organization/IssuedCrdentials.tsx b/src/components/Issuance/IssuedCrdentials.tsx similarity index 75% rename from src/components/organization/IssuedCrdentials.tsx rename to src/components/Issuance/IssuedCrdentials.tsx index 8b8273f7e..b296ae4b7 100644 --- a/src/components/organization/IssuedCrdentials.tsx +++ b/src/components/Issuance/IssuedCrdentials.tsx @@ -30,26 +30,28 @@ const CredentialList = () => { //Fetch all issued credential list const getIssuedCredDefs = async () => { setLoading(true) - const response = await getIssuedCredentials(IssueCredential.done); + const response = await getIssuedCredentials(IssueCredential.credentialIssued); const { data } = response as AxiosResponse - if (data?.statusCode === apiStatusCodes.API_STATUS_CREATED) { + if (data?.statusCode === apiStatusCodes.API_STATUS_SUCCESS) { const credentialList = data?.data?.map((issuedCredential: IssuedCredential) => { const schemaName = issuedCredential.metadata["_anoncreds/credential"].schemaId ? issuedCredential.metadata["_anoncreds/credential"].schemaId.split(':').slice(2).join(':') : 'Not available' - return [{ data: issuedCredential.connectionId ? issuedCredential.connectionId : 'Not available' }, { data: schemaName }, { data: dateConversion(issuedCredential.updatedAt) }, - { - data: - {issuedCredential.state.replace(/_/g, ' ').replace(/\w\S*/g, (word: string) => word.charAt(0).toUpperCase() + word.substring(1).toLowerCase())} - - }, { - data: issuedCredential?.isRevocable ? - : Non revocable - }]; + return { + data: [{ data: issuedCredential.connectionId ? issuedCredential.connectionId : 'Not available' }, { data: schemaName }, { data: dateConversion(issuedCredential.updatedAt) }, + { + data: + {issuedCredential.state.replace(/_/g, ' ').replace(/\w\S*/g, (word: string) => word.charAt(0).toUpperCase() + word.substring(1).toLowerCase())} + + }, { + data: issuedCredential?.isRevocable ? + : Non revocable + }] + }; }) setIssuedCredList(credentialList) diff --git a/src/components/Issuance/SchemaSelection.tsx b/src/components/Issuance/SchemaSelection.tsx index 1ec4c759d..5adec0144 100644 --- a/src/components/Issuance/SchemaSelection.tsx +++ b/src/components/Issuance/SchemaSelection.tsx @@ -1,12 +1,15 @@ 'use client'; +import { setToLocalStorage } from "../../api/Auth"; +import { storageKeys } from "../../config/CommonConstant"; import { pathRoutes } from "../../config/pathRoutes"; import SchemaList from "../Resources/Schema/SchemasList"; const SchemaSelection = () => { - const schemaSelectionCallback = (schemaId: string) => { - window.location.href = `${pathRoutes.organizations.Issuance.credDef}?schemaId=${schemaId}` + const schemaSelectionCallback = async (schemaId: string) => { + await setToLocalStorage(storageKeys.SCHEMA_ID, schemaId) + window.location.href = `${pathRoutes.organizations.Issuance.credDef}` } return ( diff --git a/src/config/CommonConstant.ts b/src/config/CommonConstant.ts index e651bfabf..1639e5cc5 100644 --- a/src/config/CommonConstant.ts +++ b/src/config/CommonConstant.ts @@ -21,5 +21,8 @@ export const storageKeys = { ORG_ROLES: 'org_roles', USER_PROFILE : 'user_profile', PERMISSIONS: 'user_permissions', - USER_EMAIL: 'user_email' -} \ No newline at end of file + USER_EMAIL: 'user_email', + SELECTED_USER:'selected_user', + SCHEMA_ID:'schema_id', + CRED_DEF_ID:'cred_def_id' +} diff --git a/src/config/apiRoutes.ts b/src/config/apiRoutes.ts index 8fd63d15a..ca4315736 100644 --- a/src/config/apiRoutes.ts +++ b/src/config/apiRoutes.ts @@ -47,6 +47,7 @@ export const apiRoutes = { Issuance:{ getIssuedCredentials:'/issue-credentials', getCredDefBySchemaId :'/schemas/credential-definitions', - getAllConnections:'/connections' + getAllConnections:'/connections', + issueCredential:'/issue-credentials/create-offer' } } diff --git a/src/config/pathRoutes.ts b/src/config/pathRoutes.ts index c8fed3a19..fbf9df02f 100644 --- a/src/config/pathRoutes.ts +++ b/src/config/pathRoutes.ts @@ -22,7 +22,8 @@ export const pathRoutes = { Issuance: { schema: '/organizations/issued-credentials/schemas', credDef:'/organizations/issued-credentials/schemas/cred-defs', - connections:'/organizations/issued-credentials/schemas/cred-defs/connections' + connections:'/organizations/issued-credentials/schemas/cred-defs/connections', + issuance:'/organizations/issued-credentials/schemas/cred-defs/connections/issuance' }, }, ecosystems: { diff --git a/src/pages/organizations/issued-credentials/index.astro b/src/pages/organizations/issued-credentials/index.astro index 01c43aed7..700ae5bb1 100644 --- a/src/pages/organizations/issued-credentials/index.astro +++ b/src/pages/organizations/issued-credentials/index.astro @@ -1,9 +1,8 @@ --- -import LayoutSidebar from "../../../app/LayoutSidebar.astro"; -import CredentialList from "../../../components/organization/IssuedCrdentials"; - +import LayoutSidebar from '../../../app/LayoutSidebar.astro'; +import CredentialList from '../../../components/Issuance/IssuedCrdentials'; --- - + diff --git a/src/pages/organizations/issued-credentials/schemas/cred-defs/connections/issuance.astro b/src/pages/organizations/issued-credentials/schemas/cred-defs/connections/issuance.astro new file mode 100644 index 000000000..ebb605d43 --- /dev/null +++ b/src/pages/organizations/issued-credentials/schemas/cred-defs/connections/issuance.astro @@ -0,0 +1,8 @@ +--- +import LayoutSidebar from "../../../../../../app/LayoutSidebar.astro"; +import IssueCred from "../../../../../../components/Issuance/Issuance"; +--- + + + + From a6d1abacca92508c424ef797d954254e54ebfdbb Mon Sep 17 00:00:00 2001 From: "@nishad.shirsat" Date: Fri, 4 Aug 2023 20:24:06 +0530 Subject: [PATCH 9/9] Changed github workflow to main branch Signed-off-by: @nishad.shirsat --- .github/workflows/deploy.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index c3081c76d..1f877cc6f 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,9 +1,9 @@ name: Deploy on: push: - branches: deno-env-deploy + branches: main pull_request: - branches: deno-env-deploy + branches: main jobs: deploy: