Feature/vega core (#376)
* Initial commit after nx create * Add .env files * Add working commit for poc * Make deal-ticket-manager.tsx accept children as props and export more components to be consumed by external apps * Add stepper component to simple trading app * Add basic prototype for simple trading app with stepper component * Remove unnecessary flags and env variables * Change simple trading app port * Refactor deal ticket container to be more dry * Refactor deal ticket to be more dry * Refactor app loader, remove tendermint socket and change providers for App.tsx in simple trading app * Remove example cypress files and change config * Fix linting issues
This commit is contained in:
parent
6bccfaf8ab
commit
7266ac9b37
10
apps/simple-trading-app-e2e/.eslintrc.json
Normal file
10
apps/simple-trading-app-e2e/.eslintrc.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": ["plugin:cypress/recommended", "../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
16
apps/simple-trading-app-e2e/cypress.json
Normal file
16
apps/simple-trading-app-e2e/cypress.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"baseUrl": "http://localhost:4200",
|
||||
"fileServerFolder": ".",
|
||||
"testFiles": "*.{ts,feature,features}",
|
||||
"ignoreTestFiles": "**/*.js",
|
||||
"fixturesFolder": "./src/fixtures",
|
||||
"integrationFolder": "./src/integration",
|
||||
"modifyObstructiveCode": false,
|
||||
"supportFile": "./src/support/index.ts",
|
||||
"pluginsFile": false,
|
||||
"video": true,
|
||||
"videosFolder": "../../dist/cypress/apps/simple-trading-app-e2e/videos",
|
||||
"screenshotsFolder": "../../dist/cypress/apps/simple-trading-app-e2e/screenshots",
|
||||
"chromeWebSecurity": false,
|
||||
"projectId": "et4snf"
|
||||
}
|
28
apps/simple-trading-app-e2e/project.json
Normal file
28
apps/simple-trading-app-e2e/project.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"root": "apps/simple-trading-app-e2e",
|
||||
"sourceRoot": "apps/simple-trading-app-e2e/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"e2e": {
|
||||
"executor": "@nrwl/cypress:cypress",
|
||||
"options": {
|
||||
"cypressConfig": "apps/simple-trading-app-e2e/cypress.json",
|
||||
"devServerTarget": "simple-trading-app:serve"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"devServerTarget": "simple-trading-app:serve:production"
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nrwl/linter:eslint",
|
||||
"outputs": ["{options.outputFile}"],
|
||||
"options": {
|
||||
"lintFilePatterns": ["apps/simple-trading-app-e2e/**/*.{js,ts}"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [],
|
||||
"implicitDependencies": ["simple-trading-app"]
|
||||
}
|
0
apps/simple-trading-app-e2e/src/support/app.po.ts
Normal file
0
apps/simple-trading-app-e2e/src/support/app.po.ts
Normal file
9
apps/simple-trading-app-e2e/src/support/commands.ts
Normal file
9
apps/simple-trading-app-e2e/src/support/commands.ts
Normal file
@ -0,0 +1,9 @@
|
||||
// ***********************************************
|
||||
// This example commands.js shows you how to
|
||||
// create various custom commands and overwrite
|
||||
// existing commands.
|
||||
//
|
||||
// For more comprehensive examples of custom
|
||||
// commands please read more here:
|
||||
// https://on.cypress.io/custom-commands
|
||||
// ***********************************************
|
17
apps/simple-trading-app-e2e/src/support/index.ts
Normal file
17
apps/simple-trading-app-e2e/src/support/index.ts
Normal file
@ -0,0 +1,17 @@
|
||||
// ***********************************************************
|
||||
// This example support/index.js is processed and
|
||||
// loaded automatically before your test files.
|
||||
//
|
||||
// This is a great place to put global configuration and
|
||||
// behavior that modifies Cypress.
|
||||
//
|
||||
// You can change the location of this file or turn off
|
||||
// automatically serving support files with the
|
||||
// 'supportFile' configuration option.
|
||||
//
|
||||
// You can read more here:
|
||||
// https://on.cypress.io/configuration
|
||||
// ***********************************************************
|
||||
|
||||
// Import commands.js using ES2015 syntax:
|
||||
import './commands';
|
10
apps/simple-trading-app-e2e/tsconfig.json
Normal file
10
apps/simple-trading-app-e2e/tsconfig.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": false,
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"allowJs": true,
|
||||
"types": ["cypress", "node"]
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.js"]
|
||||
}
|
11
apps/simple-trading-app/.babelrc
Normal file
11
apps/simple-trading-app/.babelrc
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@nrwl/react/babel",
|
||||
{
|
||||
"runtime": "automatic"
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": []
|
||||
}
|
16
apps/simple-trading-app/.browserslistrc
Normal file
16
apps/simple-trading-app/.browserslistrc
Normal file
@ -0,0 +1,16 @@
|
||||
# This file is used by:
|
||||
# 1. autoprefixer to adjust CSS to support the below specified browsers
|
||||
# 2. babel preset-env to adjust included polyfills
|
||||
#
|
||||
# For additional information regarding the format and rule options, please see:
|
||||
# https://github.com/browserslist/browserslist#queries
|
||||
#
|
||||
# If you need to support different browsers in production, you may tweak the list below.
|
||||
|
||||
last 1 Chrome version
|
||||
last 1 Firefox version
|
||||
last 2 Edge major versions
|
||||
last 2 Safari major version
|
||||
last 2 iOS major versions
|
||||
Firefox ESR
|
||||
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
19
apps/simple-trading-app/.env
Normal file
19
apps/simple-trading-app/.env
Normal file
@ -0,0 +1,19 @@
|
||||
# React Environment Variables
|
||||
# https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables#expanding-environment-variables-in-env
|
||||
|
||||
# Netlify Environment Variables
|
||||
# https://www.netlify.com/docs/continuous-deployment/#environment-variables
|
||||
NX_VERSION=$npm_package_version
|
||||
NX_REPOSITORY_URL=$REPOSITORY_URL
|
||||
NX_BRANCH=$BRANCH
|
||||
NX_PULL_REQUEST=$PULL_REQUEST
|
||||
NX_HEAD=$HEAD
|
||||
NX_COMMIT_REF=$COMMIT_REF
|
||||
NX_CONTEXT=$CONTEXT
|
||||
NX_REVIEW_ID=$REVIEW_ID
|
||||
NX_INCOMING_HOOK_TITLE=$INCOMING_HOOK_TITLE
|
||||
NX_INCOMING_HOOK_URL=$INCOMING_HOOK_URL
|
||||
NX_INCOMING_HOOK_BODY=$INCOMING_HOOK_BODY
|
||||
NX_URL=$URL
|
||||
NX_DEPLOY_URL=$DEPLOY_URL
|
||||
NX_DEPLOY_PRIME_URL=$DEPLOY_PRIME_URL
|
4
apps/simple-trading-app/.env.capsule
Normal file
4
apps/simple-trading-app/.env.capsule
Normal file
@ -0,0 +1,4 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_URL = "http://localhost:3028/query"
|
||||
NX_VEGA_ENV = 'LOCAL'
|
||||
NX_VEGA_REST = 'http://localhost:3029'
|
4
apps/simple-trading-app/.env.devent
Normal file
4
apps/simple-trading-app/.env.devent
Normal file
@ -0,0 +1,4 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_URL = "https://n04.d.vega.xyz/query"
|
||||
NX_VEGA_ENV = 'DEVNET'
|
||||
NX_VEGA_REST = 'https://n04.d.vega.xyz/datanode/rest'
|
4
apps/simple-trading-app/.env.mainnet
Normal file
4
apps/simple-trading-app/.env.mainnet
Normal file
@ -0,0 +1,4 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_URL = "https://api.token.vega.xyz/query"
|
||||
NX_VEGA_ENV = 'MAINNET'
|
||||
NX_VEGA_REST = 'https://api.token.vega.xyz/'
|
4
apps/simple-trading-app/.env.stagnet1
Normal file
4
apps/simple-trading-app/.env.stagnet1
Normal file
@ -0,0 +1,4 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_URL = "https://n03.s.vega.xyz/query"
|
||||
NX_VEGA_ENV = 'STAGNET'
|
||||
NX_VEGA_REST = 'https://n03.s.vega.xyz/datanode/rest'
|
4
apps/simple-trading-app/.env.stagnet2
Normal file
4
apps/simple-trading-app/.env.stagnet2
Normal file
@ -0,0 +1,4 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_URL = "https://n03.stagnet2.vega.xyz/query"
|
||||
NX_VEGA_ENV = 'STAGNET2'
|
||||
NX_VEGA_REST = 'https://n01.stagnet2.vega.xyz/datanode/rest'
|
4
apps/simple-trading-app/.env.testnet
Normal file
4
apps/simple-trading-app/.env.testnet
Normal file
@ -0,0 +1,4 @@
|
||||
# App configuration variables
|
||||
NX_VEGA_URL = "https://lb.testnet.vega.xyz/query"
|
||||
NX_VEGA_ENV = 'TESTNET'
|
||||
NX_VEGA_REST = 'https://lb.testnet.vega.xyz/datanode/rest'
|
18
apps/simple-trading-app/.eslintrc.json
Normal file
18
apps/simple-trading-app/.eslintrc.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": ["plugin:@nrwl/nx/react", "../../.eslintrc.json"],
|
||||
"ignorePatterns": ["!**/*"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.ts", "*.tsx"],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": ["*.js", "*.jsx"],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
11
apps/simple-trading-app/jest.config.js
Normal file
11
apps/simple-trading-app/jest.config.js
Normal file
@ -0,0 +1,11 @@
|
||||
module.exports = {
|
||||
displayName: 'simple-trading-app',
|
||||
preset: '../../jest.preset.js',
|
||||
transform: {
|
||||
'^(?!.*\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest',
|
||||
'^.+\\.[tj]sx?$': ['babel-jest', { presets: ['@nrwl/next/babel'] }],
|
||||
},
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
|
||||
coverageDirectory: '../../coverage/apps/simple-trading-app',
|
||||
setupFilesAfterEnv: ['./setup-tests.ts'],
|
||||
};
|
10
apps/simple-trading-app/postcss.config.js
Normal file
10
apps/simple-trading-app/postcss.config.js
Normal file
@ -0,0 +1,10 @@
|
||||
const { join } = require('path');
|
||||
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {
|
||||
config: join(__dirname, 'tailwind.config.js'),
|
||||
},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
74
apps/simple-trading-app/project.json
Normal file
74
apps/simple-trading-app/project.json
Normal file
@ -0,0 +1,74 @@
|
||||
{
|
||||
"root": "apps/simple-trading-app",
|
||||
"sourceRoot": "apps/simple-trading-app/src",
|
||||
"projectType": "application",
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nrwl/web:webpack",
|
||||
"outputs": ["{options.outputPath}"],
|
||||
"defaultConfiguration": "production",
|
||||
"options": {
|
||||
"compiler": "babel",
|
||||
"outputPath": "dist/apps/simple-trading-app",
|
||||
"index": "apps/simple-trading-app/src/index.html",
|
||||
"baseHref": "/",
|
||||
"main": "apps/simple-trading-app/src/main.tsx",
|
||||
"polyfills": "apps/simple-trading-app/src/polyfills.ts",
|
||||
"tsConfig": "apps/simple-trading-app/tsconfig.app.json",
|
||||
"assets": [
|
||||
"apps/simple-trading-app/src/favicon.ico",
|
||||
"apps/simple-trading-app/src/assets"
|
||||
],
|
||||
"styles": ["apps/simple-trading-app/src/styles.scss"],
|
||||
"scripts": [],
|
||||
"webpackConfig": "@nrwl/react/plugins/webpack"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "apps/simple-trading-app/src/environments/environment.ts",
|
||||
"with": "apps/simple-trading-app/src/environments/environment.prod.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"sourceMap": false,
|
||||
"namedChunks": false,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve": {
|
||||
"executor": "@nrwl/web:dev-server",
|
||||
"options": {
|
||||
"buildTarget": "simple-trading-app:build",
|
||||
"hmr": true,
|
||||
"port": 4001
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"buildTarget": "simple-trading-app:build:production",
|
||||
"hmr": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nrwl/linter:eslint",
|
||||
"outputs": ["{options.outputFile}"],
|
||||
"options": {
|
||||
"lintFilePatterns": ["apps/simple-trading-app/**/*.{ts,tsx,js,jsx}"]
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nrwl/jest:jest",
|
||||
"outputs": ["coverage/apps/simple-trading-app"],
|
||||
"options": {
|
||||
"jestConfig": "apps/simple-trading-app/jest.config.js",
|
||||
"passWithNoTests": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": []
|
||||
}
|
15
apps/simple-trading-app/setup-tests.ts
Normal file
15
apps/simple-trading-app/setup-tests.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
writable: true,
|
||||
value: jest.fn().mockImplementation((query) => ({
|
||||
matches: false,
|
||||
media: query,
|
||||
onchange: null,
|
||||
addListener: jest.fn(), // Deprecated
|
||||
removeListener: jest.fn(), // Deprecated
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener: jest.fn(),
|
||||
dispatchEvent: jest.fn(),
|
||||
})),
|
||||
});
|
77
apps/simple-trading-app/src/app/app.tsx
Normal file
77
apps/simple-trading-app/src/app/app.tsx
Normal file
@ -0,0 +1,77 @@
|
||||
import { useState, useMemo } from 'react';
|
||||
import { ApolloProvider } from '@apollo/client';
|
||||
import { ThemeContext } from '@vegaprotocol/react-helpers';
|
||||
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
|
||||
import { createClient } from './lib/apollo-client';
|
||||
import { DATA_SOURCES } from './config';
|
||||
import {
|
||||
VegaConnectDialog,
|
||||
VegaManageDialog,
|
||||
VegaWalletProvider,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import { DealTicketContainer } from './components/deal-ticket';
|
||||
import { VegaWalletConnectButton } from './components/vega-wallet-connect-button';
|
||||
import { ThemeSwitcher } from '@vegaprotocol/ui-toolkit';
|
||||
import { Connectors } from './lib/vega-connectors';
|
||||
import '../styles.scss';
|
||||
import { AppLoader } from './components/app-loader';
|
||||
|
||||
function App() {
|
||||
const [theme, toggleTheme] = useThemeSwitcher();
|
||||
const [vegaWallet, setVegaWallet] = useState({
|
||||
connect: false,
|
||||
manage: false,
|
||||
});
|
||||
|
||||
const client = useMemo(() => createClient(DATA_SOURCES.dataNodeUrl), []);
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={theme}>
|
||||
<ApolloProvider client={client}>
|
||||
<VegaWalletProvider>
|
||||
<AppLoader>
|
||||
<div className="h-full dark:bg-black dark:text-white-60 bg-white text-black-60 grid grid-rows-[min-content,1fr]">
|
||||
<div className="flex items-stretch border-b-[7px] border-vega-yellow">
|
||||
<div className="flex items-center gap-4 ml-auto mr-8">
|
||||
<VegaWalletConnectButton
|
||||
setConnectDialog={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, connect: open }))
|
||||
}
|
||||
setManageDialog={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, manage: open }))
|
||||
}
|
||||
/>
|
||||
<ThemeSwitcher onToggle={toggleTheme} className="-my-4" />
|
||||
</div>
|
||||
</div>
|
||||
<main>
|
||||
<div className="md:w-4/5 lg:w-3/5 xl:w-1/3 mx-auto">
|
||||
<DealTicketContainer
|
||||
marketId={
|
||||
'0e4c4e0ce6626ea5c6bf5b5b510afadb3c91627aa9ff61e4c7e37ef8394f2c6f'
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
<VegaConnectDialog
|
||||
connectors={Connectors}
|
||||
dialogOpen={vegaWallet.connect}
|
||||
setDialogOpen={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, connect: open }))
|
||||
}
|
||||
/>
|
||||
<VegaManageDialog
|
||||
dialogOpen={vegaWallet.manage}
|
||||
setDialogOpen={(open) =>
|
||||
setVegaWallet((x) => ({ ...x, manage: open }))
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</AppLoader>
|
||||
</VegaWalletProvider>
|
||||
</ApolloProvider>
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
@ -0,0 +1,19 @@
|
||||
import { useEagerConnect } from '@vegaprotocol/wallet';
|
||||
import type { ReactNode } from 'react';
|
||||
import { Connectors } from '../../lib/vega-connectors';
|
||||
|
||||
interface AppLoaderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component to handle any app initialization, startup querys and other things
|
||||
* that must happen for it can be used
|
||||
*/
|
||||
export function AppLoader({ children }: AppLoaderProps) {
|
||||
// Get keys from vega wallet immediately
|
||||
useEagerConnect(Connectors);
|
||||
|
||||
// eslint-disable-next-line react/jsx-no-useless-fragment
|
||||
return <>{children}</>;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
import type { DealTicketContainerProps } from '@vegaprotocol/deal-ticket';
|
||||
import {
|
||||
DealTicketManager,
|
||||
DealTicketContainer as Container,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import { DealTicketSteps } from './deal-ticket-steps';
|
||||
|
||||
export const DealTicketContainer = ({ marketId }: DealTicketContainerProps) => {
|
||||
return (
|
||||
<Container marketId={marketId}>
|
||||
{(data) => (
|
||||
<DealTicketManager market={data.market}>
|
||||
<DealTicketSteps market={data.market} />
|
||||
</DealTicketManager>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
};
|
@ -0,0 +1,155 @@
|
||||
import * as React from 'react';
|
||||
import type { FormEvent } from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import { Stepper } from '../stepper';
|
||||
import type { Order, DealTicketQuery_market } from '@vegaprotocol/deal-ticket';
|
||||
import {
|
||||
ExpirySelector,
|
||||
SideSelector,
|
||||
SubmitButton,
|
||||
TimeInForceSelector,
|
||||
TypeSelector,
|
||||
useOrderState,
|
||||
useOrderSubmit,
|
||||
DealTicketLimitForm,
|
||||
DealTicketMarketForm,
|
||||
} from '@vegaprotocol/deal-ticket';
|
||||
import {
|
||||
OrderSide,
|
||||
OrderTimeInForce,
|
||||
OrderType,
|
||||
VegaTxStatus,
|
||||
} from '@vegaprotocol/wallet';
|
||||
import { addDecimal } from '@vegaprotocol/react-helpers';
|
||||
|
||||
interface DealTicketMarketProps {
|
||||
market: DealTicketQuery_market;
|
||||
}
|
||||
|
||||
const DEFAULT_ORDER: Order = {
|
||||
type: OrderType.Market,
|
||||
side: OrderSide.Buy,
|
||||
size: '1',
|
||||
timeInForce: OrderTimeInForce.IOC,
|
||||
};
|
||||
|
||||
export const DealTicketSteps = ({ market }: DealTicketMarketProps) => {
|
||||
const [order, updateOrder] = useOrderState(DEFAULT_ORDER);
|
||||
const { submit, transaction } = useOrderSubmit(market);
|
||||
|
||||
const transactionStatus =
|
||||
transaction.status === VegaTxStatus.Requested ||
|
||||
transaction.status === VegaTxStatus.Pending
|
||||
? 'pending'
|
||||
: 'default';
|
||||
|
||||
let ticket = null;
|
||||
|
||||
if (order.type === OrderType.Market) {
|
||||
ticket = (
|
||||
<DealTicketMarketForm
|
||||
size={order.size}
|
||||
onSizeChange={(size) => updateOrder({ size })}
|
||||
price={
|
||||
market.depth.lastTrade
|
||||
? addDecimal(market.depth.lastTrade.price, market.decimalPlaces)
|
||||
: undefined
|
||||
}
|
||||
quoteName={market.tradableInstrument.instrument.product.quoteName}
|
||||
/>
|
||||
);
|
||||
} else if (order.type === OrderType.Limit) {
|
||||
ticket = (
|
||||
<DealTicketLimitForm
|
||||
price={order.price}
|
||||
size={order.size}
|
||||
quoteName={market.tradableInstrument.instrument.product.quoteName}
|
||||
onSizeChange={(size) => updateOrder({ size })}
|
||||
onPriceChange={(price) => updateOrder({ price })}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
throw new Error('Invalid ticket type');
|
||||
}
|
||||
|
||||
const handleSubmit = (e: FormEvent<HTMLFormElement>): Promise<void> => {
|
||||
e.preventDefault();
|
||||
return submit(order);
|
||||
};
|
||||
|
||||
const steps = [
|
||||
{
|
||||
label: 'Select Asset',
|
||||
description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`,
|
||||
component: <div />,
|
||||
},
|
||||
{
|
||||
label: 'Select Order Type',
|
||||
description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`,
|
||||
component: (
|
||||
<TypeSelector
|
||||
order={order}
|
||||
onSelect={(type) => updateOrder({ type })}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Select Market Position',
|
||||
description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`,
|
||||
component: (
|
||||
<SideSelector
|
||||
order={order}
|
||||
onSelect={(side) => updateOrder({ side })}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Select Order Size',
|
||||
description:
|
||||
'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
|
||||
component: ticket,
|
||||
},
|
||||
{
|
||||
label: 'Select Time In Force',
|
||||
description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`,
|
||||
component: (
|
||||
<>
|
||||
<TimeInForceSelector
|
||||
order={order}
|
||||
onSelect={(timeInForce) => updateOrder({ timeInForce })}
|
||||
/>
|
||||
{order.timeInForce === OrderTimeInForce.GTT && (
|
||||
<ExpirySelector
|
||||
order={order}
|
||||
onSelect={(date) => {
|
||||
if (date) {
|
||||
updateOrder({ expiration: date });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: 'Review & Submit Order',
|
||||
description: `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.`,
|
||||
component: (
|
||||
<Box sx={{ mb: 2 }}>
|
||||
<SubmitButton
|
||||
transactionStatus={transactionStatus}
|
||||
market={market}
|
||||
order={order}
|
||||
/>
|
||||
</Box>
|
||||
),
|
||||
disabled: true,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit} className="px-4 py-8">
|
||||
<Stepper steps={steps} />
|
||||
</form>
|
||||
);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export { DealTicketContainer } from './deal-ticket-container';
|
@ -0,0 +1 @@
|
||||
export { default as Stepper } from './stepper';
|
@ -0,0 +1,93 @@
|
||||
import * as React from 'react';
|
||||
import type { ReactNode } from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import { Button } from '@vegaprotocol/ui-toolkit';
|
||||
import Stepper from '@mui/material/Stepper';
|
||||
import Step from '@mui/material/Step';
|
||||
import StepLabel from '@mui/material/StepLabel';
|
||||
import StepContent from '@mui/material/StepContent';
|
||||
import Paper from '@mui/material/Paper';
|
||||
import Divider from '@mui/material/Divider';
|
||||
import Typography from '@mui/material/Typography';
|
||||
|
||||
type Step = {
|
||||
label: string;
|
||||
description: string;
|
||||
component: ReactNode;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
interface StepperProps {
|
||||
steps: Step[];
|
||||
}
|
||||
|
||||
export default ({ steps }: StepperProps) => {
|
||||
const [activeStep, setActiveStep] = React.useState(0);
|
||||
|
||||
const handleClick = (index: typeof activeStep) => {
|
||||
setActiveStep(index);
|
||||
};
|
||||
|
||||
const handleNext = () => {
|
||||
setActiveStep((prevActiveStep) => prevActiveStep + 1);
|
||||
};
|
||||
|
||||
const handleBack = () => {
|
||||
setActiveStep((prevActiveStep) => prevActiveStep - 1);
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
setActiveStep(0);
|
||||
};
|
||||
|
||||
return (
|
||||
<Paper square elevation={1} sx={{ p: 3, mt: 5 }}>
|
||||
<Stepper activeStep={activeStep} orientation="vertical">
|
||||
{steps.map((step, index) => (
|
||||
<Step key={step.label}>
|
||||
<StepLabel
|
||||
optional={
|
||||
index === steps.length - 1 ? (
|
||||
<Typography variant="caption">Last step</Typography>
|
||||
) : null
|
||||
}
|
||||
style={{ cursor: 'pointer' }}
|
||||
onClick={() => handleClick(index)}
|
||||
>
|
||||
{step.label}
|
||||
</StepLabel>
|
||||
<StepContent>
|
||||
<Typography sx={{ mb: 2 }}>{step.description}</Typography>
|
||||
{step.component}
|
||||
<Divider sx={{ mb: 2 }} />
|
||||
<Box>
|
||||
<div>
|
||||
<Button
|
||||
variant="secondary"
|
||||
onClick={handleNext}
|
||||
disabled={step.disabled}
|
||||
>
|
||||
{index === steps.length - 1 ? 'Finish' : 'Continue'}
|
||||
</Button>
|
||||
<Button
|
||||
variant="inline"
|
||||
disabled={index === 0}
|
||||
onClick={handleBack}
|
||||
>
|
||||
Back
|
||||
</Button>
|
||||
</div>
|
||||
</Box>
|
||||
</StepContent>
|
||||
</Step>
|
||||
))}
|
||||
</Stepper>
|
||||
{activeStep === steps.length && (
|
||||
<Paper square elevation={0} sx={{ p: 3 }}>
|
||||
<Typography>All steps completed - you're finished</Typography>
|
||||
<Button onClick={handleReset}>Reset</Button>
|
||||
</Paper>
|
||||
)}
|
||||
</Paper>
|
||||
);
|
||||
};
|
@ -0,0 +1 @@
|
||||
export { VegaWalletConnectButton } from './vega-wallet-connect-button';
|
@ -0,0 +1,38 @@
|
||||
import { truncateByChars } from '@vegaprotocol/react-helpers';
|
||||
import { useVegaWallet } from '@vegaprotocol/wallet';
|
||||
|
||||
export interface VegaWalletConnectButtonProps {
|
||||
setConnectDialog: (isOpen: boolean) => void;
|
||||
setManageDialog: (isOpen: boolean) => void;
|
||||
}
|
||||
|
||||
export const VegaWalletConnectButton = ({
|
||||
setConnectDialog,
|
||||
setManageDialog,
|
||||
}: VegaWalletConnectButtonProps) => {
|
||||
const { keypair } = useVegaWallet();
|
||||
const isConnected = keypair !== null;
|
||||
|
||||
const handleClick = () => {
|
||||
if (isConnected) {
|
||||
setManageDialog(true);
|
||||
} else {
|
||||
setConnectDialog(true);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<span>
|
||||
{isConnected && (
|
||||
<span className="text-ui-small font-mono mr-2">Vega key:</span>
|
||||
)}
|
||||
<button
|
||||
data-testid="connect-vega-wallet"
|
||||
onClick={handleClick}
|
||||
className="ml-auto inline-block text-ui-small font-mono hover:underline"
|
||||
>
|
||||
{isConnected ? truncateByChars(keypair.pub) : 'Connect Vega wallet'}
|
||||
</button>
|
||||
</span>
|
||||
);
|
||||
};
|
5
apps/simple-trading-app/src/app/config/index.tsx
Normal file
5
apps/simple-trading-app/src/app/config/index.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
export const DATA_SOURCES = {
|
||||
dataNodeUrl: process.env['NX_VEGA_URL'] as string,
|
||||
envName: process.env['NX_VEGA_ENV'] as string,
|
||||
restEndpoint: process.env['NX_VEGA_REST'] as string,
|
||||
};
|
53
apps/simple-trading-app/src/app/lib/apollo-client.tsx
Normal file
53
apps/simple-trading-app/src/app/lib/apollo-client.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client';
|
||||
import { onError } from '@apollo/client/link/error';
|
||||
import { RetryLink } from '@apollo/client/link/retry';
|
||||
|
||||
export function createClient(base?: string) {
|
||||
if (!base) {
|
||||
throw new Error('Base must be passed into createClient!');
|
||||
}
|
||||
const gqlPath = 'query';
|
||||
const urlHTTP = new URL(gqlPath, base);
|
||||
const urlWS = new URL(gqlPath, base);
|
||||
// Replace http with ws, preserving if its a secure connection eg. https => wss
|
||||
urlWS.protocol = urlWS.protocol.replace('http', 'ws');
|
||||
|
||||
const cache = new InMemoryCache({
|
||||
typePolicies: {
|
||||
Query: {},
|
||||
Account: {
|
||||
keyFields: false,
|
||||
fields: {
|
||||
balanceFormatted: {},
|
||||
},
|
||||
},
|
||||
Node: {
|
||||
keyFields: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const retryLink = new RetryLink({
|
||||
delay: {
|
||||
initial: 300,
|
||||
max: 10000,
|
||||
jitter: true,
|
||||
},
|
||||
});
|
||||
|
||||
const httpLink = new HttpLink({
|
||||
uri: urlHTTP.href,
|
||||
credentials: 'same-origin',
|
||||
});
|
||||
|
||||
const errorLink = onError(({ graphQLErrors, networkError }) => {
|
||||
console.log(graphQLErrors);
|
||||
console.log(networkError);
|
||||
});
|
||||
|
||||
return new ApolloClient({
|
||||
connectToDevTools: process.env['NODE_ENV'] === 'development',
|
||||
link: from([errorLink, retryLink, httpLink]),
|
||||
cache,
|
||||
});
|
||||
}
|
7
apps/simple-trading-app/src/app/lib/vega-connectors.ts
Normal file
7
apps/simple-trading-app/src/app/lib/vega-connectors.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { RestConnector } from '@vegaprotocol/wallet';
|
||||
|
||||
export const rest = new RestConnector();
|
||||
|
||||
export const Connectors = {
|
||||
rest,
|
||||
};
|
0
apps/simple-trading-app/src/assets/.gitkeep
Normal file
0
apps/simple-trading-app/src/assets/.gitkeep
Normal file
@ -0,0 +1,3 @@
|
||||
export const environment = {
|
||||
production: true,
|
||||
};
|
6
apps/simple-trading-app/src/environments/environment.ts
Normal file
6
apps/simple-trading-app/src/environments/environment.ts
Normal file
@ -0,0 +1,6 @@
|
||||
// This file can be replaced during build by using the `fileReplacements` array.
|
||||
// When building for production, this file is replaced with `environment.prod.ts`.
|
||||
|
||||
export const environment = {
|
||||
production: false,
|
||||
};
|
BIN
apps/simple-trading-app/src/favicon.ico
Normal file
BIN
apps/simple-trading-app/src/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
14
apps/simple-trading-app/src/index.html
Normal file
14
apps/simple-trading-app/src/index.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Simple Trading App</title>
|
||||
<base href="/" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="icon" type="image/x-icon" href="favicon.ico" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
14
apps/simple-trading-app/src/main.tsx
Normal file
14
apps/simple-trading-app/src/main.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import { StrictMode } from 'react';
|
||||
import * as ReactDOM from 'react-dom';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
|
||||
import App from './app/app';
|
||||
|
||||
ReactDOM.render(
|
||||
<StrictMode>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</StrictMode>,
|
||||
document.getElementById('root')
|
||||
);
|
7
apps/simple-trading-app/src/polyfills.ts
Normal file
7
apps/simple-trading-app/src/polyfills.ts
Normal file
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Polyfill stable language features. These imports will be optimized by `@babel/preset-env`.
|
||||
*
|
||||
* See: https://github.com/zloirock/core-js#babel
|
||||
*/
|
||||
import 'core-js/stable';
|
||||
import 'regenerator-runtime/runtime';
|
9
apps/simple-trading-app/src/styles.scss
Normal file
9
apps/simple-trading-app/src/styles.scss
Normal file
@ -0,0 +1,9 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
html,
|
||||
body,
|
||||
#__next {
|
||||
@apply h-full;
|
||||
}
|
14
apps/simple-trading-app/tailwind.config.js
Normal file
14
apps/simple-trading-app/tailwind.config.js
Normal file
@ -0,0 +1,14 @@
|
||||
const { join } = require('path');
|
||||
const { createGlobPatternsForDependencies } = require('@nrwl/next/tailwind');
|
||||
const theme = require('../../libs/tailwindcss-config/src/theme');
|
||||
const vegaCustomClasses = require('../../libs/tailwindcss-config/src/vega-custom-classes');
|
||||
|
||||
module.exports = {
|
||||
content: [
|
||||
join(__dirname, 'src/**/*.{js,ts,jsx,tsx}'),
|
||||
...createGlobPatternsForDependencies(__dirname),
|
||||
],
|
||||
darkMode: 'class',
|
||||
theme,
|
||||
plugins: [vegaCustomClasses],
|
||||
};
|
22
apps/simple-trading-app/tsconfig.app.json
Normal file
22
apps/simple-trading-app/tsconfig.app.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"types": ["node"]
|
||||
},
|
||||
"files": [
|
||||
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
|
||||
"../../node_modules/@nrwl/react/typings/image.d.ts"
|
||||
],
|
||||
"exclude": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.js",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.test.jsx"
|
||||
],
|
||||
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
|
||||
}
|
25
apps/simple-trading-app/tsconfig.json
Normal file
25
apps/simple-trading-app/tsconfig.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
"allowJs": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitOverride": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.app.json"
|
||||
},
|
||||
{
|
||||
"path": "./tsconfig.spec.json"
|
||||
}
|
||||
]
|
||||
}
|
20
apps/simple-trading-app/tsconfig.spec.json
Normal file
20
apps/simple-trading-app/tsconfig.spec.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../dist/out-tsc",
|
||||
"module": "commonjs",
|
||||
"types": ["jest", "node"],
|
||||
"jsx": "react"
|
||||
},
|
||||
"include": [
|
||||
"**/*.test.ts",
|
||||
"**/*.spec.ts",
|
||||
"**/*.test.tsx",
|
||||
"**/*.spec.tsx",
|
||||
"**/*.test.js",
|
||||
"**/*.spec.js",
|
||||
"**/*.test.jsx",
|
||||
"**/*.spec.jsx",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
import { AsyncRenderer, Splash } from '@vegaprotocol/ui-toolkit';
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
import { DealTicketManager } from './deal-ticket-manager';
|
||||
import type { DealTicketQuery } from './__generated__/DealTicketQuery';
|
||||
import type {
|
||||
DealTicketQuery,
|
||||
DealTicketQuery_market,
|
||||
} from './__generated__/DealTicketQuery';
|
||||
import { t } from '@vegaprotocol/react-helpers';
|
||||
|
||||
const DEAL_TICKET_QUERY = gql`
|
||||
@ -29,11 +32,19 @@ const DEAL_TICKET_QUERY = gql`
|
||||
}
|
||||
`;
|
||||
|
||||
interface DealTicketContainerProps {
|
||||
type childrenProps = {
|
||||
market: DealTicketQuery_market;
|
||||
};
|
||||
|
||||
export interface DealTicketContainerProps {
|
||||
marketId: string;
|
||||
children?(props: childrenProps): JSX.Element;
|
||||
}
|
||||
|
||||
export const DealTicketContainer = ({ marketId }: DealTicketContainerProps) => {
|
||||
export const DealTicketContainer = ({
|
||||
marketId,
|
||||
children,
|
||||
}: DealTicketContainerProps) => {
|
||||
const { data, loading, error } = useQuery(DEAL_TICKET_QUERY, {
|
||||
variables: { marketId },
|
||||
});
|
||||
@ -41,7 +52,11 @@ export const DealTicketContainer = ({ marketId }: DealTicketContainerProps) => {
|
||||
return (
|
||||
<AsyncRenderer<DealTicketQuery> data={data} loading={loading} error={error}>
|
||||
{data && data.market ? (
|
||||
<DealTicketManager market={data.market} />
|
||||
children ? (
|
||||
children(data)
|
||||
) : (
|
||||
<DealTicketManager market={data.market} />
|
||||
)
|
||||
) : (
|
||||
<Splash>
|
||||
<p>{t('Could not load market')}</p>
|
||||
|
45
libs/deal-ticket/src/deal-ticket-limit-form.tsx
Normal file
45
libs/deal-ticket/src/deal-ticket-limit-form.tsx
Normal file
@ -0,0 +1,45 @@
|
||||
import { FormGroup, Input } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
export interface DealTicketLimitFormProps {
|
||||
quoteName: string;
|
||||
price?: string;
|
||||
size: string;
|
||||
onSizeChange: (size: string) => void;
|
||||
onPriceChange: (price: string) => void;
|
||||
}
|
||||
|
||||
export const DealTicketLimitForm = ({
|
||||
size,
|
||||
price,
|
||||
onSizeChange,
|
||||
onPriceChange,
|
||||
quoteName,
|
||||
}: DealTicketLimitFormProps) => {
|
||||
return (
|
||||
<div className="flex items-center gap-8">
|
||||
<div className="flex-1">
|
||||
<FormGroup label="Amount">
|
||||
<Input
|
||||
value={size}
|
||||
onChange={(e) => onSizeChange(e.target.value)}
|
||||
className="w-full"
|
||||
type="number"
|
||||
data-testid="order-size"
|
||||
/>
|
||||
</FormGroup>
|
||||
</div>
|
||||
<div>@</div>
|
||||
<div className="flex-1">
|
||||
<FormGroup label={`Price (${quoteName})`} labelAlign="right">
|
||||
<Input
|
||||
value={price}
|
||||
onChange={(e) => onPriceChange(e.target.value)}
|
||||
className="w-full"
|
||||
type="number"
|
||||
data-testid="order-price"
|
||||
/>
|
||||
</FormGroup>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,9 +1,9 @@
|
||||
import { FormGroup, Input } from '@vegaprotocol/ui-toolkit';
|
||||
import { OrderTimeInForce } from '@vegaprotocol/wallet';
|
||||
import type { TransactionStatus } from './deal-ticket';
|
||||
import { ExpirySelector } from './expiry-selector';
|
||||
import { SideSelector } from './side-selector';
|
||||
import { SubmitButton } from './submit-button';
|
||||
import { DealTicketLimitForm } from './deal-ticket-limit-form';
|
||||
import { TimeInForceSelector } from './time-in-force-selector';
|
||||
import { TypeSelector } from './type-selector';
|
||||
import type { Order } from './use-order-state';
|
||||
@ -26,34 +26,13 @@ export const DealTicketLimit = ({
|
||||
<>
|
||||
<TypeSelector order={order} onSelect={(type) => updateOrder({ type })} />
|
||||
<SideSelector order={order} onSelect={(side) => updateOrder({ side })} />
|
||||
<div className="flex items-center gap-8">
|
||||
<div className="flex-1">
|
||||
<FormGroup label="Amount">
|
||||
<Input
|
||||
value={order.size}
|
||||
onChange={(e) => updateOrder({ size: e.target.value })}
|
||||
className="w-full"
|
||||
type="number"
|
||||
data-testid="order-size"
|
||||
/>
|
||||
</FormGroup>
|
||||
</div>
|
||||
<div>@</div>
|
||||
<div className="flex-1">
|
||||
<FormGroup
|
||||
label={`Price (${market.tradableInstrument.instrument.product.quoteName})`}
|
||||
labelAlign="right"
|
||||
>
|
||||
<Input
|
||||
value={order.price}
|
||||
onChange={(e) => updateOrder({ price: e.target.value })}
|
||||
className="w-full"
|
||||
type="number"
|
||||
data-testid="order-price"
|
||||
/>
|
||||
</FormGroup>
|
||||
</div>
|
||||
</div>
|
||||
<DealTicketLimitForm
|
||||
price={order.price}
|
||||
size={order.size}
|
||||
quoteName={market.tradableInstrument.instrument.product.quoteName}
|
||||
onSizeChange={(size) => updateOrder({ size })}
|
||||
onPriceChange={(price) => updateOrder({ price })}
|
||||
/>
|
||||
<TimeInForceSelector
|
||||
order={order}
|
||||
onSelect={(timeInForce) => updateOrder({ timeInForce })}
|
||||
|
@ -1,3 +1,4 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Dialog, Intent } from '@vegaprotocol/ui-toolkit';
|
||||
import { OrderStatus } from '@vegaprotocol/types';
|
||||
@ -7,11 +8,15 @@ import { useOrderSubmit } from './use-order-submit';
|
||||
import { OrderDialog } from './order-dialog';
|
||||
import type { DealTicketQuery_market } from './__generated__/DealTicketQuery';
|
||||
|
||||
interface DealTicketManagerProps {
|
||||
export interface DealTicketManagerProps {
|
||||
market: DealTicketQuery_market;
|
||||
children?: ReactNode | ReactNode[];
|
||||
}
|
||||
|
||||
export const DealTicketManager = ({ market }: DealTicketManagerProps) => {
|
||||
export const DealTicketManager = ({
|
||||
market,
|
||||
children,
|
||||
}: DealTicketManagerProps) => {
|
||||
const [orderDialogOpen, setOrderDialogOpen] = useState(false);
|
||||
const { submit, transaction, finalizedOrder, reset } = useOrderSubmit(market);
|
||||
|
||||
@ -47,16 +52,18 @@ export const DealTicketManager = ({ market }: DealTicketManagerProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<DealTicket
|
||||
market={market}
|
||||
submit={submit}
|
||||
transactionStatus={
|
||||
transaction.status === VegaTxStatus.Requested ||
|
||||
transaction.status === VegaTxStatus.Pending
|
||||
? 'pending'
|
||||
: 'default'
|
||||
}
|
||||
/>
|
||||
{children || (
|
||||
<DealTicket
|
||||
market={market}
|
||||
submit={submit}
|
||||
transactionStatus={
|
||||
transaction.status === VegaTxStatus.Requested ||
|
||||
transaction.status === VegaTxStatus.Pending
|
||||
? 'pending'
|
||||
: 'default'
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<Dialog
|
||||
open={orderDialogOpen}
|
||||
onChange={(isOpen) => {
|
||||
|
41
libs/deal-ticket/src/deal-ticket-market-form.tsx
Normal file
41
libs/deal-ticket/src/deal-ticket-market-form.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
import { FormGroup, Input } from '@vegaprotocol/ui-toolkit';
|
||||
|
||||
export interface DealTicketMarketFormProps {
|
||||
quoteName?: string;
|
||||
price?: string;
|
||||
size: string;
|
||||
onSizeChange: (size: string) => void;
|
||||
}
|
||||
|
||||
export const DealTicketMarketForm = ({
|
||||
size,
|
||||
onSizeChange,
|
||||
price,
|
||||
quoteName,
|
||||
}: DealTicketMarketFormProps) => {
|
||||
return (
|
||||
<div className="flex items-center gap-8">
|
||||
<div className="flex-1">
|
||||
<FormGroup label="Amount">
|
||||
<Input
|
||||
value={size}
|
||||
onChange={(e) => onSizeChange(e.target.value)}
|
||||
className="w-full"
|
||||
type="number"
|
||||
data-testid="order-size"
|
||||
/>
|
||||
</FormGroup>
|
||||
</div>
|
||||
<div className="pt-4">@</div>
|
||||
<div className="flex-1 pt-4" data-testid="last-price">
|
||||
{price && quoteName ? (
|
||||
<>
|
||||
~{price} {quoteName}
|
||||
</>
|
||||
) : (
|
||||
'-'
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1,12 +1,12 @@
|
||||
import { addDecimal } from '@vegaprotocol/react-helpers';
|
||||
import { FormGroup, Input } from '@vegaprotocol/ui-toolkit';
|
||||
import type { TransactionStatus } from './deal-ticket';
|
||||
import { SideSelector } from './side-selector';
|
||||
import { DealTicketMarketForm } from './deal-ticket-market-form';
|
||||
import { SubmitButton } from './submit-button';
|
||||
import { TimeInForceSelector } from './time-in-force-selector';
|
||||
import { TypeSelector } from './type-selector';
|
||||
import type { Order } from './use-order-state';
|
||||
import type { DealTicketQuery_market } from './__generated__/DealTicketQuery';
|
||||
import { addDecimal } from '@vegaprotocol/react-helpers';
|
||||
|
||||
interface DealTicketMarketProps {
|
||||
order: Order;
|
||||
@ -25,30 +25,16 @@ export const DealTicketMarket = ({
|
||||
<>
|
||||
<TypeSelector order={order} onSelect={(type) => updateOrder({ type })} />
|
||||
<SideSelector order={order} onSelect={(side) => updateOrder({ side })} />
|
||||
<div className="flex items-center gap-8">
|
||||
<div className="flex-1">
|
||||
<FormGroup label="Amount">
|
||||
<Input
|
||||
value={order.size}
|
||||
onChange={(e) => updateOrder({ size: e.target.value })}
|
||||
className="w-full"
|
||||
type="number"
|
||||
data-testid="order-size"
|
||||
/>
|
||||
</FormGroup>
|
||||
</div>
|
||||
<div className="pt-4">@</div>
|
||||
<div className="flex-1 pt-4" data-testid="last-price">
|
||||
{market.depth.lastTrade ? (
|
||||
<>
|
||||
~{addDecimal(market.depth.lastTrade.price, market.decimalPlaces)}{' '}
|
||||
{market.tradableInstrument.instrument.product.quoteName}
|
||||
</>
|
||||
) : (
|
||||
'-'
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<DealTicketMarketForm
|
||||
size={order.size}
|
||||
onSizeChange={(size) => updateOrder({ size })}
|
||||
price={
|
||||
market.depth.lastTrade
|
||||
? addDecimal(market.depth.lastTrade.price, market.decimalPlaces)
|
||||
: undefined
|
||||
}
|
||||
quoteName={market.tradableInstrument.instrument.product.quoteName}
|
||||
/>
|
||||
<TimeInForceSelector
|
||||
order={order}
|
||||
onSelect={(timeInForce) => updateOrder({ timeInForce })}
|
||||
|
@ -1,5 +1,15 @@
|
||||
export * from './expiry-selector';
|
||||
export * from './type-selector';
|
||||
export * from './time-in-force-selector';
|
||||
export * from './submit-button';
|
||||
export * from './side-selector';
|
||||
export * from './deal-ticket';
|
||||
export * from './deal-ticket-limit-form';
|
||||
export * from './deal-ticket-market-form';
|
||||
export * from './deal-ticket-manager';
|
||||
export * from './order-dialog';
|
||||
export * from './use-order-state';
|
||||
export * from './use-order-submit';
|
||||
export * from './deal-ticket-container';
|
||||
export * from './__generated__/DealTicketQuery';
|
||||
export * from './__generated__/OrderEvent';
|
||||
|
@ -6,6 +6,8 @@ module.exports = {
|
||||
sm: '640px',
|
||||
md: '768px',
|
||||
lg: '960px',
|
||||
xl: '1280px',
|
||||
xxl: '1536px',
|
||||
},
|
||||
colors: {
|
||||
transparent: 'transparent',
|
||||
|
@ -13,6 +13,9 @@
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.9.0",
|
||||
"@emotion/styled": "^11.8.1",
|
||||
"@mui/material": "^5.6.2",
|
||||
"@apollo/client": "^3.5.8",
|
||||
"@blueprintjs/core": "^3.47.0",
|
||||
"@blueprintjs/icons": "^3.32.0",
|
||||
|
@ -14,6 +14,8 @@
|
||||
"order-list": "libs/order-list",
|
||||
"positions": "libs/positions",
|
||||
"react-helpers": "libs/react-helpers",
|
||||
"simple-trading-app": "apps/simple-trading-app",
|
||||
"simple-trading-app-e2e": "apps/simple-trading-app-e2e",
|
||||
"static": "apps/static",
|
||||
"stats": "apps/stats",
|
||||
"stats-e2e": "apps/stats-e2e",
|
||||
|
223
yarn.lock
223
yarn.lock
@ -672,7 +672,7 @@
|
||||
dependencies:
|
||||
"@babel/helper-plugin-utils" "^7.14.5"
|
||||
|
||||
"@babel/plugin-syntax-jsx@^7.16.7":
|
||||
"@babel/plugin-syntax-jsx@^7.12.13", "@babel/plugin-syntax-jsx@^7.16.7":
|
||||
version "7.16.7"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz#50b6571d13f764266a113d77c82b4a6508bbe665"
|
||||
integrity sha512-Esxmk7YjA8QysKeT3VhTXvF6y77f/a91SIs4pWb4H2eWGQkCKFgQaG6hdoEVZtGsrAcb2K5BW66XsOErD4WU3Q==
|
||||
@ -1217,7 +1217,7 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.14.8", "@babel/runtime@^7.16.0", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
|
||||
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.14.8", "@babel/runtime@^7.16.0", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2":
|
||||
version "7.17.9"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72"
|
||||
integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==
|
||||
@ -1413,6 +1413,24 @@
|
||||
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
|
||||
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
|
||||
|
||||
"@emotion/babel-plugin@^11.7.1":
|
||||
version "11.9.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.9.2.tgz#723b6d394c89fb2ef782229d92ba95a740576e95"
|
||||
integrity sha512-Pr/7HGH6H6yKgnVFNEj2MVlreu3ADqftqjqwUvDy/OJzKFgxKeTQ+eeUf20FOTuHVkDON2iNa25rAXVYtWJCjw==
|
||||
dependencies:
|
||||
"@babel/helper-module-imports" "^7.12.13"
|
||||
"@babel/plugin-syntax-jsx" "^7.12.13"
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@emotion/hash" "^0.8.0"
|
||||
"@emotion/memoize" "^0.7.5"
|
||||
"@emotion/serialize" "^1.0.2"
|
||||
babel-plugin-macros "^2.6.1"
|
||||
convert-source-map "^1.5.0"
|
||||
escape-string-regexp "^4.0.0"
|
||||
find-root "^1.1.0"
|
||||
source-map "^0.5.7"
|
||||
stylis "4.0.13"
|
||||
|
||||
"@emotion/cache@^10.0.27":
|
||||
version "10.0.29"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0"
|
||||
@ -1423,6 +1441,17 @@
|
||||
"@emotion/utils" "0.11.3"
|
||||
"@emotion/weak-memoize" "0.2.5"
|
||||
|
||||
"@emotion/cache@^11.7.1":
|
||||
version "11.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.7.1.tgz#08d080e396a42e0037848214e8aa7bf879065539"
|
||||
integrity sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A==
|
||||
dependencies:
|
||||
"@emotion/memoize" "^0.7.4"
|
||||
"@emotion/sheet" "^1.1.0"
|
||||
"@emotion/utils" "^1.0.0"
|
||||
"@emotion/weak-memoize" "^0.2.5"
|
||||
stylis "4.0.13"
|
||||
|
||||
"@emotion/core@^10.1.1":
|
||||
version "10.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.3.1.tgz#4021b6d8b33b3304d48b0bb478485e7d7421c69d"
|
||||
@ -1444,7 +1473,7 @@
|
||||
"@emotion/utils" "0.11.3"
|
||||
babel-plugin-emotion "^10.0.27"
|
||||
|
||||
"@emotion/hash@0.8.0":
|
||||
"@emotion/hash@0.8.0", "@emotion/hash@^0.8.0":
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413"
|
||||
integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==
|
||||
@ -1456,11 +1485,36 @@
|
||||
dependencies:
|
||||
"@emotion/memoize" "0.7.4"
|
||||
|
||||
"@emotion/is-prop-valid@^1.1.2":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.1.2.tgz#34ad6e98e871aa6f7a20469b602911b8b11b3a95"
|
||||
integrity sha512-3QnhqeL+WW88YjYbQL5gUIkthuMw7a0NGbZ7wfFVk2kg/CK5w8w5FFa0RzWjyY1+sujN0NWbtSHH6OJmWHtJpQ==
|
||||
dependencies:
|
||||
"@emotion/memoize" "^0.7.4"
|
||||
|
||||
"@emotion/memoize@0.7.4":
|
||||
version "0.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb"
|
||||
integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==
|
||||
|
||||
"@emotion/memoize@^0.7.4", "@emotion/memoize@^0.7.5":
|
||||
version "0.7.5"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.5.tgz#2c40f81449a4e554e9fc6396910ed4843ec2be50"
|
||||
integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==
|
||||
|
||||
"@emotion/react@^11.9.0":
|
||||
version "11.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.9.0.tgz#b6d42b1db3bd7511e7a7c4151dc8bc82e14593b8"
|
||||
integrity sha512-lBVSF5d0ceKtfKCDQJveNAtkC7ayxpVlgOohLgXqRwqWr9bOf4TZAFFyIcNngnV6xK6X4x2ZeXq7vliHkoVkxQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@emotion/babel-plugin" "^11.7.1"
|
||||
"@emotion/cache" "^11.7.1"
|
||||
"@emotion/serialize" "^1.0.3"
|
||||
"@emotion/utils" "^1.1.0"
|
||||
"@emotion/weak-memoize" "^0.2.5"
|
||||
hoist-non-react-statics "^3.3.1"
|
||||
|
||||
"@emotion/serialize@^0.11.15", "@emotion/serialize@^0.11.16":
|
||||
version "0.11.16"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.16.tgz#dee05f9e96ad2fb25a5206b6d759b2d1ed3379ad"
|
||||
@ -1472,11 +1526,27 @@
|
||||
"@emotion/utils" "0.11.3"
|
||||
csstype "^2.5.7"
|
||||
|
||||
"@emotion/serialize@^1.0.2", "@emotion/serialize@^1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.0.3.tgz#99e2060c26c6292469fb30db41f4690e1c8fea63"
|
||||
integrity sha512-2mSSvgLfyV3q+iVh3YWgNlUc2a9ZlDU7DjuP5MjK3AXRR0dYigCrP99aeFtaB2L/hjfEZdSThn5dsZ0ufqbvsA==
|
||||
dependencies:
|
||||
"@emotion/hash" "^0.8.0"
|
||||
"@emotion/memoize" "^0.7.4"
|
||||
"@emotion/unitless" "^0.7.5"
|
||||
"@emotion/utils" "^1.0.0"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@emotion/sheet@0.9.4":
|
||||
version "0.9.4"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.4.tgz#894374bea39ec30f489bbfc3438192b9774d32e5"
|
||||
integrity sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==
|
||||
|
||||
"@emotion/sheet@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.1.0.tgz#56d99c41f0a1cda2726a05aa6a20afd4c63e58d2"
|
||||
integrity sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==
|
||||
|
||||
"@emotion/styled-base@^10.3.0":
|
||||
version "10.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/styled-base/-/styled-base-10.3.0.tgz#9aa2c946100f78b47316e4bc6048321afa6d4e36"
|
||||
@ -1495,12 +1565,23 @@
|
||||
"@emotion/styled-base" "^10.3.0"
|
||||
babel-plugin-emotion "^10.0.27"
|
||||
|
||||
"@emotion/styled@^11.8.1":
|
||||
version "11.8.1"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.8.1.tgz#856f6f63aceef0eb783985fa2322e2bf66d04e17"
|
||||
integrity sha512-OghEVAYBZMpEquHZwuelXcRjRJQOVayvbmNR0zr174NHdmMgrNkLC6TljKC5h9lZLkN5WGrdUcrKlOJ4phhoTQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
"@emotion/babel-plugin" "^11.7.1"
|
||||
"@emotion/is-prop-valid" "^1.1.2"
|
||||
"@emotion/serialize" "^1.0.2"
|
||||
"@emotion/utils" "^1.1.0"
|
||||
|
||||
"@emotion/stylis@0.8.5":
|
||||
version "0.8.5"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04"
|
||||
integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==
|
||||
|
||||
"@emotion/unitless@0.7.5":
|
||||
"@emotion/unitless@0.7.5", "@emotion/unitless@^0.7.5":
|
||||
version "0.7.5"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed"
|
||||
integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==
|
||||
@ -1510,7 +1591,12 @@
|
||||
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.3.tgz#a759863867befa7e583400d322652a3f44820924"
|
||||
integrity sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==
|
||||
|
||||
"@emotion/weak-memoize@0.2.5":
|
||||
"@emotion/utils@^1.0.0", "@emotion/utils@^1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.1.0.tgz#86b0b297f3f1a0f2bdb08eeac9a2f49afd40d0cf"
|
||||
integrity sha512-iRLa/Y4Rs5H/f2nimczYmS5kFJEbpiVvgN3XVfZ022IYhuNA1IRSHEizcof88LtCTXtl9S2Cxt32KgaXEu72JQ==
|
||||
|
||||
"@emotion/weak-memoize@0.2.5", "@emotion/weak-memoize@^0.2.5":
|
||||
version "0.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46"
|
||||
integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
|
||||
@ -2308,6 +2394,86 @@
|
||||
call-me-maybe "^1.0.1"
|
||||
glob-to-regexp "^0.3.0"
|
||||
|
||||
"@mui/base@5.0.0-alpha.78":
|
||||
version "5.0.0-alpha.78"
|
||||
resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-alpha.78.tgz#9d0ee8c913969f60cd7072a6082e3c0652be0b74"
|
||||
integrity sha512-5L+GNe2M9/tFjQpjK2r837+kzRg/l6D5R9SQbG1wmSWejw5Ei8P+KXIgS/NLNi9g7dUT8bnCyzz9AZKQX1Jsfg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
"@emotion/is-prop-valid" "^1.1.2"
|
||||
"@mui/types" "^7.1.3"
|
||||
"@mui/utils" "^5.6.1"
|
||||
"@popperjs/core" "^2.11.5"
|
||||
clsx "^1.1.1"
|
||||
prop-types "^15.7.2"
|
||||
react-is "^17.0.2"
|
||||
|
||||
"@mui/material@^5.6.2":
|
||||
version "5.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.6.3.tgz#a5b6cd1b0417fca67a65172530ff5573ab7bc453"
|
||||
integrity sha512-2VovFsbCEhic29NYoBF7zFrpH2sEOlKXXDhGjzxmWiI9OnC3SX63hapWunjaVsiRINVnjuMHuW1MOs4UtV8Gfg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
"@mui/base" "5.0.0-alpha.78"
|
||||
"@mui/system" "^5.6.3"
|
||||
"@mui/types" "^7.1.3"
|
||||
"@mui/utils" "^5.6.1"
|
||||
"@types/react-transition-group" "^4.4.4"
|
||||
clsx "^1.1.1"
|
||||
csstype "^3.0.11"
|
||||
hoist-non-react-statics "^3.3.2"
|
||||
prop-types "^15.7.2"
|
||||
react-is "^17.0.2"
|
||||
react-transition-group "^4.4.2"
|
||||
|
||||
"@mui/private-theming@^5.6.2":
|
||||
version "5.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.6.2.tgz#c42da32f8b9481ba12885176c0168a355727c189"
|
||||
integrity sha512-IbrSfFXfiZdyhRMC2bgGTFtb16RBQ5mccmjeh3MtAERWuepiCK7gkW5D9WhEsfTu6iez+TEjeUKSgmMHlsM2mg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
"@mui/utils" "^5.6.1"
|
||||
prop-types "^15.7.2"
|
||||
|
||||
"@mui/styled-engine@^5.6.1":
|
||||
version "5.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.6.1.tgz#e2c859a4dbdd65af89e77703a0725285aef471fd"
|
||||
integrity sha512-jEhH6TBY8jc9S8yVncXmoTYTbATjEu44RMFXj6sIYfKr5NArVwTwRo3JexLL0t3BOAiYM4xsFLgfKEIvB9SAeQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
"@emotion/cache" "^11.7.1"
|
||||
prop-types "^15.7.2"
|
||||
|
||||
"@mui/system@^5.6.3":
|
||||
version "5.6.3"
|
||||
resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.6.3.tgz#a03ad6d61b0b7d304a8af60374e27e71e7818ef7"
|
||||
integrity sha512-4SRi52a4ttZ2S4EHEDE8arVNuKqyQLTYUTF80WAZ0tQwnG20qwlBtzcrywCGItmVAMl7RUaYopyWOx3yVPvrmQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
"@mui/private-theming" "^5.6.2"
|
||||
"@mui/styled-engine" "^5.6.1"
|
||||
"@mui/types" "^7.1.3"
|
||||
"@mui/utils" "^5.6.1"
|
||||
clsx "^1.1.1"
|
||||
csstype "^3.0.11"
|
||||
prop-types "^15.7.2"
|
||||
|
||||
"@mui/types@^7.1.3":
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.1.3.tgz#d7636f3046110bcccc63e6acfd100e2ad9ca712a"
|
||||
integrity sha512-DDF0UhMBo4Uezlk+6QxrlDbchF79XG6Zs0zIewlR4c0Dt6GKVFfUtzPtHCH1tTbcSlq/L2bGEdiaoHBJ9Y1gSA==
|
||||
|
||||
"@mui/utils@^5.6.1":
|
||||
version "5.6.1"
|
||||
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.6.1.tgz#4ab79a21bd481555d9a588f4b18061b3c28ea5db"
|
||||
integrity sha512-CPrzrkiBusCZBLWu0Sg5MJvR3fKJyK3gKecLVX012LULyqg2U64Oz04BKhfkbtBrPBbSQxM+DWW9B1c9hmV9nQ==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.17.2"
|
||||
"@types/prop-types" "^15.7.4"
|
||||
"@types/react-is" "^16.7.1 || ^17.0.0"
|
||||
prop-types "^15.7.2"
|
||||
react-is "^17.0.2"
|
||||
|
||||
"@napi-rs/triples@1.0.3":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/triples/-/triples-1.0.3.tgz#76d6d0c3f4d16013c61e45dfca5ff1e6c31ae53c"
|
||||
@ -3054,7 +3220,7 @@
|
||||
schema-utils "^3.0.0"
|
||||
source-map "^0.7.3"
|
||||
|
||||
"@popperjs/core@^2.5.4", "@popperjs/core@^2.6.0":
|
||||
"@popperjs/core@^2.11.5", "@popperjs/core@^2.5.4", "@popperjs/core@^2.6.0":
|
||||
version "2.11.5"
|
||||
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.5.tgz#db5a11bf66bdab39569719555b0f76e138d7bd64"
|
||||
integrity sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw==
|
||||
@ -5320,7 +5486,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.26.0.tgz#a1c3809b0ad61c62cac6d4e0c56d610c910b7654"
|
||||
integrity sha512-ZTaqn/qSqUuAq1YwvOFQfVW1AR/oQJlLSZVustdjwI+GZ8kr0MSHBj0tsXPW1EqHubx50gtBEjbPGsdZwQwCjQ==
|
||||
|
||||
"@types/prop-types@*":
|
||||
"@types/prop-types@*", "@types/prop-types@^15.7.4":
|
||||
version "15.7.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
|
||||
integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
|
||||
@ -5368,6 +5534,13 @@
|
||||
dependencies:
|
||||
"@types/react" "^17"
|
||||
|
||||
"@types/react-is@^16.7.1 || ^17.0.0":
|
||||
version "17.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-is/-/react-is-17.0.3.tgz#2d855ba575f2fc8d17ef9861f084acc4b90a137a"
|
||||
integrity sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-router-dom@5.3.1":
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.1.tgz#76700ccce6529413ec723024b71f01fc77a4a980"
|
||||
@ -5399,6 +5572,13 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-transition-group@^4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e"
|
||||
integrity sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-virtualized-auto-sizer@^1.0.0", "@types/react-virtualized-auto-sizer@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz#b3187dae1dfc4c15880c9cfc5b45f2719ea6ebd4"
|
||||
@ -7325,7 +7505,7 @@ babel-plugin-jest-hoist@^27.5.1:
|
||||
"@types/babel__core" "^7.0.0"
|
||||
"@types/babel__traverse" "^7.0.6"
|
||||
|
||||
babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.8.0:
|
||||
babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.6.1, babel-plugin-macros@^2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138"
|
||||
integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==
|
||||
@ -9411,7 +9591,7 @@ csstype@^2.5.7:
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.20.tgz#9229c65ea0b260cf4d3d997cb06288e36a8d6dda"
|
||||
integrity sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==
|
||||
|
||||
csstype@^3.0.2, csstype@^3.0.4:
|
||||
csstype@^3.0.11, csstype@^3.0.2, csstype@^3.0.4:
|
||||
version "3.0.11"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33"
|
||||
integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==
|
||||
@ -10049,6 +10229,14 @@ dom-helpers@^3.4.0:
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
|
||||
dom-helpers@^5.0.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
|
||||
integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.8.7"
|
||||
csstype "^3.0.2"
|
||||
|
||||
dom-serializer@0:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
|
||||
@ -12369,7 +12557,7 @@ hmac-drbg@^1.0.1:
|
||||
minimalistic-assert "^1.0.0"
|
||||
minimalistic-crypto-utils "^1.0.1"
|
||||
|
||||
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
|
||||
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
|
||||
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
|
||||
@ -17571,6 +17759,16 @@ react-transition-group@2.9.0, react-transition-group@^2.9.0:
|
||||
prop-types "^15.6.2"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
|
||||
react-transition-group@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
|
||||
integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
dom-helpers "^5.0.1"
|
||||
loose-envify "^1.4.0"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
react-use-websocket@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-use-websocket/-/react-use-websocket-3.0.0.tgz#754cb8eea76f55d31c5676d4abe3e573bc2cea04"
|
||||
@ -19385,6 +19583,11 @@ stylis@3.5.4:
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe"
|
||||
integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==
|
||||
|
||||
stylis@4.0.13:
|
||||
version "4.0.13"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.13.tgz#f5db332e376d13cc84ecfe5dace9a2a51d954c91"
|
||||
integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==
|
||||
|
||||
stylus-loader@^6.2.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-6.2.0.tgz#0ba499e744e7fb9d9b3977784c8639728a7ced8c"
|
||||
|
Loading…
Reference in New Issue
Block a user