Skip to content

Commit

Permalink
chore: update tables ui
Browse files Browse the repository at this point in the history
  • Loading branch information
Oleksandr Raspopov committed Dec 24, 2024
1 parent 9f5b19b commit d1c706d
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 94 deletions.
14 changes: 10 additions & 4 deletions ui/src/components/connections/CredentialsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,17 @@ export function CredentialsTable({ userID }: { userID: string }) {
dataIndex: "schemaType",
ellipsis: { showTitle: false },
key: "schemaType",
render: (schemaType: Credential["schemaType"]) => (
<Tooltip placement="topLeft" title={schemaType}>
<Typography.Text strong>{schemaType}</Typography.Text>
</Tooltip>
render: (schemaType: Credential["schemaType"], credential: Credential) => (
<Typography.Link
onClick={() =>
navigate(generatePath(ROUTES.credentialDetails.path, { credentialID: credential.id }))
}
strong
>
{schemaType}
</Typography.Link>
),

sorter: ({ schemaType: a }, { schemaType: b }) => a.localeCompare(b),
title: "Credential",
},
Expand Down
13 changes: 9 additions & 4 deletions ui/src/components/credentials/CredentialsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,15 @@ export function CredentialsTable() {
dataIndex: "schemaType",
ellipsis: { showTitle: false },
key: "schemaType",
render: (schemaType: Credential["schemaType"]) => (
<Tooltip placement="topLeft" title={schemaType}>
<Typography.Text strong>{schemaType}</Typography.Text>
</Tooltip>
render: (schemaType: Credential["schemaType"], credential: Credential) => (
<Typography.Link
onClick={() =>
navigate(generatePath(ROUTES.credentialDetails.path, { credentialID: credential.id }))
}
strong
>
{schemaType}
</Typography.Link>
),
sorter: {
multiple: 1,
Expand Down
12 changes: 7 additions & 5 deletions ui/src/components/credentials/LinksTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import {
Table,
TableColumnsType,
Tag,
Tooltip,
Typography,
} from "antd";

Expand Down Expand Up @@ -97,10 +96,13 @@ export function LinksTable() {
dataIndex: "schemaType",
ellipsis: true,
key: "schemaType",
render: (schemaType: Link["schemaType"]) => (
<Tooltip placement="topLeft" title={schemaType}>
<Typography.Text strong>{schemaType}</Typography.Text>
</Tooltip>
render: (schemaType: Link["schemaType"], link: Link) => (
<Typography.Link
onClick={() => navigate(generatePath(ROUTES.linkDetails.path, { linkID: link.id }))}
strong
>
{schemaType}
</Typography.Link>
),
sorter: ({ schemaType: a }, { schemaType: b }) => a.localeCompare(b),
title: "Credential",
Expand Down
42 changes: 37 additions & 5 deletions ui/src/components/identities/IdentitiesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ import {
Table,
TableColumnsType,
Tag,
Tooltip,
Typography,
} from "antd";
import { useCallback, useEffect, useState } from "react";
import { generatePath, useNavigate, useSearchParams } from "react-router-dom";
import IconIssuers from "src/assets/icons/building-08.svg?react";
import IconCheckMark from "src/assets/icons/check.svg?react";
import IconCopy from "src/assets/icons/copy-01.svg?react";
import IconDots from "src/assets/icons/dots-vertical.svg?react";
import IconInfoCircle from "src/assets/icons/info-circle.svg?react";
import IconPlus from "src/assets/icons/plus.svg?react";
Expand Down Expand Up @@ -81,9 +84,18 @@ export function IdentitiesTable({ handleAddIdentity }: { handleAddIdentity: () =
dataIndex: "displayName",
key: "displayName",
render: (displayName: Identity["displayName"], identity: Identity) => (
<Typography.Text strong>
<Typography.Link
onClick={() =>
navigate(
generatePath(ROUTES.identityDetails.path, {
identityID: identity.identifier,
})
)
}
strong
>
{displayName || formatIdentifier(identity.identifier, { short: true })}
</Typography.Text>
</Typography.Link>
),
sorter: (a, b) =>
(a.displayName || a.identifier).localeCompare(b.displayName || b.identifier),
Expand All @@ -93,24 +105,44 @@ export function IdentitiesTable({ handleAddIdentity }: { handleAddIdentity: () =
dataIndex: "identifier",
key: "identifier",
render: (identifier: Identity["identifier"]) => (
<Typography.Text strong>{formatIdentifier(identifier)}</Typography.Text>
<Tooltip title={identifier}>
<Typography.Text
copyable={{
icon: [<IconCopy key={0} />, <IconCheckMark key={1} />],
}}
ellipsis={{
suffix: identifier.slice(-5),
}}
>
{identifier}
</Typography.Text>
</Tooltip>
),
sorter: ({ identifier: a }, { identifier: b }) => a.localeCompare(b),
title: "DID",
},
{
dataIndex: "credentialStatusType",
key: "credentialStatusType",
render: (credentialStatusType: Identity["credentialStatusType"]) => (
<Typography.Text>{credentialStatusType}</Typography.Text>
),
sorter: ({ identifier: a }, { identifier: b }) => a.localeCompare(b),
title: "Credential status",
},
{
dataIndex: "blockchain",
key: "blockchain",
render: (blockchain: Identity["blockchain"]) => (
<Typography.Text strong>{blockchain}</Typography.Text>
<Typography.Text>{blockchain}</Typography.Text>
),
sorter: ({ blockchain: a }, { blockchain: b }) => a.localeCompare(b),
title: "Blockchain",
},
{
dataIndex: "network",
key: "network",
render: (network: Identity["network"]) => <Typography.Text strong>{network}</Typography.Text>,
render: (network: Identity["network"]) => <Typography.Text>{network}</Typography.Text>,
sorter: ({ network: a }, { network: b }) => a.localeCompare(b),
title: "Network",
},
Expand Down
113 changes: 47 additions & 66 deletions ui/src/components/identities/Identity.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
import { App, Button, Card, Divider, Flex, Form, Input, Space } from "antd";
import { App, Button, Card, Divider, Flex, Form, Input, Space, Typography } from "antd";
import { useCallback, useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { useIdentityContext } from "../../contexts/Identity";

import { getIdentity, updateIdentityDisplayName } from "src/adapters/api/identities";
import { IdentityDetailsFormData } from "src/adapters/parsers/view";
import CheckIcon from "src/assets/icons/check.svg?react";
import EditIcon from "src/assets/icons/edit-02.svg?react";
import CloseIcon from "src/assets/icons/x-close.svg?react";
import { IdentityAuthCredentials } from "src/components/identities/IdentityAuthCredentials";
import { Detail } from "src/components/shared/Detail";
import { EditModal } from "src/components/shared/EditModal";
import { ErrorResult } from "src/components/shared/ErrorResult";
import { LoadingResult } from "src/components/shared/LoadingResult";
import { SiderLayoutContent } from "src/components/shared/SiderLayoutContent";
import { useEnvContext } from "src/contexts/Env";
import { AppError, IdentityDetails } from "src/domain";
import {
AsyncTask,
hasAsyncTaskFailed,
isAsyncTaskDataAvailable,
isAsyncTaskStarting,
} from "src/utils/async";
import { AsyncTask, hasAsyncTaskFailed, isAsyncTaskStarting } from "src/utils/async";
import { isAbortedError, makeRequestAbortable } from "src/utils/browser";
import { IDENTITY_DETAILS, VALUE_REQUIRED } from "src/utils/constants";
import { formatIdentifier } from "src/utils/forms";
Expand All @@ -29,9 +23,9 @@ export function Identity() {
const [identity, setIdentity] = useState<AsyncTask<IdentityDetails, AppError>>({
status: "pending",
});
const { fetchIdentities, identityList } = useIdentityContext();

const [displayNameEditable, setDisplayNameEditable] = useState(false);
const [isEditModalOpen, setIsEditModalOpen] = useState(false);

const { message } = App.useApp();
const [form] = Form.useForm<IdentityDetailsFormData>();

Expand Down Expand Up @@ -70,27 +64,16 @@ export function Identity() {
return <ErrorResult error="No identifier provided." />;
}

const handleEditDisplayName = (formValues: IdentityDetailsFormData) => {
const isUnique =
isAsyncTaskDataAvailable(identityList) &&
!identityList.data.some(
(identity) =>
identity.identifier !== identifier && identity.displayName === formValues.displayName
);

if (!isUnique) {
return void message.error(`${formValues.displayName} already exists`);
}

return void updateIdentityDisplayName({
displayName: formValues.displayName.trim(),
const handleEdit = () => {
const { displayName } = form.getFieldsValue();
void updateIdentityDisplayName({
displayName,
env,
identifier,
}).then((response) => {
setIsEditModalOpen(false);
if (response.success) {
void fetchIdentity().then(() => {
setDisplayNameEditable(false);
makeRequestAbortable(fetchIdentities);
void message.success("Identity edited successfully");
});
} else {
Expand Down Expand Up @@ -130,44 +113,19 @@ export function Identity() {
<>
<Card
className="centered"
styles={{ header: { border: "none" } }}
title={
<Flex align="center" gap={8} style={{ paddingTop: "24px" }}>
{displayNameEditable ? (
<Form
form={form}
initialValues={{ displayName: identity.data.displayName }}
onFinish={handleEditDisplayName}
style={{ width: "100%" }}
>
<Flex gap={16}>
<Form.Item
name="displayName"
rules={[{ message: VALUE_REQUIRED, required: true }]}
style={{ marginBottom: 0, width: "50%" }}
>
<Input placeholder="Enter name" />
</Form.Item>
<Flex gap={8}>
<Button
icon={<CloseIcon />}
onClick={() => setDisplayNameEditable(false)}
/>
<Button htmlType="submit" icon={<CheckIcon />} onClick={() => {}} />
</Flex>
</Flex>
</Form>
) : (
<>
{identity.data.displayName}
<Button
icon={<EditIcon />}
onClick={() => setDisplayNameEditable(true)}
size="small"
type="text"
/>
</>
)}
<Flex align="center" gap={8} justify="space-between">
<Typography.Text style={{ fontWeight: 600 }}>
{identity.data.displayName}
</Typography.Text>
<Flex gap={8}>
<Button
icon={<EditIcon />}
onClick={() => setIsEditModalOpen(true)}
style={{ flexShrink: 0 }}
type="text"
/>
</Flex>
</Flex>
}
>
Expand Down Expand Up @@ -195,8 +153,31 @@ export function Identity() {
<Divider />

{identity.data.authCredentialsIDs.length && (
<IdentityAuthCredentials IDs={identity.data.authCredentialsIDs} />
<IdentityAuthCredentials
identityID={identifier}
IDs={identity.data.authCredentialsIDs}
/>
)}

<EditModal
onClose={() => setIsEditModalOpen(false)}
onSubmit={handleEdit}
open={isEditModalOpen}
title="Edit identity"
>
<Form
form={form}
initialValues={{ displayName: identity.data.displayName }}
layout="vertical"
>
<Form.Item
name="displayName"
rules={[{ message: VALUE_REQUIRED, required: true }]}
>
<Input placeholder="Enter name" />
</Form.Item>
</Form>
</EditModal>
</>
);
}
Expand Down
14 changes: 9 additions & 5 deletions ui/src/components/identities/IdentityAuthCredentials.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,21 @@ import { CredentialRevokeModal } from "src/components/shared/CredentialRevokeMod
import { TableCard } from "src/components/shared/TableCard";

import { useEnvContext } from "src/contexts/Env";
import { useIdentityContext } from "src/contexts/Identity";
import { AppError, AuthCredential } from "src/domain";
import { ROUTES } from "src/routes";
import { AsyncTask, isAsyncTaskDataAvailable, isAsyncTaskStarting } from "src/utils/async";
import { isAbortedError, makeRequestAbortable } from "src/utils/browser";
import { DOTS_DROPDOWN_WIDTH, ISSUE_DATE, REVOCATION, REVOKE } from "src/utils/constants";
import { formatDate } from "src/utils/forms";

export function IdentityAuthCredentials({ IDs }: { IDs: Array<string> }) {
export function IdentityAuthCredentials({
identityID,
IDs,
}: {
IDs: Array<string>;
identityID: string;
}) {
const env = useEnvContext();
const { identifier } = useIdentityContext();
const navigate = useNavigate();

const [credentials, setCredentials] = useState<AsyncTask<AuthCredential[], AppError>>({
Expand All @@ -57,7 +61,7 @@ export function IdentityAuthCredentials({ IDs }: { IDs: Array<string> }) {

const response = await getAuthCredentialsByIDs({
env,
identifier,
identifier: identityID,
IDs,
signal,
});
Expand All @@ -74,7 +78,7 @@ export function IdentityAuthCredentials({ IDs }: { IDs: Array<string> }) {
}
}
},
[env, identifier, IDs]
[env, identityID, IDs]
);

const tableColumns: TableColumnsType<AuthCredential> = [
Expand Down
Loading

0 comments on commit d1c706d

Please sign in to comment.