Skip to content

Commit

Permalink
Node Categories (#99)
Browse files Browse the repository at this point in the history
* Add categories to nodes

* Update Header.tsx

* Add labels to txn listing
  • Loading branch information
tubarao312 authored Mar 12, 2024
1 parent 2c119f6 commit 2febd5b
Show file tree
Hide file tree
Showing 13 changed files with 407 additions and 19 deletions.
125 changes: 123 additions & 2 deletions src/api/labels/labels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,26 @@
* OpenAPI spec version: 1.0
*/
import {
useMutation
useMutation,
useQuery
} from 'react-query'
import type {
MutationFunction,
UseMutationOptions
QueryFunction,
QueryKey,
UseMutationOptions,
UseQueryOptions,
UseQueryResult
} from 'react-query'
import type {
GetCategory200
} from '../model/getCategory200'
import type {
GetCategoryBody
} from '../model/getCategoryBody'
import type {
GetLabels200
} from '../model/getLabels200'
import type {
SearchLabels200
} from '../model/searchLabels200'
Expand All @@ -22,6 +36,64 @@ import { instance } from '.././instance';



/**
* Get labels for an address
*/
export const getLabels = (
address: string,
signal?: AbortSignal
) => {


return instance<GetLabels200>(
{url: `/addresses/${address}/labels`, method: 'GET', signal
},
);
}


export const getGetLabelsQueryKey = (address: string,) => {
return [`/addresses/${address}/labels`] as const;
}


export const getGetLabelsQueryOptions = <TData = Awaited<ReturnType<typeof getLabels>>, TError = unknown>(address: string, options?: { query?:UseQueryOptions<Awaited<ReturnType<typeof getLabels>>, TError, TData>, }
) => {

const {query: queryOptions} = options ?? {};

const queryKey = queryOptions?.queryKey ?? getGetLabelsQueryKey(address);



const queryFn: QueryFunction<Awaited<ReturnType<typeof getLabels>>> = ({ signal }) => getLabels(address, signal);





return { queryKey, queryFn, enabled: !!(address), ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof getLabels>>, TError, TData> & { queryKey: QueryKey }
}

export type GetLabelsQueryResult = NonNullable<Awaited<ReturnType<typeof getLabels>>>
export type GetLabelsQueryError = unknown

export const useGetLabels = <TData = Awaited<ReturnType<typeof getLabels>>, TError = unknown>(
address: string, options?: { query?:UseQueryOptions<Awaited<ReturnType<typeof getLabels>>, TError, TData>, }

): UseQueryResult<TData, TError> & { queryKey: QueryKey } => {

const queryOptions = getGetLabelsQueryOptions(address,options)

const query = useQuery(queryOptions) as UseQueryResult<TData, TError> & { queryKey: QueryKey };

query.queryKey = queryOptions.queryKey ;

return query;
}



/**
* Search labels and returns the labels that match the query limited by the set limit
*/
Expand Down Expand Up @@ -71,4 +143,53 @@ export const getSearchLabelsMutationOptions = <TError = unknown,

return useMutation(mutationOptions);
}
/**
* Get category for a list of labels
*/
export const getCategory = (
getCategoryBody: GetCategoryBody,
) => {


return instance<GetCategory200>(
{url: `/labels/get-category`, method: 'POST',
headers: {'Content-Type': 'application/json', },
data: getCategoryBody
},
);
}



export const getGetCategoryMutationOptions = <TError = unknown,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof getCategory>>, TError,{data: GetCategoryBody}, TContext>, }
): UseMutationOptions<Awaited<ReturnType<typeof getCategory>>, TError,{data: GetCategoryBody}, TContext> => {
const {mutation: mutationOptions} = options ?? {};




const mutationFn: MutationFunction<Awaited<ReturnType<typeof getCategory>>, {data: GetCategoryBody}> = (props) => {
const {data} = props ?? {};

return getCategory(data,)
}




return { mutationFn, ...mutationOptions }}

export type GetCategoryMutationResult = NonNullable<Awaited<ReturnType<typeof getCategory>>>
export type GetCategoryMutationBody = GetCategoryBody
export type GetCategoryMutationError = unknown

export const useGetCategory = <TError = unknown,
TContext = unknown>(options?: { mutation?:UseMutationOptions<Awaited<ReturnType<typeof getCategory>>, TError,{data: GetCategoryBody}, TContext>, }
) => {

const mutationOptions = getGetCategoryMutationOptions(options);

return useMutation(mutationOptions);
}

11 changes: 11 additions & 0 deletions src/api/model/getCategory200.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Generated by orval v6.23.0 🍺
* Do not edit manually.
* compliance-queries-api
* The ward's compliance queires endpoints
* OpenAPI spec version: 1.0
*/

export type GetCategory200 = {
categories?: string[];
};
11 changes: 11 additions & 0 deletions src/api/model/getCategoryBody.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Generated by orval v6.23.0 🍺
* Do not edit manually.
* compliance-queries-api
* The ward's compliance queires endpoints
* OpenAPI spec version: 1.0
*/

export type GetCategoryBody = {
labels?: string[];
};
14 changes: 14 additions & 0 deletions src/api/model/getCategoryParams.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Generated by orval v6.23.0 🍺
* Do not edit manually.
* compliance-queries-api
* The ward's compliance queires endpoints
* OpenAPI spec version: 1.0
*/

export type GetCategoryParams = {
/**
* The labels to get categories for
*/
labels: string[];
};
12 changes: 12 additions & 0 deletions src/api/model/getLabels200.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Generated by orval v6.23.0 🍺
* Do not edit manually.
* compliance-queries-api
* The ward's compliance queires endpoints
* OpenAPI spec version: 1.0
*/
import type { GetLabels200Data } from './getLabels200Data';

export type GetLabels200 = {
data?: GetLabels200Data;
};
12 changes: 12 additions & 0 deletions src/api/model/getLabels200Data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Generated by orval v6.23.0 🍺
* Do not edit manually.
* compliance-queries-api
* The ward's compliance queires endpoints
* OpenAPI spec version: 1.0
*/
import type { Label } from './label';

export type GetLabels200Data = {
labels?: Label[];
};
5 changes: 5 additions & 0 deletions src/api/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,14 @@ export * from './category';
export * from './entity';
export * from './errorResponse';
export * from './exposure';
export * from './getCategory200';
export * from './getCategoryBody';
export * from './getCategoryParams';
export * from './getCombinedTransactions200';
export * from './getCombinedTransactionsParams';
export * from './getCombinedTransactionsTransactionType';
export * from './getLabels200';
export * from './getLabels200Data';
export * from './getTokenMetadata200';
export * from './getTokenMetadataBody';
export * from './getTransactions200';
Expand Down
60 changes: 60 additions & 0 deletions src/api/ward-analytics-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,34 @@ paths:
type: integer
page_size:
type: integer
/addresses/{address}/labels:
get:
operationId: get-labels
description: Get labels for an address
tags:
- labels
parameters:
- name: address
in: path
description: The address to get labels for
required: true
schema:
type: string
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
labels:
type: array
items:
$ref: "#/components/schemas/Label"
/labels/search-labels:
post:
operationId: search-labels
Expand Down Expand Up @@ -160,6 +188,38 @@ paths:
required:
- labels

# Accepts a list of labels and returns a list of categories in {"categories": []} format
/labels/get-category:
post:
operationId: get-category
description: Get category for a list of labels
tags:
- labels
requestBody:
content:
application/json:
schema:
type: object
properties:
labels:
type: array
items:
type: string
responses:
"200":
description: OK
content:
application/json:
schema:
type: object
properties:
categories:
type: array
items:
type: string
required:
- categories

components:
schemas:
# Address Analysis
Expand Down
10 changes: 5 additions & 5 deletions src/components/common/RiskIndicator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ const RiskIndicator: FC<RiskIndicatorProps> = ({
return (
<span
className={clsx(
"group my-1 flex h-11 w-11 items-center justify-center rounded-md text-lg font-semibold shadow-sm ring-1",
"group my-1 flex h-12 w-12 items-center justify-center rounded-md text-lg font-semibold shadow-sm ring-1",
color?.textColor,
color?.backgroundColor,
color?.hoveredBackgroundColor,
Expand All @@ -53,13 +53,13 @@ const RiskIndicator: FC<RiskIndicatorProps> = ({
</li>
<li className="flex flex-row items-center gap-x-1">
<ArrowsPointingInIcon className="h-5 w-5 text-blue-200" />
<span className="font-bold">Direct Exposure,</span> both incoming and
outgoing
<span className="font-bold">Direct Exposure,</span> both incoming
and outgoing
</li>
<li className="flex flex-row items-center gap-x-1">
<ChevronDoubleDownIcon className="h-5 w-5 text-blue-200" />
<span className="font-bold">Indirect Exposure,</span> both incoming and
outgoing
<span className="font-bold">Indirect Exposure,</span> both
incoming and outgoing
</li>
</ul>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
BarsArrowDownIcon,
CheckIcon,
PlusIcon,
TagIcon,
} from "@heroicons/react/16/solid";
import { FC, useContext, useEffect, useState } from "react";
import { Output, Transaction } from "../../../../../api/model";
Expand All @@ -21,6 +22,7 @@ import {
import { GraphContext } from "../../../Graph";

import TokenLogo from "../../../../common/TokenLogo";
import { useGetLabels } from "../../../../../api/labels/labels";

interface TransactionRowProps {
usdValue: number;
Expand Down Expand Up @@ -50,6 +52,27 @@ const TransactionRow: FC<TransactionRowProps> = ({
day: "numeric",
});

const [label, setLabel] = useState<string>();
const { refetch } = useGetLabels(addresses[0], {
query: {
enabled: false,
refetchOnWindowFocus: false,
retry: true,
cacheTime: 1000, // 1 second
staleTime: 1000, // 1 second
onSuccess: (data) => {
const l = data.data!.labels!;
if (l.length > 0) {
setLabel(l[0].label);
}
},
},
});

useEffect(() => {
refetch();
}, [addresses]);

const addressText: string =
addresses.length === 1
? addresses[0].slice(0, 8) + "..." + addresses[0].slice(-8)
Expand All @@ -76,6 +99,7 @@ const TransactionRow: FC<TransactionRowProps> = ({
Icon={incoming ? ArrowDownLeftIcon : ArrowUpRightIcon}
text={incoming ? "IN" : "OUT"}
/>
{label && <Badge color={Colors.GRAY} Icon={TagIcon} text={label} />}
</span>
</td>
<td className="text-left text-sm font-normal text-gray-900 group-hover:bg-gray-100">
Expand Down
Loading

0 comments on commit 2febd5b

Please sign in to comment.