Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions packages/apps/human-app/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@
"start:prod": "serve -s dist",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview",
"prepare": "husky"
"prepare": "husky",
"test": "vitest --run",
"test:watch": "vitest"
},
"lint-staged": {
"*.{ts,tsx}": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0"
},
"dependencies": {
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@faker-js/faker": "^9.7.0",
"@fontsource/inter": "^5.0.17",
"@hcaptcha/react-hcaptcha": "^0.3.6",
"@hookform/resolvers": "^3.3.4",
"@hookform/resolvers": "^5.0.1",
"@human-protocol/sdk": "*",
"@mui/icons-material": "^7.0.1",
"@mui/material": "^5.16.7",
Expand All @@ -38,7 +41,7 @@
"query-string": "^9.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.53.2",
"react-hook-form": "^7.55.0",
"react-i18next": "^15.1.0",
"react-imask": "^7.4.0",
"react-number-format": "^5.4.3",
Expand Down Expand Up @@ -70,6 +73,7 @@
"lint-staged": "^15.4.3",
"prettier": "^3.4.2",
"typescript": "^5.6.3",
"vite": "^6.2.4"
"vite": "^6.2.4",
"vitest": "^3.1.1"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export function SignInForm({
}: Readonly<SignInFormProps>) {
const { t } = useTranslation();

const methods = useForm<SignInDto>({
const methods = useForm({
defaultValues: {
email: '',
password: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Input } from '@/shared/components/data-entry/input';
import type { EthKVStoreKeyValues } from '@/modules/smart-contracts/EthKVStore/config';
import {
EthKVStoreKeys,
Role,
OPERATOR_ROLES,
} from '@/modules/smart-contracts/EthKVStore/config';
import { Select } from '@/shared/components/data-entry/select';
import { MultiSelect } from '@/shared/components/data-entry/multi-select';
Expand All @@ -17,12 +17,6 @@ import { useColorMode } from '@/shared/contexts/color-mode';
import { PercentsInputMask } from '@/shared/components/data-entry/input-masks';
import { sortFormKeys, STORE_KEYS_ORDER } from '../../utils';

const OPTIONS = [
Role.EXCHANGE_ORACLE,
Role.JOB_LAUNCHER,
Role.RECORDING_ORACLE,
];

const formInputsConfig: Record<EthKVStoreKeyValues, React.ReactElement> = {
[EthKVStoreKeys.Fee]: (
<Input
Expand Down Expand Up @@ -58,7 +52,7 @@ const formInputsConfig: Record<EthKVStoreKeyValues, React.ReactElement> = {
isChipRenderValue
label={t('operator.addKeysPage.existingKeys.role')}
name={EthKVStoreKeys.Role}
options={OPTIONS.map((role, i) => ({
options={OPERATOR_ROLES.map((role, i) => ({
name: role,
value: role,
id: i,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Input } from '@/shared/components/data-entry/input';
import type { EthKVStoreKeyValues } from '@/modules/smart-contracts/EthKVStore/config';
import {
EthKVStoreKeys,
Role,
OPERATOR_ROLES,
} from '@/modules/smart-contracts/EthKVStore/config';
import { Select } from '@/shared/components/data-entry/select';
import { MultiSelect } from '@/shared/components/data-entry/multi-select';
Expand All @@ -13,12 +13,6 @@ import type { GetEthKVStoreValuesSuccessResponse } from '@/modules/operator/hook
import { PercentsInputMask } from '@/shared/components/data-entry/input-masks';
import { sortFormKeys, STORE_KEYS_ORDER } from '../../utils';

const OPTIONS = [
Role.EXCHANGE_ORACLE,
Role.JOB_LAUNCHER,
Role.RECORDING_ORACLE,
];

const formInputsConfig: Record<EthKVStoreKeyValues, React.ReactElement> = {
[EthKVStoreKeys.Fee]: (
<Input
Expand Down Expand Up @@ -54,7 +48,7 @@ const formInputsConfig: Record<EthKVStoreKeyValues, React.ReactElement> = {
isChipRenderValue
label={t('operator.addKeysPage.existingKeys.role')}
name={EthKVStoreKeys.Role}
options={OPTIONS.map((role, i) => ({
options={OPERATOR_ROLES.map((role, i) => ({
name: role,
value: role,
id: i,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useState } from 'react';
import { Grid } from '@mui/material';
import { zodResolver } from '@hookform/resolvers/zod';
import type { UseFormReturn } from 'react-hook-form';
import { FormProvider, useForm } from 'react-hook-form';
import type { GetEthKVStoreValuesSuccessResponse } from '@/modules/operator/hooks/use-get-keys';
import { useResetMutationErrors } from '@/shared/hooks/use-reset-mutation-errors';
Expand All @@ -13,25 +12,14 @@ import {
import { EditExistingKeysForm } from './edit-existing-keys-form';
import { ExistingKeys } from './existing-keys';

export type UseFormResult = UseFormReturn<
GetEthKVStoreValuesSuccessResponse,
EditEthKVStoreValuesMutationData
>;

export function ExistingKeysForm({
keysData,
}: Readonly<{
keysData: GetEthKVStoreValuesSuccessResponse;
}>) {
const [editMode, setEditMode] = useState(false);
const existingKeysMutation = useEditExistingKeysMutation();
const pendingKeysMutation = useEditExistingKeysMutation();
const existingKeysMethods = useForm<
GetEthKVStoreValuesSuccessResponse,
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- automatic inferring
any,
EditEthKVStoreValuesMutationData
>({
const existingKeysMethods = useForm({
defaultValues: keysData,
resolver: zodResolver(getEditEthKVStoreValuesMutationSchema(keysData)),
});
Expand All @@ -52,14 +40,7 @@ export function ExistingKeysForm({
gap: '3rem',
}}
>
<FormProvider<
GetEthKVStoreValuesSuccessResponse,
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- automatic inferring
any,
EditEthKVStoreValuesMutationData
>
{...existingKeysMethods}
>
<FormProvider {...existingKeysMethods}>
<form
onSubmit={(event) => {
void existingKeysMethods.handleSubmit(handleEditExistingKeys)(
Expand All @@ -74,7 +55,7 @@ export function ExistingKeysForm({
loading: existingKeysMutation.isPending,
type: 'submit',
variant: 'contained',
disabled: pendingKeysMutation.isPending,
disabled: existingKeysMutation.isPending,
}}
/>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,7 @@ export function PendingKeysForm({
}>) {
const pendingKeysMutation = useEditExistingKeysMutation();

const pendingKeysMethods = useForm<
GetEthKVStoreValuesSuccessResponse,
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- automatic inferring
any,
EditEthKVStoreValuesMutationData
>({
const pendingKeysMethods = useForm({
defaultValues: {},
resolver: zodResolver(setEthKVStoreValuesMutationSchema(keysData)),
});
Expand All @@ -35,14 +30,7 @@ export function PendingKeysForm({
useResetMutationErrors(pendingKeysMethods.watch, pendingKeysMutation.reset);

return (
<FormProvider<
GetEthKVStoreValuesSuccessResponse,
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- automatic inferring
any,
EditEthKVStoreValuesMutationData
>
{...pendingKeysMethods}
>
<FormProvider {...pendingKeysMethods}>
<form
onSubmit={(event) => {
void pendingKeysMethods.handleSubmit(handleEditPendingKey)(event);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export function StakeForm({
}>) {
const addStakeMutation = useAddStake();

const methods = useForm<AddStakeCallArguments>({
const methods = useForm({
defaultValues: {
// Since we deal with numbers that may have huge decimal extensions,
// we are using strings as a safer solution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import { t } from 'i18next';
import {
EthKVStoreKeys,
JobType,
Role,
OPERATOR_ROLES,
} from '@/modules/smart-contracts/EthKVStore/config';
import type { GetEthKVStoreValuesSuccessResponse } from '@/modules/operator/hooks/use-get-keys';
import { type GetEthKVStoreValuesSuccessResponse } from '@/modules/operator/hooks/use-get-keys';
import { urlDomainSchema } from '@/shared/schemas';

const fieldsValidations = {
[EthKVStoreKeys.PublicKey]: urlDomainSchema,
[EthKVStoreKeys.Url]: urlDomainSchema,
[EthKVStoreKeys.WebhookUrl]: urlDomainSchema,
[EthKVStoreKeys.Role]: z.nativeEnum(Role),
[EthKVStoreKeys.Role]: z.enum(OPERATOR_ROLES),
[EthKVStoreKeys.JobTypes]: z.array(z.nativeEnum(JobType)).min(1),
[EthKVStoreKeys.Fee]: z.coerce
// eslint-disable-next-line camelcase
Expand Down Expand Up @@ -62,43 +62,51 @@ export const setEthKVStoreValuesMutationSchema = (
export const getEditEthKVStoreValuesMutationSchema = (
initialData: GetEthKVStoreValuesSuccessResponse
) => {
return editEthKVStoreValuesMutationSchema.transform((newData, ctx) => {
const fieldsThatHasChanges: EditEthKVStoreValuesMutationData = {};
Object.values(EthKVStoreKeys).forEach((key) => {
const newFiledData = newData[key];
const initialFiledData = initialData[key];
return editEthKVStoreValuesMutationSchema.transform<EditEthKVStoreValuesMutationData>(
(newData, ctx) => {
const fieldsThatHasChanges: EditEthKVStoreValuesMutationData = {};
Object.values(EthKVStoreKeys).forEach((key) => {
const newFiledData = newData[key];
const initialFiledData = initialData[key];

if (Array.isArray(newFiledData) && Array.isArray(initialFiledData)) {
if (
newFiledData.sort().toString() === initialFiledData.sort().toString()
let hasFieldChanged = false;
if (Array.isArray(newFiledData) && Array.isArray(initialFiledData)) {
if (
newFiledData.sort().toString() !==
initialFiledData.sort().toString()
) {
hasFieldChanged = true;
}
} else if (
typeof newFiledData === 'number' &&
newFiledData.toString() !== initialFiledData?.toString()
) {
return;
hasFieldChanged = true;
} else {
// eslint-disable-next-line eqeqeq -- expect to do conversion for this compare
hasFieldChanged = newFiledData != initialFiledData;
}
Object.assign(fieldsThatHasChanges, { [key]: newFiledData.toString() });
return;
}

if (
typeof newFiledData === 'number' &&
newFiledData.toString() !== initialFiledData?.toString()
) {
Object.assign(fieldsThatHasChanges, { [key]: newFiledData });
return;
}
if (hasFieldChanged) {
Object.assign(fieldsThatHasChanges, { [key]: newFiledData });
}
});

// eslint-disable-next-line eqeqeq -- expect to do conversion for this compare
if (newFiledData != initialFiledData) {
Object.assign(fieldsThatHasChanges, { [key]: newFiledData });
if (Object.values(fieldsThatHasChanges).length === 0) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: t('operator.addKeysPage.editKeysForm.error'),
path: ['form'],
});

return z.NEVER;
}
});

if (!Object.values(fieldsThatHasChanges).length) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: t('operator.addKeysPage.editKeysForm.error'),
path: ['form'],
});
return fieldsThatHasChanges;
}
return fieldsThatHasChanges;
});
) as z.ZodType<
EditEthKVStoreValuesMutationData,
z.ZodTypeDef,
GetEthKVStoreValuesSuccessResponse
>;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { describe, expect, it } from 'vitest';
import { stakedAmountFormatter } from '../staked-amount-formatter';
import '@/shared/i18n/i18n';

describe('stakedAmountFormatter Function', () => {
it('should format amounts with no decimal part correctly', () => {
const amount = BigInt('1000000000000000000');

const result = stakedAmountFormatter(amount);
expect(result).toBe('1 HMT');
});

it('should format amounts with decimal part correctly', () => {
const amount = BigInt('1500000000000000000');

const result = stakedAmountFormatter(amount);
expect(result).toBe('1.5 HMT');
});

it('should handle very small amounts', () => {
const amount = BigInt('1');

const result = stakedAmountFormatter(amount);
expect(result).toBe('0.000000000000000001 HMT');
});

it('should handle zero amount', () => {
const amount = BigInt('0');

const result = stakedAmountFormatter(amount);
expect(result).toBe('0 HMT');
});

it('should handle large amounts', () => {
const amount = BigInt('1000000000000000000000');

const result = stakedAmountFormatter(amount);
expect(result).toBe('1000 HMT');
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import type { UseFormReturn } from 'react-hook-form';
import { t } from 'i18next';
import {
PageCardError,
Expand All @@ -7,19 +6,10 @@ import {
} from '@/shared/components/ui/page-card';
import { getErrorMessageForError, jsonRpcErrorHandler } from '@/shared/errors';
import { Alert } from '@/shared/components/ui/alert';
import {
type GetEthKVStoreValuesSuccessResponse,
useGetKeys,
} from '@/modules/operator/hooks';
import { useGetKeys } from '@/modules/operator/hooks';
import { useEditExistingKeysMutationState } from '../hooks';
import { type EditEthKVStoreValuesMutationData } from '../schema';
import { AddKeysForm } from '../components/add-keys';

export type UseFormResult = UseFormReturn<
GetEthKVStoreValuesSuccessResponse,
EditEthKVStoreValuesMutationData
>;

export function AddKeysOperatorPage() {
const {
data: keysData,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,7 @@ export function AddStakeOperatorPage() {
);
}

if (
isGetStakedAmountPending ||
isDecimalsDataPending ||
decimalsData === undefined
) {
if (isGetStakedAmountPending || isDecimalsDataPending) {
return <PageCardLoader />;
}

Expand Down
Loading
Loading