Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into issue-#1448
Browse files Browse the repository at this point in the history
  • Loading branch information
GrandSchtroumpf committed Sep 10, 2024
2 parents 62f1206 + 7635eb8 commit f03e915
Show file tree
Hide file tree
Showing 51 changed files with 454 additions and 142 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ The file `common.ts` with type [`AppConfig`](src/config/types.ts) contains impor
- `selectedConnectors`: List of connectors to make available by default in the wallet selection modal that will be shown even if the connector is not injected.
- `blockedConnectors`: List of EIP-6963 injected connectors names to block in the wallet selection modal.
- `isSimulatorEnabled`: Flag to enable the simulation page.
- `showStrategyRoi`: Optional flag to show the Strategy ROI in the Strategy Block. ROI is hidden by default.
- `network`
- `name`: Network name.
- `logoUrl`: Network logo URL.
Expand All @@ -265,7 +266,7 @@ The file `common.ts` with type [`AppConfig`](src/config/types.ts) contains impor
- `popularTokens`: List of popular tokens to be used in the app when opening the token selection modal.
- `addresses`/`carbon` and `addresses/utils`: CarbonController, Voucher and multicall3 contract addresses.
- `tokenListOverride`: Token list override to be used in the app when fetching the token list. Tokens in the list will override any other token with the same address.
- `tokenLists`: List of token lists including the uri and the parser to be used to parse the token list.
- `tokenLists`: List of token lists including the uri and the parser name to be used to parse the token list. Please update the tokenParserMap in the `src/config/utils.ts` file to include the parser name and the parser function.
- `sdk`/`cacheTTL`: When the app loads, it will ignore any cached data if it is older than the cacheTTL time in milliseconds. If set to 0, the app will always ignore the cache data and fetch new data on load.
#### Gas token different than native token
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified e2e/screenshots/strategy/overlapping/Overlapping/withdraw/form.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
"tailwindcss": "3.4.3",
"typechain": "^8.1.0",
"typescript": "^5.3.3",
"valibot": "^0.28.1",
"valibot": "^0.34.0",
"viem": "2.x",
"vite": "5.3.2",
"vite-plugin-svgr": "^2.4.0",
Expand Down
4 changes: 2 additions & 2 deletions src/components/activity/ActivityProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ type ParamsKey = Extract<keyof QueryActivityParams, string>;
export const ActivityProvider: FC<Props> = ({ children, params }) => {
const nav = useNavigate();
const searchParams: ActivitySearchParams = useSearch({ strict: false });
const limit = searchParams.limit ?? 10;
const offset = searchParams.offset ?? 0;
const limit = searchParams.limit;
const offset = searchParams.offset;

const queryParams = getQueryParams(params, searchParams);
// Query the list
Expand Down
19 changes: 15 additions & 4 deletions src/components/activity/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
SearchParamsValidator,
validArrayOf,
validLiteral,
validNumberType,
validNumber,
validString,
validateSearchParams,
} from 'libs/routing/utils';
Expand Down Expand Up @@ -45,10 +45,21 @@ export const activityValidators: SearchParamsValidator<ActivitySearchParams> = {
pairs: validArrayOf(validString),
start: validString,
end: validString,
limit: validNumberType,
offset: validNumberType,
limit: validNumber,
offset: validNumber,
};
export const validateActivityParams = (
search: Record<string, string>
): ActivitySearchParams => {
const rawSearch = validateSearchParams(activityValidators)(search);
const limit = Number(rawSearch.limit ?? 10);
const offset = Number(rawSearch.offset ?? 0);
return {
...rawSearch,
limit,
offset,
};
};
export const validateActivityParams = validateSearchParams(activityValidators);

export const activityHasPairs = (activity: Activity, pairs: string[] = []) => {
if (pairs.length === 0) return true;
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/approval/ApproveToken.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const ApproveToken: FC<Props> = ({
const { getTokenById } = useTokens();
const token = getTokenById(data?.address || '');
const mutation = useSetUserApproval();
// Gasprice on SEI is cheap, best practice is to use exact amount approval
// When gasprice is cheap, best practice is to use exact amount approval
const [isLimited, setIsLimited] = useState(
!!config.network.defaultLimitedApproval
);
Expand Down
3 changes: 2 additions & 1 deletion src/components/core/error/ErrorUserBlocked.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { NewTabLink, externalLinks } from 'libs/routing';
import { ErrorWrapper } from 'components/core/error/ErrorWrapper';
import { Button } from 'components/common/button';
import { ReactComponent as IconWarning } from 'assets/icons/warning.svg';
import config from 'config';

export const ErrorUserBlocked = () => {
const { disconnect } = useWagmi();
Expand All @@ -11,7 +12,7 @@ export const ErrorUserBlocked = () => {
<ErrorWrapper
icon={<IconWarning />}
title="Wallet Blocked"
text="For compliance reasons, this wallet has been blocked from using the Carbon App."
text={`For compliance reasons, this wallet has been blocked from using the ${config.appName} App.`}
variant="error"
>
<div className="space-y-10">
Expand Down
97 changes: 97 additions & 0 deletions src/components/debug/DebugConfig.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { FormEvent, useLayoutEffect, useRef, useState } from 'react';
import { lsService } from 'services/localeStorage';
import { Button } from 'components/common/button';
import { Warning } from 'components/common/WarningMessageWithIcon';
import { defaultConfig } from 'config';
import { AppConfigSchema } from 'config/configSchema';
import { AppConfig } from 'config/types';
import * as v from 'valibot';

const formatConfig = (config?: Partial<AppConfig>) =>
JSON.stringify(config, undefined, 4);

export const DebugConfig = () => {
const savedConfigOverride = formatConfig(lsService.getItem('configOverride'));
const [configOverride, setConfigOverride] = useState(savedConfigOverride);
const [error, setError] = useState('');
const textAreaRef = useRef<HTMLTextAreaElement>(null);

const errorMessage = 'Failed parsing JSON file';
const saveConfigOverride = (configOverride?: string) => {
try {
if (!configOverride) {
setConfigOverride('');
lsService.removeItem('configOverride');
} else {
const parsedConfig = JSON.parse(configOverride || '');
v.parse(v.partial(AppConfigSchema), parsedConfig);
lsService.setItem('configOverride', parsedConfig);
}
setError('');
window?.location.reload();
} catch (error) {
setError(errorMessage);
}
};

const handleConfigChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
setConfigOverride(e.target.value);
};

useLayoutEffect(() => {
if (!textAreaRef.current) return;
textAreaRef.current.style.height = 'inherit'; // to reduce on delete
const defaultHeight = 5; // px
const newHeight = Math.max(textAreaRef.current.scrollHeight, defaultHeight); // px
textAreaRef.current.style.height = `${newHeight}px`;
}, [configOverride]);

const handleLoadDefault = () => {
const parsedDefaultConfig = formatConfig(defaultConfig);
setConfigOverride(parsedDefaultConfig);
};

const submit = (e: FormEvent) => {
e.preventDefault();
saveConfigOverride(configOverride);
};

const reset = (e: FormEvent) => {
e.preventDefault();
saveConfigOverride();
};

return (
<form
onSubmit={submit}
onReset={reset}
className="rounded-18 bg-background-900 flex flex-col items-center space-y-20 p-20"
>
<h2 className="text-center">Set Config</h2>
<label htmlFor="custom-config-json">Config Override</label>

<div className="w-full">
<textarea
ref={textAreaRef}
id="custom-config-json"
placeholder="Enter config file overrides in JSON format"
value={configOverride}
onChange={handleConfigChange}
className="rounded-18 w-full break-all bg-black px-16 py-8"
/>
</div>
{!!error && (
<Warning isError message={error} htmlFor="custom-config-json" />
)}
<Button data-testid="save-config" type="submit" fullWidth>
Save
</Button>
<Button type="button" onClick={handleLoadDefault} fullWidth>
Load Default Config
</Button>
<Button type="reset" fullWidth>
Reset
</Button>
</form>
);
};
4 changes: 2 additions & 2 deletions src/components/simulator/input/BuySellBlockNew/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const BuySellHeader: FC<Props> = (props) => {
sendEventOnMount={{ buy }}
iconClassName="text-white/60"
element={
<>
<p>
This section will define the order details in which you are
willing to {buy ? 'buy' : 'sell'} {base.symbol} at.
<br />
Expand All @@ -87,7 +87,7 @@ export const BuySellHeader: FC<Props> = (props) => {
<br />
<b>Range</b> will allow you to define a range of prices to{' '}
{buy ? 'buy' : 'sell'} the token at.
</>
</p>
}
/>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/components/strategies/common/OrderHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const OrderHeader: FC<Props> = (props) => {
sendEventOnMount={{ buy }}
iconClassName="text-white/60"
element={
<>
<p>
This section will define the order details in which you are willing
to {buy ? 'buy' : 'sell'} {base.symbol} at.
<br />
Expand All @@ -72,7 +72,7 @@ export const OrderHeader: FC<Props> = (props) => {
<br />
<b>Range</b> will allow you to define a range of prices to{' '}
{buy ? 'buy' : 'sell'} the token at.
</>
</p>
}
/>
</header>
Expand Down
8 changes: 7 additions & 1 deletion src/components/strategies/overview/StrategyContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { StrategyBlockCreate } from 'components/strategies/overview/strategyBloc
import { CarbonLogoLoading } from 'components/common/CarbonLogoLoading';
import { cn } from 'utils/helpers';
import styles from './StrategyContent.module.css';
import config from 'config';

type Props = {
strategies: StrategyWithFiat[];
Expand Down Expand Up @@ -44,7 +45,12 @@ export const _StrategyContent: FC<Props> = ({
className={cn('xl:gap-25 grid gap-20 lg:gap-10', styles.strategyList)}
>
{strategies.map((s) => (
<StrategyBlock key={s.id} strategy={s} isExplorer={isExplorer} />
<StrategyBlock
key={s.id}
strategy={s}
isExplorer={isExplorer}
showStrategyRoi={config.showStrategyRoi}
/>
))}
{!isExplorer && <StrategyBlockCreate />}
</ul>
Expand Down
10 changes: 10 additions & 0 deletions src/components/strategies/overview/StrategyFilterSort.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ReactComponent as IconFilter } from 'assets/icons/filter.svg';
import { lsService } from 'services/localeStorage';
import { useStrategyCtx } from 'hooks/useStrategies';
import { cn } from 'utils/helpers';
import config from 'config';

// [START] Used for localStorage migration: Remove it after Nov 2023
export enum EnumStrategySort {
Expand All @@ -31,6 +32,9 @@ const isEnumSort = (

export const getSortFromLS = (): StrategySort => {
const sort = lsService.getItem('strategyOverviewSort');
const isRoiSort = sort === 'roiDesc' || sort === 'roiAsc';
if (!config.showStrategyRoi && (sort === undefined || isRoiSort))
return 'recent';
if (sort === undefined) return 'roiDesc';
return isEnumSort(sort) ? strategySortMapping[sort] : sort;
};
Expand Down Expand Up @@ -74,6 +78,12 @@ export const strategySort = {
roiDesc: 'ROI (Descending)',
totalBudgetDesc: 'Total Budget',
};

if (config.showStrategyRoi) {
strategySort['roiAsc'] = '';
strategySort['roiDesc'] = '';
}

export type StrategySort = keyof typeof strategySort;

interface Props {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@ import { m, mItemVariant } from 'libs/motion';
import { StrategyBlockBuySell } from 'components/strategies/overview/strategyBlock/StrategyBlockBuySell';

import { cn } from 'utils/helpers';
import { StrategyBlockRoi } from './StrategyBlockRoi';
import { StrategyBlockBudget } from './StrategyBlockBudget';
import { StrategyBlockHeader } from './StrategyBlockHeader';
import { StrategyGraph } from './StrategyGraph';
import { StrategyBlockInfo } from './StrategyBlockInfo';

interface Props {
strategy: StrategyWithFiat;
className?: string;
isExplorer?: boolean;
showStrategyRoi?: boolean;
}

export const StrategyBlock: FC<Props> = ({
strategy,
className,
isExplorer,
showStrategyRoi,
}) => {
return (
<m.li
Expand All @@ -30,8 +31,10 @@ export const StrategyBlock: FC<Props> = ({
data-testid={`${strategy.base.symbol}/${strategy.quote.symbol}`}
>
<StrategyBlockHeader strategy={strategy} isExplorer={isExplorer} />
<StrategyBlockRoi strategy={strategy} />
<StrategyBlockBudget strategy={strategy} />
<StrategyBlockInfo
strategy={strategy}
showStrategyRoi={showStrategyRoi}
/>
<div
className={cn(
'rounded-8 border-background-800 col-start-1 col-end-3 grid grid-cols-2 grid-rows-[auto_auto] border-2',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import { useFiatCurrency } from 'hooks/useFiatCurrency';
import { StrategyWithFiat } from 'libs/queries';

interface Props {
fullWidth?: boolean;
strategy: StrategyWithFiat;
}

export const StrategyBlockBudget: FC<Props> = ({ strategy }) => {
export const StrategyBlockBudget: FC<Props> = ({ strategy, fullWidth }) => {
const baseFiat = useFiatCurrency(strategy.base);
const quoteFiat = useFiatCurrency(strategy.quote);
const noFiatValue = !baseFiat.hasFiatValue() && !quoteFiat.hasFiatValue();
Expand All @@ -22,7 +23,8 @@ export const StrategyBlockBudget: FC<Props> = ({ strategy }) => {
<article
className={cn(
'rounded-8 border-background-800 flex flex-col border-2 p-16',
strategy.status === 'active' ? '' : 'opacity-50'
strategy.status === 'active' ? '' : 'opacity-50',
!!fullWidth ? 'col-start-1 col-end-3 flex-row justify-between' : ''
)}
>
<Tooltip element={<TooltipContent />}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { FC } from 'react';
import { StrategyWithFiat } from 'libs/queries';
import { StrategyBlockRoi } from 'components/strategies/overview/strategyBlock/StrategyBlockRoi';
import { StrategyBlockBudget } from 'components/strategies/overview/strategyBlock/StrategyBlockBudget';

interface Props {
strategy: StrategyWithFiat;
showStrategyRoi?: boolean;
}

export const StrategyBlockInfo: FC<Props> = ({ strategy, showStrategyRoi }) => {
return (
<>
{!!showStrategyRoi && <StrategyBlockRoi strategy={strategy} />}
<StrategyBlockBudget strategy={strategy} fullWidth={!showStrategyRoi} />
</>
);
};
8 changes: 5 additions & 3 deletions src/components/strategies/overview/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@ export const getCompareFunctionBySortType = (sortType: StrategySort) => {
return sortFn[sortType] ?? sortFn['roiDesc'];
};
export const getSortAndFilterItems = () => {
const sortItems = Object.entries(strategySort).map(([item, title]) => {
return { item: item as StrategySort, title };
});
const sortItems = Object.entries(strategySort)
.filter(([_item, title]) => !!title)
.map(([item, title]) => {
return { item: item as StrategySort, title };
});

const filterItems = Object.entries(strategyFilter).map(([item, title]) => {
return { item: item as StrategyFilter, title };
Expand Down
1 change: 1 addition & 0 deletions src/config/celo/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const commonConfig: AppConfig = {
blockedConnectors: ['Tailwind', 'Compass Wallet', 'Seif'],
walletConnectProjectId: '',
isSimulatorEnabled: false,
showStrategyRoi: true,
policiesLastUpdated: '31 Jul, 2024',
network: {
name: 'Celo Network',
Expand Down
Loading

0 comments on commit f03e915

Please sign in to comment.