* feat: [#155] move grid tab to ui-toolkit and add info component in the tabbed ticket * feat: [#155] add accordion component + storybook * feat: [#155] styling updates, unit tests and export ui-toolkit * feat: [#155] generate deal ticket query and info-market.tsx updates * feat: [#155] move grid tab to ui-toolkit and add info component in the tabbed ticket * feat: [#155] add accordion component + storybook * feat: [#155] styling updates, unit tests and export ui-toolkit * feat: [#155] generate deal ticket query and info-market.tsx updates * fix: [#155] styling updates to mimic figma * fix: [#155] fix trading-e2e generate deal ticket query * feat: [#155] remove open field, add omits configurable * fix: [#155] row component in info market * feat: market info/accordion styling tweaks * fix: [#155] add risk models and fix readme * fix: [#155] update generate deal ticket query to fix test * fix: [#155] fix cypress test data Co-authored-by: PeteWilliams <me@petewilliams.info>
This commit is contained in:
parent
0414b26fed
commit
675716089a
10
README.md
10
README.md
@ -47,11 +47,11 @@ For shared Cypress logic, commands and steps.
|
|||||||
|
|
||||||
### [Web3](./libs/web3)
|
### [Web3](./libs/web3)
|
||||||
|
|
||||||
A ulitity library for connecting to the Ethereum network and interacting with Vega Web3 contracts.
|
A utility library for connecting to the Ethereum network and interacting with Vega Web3 contracts.
|
||||||
|
|
||||||
### [React Helpers](./libs/react-helpers)
|
### [React Helpers](./libs/react-helpers)
|
||||||
|
|
||||||
Generic react helpers that can be used across multilpe applications, along with other utilties.
|
Generic react helpers that can be used across multilpe applications, along with other utilities.
|
||||||
|
|
||||||
# 💻 Develop
|
# 💻 Develop
|
||||||
|
|
||||||
@ -107,7 +107,7 @@ Visit the [Nx Documentation](https://nx.dev/getting-started/intro) to learn more
|
|||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
The [Dockerfile](./Dockerfile) for running the frontends is pretty basic, merely building the application with the APP arg that is passed in and serving the application from [nginx](./nginx/nginx.conf). The only complexity that exists is that there is a script which allows the passing of run time environement variabels to the containers. See configuration below for how to do this.
|
The [Dockerfile](./Dockerfile) for running the frontends is pretty basic, merely building the application with the APP arg that is passed in and serving the application from [nginx](./nginx/nginx.conf). The only complexity that exists is that there is a script which allows the passing of run time environment variables to the containers. See configuration below for how to do this.
|
||||||
|
|
||||||
You can build any of the containers locally with the following command:
|
You can build any of the containers locally with the following command:
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ docker run -p 3000:80 [TAG]
|
|||||||
|
|
||||||
## Config
|
## Config
|
||||||
|
|
||||||
As envrionment variabels are build time and not run time in frontend applications. We have built a system which allows for passing run time environment variables, this generates a JSON file that will override the default environement vairbales that the container was built with (which is always testnet, using the default .env files).
|
As environment variables are build time and not run time in frontend applications. We have built a system which allows for passing run time environment variables, this generates a JSON file that will override the default environment variables that the container was built with (which is always testnet, using the default .env files).
|
||||||
|
|
||||||
In order to override specific environment variables you can pass these to the container like this:
|
In order to override specific environment variables you can pass these to the container like this:
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ Which will now point the app to use a devnet data node. To see a list of all pos
|
|||||||
|
|
||||||
Coming soon! You will be able to run the containers within Vega Capsule.
|
Coming soon! You will be able to run the containers within Vega Capsule.
|
||||||
|
|
||||||
You can run against a local intance of Vega Cpasule today by using the .env.capsule present in the apps.
|
You can run against a local instance of Vega Capsule today by using the .env.capsule present in the apps.
|
||||||
|
|
||||||
# 📑 License
|
# 📑 License
|
||||||
|
|
||||||
|
@ -24,10 +24,10 @@ describe('NetworkParametersTable', () => {
|
|||||||
);
|
);
|
||||||
const rows = screen.getAllByTestId('key-value-table-row');
|
const rows = screen.getAllByTestId('key-value-table-row');
|
||||||
expect(rows[0].children[0]).toHaveTextContent(
|
expect(rows[0].children[0]).toHaveTextContent(
|
||||||
'market.fee.factors.infrastructureFee'
|
'Market Fee Factors Infrastructure Fee'
|
||||||
);
|
);
|
||||||
expect(rows[1].children[0]).toHaveTextContent(
|
expect(rows[1].children[0]).toHaveTextContent(
|
||||||
'market.liquidityProvision.minLpStakeQuantumMultiple'
|
'Market Liquidity Provision Min Lp Stake Quantum Multiple'
|
||||||
);
|
);
|
||||||
expect(rows[0].children[1]).toHaveTextContent('0.0005');
|
expect(rows[0].children[1]).toHaveTextContent('0.0005');
|
||||||
expect(rows[1].children[1]).toHaveTextContent('1');
|
expect(rows[1].children[1]).toHaveTextContent('1');
|
||||||
@ -54,10 +54,10 @@ describe('NetworkParametersTable', () => {
|
|||||||
);
|
);
|
||||||
const rows = screen.getAllByTestId('key-value-table-row');
|
const rows = screen.getAllByTestId('key-value-table-row');
|
||||||
expect(rows[0].children[0]).toHaveTextContent(
|
expect(rows[0].children[0]).toHaveTextContent(
|
||||||
'market.fee.factors.infrastructureFee'
|
'Market Fee Factors Infrastructure Fee'
|
||||||
);
|
);
|
||||||
expect(rows[1].children[0]).toHaveTextContent(
|
expect(rows[1].children[0]).toHaveTextContent(
|
||||||
'market.liquidityProvision.minLpStakeQuantumMultiple'
|
'Market Liquidity Provision Min Lp Stake Quantum Multiple'
|
||||||
);
|
);
|
||||||
expect(rows[0].children[1]).toHaveTextContent('0.0005');
|
expect(rows[0].children[1]).toHaveTextContent('0.0005');
|
||||||
expect(rows[1].children[1]).toHaveTextContent('1');
|
expect(rows[1].children[1]).toHaveTextContent('1');
|
@ -16,6 +16,7 @@ import type {
|
|||||||
NetworkParametersQuery_networkParameters,
|
NetworkParametersQuery_networkParameters,
|
||||||
} from './__generated__/NetworkParametersQuery';
|
} from './__generated__/NetworkParametersQuery';
|
||||||
import orderBy from 'lodash/orderBy';
|
import orderBy from 'lodash/orderBy';
|
||||||
|
import startCase from 'lodash/startCase';
|
||||||
|
|
||||||
const BIG_NUMBER_PARAMS = [
|
const BIG_NUMBER_PARAMS = [
|
||||||
'spam.protection.delegation.min.tokens',
|
'spam.protection.delegation.min.tokens',
|
||||||
@ -42,7 +43,7 @@ export const renderRow = ({
|
|||||||
const isSyntaxRow = isJsonObject(value);
|
const isSyntaxRow = isJsonObject(value);
|
||||||
return (
|
return (
|
||||||
<KeyValueTableRow key={key} inline={!isSyntaxRow}>
|
<KeyValueTableRow key={key} inline={!isSyntaxRow}>
|
||||||
{key}
|
{startCase(key)}
|
||||||
{isSyntaxRow ? (
|
{isSyntaxRow ? (
|
||||||
<SyntaxHighlighter data={JSON.parse(value)} />
|
<SyntaxHighlighter data={JSON.parse(value)} />
|
||||||
) : isNaN(Number(value)) ? (
|
) : isNaN(Number(value)) ? (
|
||||||
|
@ -1,22 +1,70 @@
|
|||||||
|
import type { DealTicketQuery } from '@vegaprotocol/deal-ticket';
|
||||||
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
|
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
|
||||||
import merge from 'lodash/merge';
|
import merge from 'lodash/merge';
|
||||||
import type { PartialDeep } from 'type-fest';
|
import type { PartialDeep } from 'type-fest';
|
||||||
import type { DealTicketQuery } from '@vegaprotocol/deal-ticket';
|
|
||||||
|
|
||||||
export const generateDealTicketQuery = (
|
export const generateDealTicketQuery = (
|
||||||
override?: PartialDeep<DealTicketQuery>
|
override?: PartialDeep<DealTicketQuery>
|
||||||
): DealTicketQuery => {
|
): DealTicketQuery => {
|
||||||
const defaultResult: DealTicketQuery = {
|
const defaultResult: DealTicketQuery = {
|
||||||
market: {
|
market: {
|
||||||
|
__typename: 'Market',
|
||||||
id: 'market-0',
|
id: 'market-0',
|
||||||
name: 'ETHBTC Quarterly (30 Jun 2022)',
|
name: 'ETHBTC Quarterly (30 Jun 2022)',
|
||||||
decimalPlaces: 2,
|
decimalPlaces: 2,
|
||||||
positionDecimalPlaces: 0,
|
positionDecimalPlaces: 0,
|
||||||
state: MarketState.Active,
|
state: MarketState.Active,
|
||||||
tradingMode: MarketTradingMode.Continuous,
|
tradingMode: MarketTradingMode.Continuous,
|
||||||
|
fees: {
|
||||||
|
__typename: 'Fees',
|
||||||
|
factors: {
|
||||||
|
__typename: 'FeeFactors',
|
||||||
|
makerFee: '0.0002',
|
||||||
|
infrastructureFee: '0.0005',
|
||||||
|
liquidityFee: '0.01',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
priceMonitoringSettings: {
|
||||||
|
__typename: 'PriceMonitoringSettings',
|
||||||
|
parameters: {
|
||||||
|
__typename: 'PriceMonitoringParameters',
|
||||||
|
triggers: [
|
||||||
|
{
|
||||||
|
__typename: 'PriceMonitoringTrigger',
|
||||||
|
horizonSecs: 43200,
|
||||||
|
probability: 0.9999999,
|
||||||
|
auctionExtensionSecs: 600,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
updateFrequencySecs: 1,
|
||||||
|
},
|
||||||
|
riskFactors: {
|
||||||
|
__typename: 'RiskFactor',
|
||||||
|
market:
|
||||||
|
'54b78c1b877e106842ae156332ccec740ad98d6bad43143ac6a029501dd7c6e0',
|
||||||
|
short: '0.008571790367285281',
|
||||||
|
long: '0.008508132993273576',
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
__typename: 'MarketData',
|
||||||
|
market: {
|
||||||
|
__typename: 'Market',
|
||||||
|
id: '54b78c1b877e106842ae156332ccec740ad98d6bad43143ac6a029501dd7c6e0',
|
||||||
|
},
|
||||||
|
markPrice: '5749',
|
||||||
|
indicativeVolume: '0',
|
||||||
|
bestBidVolume: '5',
|
||||||
|
bestOfferVolume: '1',
|
||||||
|
bestStaticBidVolume: '5',
|
||||||
|
bestStaticOfferVolume: '1',
|
||||||
|
},
|
||||||
tradableInstrument: {
|
tradableInstrument: {
|
||||||
|
__typename: 'TradableInstrument',
|
||||||
instrument: {
|
instrument: {
|
||||||
|
__typename: 'Instrument',
|
||||||
product: {
|
product: {
|
||||||
|
__typename: 'Future',
|
||||||
quoteName: 'BTC',
|
quoteName: 'BTC',
|
||||||
settlementAsset: {
|
settlementAsset: {
|
||||||
__typename: 'Asset',
|
__typename: 'Asset',
|
||||||
@ -24,11 +72,19 @@ export const generateDealTicketQuery = (
|
|||||||
symbol: 'tBTC',
|
symbol: 'tBTC',
|
||||||
name: 'tBTC TEST',
|
name: 'tBTC TEST',
|
||||||
},
|
},
|
||||||
__typename: 'Future',
|
|
||||||
},
|
},
|
||||||
__typename: 'Instrument',
|
|
||||||
},
|
},
|
||||||
__typename: 'TradableInstrument',
|
riskModel: {
|
||||||
|
__typename: 'LogNormalRiskModel',
|
||||||
|
tau: 0.0001140771161,
|
||||||
|
riskAversionParameter: 0.01,
|
||||||
|
params: {
|
||||||
|
__typename: 'LogNormalModelParams',
|
||||||
|
r: 0.016,
|
||||||
|
sigma: 0.3,
|
||||||
|
mu: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
depth: {
|
depth: {
|
||||||
__typename: 'MarketDepth',
|
__typename: 'MarketDepth',
|
||||||
@ -37,7 +93,6 @@ export const generateDealTicketQuery = (
|
|||||||
price: '100',
|
price: '100',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
__typename: 'Market',
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -12,9 +12,13 @@ import { t } from '@vegaprotocol/react-helpers';
|
|||||||
import { AccountsContainer } from '@vegaprotocol/accounts';
|
import { AccountsContainer } from '@vegaprotocol/accounts';
|
||||||
import { DepthChartContainer } from '@vegaprotocol/market-depth';
|
import { DepthChartContainer } from '@vegaprotocol/market-depth';
|
||||||
import { CandlesChartContainer } from '@vegaprotocol/candles-chart';
|
import { CandlesChartContainer } from '@vegaprotocol/candles-chart';
|
||||||
import { GridTab, GridTabs } from '../../components/grid-tabs';
|
|
||||||
import { SelectMarketDialog } from '@vegaprotocol/market-list';
|
import { SelectMarketDialog } from '@vegaprotocol/market-list';
|
||||||
import { ArrowDown, PriceCellChange } from '@vegaprotocol/ui-toolkit';
|
import {
|
||||||
|
ArrowDown,
|
||||||
|
GridTab,
|
||||||
|
GridTabs,
|
||||||
|
PriceCellChange,
|
||||||
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import type { CandleClose } from '@vegaprotocol/types';
|
import type { CandleClose } from '@vegaprotocol/types';
|
||||||
|
|
||||||
const TradingViews = {
|
const TradingViews = {
|
||||||
|
@ -3,10 +3,9 @@ import { t } from '@vegaprotocol/react-helpers';
|
|||||||
import { PositionsContainer } from '@vegaprotocol/positions';
|
import { PositionsContainer } from '@vegaprotocol/positions';
|
||||||
import { OrderListContainer } from '@vegaprotocol/order-list';
|
import { OrderListContainer } from '@vegaprotocol/order-list';
|
||||||
import { AccountsContainer } from '@vegaprotocol/accounts';
|
import { AccountsContainer } from '@vegaprotocol/accounts';
|
||||||
import { AnchorButton } from '@vegaprotocol/ui-toolkit';
|
import { AnchorButton, GridTab, GridTabs } from '@vegaprotocol/ui-toolkit';
|
||||||
|
|
||||||
import { WithdrawalsContainer } from './withdrawals/withdrawals-container';
|
import { WithdrawalsContainer } from './withdrawals/withdrawals-container';
|
||||||
import { GridTab, GridTabs } from '../../components/grid-tabs';
|
|
||||||
|
|
||||||
const Portfolio = () => {
|
const Portfolio = () => {
|
||||||
const tabClassName = 'p-[16px] pl-[316px]';
|
const tabClassName = 'p-[16px] pl-[316px]';
|
||||||
|
132
libs/deal-ticket/src/__generated__/DealTicketQuery.ts
generated
132
libs/deal-ticket/src/__generated__/DealTicketQuery.ts
generated
@ -1,132 +0,0 @@
|
|||||||
/* tslint:disable */
|
|
||||||
/* eslint-disable */
|
|
||||||
// @generated
|
|
||||||
// This file was automatically generated and should not be edited.
|
|
||||||
|
|
||||||
import { MarketState, MarketTradingMode } from "@vegaprotocol/types";
|
|
||||||
|
|
||||||
// ====================================================
|
|
||||||
// GraphQL query operation: DealTicketQuery
|
|
||||||
// ====================================================
|
|
||||||
|
|
||||||
export interface DealTicketQuery_market_tradableInstrument_instrument_product_settlementAsset {
|
|
||||||
__typename: "Asset";
|
|
||||||
/**
|
|
||||||
* The id of the asset
|
|
||||||
*/
|
|
||||||
id: string;
|
|
||||||
/**
|
|
||||||
* The symbol of the asset (e.g: GBP)
|
|
||||||
*/
|
|
||||||
symbol: string;
|
|
||||||
/**
|
|
||||||
* The full name of the asset (e.g: Great British Pound)
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DealTicketQuery_market_tradableInstrument_instrument_product {
|
|
||||||
__typename: "Future";
|
|
||||||
/**
|
|
||||||
* String representing the quote (e.g. BTCUSD -> USD is quote)
|
|
||||||
*/
|
|
||||||
quoteName: string;
|
|
||||||
/**
|
|
||||||
* The name of the asset (string)
|
|
||||||
*/
|
|
||||||
settlementAsset: DealTicketQuery_market_tradableInstrument_instrument_product_settlementAsset;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DealTicketQuery_market_tradableInstrument_instrument {
|
|
||||||
__typename: "Instrument";
|
|
||||||
/**
|
|
||||||
* A reference to or instance of a fully specified product, including all required product parameters for that product (Product union)
|
|
||||||
*/
|
|
||||||
product: DealTicketQuery_market_tradableInstrument_instrument_product;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DealTicketQuery_market_tradableInstrument {
|
|
||||||
__typename: "TradableInstrument";
|
|
||||||
/**
|
|
||||||
* An instance of or reference to a fully specified instrument.
|
|
||||||
*/
|
|
||||||
instrument: DealTicketQuery_market_tradableInstrument_instrument;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DealTicketQuery_market_depth_lastTrade {
|
|
||||||
__typename: "Trade";
|
|
||||||
/**
|
|
||||||
* The price of the trade (probably initially the passive order price, other determination algorithms are possible though) (uint64)
|
|
||||||
*/
|
|
||||||
price: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DealTicketQuery_market_depth {
|
|
||||||
__typename: "MarketDepth";
|
|
||||||
/**
|
|
||||||
* Last trade for the given market (if available)
|
|
||||||
*/
|
|
||||||
lastTrade: DealTicketQuery_market_depth_lastTrade | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DealTicketQuery_market {
|
|
||||||
__typename: "Market";
|
|
||||||
/**
|
|
||||||
* Market ID
|
|
||||||
*/
|
|
||||||
id: string;
|
|
||||||
/**
|
|
||||||
* Market full name
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
/**
|
|
||||||
* decimalPlaces indicates the number of decimal places that an integer must be shifted by in order to get a correct
|
|
||||||
* number denominated in the currency of the Market. (uint64)
|
|
||||||
*
|
|
||||||
* Examples:
|
|
||||||
* Currency Balance decimalPlaces Real Balance
|
|
||||||
* GBP 100 0 GBP 100
|
|
||||||
* GBP 100 2 GBP 1.00
|
|
||||||
* GBP 100 4 GBP 0.01
|
|
||||||
* GBP 1 4 GBP 0.0001 ( 0.01p )
|
|
||||||
*
|
|
||||||
* GBX (pence) 100 0 GBP 1.00 (100p )
|
|
||||||
* GBX (pence) 100 2 GBP 0.01 ( 1p )
|
|
||||||
* GBX (pence) 100 4 GBP 0.0001 ( 0.01p )
|
|
||||||
* GBX (pence) 1 4 GBP 0.000001 ( 0.0001p)
|
|
||||||
*/
|
|
||||||
decimalPlaces: number;
|
|
||||||
/**
|
|
||||||
* positionDecimalPlaces indicated the number of decimal places that an integer must be shifted in order to get a correct size (uint64).
|
|
||||||
* i.e. 0 means there are no fractional orders for the market, and order sizes are always whole sizes.
|
|
||||||
* 2 means sizes given as 10^2 * desired size, e.g. a desired size of 1.23 is represented as 123 in this market.
|
|
||||||
*/
|
|
||||||
positionDecimalPlaces: number;
|
|
||||||
/**
|
|
||||||
* Current state of the market
|
|
||||||
*/
|
|
||||||
state: MarketState;
|
|
||||||
/**
|
|
||||||
* Current mode of execution of the market
|
|
||||||
*/
|
|
||||||
tradingMode: MarketTradingMode;
|
|
||||||
/**
|
|
||||||
* An instance of or reference to a tradable instrument.
|
|
||||||
*/
|
|
||||||
tradableInstrument: DealTicketQuery_market_tradableInstrument;
|
|
||||||
/**
|
|
||||||
* Current depth on the order book for this market
|
|
||||||
*/
|
|
||||||
depth: DealTicketQuery_market_depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DealTicketQuery {
|
|
||||||
/**
|
|
||||||
* An instrument that is trading on the VEGA network
|
|
||||||
*/
|
|
||||||
market: DealTicketQuery_market | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DealTicketQueryVariables {
|
|
||||||
marketId: string;
|
|
||||||
}
|
|
@ -9,12 +9,150 @@ import { MarketState, MarketTradingMode } from "@vegaprotocol/types";
|
|||||||
// GraphQL query operation: DealTicketQuery
|
// GraphQL query operation: DealTicketQuery
|
||||||
// ====================================================
|
// ====================================================
|
||||||
|
|
||||||
|
export interface DealTicketQuery_market_fees_factors {
|
||||||
|
__typename: "FeeFactors";
|
||||||
|
/**
|
||||||
|
* The factor applied to calculate MakerFees, a non-negative float
|
||||||
|
*/
|
||||||
|
makerFee: string;
|
||||||
|
/**
|
||||||
|
* The factor applied to calculate InfrastructureFees, a non-negative float
|
||||||
|
*/
|
||||||
|
infrastructureFee: string;
|
||||||
|
/**
|
||||||
|
* The factor applied to calculate LiquidityFees, a non-negative float
|
||||||
|
*/
|
||||||
|
liquidityFee: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DealTicketQuery_market_fees {
|
||||||
|
__typename: "Fees";
|
||||||
|
/**
|
||||||
|
* The factors used to calculate the different fees
|
||||||
|
*/
|
||||||
|
factors: DealTicketQuery_market_fees_factors;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DealTicketQuery_market_priceMonitoringSettings_parameters_triggers {
|
||||||
|
__typename: "PriceMonitoringTrigger";
|
||||||
|
/**
|
||||||
|
* Price monitoring projection horizon τ in seconds (> 0).
|
||||||
|
*/
|
||||||
|
horizonSecs: number;
|
||||||
|
/**
|
||||||
|
* Price monitoring probability level p. (>0 and < 1)
|
||||||
|
*/
|
||||||
|
probability: number;
|
||||||
|
/**
|
||||||
|
* Price monitoring auction extension duration in seconds should the price
|
||||||
|
* breach it's theoretical level over the specified horizon at the specified
|
||||||
|
* probability level (> 0)
|
||||||
|
*/
|
||||||
|
auctionExtensionSecs: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DealTicketQuery_market_priceMonitoringSettings_parameters {
|
||||||
|
__typename: "PriceMonitoringParameters";
|
||||||
|
/**
|
||||||
|
* The list of triggers for this price monitoring
|
||||||
|
*/
|
||||||
|
triggers: DealTicketQuery_market_priceMonitoringSettings_parameters_triggers[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DealTicketQuery_market_priceMonitoringSettings {
|
||||||
|
__typename: "PriceMonitoringSettings";
|
||||||
|
/**
|
||||||
|
* Specified a set of PriceMonitoringParameters to be use for price monitoring purposes
|
||||||
|
*/
|
||||||
|
parameters: DealTicketQuery_market_priceMonitoringSettings_parameters | null;
|
||||||
|
/**
|
||||||
|
* How often (in seconds) the price monitoring bounds should be updated
|
||||||
|
*/
|
||||||
|
updateFrequencySecs: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DealTicketQuery_market_riskFactors {
|
||||||
|
__typename: "RiskFactor";
|
||||||
|
/**
|
||||||
|
* market the risk factor was emitted for
|
||||||
|
*/
|
||||||
|
market: string;
|
||||||
|
/**
|
||||||
|
* short factor
|
||||||
|
*/
|
||||||
|
short: string;
|
||||||
|
/**
|
||||||
|
* long factor
|
||||||
|
*/
|
||||||
|
long: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DealTicketQuery_market_data_market {
|
||||||
|
__typename: "Market";
|
||||||
|
/**
|
||||||
|
* Market ID
|
||||||
|
*/
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DealTicketQuery_market_data {
|
||||||
|
__typename: "MarketData";
|
||||||
|
/**
|
||||||
|
* market id of the associated mark price
|
||||||
|
*/
|
||||||
|
market: DealTicketQuery_market_data_market;
|
||||||
|
/**
|
||||||
|
* the mark price (actually an unsigned int)
|
||||||
|
*/
|
||||||
|
markPrice: string;
|
||||||
|
/**
|
||||||
|
* indicative volume if the auction ended now, 0 if not in auction mode
|
||||||
|
*/
|
||||||
|
indicativeVolume: string;
|
||||||
|
/**
|
||||||
|
* the aggregated volume being bid at the best bid price.
|
||||||
|
*/
|
||||||
|
bestBidVolume: string;
|
||||||
|
/**
|
||||||
|
* the aggregated volume being offered at the best offer price.
|
||||||
|
*/
|
||||||
|
bestOfferVolume: string;
|
||||||
|
/**
|
||||||
|
* the aggregated volume being offered at the best static bid price, excluding pegged orders
|
||||||
|
*/
|
||||||
|
bestStaticBidVolume: string;
|
||||||
|
/**
|
||||||
|
* the aggregated volume being offered at the best static offer price, excluding pegged orders.
|
||||||
|
*/
|
||||||
|
bestStaticOfferVolume: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DealTicketQuery_market_tradableInstrument_instrument_product_settlementAsset {
|
||||||
|
__typename: "Asset";
|
||||||
|
/**
|
||||||
|
* The id of the asset
|
||||||
|
*/
|
||||||
|
id: string;
|
||||||
|
/**
|
||||||
|
* The symbol of the asset (e.g: GBP)
|
||||||
|
*/
|
||||||
|
symbol: string;
|
||||||
|
/**
|
||||||
|
* The full name of the asset (e.g: Great British Pound)
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface DealTicketQuery_market_tradableInstrument_instrument_product {
|
export interface DealTicketQuery_market_tradableInstrument_instrument_product {
|
||||||
__typename: "Future";
|
__typename: "Future";
|
||||||
/**
|
/**
|
||||||
* String representing the quote (e.g. BTCUSD -> USD is quote)
|
* String representing the quote (e.g. BTCUSD -> USD is quote)
|
||||||
*/
|
*/
|
||||||
quoteName: string;
|
quoteName: string;
|
||||||
|
/**
|
||||||
|
* The name of the asset (string)
|
||||||
|
*/
|
||||||
|
settlementAsset: DealTicketQuery_market_tradableInstrument_instrument_product_settlementAsset;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DealTicketQuery_market_tradableInstrument_instrument {
|
export interface DealTicketQuery_market_tradableInstrument_instrument {
|
||||||
@ -25,12 +163,70 @@ export interface DealTicketQuery_market_tradableInstrument_instrument {
|
|||||||
product: DealTicketQuery_market_tradableInstrument_instrument_product;
|
product: DealTicketQuery_market_tradableInstrument_instrument_product;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DealTicketQuery_market_tradableInstrument_riskModel_LogNormalRiskModel_params {
|
||||||
|
__typename: "LogNormalModelParams";
|
||||||
|
/**
|
||||||
|
* r parameter
|
||||||
|
*/
|
||||||
|
r: number;
|
||||||
|
/**
|
||||||
|
* sigma parameter
|
||||||
|
*/
|
||||||
|
sigma: number;
|
||||||
|
/**
|
||||||
|
* mu parameter
|
||||||
|
*/
|
||||||
|
mu: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DealTicketQuery_market_tradableInstrument_riskModel_LogNormalRiskModel {
|
||||||
|
__typename: "LogNormalRiskModel";
|
||||||
|
/**
|
||||||
|
* Tau parameter of the risk model
|
||||||
|
*/
|
||||||
|
tau: number;
|
||||||
|
/**
|
||||||
|
* Lambda parameter of the risk model
|
||||||
|
*/
|
||||||
|
riskAversionParameter: number;
|
||||||
|
/**
|
||||||
|
* Params for the log normal risk model
|
||||||
|
*/
|
||||||
|
params: DealTicketQuery_market_tradableInstrument_riskModel_LogNormalRiskModel_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DealTicketQuery_market_tradableInstrument_riskModel_SimpleRiskModel_params {
|
||||||
|
__typename: "SimpleRiskModelParams";
|
||||||
|
/**
|
||||||
|
* Risk factor for long
|
||||||
|
*/
|
||||||
|
factorLong: number;
|
||||||
|
/**
|
||||||
|
* Risk factor for short
|
||||||
|
*/
|
||||||
|
factorShort: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DealTicketQuery_market_tradableInstrument_riskModel_SimpleRiskModel {
|
||||||
|
__typename: "SimpleRiskModel";
|
||||||
|
/**
|
||||||
|
* Params for the simple risk model
|
||||||
|
*/
|
||||||
|
params: DealTicketQuery_market_tradableInstrument_riskModel_SimpleRiskModel_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DealTicketQuery_market_tradableInstrument_riskModel = DealTicketQuery_market_tradableInstrument_riskModel_LogNormalRiskModel | DealTicketQuery_market_tradableInstrument_riskModel_SimpleRiskModel;
|
||||||
|
|
||||||
export interface DealTicketQuery_market_tradableInstrument {
|
export interface DealTicketQuery_market_tradableInstrument {
|
||||||
__typename: "TradableInstrument";
|
__typename: "TradableInstrument";
|
||||||
/**
|
/**
|
||||||
* An instance of or reference to a fully specified instrument.
|
* An instance of or reference to a fully specified instrument.
|
||||||
*/
|
*/
|
||||||
instrument: DealTicketQuery_market_tradableInstrument_instrument;
|
instrument: DealTicketQuery_market_tradableInstrument_instrument;
|
||||||
|
/**
|
||||||
|
* A reference to a risk model that is valid for the instrument
|
||||||
|
*/
|
||||||
|
riskModel: DealTicketQuery_market_tradableInstrument_riskModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DealTicketQuery_market_depth_lastTrade {
|
export interface DealTicketQuery_market_depth_lastTrade {
|
||||||
@ -90,6 +286,22 @@ export interface DealTicketQuery_market {
|
|||||||
* Current mode of execution of the market
|
* Current mode of execution of the market
|
||||||
*/
|
*/
|
||||||
tradingMode: MarketTradingMode;
|
tradingMode: MarketTradingMode;
|
||||||
|
/**
|
||||||
|
* Fees related data
|
||||||
|
*/
|
||||||
|
fees: DealTicketQuery_market_fees;
|
||||||
|
/**
|
||||||
|
* Price monitoring settings for the market
|
||||||
|
*/
|
||||||
|
priceMonitoringSettings: DealTicketQuery_market_priceMonitoringSettings;
|
||||||
|
/**
|
||||||
|
* risk factors for the market
|
||||||
|
*/
|
||||||
|
riskFactors: DealTicketQuery_market_riskFactors | null;
|
||||||
|
/**
|
||||||
|
* marketData for the given market
|
||||||
|
*/
|
||||||
|
data: DealTicketQuery_market_data | null;
|
||||||
/**
|
/**
|
||||||
* An instance of or reference to a tradable instrument.
|
* An instance of or reference to a tradable instrument.
|
||||||
*/
|
*/
|
||||||
|
2
libs/deal-ticket/src/components/__generated__/index.ts
generated
Normal file
2
libs/deal-ticket/src/components/__generated__/index.ts
generated
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './DealTicketQuery';
|
||||||
|
export * from './OrderEvent';
|
@ -1,11 +1,14 @@
|
|||||||
import { gql, useQuery } from '@apollo/client';
|
import { gql, useQuery } from '@apollo/client';
|
||||||
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
import {
|
||||||
|
AsyncRenderer,
|
||||||
|
GridTab,
|
||||||
|
GridTabs,
|
||||||
|
Splash,
|
||||||
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
import { DealTicketManager } from './deal-ticket-manager';
|
import { DealTicketManager } from './deal-ticket-manager';
|
||||||
import type {
|
|
||||||
DealTicketQuery,
|
|
||||||
DealTicketQuery_market,
|
|
||||||
} from '../__generated__/DealTicketQuery';
|
|
||||||
import { t } from '@vegaprotocol/react-helpers';
|
import { t } from '@vegaprotocol/react-helpers';
|
||||||
|
import { Info } from './info-market';
|
||||||
|
import type { DealTicketQuery_market, DealTicketQuery } from './__generated__';
|
||||||
|
|
||||||
const DEAL_TICKET_QUERY = gql`
|
const DEAL_TICKET_QUERY = gql`
|
||||||
query DealTicketQuery($marketId: ID!) {
|
query DealTicketQuery($marketId: ID!) {
|
||||||
@ -16,6 +19,40 @@ const DEAL_TICKET_QUERY = gql`
|
|||||||
positionDecimalPlaces
|
positionDecimalPlaces
|
||||||
state
|
state
|
||||||
tradingMode
|
tradingMode
|
||||||
|
fees {
|
||||||
|
factors {
|
||||||
|
makerFee
|
||||||
|
infrastructureFee
|
||||||
|
liquidityFee
|
||||||
|
}
|
||||||
|
}
|
||||||
|
priceMonitoringSettings {
|
||||||
|
parameters {
|
||||||
|
triggers {
|
||||||
|
horizonSecs
|
||||||
|
probability
|
||||||
|
auctionExtensionSecs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateFrequencySecs
|
||||||
|
}
|
||||||
|
riskFactors {
|
||||||
|
market
|
||||||
|
short
|
||||||
|
long
|
||||||
|
}
|
||||||
|
data {
|
||||||
|
market {
|
||||||
|
id
|
||||||
|
}
|
||||||
|
markPrice
|
||||||
|
indicativeVolume
|
||||||
|
bestBidVolume
|
||||||
|
bestOfferVolume
|
||||||
|
bestStaticBidVolume
|
||||||
|
bestStaticOfferVolume
|
||||||
|
indicativeVolume
|
||||||
|
}
|
||||||
tradableInstrument {
|
tradableInstrument {
|
||||||
instrument {
|
instrument {
|
||||||
product {
|
product {
|
||||||
@ -29,6 +66,23 @@ const DEAL_TICKET_QUERY = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
riskModel {
|
||||||
|
... on LogNormalRiskModel {
|
||||||
|
tau
|
||||||
|
riskAversionParameter
|
||||||
|
params {
|
||||||
|
r
|
||||||
|
sigma
|
||||||
|
mu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
... on SimpleRiskModel {
|
||||||
|
params {
|
||||||
|
factorLong
|
||||||
|
factorShort
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
depth {
|
depth {
|
||||||
lastTrade {
|
lastTrade {
|
||||||
@ -57,7 +111,13 @@ export const DealTicketContainer = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AsyncRenderer<DealTicketQuery> data={data} loading={loading} error={error}>
|
<GridTabs>
|
||||||
|
<GridTab id="ticket" name={t('Ticket')}>
|
||||||
|
<AsyncRenderer<DealTicketQuery>
|
||||||
|
data={data}
|
||||||
|
loading={loading}
|
||||||
|
error={error}
|
||||||
|
>
|
||||||
{data && data.market ? (
|
{data && data.market ? (
|
||||||
children ? (
|
children ? (
|
||||||
children(data)
|
children(data)
|
||||||
@ -70,5 +130,26 @@ export const DealTicketContainer = ({
|
|||||||
</Splash>
|
</Splash>
|
||||||
)}
|
)}
|
||||||
</AsyncRenderer>
|
</AsyncRenderer>
|
||||||
|
</GridTab>
|
||||||
|
<GridTab id="info" name={t('Info')}>
|
||||||
|
<AsyncRenderer<DealTicketQuery>
|
||||||
|
data={data}
|
||||||
|
loading={loading}
|
||||||
|
error={error}
|
||||||
|
>
|
||||||
|
{data && data.market ? (
|
||||||
|
children ? (
|
||||||
|
children(data)
|
||||||
|
) : (
|
||||||
|
<Info market={data.market} />
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
<Splash>
|
||||||
|
<p>{t('Could not load market')}</p>
|
||||||
|
</Splash>
|
||||||
|
)}
|
||||||
|
</AsyncRenderer>
|
||||||
|
</GridTab>
|
||||||
|
</GridTabs>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@ import { VegaTxStatus } from '@vegaprotocol/wallet';
|
|||||||
import { DealTicket } from './deal-ticket';
|
import { DealTicket } from './deal-ticket';
|
||||||
import { OrderDialog } from './order-dialog';
|
import { OrderDialog } from './order-dialog';
|
||||||
import { useOrderSubmit } from '../hooks/use-order-submit';
|
import { useOrderSubmit } from '../hooks/use-order-submit';
|
||||||
import type { DealTicketQuery_market } from '../__generated__/DealTicketQuery';
|
import type { DealTicketQuery_market } from './__generated__/DealTicketQuery';
|
||||||
|
|
||||||
export interface DealTicketManagerProps {
|
export interface DealTicketManagerProps {
|
||||||
market: DealTicketQuery_market;
|
market: DealTicketQuery_market;
|
||||||
|
@ -7,11 +7,11 @@ import { TypeSelector } from './type-selector';
|
|||||||
import { SideSelector } from './side-selector';
|
import { SideSelector } from './side-selector';
|
||||||
import { DealTicketAmount } from './deal-ticket-amount';
|
import { DealTicketAmount } from './deal-ticket-amount';
|
||||||
import { TimeInForceSelector } from './time-in-force-selector';
|
import { TimeInForceSelector } from './time-in-force-selector';
|
||||||
import { ExpirySelector } from './expiry-selector';
|
import { useOrderValidation } from '../hooks/use-order-validation';
|
||||||
import type { DealTicketQuery_market } from '../__generated__/DealTicketQuery';
|
import type { DealTicketQuery_market } from './__generated__/DealTicketQuery';
|
||||||
import type { Order } from '../utils/get-default-order';
|
import type { Order } from '../utils/get-default-order';
|
||||||
import { getDefaultOrder } from '../utils/get-default-order';
|
import { getDefaultOrder } from '../utils/get-default-order';
|
||||||
import { useOrderValidation } from '../hooks/use-order-validation';
|
import { ExpirySelector } from './expiry-selector';
|
||||||
|
|
||||||
export type TransactionStatus = 'default' | 'pending';
|
export type TransactionStatus = 'default' | 'pending';
|
||||||
|
|
||||||
|
13
libs/deal-ticket/src/components/index.ts
Normal file
13
libs/deal-ticket/src/components/index.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export * from './__generated__';
|
||||||
|
export * from './deal-ticket-amount';
|
||||||
|
export * from './deal-ticket-container';
|
||||||
|
export * from './deal-ticket-limit-amount';
|
||||||
|
export * from './deal-ticket-manager';
|
||||||
|
export * from './deal-ticket-market-amount';
|
||||||
|
export * from './deal-ticket';
|
||||||
|
export * from './expiry-selector';
|
||||||
|
export * from './info-market';
|
||||||
|
export * from './order-dialog';
|
||||||
|
export * from './side-selector';
|
||||||
|
export * from './time-in-force-selector';
|
||||||
|
export * from './type-selector';
|
193
libs/deal-ticket/src/components/info-market.tsx
Normal file
193
libs/deal-ticket/src/components/info-market.tsx
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
import {
|
||||||
|
addDecimalsFormatNumber,
|
||||||
|
formatNumber,
|
||||||
|
formatNumberPercentage,
|
||||||
|
t,
|
||||||
|
} from '@vegaprotocol/react-helpers';
|
||||||
|
import {
|
||||||
|
KeyValueTable,
|
||||||
|
KeyValueTableRow,
|
||||||
|
AccordionPanel,
|
||||||
|
} from '@vegaprotocol/ui-toolkit';
|
||||||
|
import startCase from 'lodash/startCase';
|
||||||
|
import pick from 'lodash/pick';
|
||||||
|
import omit from 'lodash/omit';
|
||||||
|
import type { DealTicketQuery_market } from './__generated__/DealTicketQuery';
|
||||||
|
import BigNumber from 'bignumber.js';
|
||||||
|
|
||||||
|
export interface InfoProps {
|
||||||
|
market: DealTicketQuery_market;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Info = ({ market }: InfoProps) => {
|
||||||
|
const headerClassName =
|
||||||
|
'text-h5 font-bold uppercase text-black dark:text-white';
|
||||||
|
return (
|
||||||
|
<div className="p-16 flex flex-col gap-32">
|
||||||
|
<div className="flex flex-col gap-12">
|
||||||
|
<p className={headerClassName}>{t('Market data')}</p>
|
||||||
|
<AccordionPanel
|
||||||
|
key="fees"
|
||||||
|
title={t('Current fees')}
|
||||||
|
content={
|
||||||
|
<>
|
||||||
|
<MarketInfoTable data={market.fees.factors} asPercentage={true} />
|
||||||
|
<p className="text-ui-small">
|
||||||
|
{t(
|
||||||
|
'All fees are paid by price takers and are a % of the trade notional value. Fees are not paid during auction uncrossing.'
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<AccordionPanel
|
||||||
|
key="market-data"
|
||||||
|
title={t('Market data')}
|
||||||
|
content={
|
||||||
|
<MarketInfoTable
|
||||||
|
data={market.data}
|
||||||
|
decimalPlaces={market.decimalPlaces}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="flex flex-col gap-12">
|
||||||
|
<p className={headerClassName}>{t('Market specification')}</p>
|
||||||
|
<AccordionPanel
|
||||||
|
title={t('Key details')}
|
||||||
|
key="details"
|
||||||
|
content={
|
||||||
|
<MarketInfoTable
|
||||||
|
data={pick(
|
||||||
|
market,
|
||||||
|
'name',
|
||||||
|
'decimalPlaces',
|
||||||
|
'positionDecimalPlaces',
|
||||||
|
'tradingMode',
|
||||||
|
'state'
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<AccordionPanel
|
||||||
|
title={t('Instrument')}
|
||||||
|
key="instrument"
|
||||||
|
content={
|
||||||
|
<MarketInfoTable
|
||||||
|
data={{
|
||||||
|
product: market.tradableInstrument.instrument.product,
|
||||||
|
...market.tradableInstrument.instrument.product.settlementAsset,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<AccordionPanel
|
||||||
|
title={t('Risk factors')}
|
||||||
|
key="risk-factors"
|
||||||
|
content={
|
||||||
|
<MarketInfoTable
|
||||||
|
data={market.riskFactors}
|
||||||
|
unformatted={true}
|
||||||
|
omits={['market', '__typename']}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<AccordionPanel
|
||||||
|
title={t('Risk model')}
|
||||||
|
key="risk-model"
|
||||||
|
content={
|
||||||
|
<MarketInfoTable
|
||||||
|
data={market.tradableInstrument.riskModel}
|
||||||
|
unformatted={true}
|
||||||
|
omits={[]}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{(market.priceMonitoringSettings?.parameters?.triggers ?? []).map(
|
||||||
|
(trigger, i) => (
|
||||||
|
<AccordionPanel
|
||||||
|
key={`trigger-${i}`}
|
||||||
|
title={t(`Price monitoring trigger ${i + 1}`)}
|
||||||
|
content={<MarketInfoTable data={trigger} />}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
interface RowProps {
|
||||||
|
field: string;
|
||||||
|
value: any;
|
||||||
|
decimalPlaces?: number;
|
||||||
|
asPercentage?: boolean;
|
||||||
|
unformatted?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Row = ({
|
||||||
|
field,
|
||||||
|
value,
|
||||||
|
decimalPlaces,
|
||||||
|
asPercentage,
|
||||||
|
unformatted,
|
||||||
|
}: RowProps) => {
|
||||||
|
const isNumber = typeof value === 'number' || !isNaN(Number(value));
|
||||||
|
const isPrimitive = typeof value === 'string' || isNumber;
|
||||||
|
const className = 'text-black dark:text-white text-ui !px-0 !font-normal';
|
||||||
|
if (isPrimitive) {
|
||||||
|
return (
|
||||||
|
<KeyValueTableRow
|
||||||
|
key={field}
|
||||||
|
inline={isPrimitive}
|
||||||
|
muted={true}
|
||||||
|
noBorder={true}
|
||||||
|
dtClassName={className}
|
||||||
|
ddClassName={className}
|
||||||
|
>
|
||||||
|
{startCase(t(field))}
|
||||||
|
{isNumber && !unformatted
|
||||||
|
? decimalPlaces
|
||||||
|
? addDecimalsFormatNumber(value, decimalPlaces)
|
||||||
|
: asPercentage
|
||||||
|
? formatNumberPercentage(new BigNumber(value))
|
||||||
|
: formatNumber(Number(value))
|
||||||
|
: value}
|
||||||
|
</KeyValueTableRow>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface MarketInfoTableProps {
|
||||||
|
data: any;
|
||||||
|
decimalPlaces?: number;
|
||||||
|
asPercentage?: boolean;
|
||||||
|
unformatted?: boolean;
|
||||||
|
omits?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MarketInfoTable = ({
|
||||||
|
data,
|
||||||
|
decimalPlaces,
|
||||||
|
asPercentage,
|
||||||
|
unformatted,
|
||||||
|
omits = ['id', '__typename'],
|
||||||
|
}: MarketInfoTableProps) => {
|
||||||
|
return (
|
||||||
|
<KeyValueTable muted={true}>
|
||||||
|
{Object.entries(omit(data, ...omits) || []).map(([key, value]) => (
|
||||||
|
<Row
|
||||||
|
key={key}
|
||||||
|
field={key}
|
||||||
|
value={value}
|
||||||
|
decimalPlaces={decimalPlaces}
|
||||||
|
asPercentage={asPercentage}
|
||||||
|
unformatted={unformatted || key.toLowerCase().includes('volume')}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</KeyValueTable>
|
||||||
|
);
|
||||||
|
};
|
@ -1,6 +1,6 @@
|
|||||||
import { Icon, Loader } from '@vegaprotocol/ui-toolkit';
|
import { Icon, Loader } from '@vegaprotocol/ui-toolkit';
|
||||||
import type { ReactNode } from 'react';
|
import type { ReactNode } from 'react';
|
||||||
import type { OrderEvent_busEvents_event_Order } from '../__generated__/OrderEvent';
|
import type { OrderEvent_busEvents_event_Order } from './__generated__/OrderEvent';
|
||||||
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
|
import { addDecimalsFormatNumber, t } from '@vegaprotocol/react-helpers';
|
||||||
import type { VegaTxState } from '@vegaprotocol/wallet';
|
import type { VegaTxState } from '@vegaprotocol/wallet';
|
||||||
import { VegaTxStatus } from '@vegaprotocol/wallet';
|
import { VegaTxStatus } from '@vegaprotocol/wallet';
|
||||||
|
@ -8,8 +8,8 @@ import type {
|
|||||||
OrderEvent,
|
OrderEvent,
|
||||||
OrderEventVariables,
|
OrderEventVariables,
|
||||||
OrderEvent_busEvents_event_Order,
|
OrderEvent_busEvents_event_Order,
|
||||||
} from '../__generated__/OrderEvent';
|
} from '../components/__generated__/OrderEvent';
|
||||||
import type { DealTicketQuery_market } from '../__generated__/DealTicketQuery';
|
import type { DealTicketQuery_market } from '../components/__generated__/DealTicketQuery';
|
||||||
|
|
||||||
const ORDER_EVENT_SUB = gql`
|
const ORDER_EVENT_SUB = gql`
|
||||||
subscription OrderEvent($partyId: ID!) {
|
subscription OrderEvent($partyId: ID!) {
|
||||||
|
@ -8,8 +8,8 @@ import {
|
|||||||
} from '@vegaprotocol/wallet';
|
} from '@vegaprotocol/wallet';
|
||||||
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
|
import { MarketState, MarketTradingMode } from '@vegaprotocol/types';
|
||||||
import type { Order } from '../utils/get-default-order';
|
import type { Order } from '../utils/get-default-order';
|
||||||
import type { DealTicketQuery_market } from '../__generated__/DealTicketQuery';
|
|
||||||
import { ERROR_SIZE_DECIMAL } from '../utils/validate-size';
|
import { ERROR_SIZE_DECIMAL } from '../utils/validate-size';
|
||||||
|
import type { DealTicketQuery_market } from '../components/__generated__/DealTicketQuery';
|
||||||
|
|
||||||
export type ValidationProps = {
|
export type ValidationProps = {
|
||||||
step: number;
|
step: number;
|
||||||
|
@ -1,16 +1,4 @@
|
|||||||
export * from './components/expiry-selector';
|
export * from './components';
|
||||||
export * from './components/type-selector';
|
|
||||||
export * from './components/time-in-force-selector';
|
|
||||||
export * from './components/side-selector';
|
|
||||||
export * from './components/deal-ticket';
|
|
||||||
export * from './components/deal-ticket-amount';
|
|
||||||
export * from './components/deal-ticket-limit-amount';
|
|
||||||
export * from './components/deal-ticket-market-amount';
|
|
||||||
export * from './components/deal-ticket-manager';
|
|
||||||
export * from './components/order-dialog';
|
|
||||||
export * from './components/deal-ticket-container';
|
|
||||||
export * from './__generated__/DealTicketQuery';
|
|
||||||
export * from './__generated__/OrderEvent';
|
|
||||||
export * from './utils/get-default-order';
|
export * from './utils/get-default-order';
|
||||||
export * from './hooks/use-order-submit';
|
export * from './hooks/use-order-submit';
|
||||||
export * from './hooks/use-order-validation';
|
export * from './hooks/use-order-validation';
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { OrderTimeInForce, OrderType, OrderSide } from '@vegaprotocol/wallet';
|
import { OrderTimeInForce, OrderType, OrderSide } from '@vegaprotocol/wallet';
|
||||||
import type { DealTicketQuery_market } from '../__generated__/DealTicketQuery';
|
|
||||||
import { toDecimal } from '@vegaprotocol/react-helpers';
|
import { toDecimal } from '@vegaprotocol/react-helpers';
|
||||||
|
import type { DealTicketQuery_market } from '../components/__generated__/DealTicketQuery';
|
||||||
|
|
||||||
export type Order =
|
export type Order =
|
||||||
| {
|
| {
|
||||||
|
33
libs/ui-toolkit/src/components/accordion/accordion.spec.tsx
Normal file
33
libs/ui-toolkit/src/components/accordion/accordion.spec.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { fireEvent, render, screen } from '@testing-library/react';
|
||||||
|
|
||||||
|
import { AccordionPanel } from './accordion';
|
||||||
|
|
||||||
|
describe('Accordion', () => {
|
||||||
|
it('should render successfully', () => {
|
||||||
|
render(
|
||||||
|
<AccordionPanel
|
||||||
|
title={'Lorem ipsum title'}
|
||||||
|
content={'Lorem ipsum content'}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
expect(screen.queryByTestId('accordion-title')).toHaveTextContent(
|
||||||
|
'Lorem ipsum title'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should toggle and open expansion panel', () => {
|
||||||
|
render(
|
||||||
|
<AccordionPanel
|
||||||
|
title={'Lorem ipsum title'}
|
||||||
|
content={'Lorem ipsum content'}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
fireEvent.click(screen.getByTestId('accordion-toggle'));
|
||||||
|
expect(screen.queryByTestId('accordion-title')).toHaveTextContent(
|
||||||
|
'Lorem ipsum title'
|
||||||
|
);
|
||||||
|
expect(screen.getByTestId('accordion-content')).toHaveTextContent(
|
||||||
|
'Lorem ipsum content'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,17 @@
|
|||||||
|
import type { Story, Meta } from '@storybook/react';
|
||||||
|
import { AccordionPanel } from './accordion';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
component: AccordionPanel,
|
||||||
|
title: 'Accordion',
|
||||||
|
} as Meta;
|
||||||
|
|
||||||
|
const Template: Story = (args) => (
|
||||||
|
<AccordionPanel title={args.title} content={args.content} />
|
||||||
|
);
|
||||||
|
|
||||||
|
export const Default = Template.bind({});
|
||||||
|
Default.args = {
|
||||||
|
title: 'Title of expansion panel',
|
||||||
|
content: 'Lorem ipsum',
|
||||||
|
};
|
73
libs/ui-toolkit/src/components/accordion/accordion.tsx
Normal file
73
libs/ui-toolkit/src/components/accordion/accordion.tsx
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import React, { useRef, useState } from 'react';
|
||||||
|
|
||||||
|
export interface AccordionProps {
|
||||||
|
title: React.ReactNode;
|
||||||
|
content: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AccordionPanel = ({ title, content }: AccordionProps) => {
|
||||||
|
const [active, setActive] = useState(false);
|
||||||
|
const [height, setHeight] = useState('0px');
|
||||||
|
const [rotate, setRotate] = useState(
|
||||||
|
'transform duration-300 ease rotate-180'
|
||||||
|
);
|
||||||
|
|
||||||
|
const contentSpace = useRef(null);
|
||||||
|
|
||||||
|
const toggleAccordion = () => {
|
||||||
|
setActive((prevState) => !prevState);
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
setHeight(active ? '0px' : `${contentSpace.current.scrollHeight}px`);
|
||||||
|
setRotate(
|
||||||
|
active
|
||||||
|
? 'transform duration-300 ease rotate-180'
|
||||||
|
: 'transform duration-300 ease'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex flex-col">
|
||||||
|
<button
|
||||||
|
data-testid="accordion-toggle"
|
||||||
|
className="py-2 box-border appearance-none cursor-pointer focus:outline-none flex items-center justify-between border-b border-muted"
|
||||||
|
onClick={toggleAccordion}
|
||||||
|
>
|
||||||
|
<p
|
||||||
|
className="inline-block text-footnote font-bold text-h6 text-black dark:text-white pt-5 "
|
||||||
|
data-testid="accordion-title"
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</p>
|
||||||
|
<svg
|
||||||
|
width="20"
|
||||||
|
height="20"
|
||||||
|
aria-label="chevron icon"
|
||||||
|
data-testid="accordion-chevron-icon"
|
||||||
|
className={`${rotate} inline-block fill-black dark:fill-white`}
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="fillCurrent"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<rect x="3" y="12" width="2" height="2" />
|
||||||
|
<rect x="5" y="10" width="2" height="2" />
|
||||||
|
<rect x="7" y="8" width="2" height="2" />
|
||||||
|
<rect x="9" y="6" width="2" height="2" />
|
||||||
|
<rect x="11" y="8" width="2" height="2" />
|
||||||
|
<rect x="13" y="10" width="2" height="2" />
|
||||||
|
<rect x="15" y="12" width="2" height="2" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<div
|
||||||
|
ref={contentSpace}
|
||||||
|
style={{ maxHeight: `${height}` }}
|
||||||
|
data-testid="accordion-content-ref"
|
||||||
|
className="overflow-auto transition-max-height duration-300 ease-in-out"
|
||||||
|
>
|
||||||
|
<div className="pb-5" data-testid="accordion-content">
|
||||||
|
{content}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
1
libs/ui-toolkit/src/components/accordion/index.ts
Normal file
1
libs/ui-toolkit/src/components/accordion/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './accordion';
|
@ -1,3 +1,4 @@
|
|||||||
|
export * from './accordion';
|
||||||
export * from './ag-grid';
|
export * from './ag-grid';
|
||||||
export * from './arrows';
|
export * from './arrows';
|
||||||
export * from './async-renderer';
|
export * from './async-renderer';
|
||||||
@ -7,13 +8,14 @@ export * from './card';
|
|||||||
export * from './copy-with-tooltip';
|
export * from './copy-with-tooltip';
|
||||||
export * from './dialog';
|
export * from './dialog';
|
||||||
export * from './dropdown-menu';
|
export * from './dropdown-menu';
|
||||||
export * from './link';
|
|
||||||
export * from './form-group';
|
export * from './form-group';
|
||||||
|
export * from './grid-tabs';
|
||||||
export * from './icon';
|
export * from './icon';
|
||||||
export * from './indicator';
|
export * from './indicator';
|
||||||
export * from './input';
|
export * from './input';
|
||||||
export * from './input-error';
|
export * from './input-error';
|
||||||
export * from './key-value-table';
|
export * from './key-value-table';
|
||||||
|
export * from './link';
|
||||||
export * from './loader';
|
export * from './loader';
|
||||||
export * from './lozenge';
|
export * from './lozenge';
|
||||||
export * from './price-change';
|
export * from './price-change';
|
||||||
|
@ -63,6 +63,9 @@ export interface KeyValueTableRowProps
|
|||||||
numerical?: boolean; // makes all values monospace
|
numerical?: boolean; // makes all values monospace
|
||||||
muted?: boolean;
|
muted?: boolean;
|
||||||
inline?: boolean;
|
inline?: boolean;
|
||||||
|
noBorder?: boolean;
|
||||||
|
dtClassName?: string;
|
||||||
|
ddClassName?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const KeyValueTableRow = ({
|
export const KeyValueTableRow = ({
|
||||||
@ -71,9 +74,13 @@ export const KeyValueTableRow = ({
|
|||||||
muted,
|
muted,
|
||||||
numerical,
|
numerical,
|
||||||
inline = true,
|
inline = true,
|
||||||
|
noBorder = false,
|
||||||
|
dtClassName,
|
||||||
|
ddClassName,
|
||||||
}: KeyValueTableRowProps) => {
|
}: KeyValueTableRowProps) => {
|
||||||
const dlClassName = classNames(
|
const dlClassName = classNames(
|
||||||
'flex gap-1 flex-wrap justify-between border-b first:border-t border-black dark:border-white',
|
'flex gap-1 flex-wrap justify-between ',
|
||||||
|
{ 'border-b first:border-t border-black dark:border-white': !noBorder },
|
||||||
{ 'flex-col items-start': !inline },
|
{ 'flex-col items-start': !inline },
|
||||||
{ 'flex-row items-center': inline },
|
{ 'flex-row items-center': inline },
|
||||||
{
|
{
|
||||||
@ -82,18 +89,19 @@ export const KeyValueTableRow = ({
|
|||||||
},
|
},
|
||||||
className
|
className
|
||||||
);
|
);
|
||||||
const dtClassName = `break-words font-medium uppercase align-top p-4 capitalize`;
|
const dtClassNames = `break-words font-medium uppercase align-top p-4 capitalize ${dtClassName}`;
|
||||||
const ddClassName = classNames(
|
const ddClassNames = classNames(
|
||||||
'align-top p-4 text-black/60 dark:text-white/60 break-words',
|
'align-top p-4 text-black/60 dark:text-white/60 break-words',
|
||||||
{
|
{
|
||||||
'font-mono': numerical,
|
'font-mono': numerical,
|
||||||
}
|
},
|
||||||
|
ddClassName
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<dl className={dlClassName} data-testid="key-value-table-row">
|
<dl className={dlClassName} data-testid="key-value-table-row">
|
||||||
<dt className={dtClassName}>{children[0]}</dt>
|
<dt className={dtClassNames}>{children[0]}</dt>
|
||||||
<dd className={ddClassName}>{children[1]}</dd>
|
<dd className={ddClassNames}>{children[1]}</dd>
|
||||||
</dl>
|
</dl>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user