order workflow
This commit is contained in:
@@ -114,7 +114,7 @@ export function orderIsOpen(order) {
|
||||
}
|
||||
|
||||
export function isOpen(state) {
|
||||
return state < 3
|
||||
return state >= 1 && state < 3
|
||||
}
|
||||
|
||||
export function parseOrderStatus(status) {
|
||||
|
||||
@@ -19,9 +19,8 @@ export function token(chainId, addr) {
|
||||
|
||||
// async version doesnt return until it has a token value
|
||||
export async function getToken(chainId, addr) {
|
||||
// todo deprecated. use metadataMap[chainId][addr]
|
||||
const s = useStore()
|
||||
if (addr===undefined) {
|
||||
if (addr===undefined) { // todo remove check
|
||||
console.warn('getToken(addr) is deprecated. use getToken(chainId,addr)')
|
||||
addr = chainId
|
||||
chainId = s.chainId
|
||||
@@ -38,7 +37,7 @@ export async function getToken(chainId, addr) {
|
||||
const _inFlightLookups = {}
|
||||
|
||||
export async function addExtraToken(chainId, addr) {
|
||||
if (addr===undefined) {
|
||||
if (addr===undefined) { // todo remove check
|
||||
console.warn('addExtraToken(addr) is deprecated. use addExtraToken(chainId,addr)')
|
||||
addr = chainId
|
||||
chainId = s.chainId
|
||||
|
||||
@@ -7,6 +7,7 @@ import {SingletonCoroutine} from "@/misc.js";
|
||||
import {defineStore} from "pinia";
|
||||
import {ref} from "vue";
|
||||
import {metadata, metadataMap} from "@/version.js";
|
||||
import {OrderState} from "@/blockchain/orderlib.js";
|
||||
|
||||
|
||||
export const useWalletStore = defineStore('wallet', ()=>{
|
||||
@@ -17,7 +18,7 @@ export const useWalletStore = defineStore('wallet', ()=>{
|
||||
// {
|
||||
// chainId: 31337, // must never be null, even if no wallet plugin exists. chosen by app, not wallet.
|
||||
// placementTime: Date.now(),
|
||||
// submitted: false // true after the order has started to be sent to the wallet
|
||||
// state: PendingOrderState.Submitted
|
||||
// tx: null // transaction ID
|
||||
// vault: '0x...', // or null if account not logged in yet
|
||||
// order: {tokenIn:..., tokenOut:..., ...} // blockchain binary order object
|
||||
@@ -213,11 +214,12 @@ async function _discoverVaults(owner) {
|
||||
}
|
||||
if( s.account === owner ) { // double-check the account since it could have changed during our await
|
||||
s.vaults = result
|
||||
if( useWalletStore().pendingOrders.length )
|
||||
if( result.length )
|
||||
if( useWalletStore().pendingOrders.length ) {
|
||||
if (result.length)
|
||||
flushOrders(result[0])
|
||||
else
|
||||
ensureVault2(s.chainId, owner, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,20 +259,28 @@ async function doEnsureVault(chainId, owner, num) {
|
||||
console.log(`requesting vault ${owner} ${num}`)
|
||||
socket.emit('ensureVault', chainId, owner, num)
|
||||
}
|
||||
// await sleep(5000) // prevent this process from running more than once every 5 seconds
|
||||
}
|
||||
// await sleep(5000) // prevent this process from running more than once every 5 seconds
|
||||
|
||||
const ensureVaultRoutine = new SingletonCoroutine(doEnsureVault, 100)
|
||||
|
||||
|
||||
export const PendingOrderState = {
|
||||
Submitted: 100, // user clicked Place Order but the tx isn't sent to the wallet yet
|
||||
Signing: 0, // tx is sent to the wallet
|
||||
Rejected: 101, // user refused to sign the tx
|
||||
Sent: 102, // tx is awaiting blockchain mining
|
||||
}
|
||||
|
||||
|
||||
export async function pendOrder(order) {
|
||||
console.log('order', JSON.stringify(order))
|
||||
const s = useStore()
|
||||
useWalletStore().pendingOrders.push({
|
||||
chainId: s.chainId,
|
||||
placementTime: new Date(),
|
||||
placementTime: Date.now()/1000,
|
||||
vault: s.vaults.length ? s.vaults[0] : null,
|
||||
submitted: false,
|
||||
state: PendingOrderState.Submitted,
|
||||
order
|
||||
})
|
||||
ensureVault()
|
||||
@@ -303,12 +313,13 @@ export async function cancelAll(vault) {
|
||||
export function flushOrders(vault) {
|
||||
const ws = useWalletStore();
|
||||
let needsFlush = false
|
||||
for( const order of ws.pendingOrders ) {
|
||||
if (order.vault === null)
|
||||
order.vault = vault
|
||||
if (!order.submitted) {
|
||||
pendOrderAsTransaction(order)
|
||||
order.submitted = true
|
||||
for( const pend of ws.pendingOrders ) {
|
||||
if (pend.vault === null)
|
||||
pend.vault = vault
|
||||
if (pend.state === PendingOrderState.Submitted) {
|
||||
console.log('pending', pend)
|
||||
pendOrderAsTransaction(pend)
|
||||
pend.state = PendingOrderState.Signing
|
||||
needsFlush = true
|
||||
}
|
||||
}
|
||||
@@ -317,40 +328,46 @@ export function flushOrders(vault) {
|
||||
}
|
||||
|
||||
|
||||
function pendOrderAsTransaction(order) {
|
||||
function pendOrderAsTransaction(pend) {
|
||||
pendTransaction(async (signer)=> {
|
||||
const contract = contractOrNull(order.vault, vaultAbi, signer)
|
||||
const contract = contractOrNull(pend.vault, vaultAbi, signer)
|
||||
if( contract === null ) {
|
||||
console.error('vault contract was null while sending order transaction', order.vault)
|
||||
console.error('vault contract was null while sending order transaction', pend.vault)
|
||||
return null
|
||||
}
|
||||
if (!await switchChain(order.chainId)) {
|
||||
if (!await switchChain(pend.chainId)) {
|
||||
console.log('user refused chain switch')
|
||||
pend.state = PendingOrderState.Rejected
|
||||
return null
|
||||
}
|
||||
console.log('placing order', order)
|
||||
const tx = await contract.placeDexorder(order.order) // todo update status
|
||||
order.tx = tx
|
||||
console.log('placing order', pend)
|
||||
const tx = await contract.placeDexorder(pend.order) // todo update status
|
||||
pend.tx = tx
|
||||
tx.wait().then((txReceipt)=>{
|
||||
const ws = useWalletStore();
|
||||
ws.pendingOrders = ws.pendingOrders.filter((o)=>o!==order)
|
||||
ws.pendingOrders = ws.pendingOrders.filter((o)=>o!==pend)
|
||||
})
|
||||
return tx
|
||||
},
|
||||
(e) => {
|
||||
if( e.info?.error?.code === 4001 ) {
|
||||
console.log(`user rejected transaction`)
|
||||
pend.state = PendingOrderState.Rejected
|
||||
return true // returning true means we handled the error. any other return value will dump to console.
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function pendTransaction(sender) {
|
||||
export function pendTransaction(sender, errHandler) {
|
||||
const s = useStore()
|
||||
s.transactionSenders.push(sender)
|
||||
s.transactionSenders.push([sender,errHandler])
|
||||
flushTransactions()
|
||||
}
|
||||
|
||||
|
||||
const flushTransactionsRoutine = new SingletonCoroutine(asyncFlushTransactions,1)
|
||||
|
||||
let flushing = 0 // semaphore
|
||||
|
||||
export function flushTransactions() {
|
||||
flushTransactionsRoutine.invoke()
|
||||
}
|
||||
@@ -376,11 +393,12 @@ async function asyncFlushTransactions() {
|
||||
console.log('signer denied')
|
||||
return
|
||||
}
|
||||
for (const sender of senders)
|
||||
doSendTransaction(sender, signer)
|
||||
for (const [sender,errHandler] of senders)
|
||||
doSendTransaction(sender, signer, errHandler)
|
||||
s.transactionSenders = []
|
||||
}
|
||||
|
||||
function doSendTransaction(sender, signer) {
|
||||
function doSendTransaction(sender, signer, errHandler) {
|
||||
const s = useStore();
|
||||
s.removeTransactionSender(sender)
|
||||
sender(signer).then((tx)=>{
|
||||
@@ -388,11 +406,11 @@ function doSendTransaction(sender, signer) {
|
||||
console.log('sent transaction', tx)
|
||||
tx.wait().then((tr)=>console.log('tx receipt',tr))
|
||||
}
|
||||
}).catch((e)=>{
|
||||
if( e.info?.error?.code === 4001 ) {
|
||||
console.log(`user rejected transaction`)
|
||||
}
|
||||
else {
|
||||
}).catch(async (e)=>{
|
||||
let dumpErr = true
|
||||
if (errHandler!==undefined)
|
||||
dumpErr = await errHandler(e) !== true
|
||||
if (dumpErr) {
|
||||
if( e.reason && e.info )
|
||||
console.error('error sending transaction', e.reason, e.info)
|
||||
else
|
||||
|
||||
@@ -66,10 +66,7 @@ const s = useStore()
|
||||
const walletOk = typeof window.ethereum !== 'undefined'
|
||||
const providerOk = computed(()=>s.provider!==null)
|
||||
const chainOk = computed(()=>providerOk.value && s.helper!==null)
|
||||
const ok = computed(()=>{
|
||||
console.log('recompute provider ok')
|
||||
return walletOk && providerOk.value && chainOk.value
|
||||
})
|
||||
const ok = computed(()=>walletOk && providerOk.value && chainOk.value)
|
||||
function reload() {
|
||||
window.location.reload()
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
</div>
|
||||
</v-card-item>
|
||||
<v-card-actions class="d-flex justify-space-evenly mb-4">
|
||||
<v-btn variant="outlined" color="red" @click="$router.push('/vault')">Cancel</v-btn>
|
||||
<v-btn variant="outlined" color="red" @click="$router.push('/assets')">Cancel</v-btn>
|
||||
<v-btn variant="flat" color="green" :disabled="!valid()" @click="placeOrder">Place Dexorder</v-btn>
|
||||
</v-card-actions>
|
||||
</phone-card>
|
||||
|
||||
@@ -43,7 +43,10 @@
|
||||
<pair-price :base-addr="item.order.tokenIn" :quote-addr="item.order.tokenOut" :value="item.avg" :show-btn="true"/>
|
||||
</template>
|
||||
<template v-slot:item.status="{ item }">
|
||||
<v-chip v-if="item.state===OrderState.Signing" prepend-icon="mdi-signature" color="yellow">Signing</v-chip>
|
||||
<v-chip v-if="item.state===PendingOrderState.Submitted || item.state===PendingOrderState.Signing"
|
||||
prepend-icon="mdi-signature">Wallet Signing</v-chip>
|
||||
<v-chip v-if="item.state===PendingOrderState.Rejected" prepend-icon="mdi-cancel">Rejected</v-chip>
|
||||
<v-chip v-if="item.state===PendingOrderState.Sent" prepend-icon="mdi-send">Sent</v-chip>
|
||||
<v-chip v-if="item.state===OrderState.Open" class="d-none d-lg-inline-flex" prepend-icon="mdi-dots-horizontal"
|
||||
color="green">Open
|
||||
</v-chip>
|
||||
@@ -103,7 +106,6 @@
|
||||
</tr>
|
||||
</template>
|
||||
</v-data-table>
|
||||
<new-order class="mx-3 mb-3"/>
|
||||
<btn icon="mdi-delete-alert" color="red" class="mx-3 mb-3" @click="cancelAll(vaultAddr)">Cancel All Orders</btn>
|
||||
</div>
|
||||
</template>
|
||||
@@ -113,7 +115,7 @@ import {FixedNumber} from "ethers";
|
||||
import {useStore} from "@/store/store";
|
||||
import {computed, defineAsyncComponent, ref} from "vue";
|
||||
import Btn from "@/components/Btn.vue"
|
||||
import {cancelAll, cancelOrder} from "@/blockchain/wallet.js";
|
||||
import {cancelAll, cancelOrder, PendingOrderState, useWalletStore} from "@/blockchain/wallet.js";
|
||||
import {dateString, pairPriceAddr} from "@/misc.js";
|
||||
import {isOpen, OrderState} from "@/blockchain/orderlib.js";
|
||||
import NewOrder from "@/components/NewOrder.vue";
|
||||
@@ -123,6 +125,7 @@ const TokenAmount = defineAsyncComponent(()=>import('./TokenAmount.vue'))
|
||||
const TokenSymbol = defineAsyncComponent(()=>import('./TokenSymbol.vue'))
|
||||
|
||||
const s = useStore()
|
||||
const ws = useWalletStore()
|
||||
const props = defineProps(['vault'])
|
||||
const vaultAddr = computed(()=>props.vault?props.vault:s.vault)
|
||||
const inverted = ref({})
|
||||
@@ -196,6 +199,18 @@ const orders = computed(()=>{
|
||||
// ]
|
||||
const result = []
|
||||
|
||||
// in-flight orders
|
||||
for (const pend of ws.pendingOrders) {
|
||||
console.log('pended order', pend)
|
||||
result.splice(0, 0, {
|
||||
start: pend.placementTime,
|
||||
order: pend.order,
|
||||
filled: 0,
|
||||
state: pend.state
|
||||
})
|
||||
}
|
||||
|
||||
// historical orders
|
||||
if( vaultAddr.value in s.orders ) {
|
||||
for (const [index, status] of Object.entries(s.orders[vaultAddr.value]).reverse()) {
|
||||
const st = {...status}
|
||||
|
||||
@@ -23,14 +23,16 @@
|
||||
<builder-factory :order="order" :builder="b"/>
|
||||
</template>
|
||||
<div class="my-3">
|
||||
<span :style="colorStyle" class="ma-3">Add condition:</span>
|
||||
<!-- <v-btn variant="flat" prepend-icon="mdi-clock-outline" @click="build('DCABuilder')">DCA</v-btn>-->
|
||||
<v-btn :color="color" variant="text" prepend-icon="mdi-ray-vertex" @click="build(order,'LimitBuilder')">Limit</v-btn>
|
||||
<!-- <v-btn variant="flat" prepend-icon="mdi-vector-line">Line</v-btn>-->
|
||||
<!--
|
||||
mdi-ray-start-end
|
||||
mdi-vector-polyline
|
||||
-->
|
||||
<div v-if="order.builders.length===0"> <!--todo remove gralpha limitation of one builder-->
|
||||
<span :style="colorStyle" class="ma-3">Add condition:</span>
|
||||
<!-- <v-btn variant="flat" prepend-icon="mdi-clock-outline" @click="build('DCABuilder')">DCA</v-btn>-->
|
||||
<v-btn :color="color" variant="text" prepend-icon="mdi-ray-vertex" @click="build(order,'LimitBuilder')">Limit</v-btn>
|
||||
<!-- <v-btn variant="flat" prepend-icon="mdi-vector-line">Line</v-btn>-->
|
||||
<!--
|
||||
mdi-ray-start-end
|
||||
mdi-vector-polyline
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</row-bar>
|
||||
@@ -41,7 +43,7 @@
|
||||
import BuilderFactory from "@/components/chart/BuilderFactory.vue";
|
||||
import {builderFuncs, newBuilder, orderFuncs, useChartOrderStore} from "@/orderbuild.js";
|
||||
import {useOrderStore} from "@/store/store.js";
|
||||
import {computed, onMounted, onUnmounted, watch} from "vue";
|
||||
import {computed, onMounted, onUnmounted, onUpdated, watch} from "vue";
|
||||
import {lightenColor, lightenColor2} from "@/misc.js";
|
||||
import {useTheme} from "vuetify";
|
||||
import RowBar from "@/components/chart/RowBar.vue";
|
||||
@@ -98,8 +100,15 @@ function buildOrder() {
|
||||
}
|
||||
|
||||
|
||||
onMounted(()=>orderFuncs[props.order.id] = buildOrder)
|
||||
onUnmounted(()=>delete orderFuncs[props.order.id])
|
||||
let lastId = props.order.id
|
||||
orderFuncs[lastId] = buildOrder
|
||||
onUpdated(()=>{
|
||||
console.log('onUpdated', lastId, ...arguments)
|
||||
delete orderFuncs[lastId]
|
||||
orderFuncs[props.order.id] = buildOrder
|
||||
lastId = props.order.id
|
||||
})
|
||||
onUnmounted(() => delete orderFuncs[lastId])
|
||||
|
||||
|
||||
const theme = useTheme().current
|
||||
|
||||
@@ -1,31 +1,32 @@
|
||||
<template>
|
||||
<toolbar-pane>
|
||||
<toolbar-pane title="Create">
|
||||
<template v-slot:toolbar>
|
||||
<v-btn variant="flat" prepend-icon="mdi-plus" @click="co.newOrder" v-if="co.orders.length===0">New Order</v-btn>
|
||||
<!-- <v-btn variant="flat" prepend-icon="mdi-plus" @click="co.newOrder" v-if="co.orders.length===0">New Order</v-btn>-->
|
||||
<v-btn variant="text" prepend-icon="mdi-send" @click="placeOrder"
|
||||
:color="orderColor" v-if="co.orders.length>0" :disabled="co.drawing">
|
||||
Place Dexorder
|
||||
</v-btn>
|
||||
<v-btn variant="flat" prepend-icon="mdi-cancel" v-if="co.orders.length>0" @click="cancelOrder">Cancel</v-btn>
|
||||
<v-btn variant="flat" prepend-icon="mdi-delete" v-if="co.orders.length>0" @click="cancelOrder">Reset</v-btn>
|
||||
</template>
|
||||
<!-- <div v-for="b in co.builderList">{{JSON.stringify(b)}}</div>-->
|
||||
<template v-for="o in co.orders">
|
||||
<chart-order :order="o"/>
|
||||
</template>
|
||||
<v-dialog v-model="showCancel" max-width="300">
|
||||
<v-card title="Cancel Order?" text="Do you want to cancel this order and create a new one?">
|
||||
<v-card-actions>
|
||||
<v-spacer/>
|
||||
<v-btn @click="()=>showCancel=false">Keep Existing</v-btn>
|
||||
<v-btn @click="()=>{co.orders.shift(); showCancel=false}" color="red">Cancel Order</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
<needs-chart>
|
||||
<template v-for="o in co.orders">
|
||||
<chart-order :order="o"/>
|
||||
</template>
|
||||
<v-dialog v-model="showResetDialog" max-width="300">
|
||||
<v-card title="Cancel Order?" text="Do you want to cancel this order and start again?">
|
||||
<v-card-actions>
|
||||
<v-spacer/>
|
||||
<v-btn @click="()=>showResetDialog=false">Keep Existing</v-btn>
|
||||
<v-btn @click="()=>{co.resetOrders(); showResetDialog=false}" color="red">Reset Order</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
</needs-chart>
|
||||
</toolbar-pane>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {builderFuncs, orderFuncs, useChartOrderStore} from "@/orderbuild.js";
|
||||
import {orderFuncs, useChartOrderStore} from "@/orderbuild.js";
|
||||
import {addSymbolChangedCallback, removeSymbolChangedCallback} from "@/charts/chart.js";
|
||||
import {computed, onBeforeUnmount, ref} from "vue";
|
||||
import {useOrderStore, useStore} from "@/store/store.js";
|
||||
@@ -33,10 +34,10 @@ import {useOrderStore, useStore} from "@/store/store.js";
|
||||
import {routeFinder} from "@/blockchain/route.js";
|
||||
import ChartOrder from "@/components/chart/ChartOrder.vue";
|
||||
import {useTheme} from "vuetify";
|
||||
import Toolbar from "@/components/chart/Toolbar.vue";
|
||||
import {Exchange, newOrder} from "@/blockchain/orderlib.js";
|
||||
import {pendOrder} from "@/blockchain/wallet.js";
|
||||
import ToolbarPane from "@/components/chart/ToolbarPane.vue";
|
||||
import NeedsChart from "@/components/NeedsChart.vue";
|
||||
import router from "@/router/index.js";
|
||||
|
||||
const s = useStore()
|
||||
const co = useChartOrderStore()
|
||||
@@ -54,13 +55,13 @@ addSymbolChangedCallback(changeSymbol)
|
||||
onBeforeUnmount(() => removeSymbolChangedCallback(changeSymbol) )
|
||||
|
||||
|
||||
const showCancel = ref(false)
|
||||
const showResetDialog = ref(false)
|
||||
|
||||
const theme = useTheme().current
|
||||
const orderColor = computed(()=>co.orders.length===0?null : co.orders[0].buy ? theme.value.colors.success:theme.value.colors.error)
|
||||
|
||||
function cancelOrder() {
|
||||
showCancel.value = true
|
||||
showResetDialog.value = true
|
||||
}
|
||||
|
||||
|
||||
@@ -81,6 +82,8 @@ async function placeOrder() {
|
||||
}
|
||||
else {
|
||||
await pendOrder(built[0])
|
||||
co.resetOrders()
|
||||
router.push('/orders')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {computed, onBeforeUnmount, onMounted, onUnmounted, watch} from "vue";
|
||||
import {computed, onBeforeUnmount, onMounted, onUnmounted, onUpdated, watch} from "vue";
|
||||
import {chart} from "@/charts/chart.js";
|
||||
import {applyLine2, builderFuncs, useChartOrderStore} from "@/orderbuild.js";
|
||||
import Color from "color";
|
||||
@@ -120,8 +120,18 @@ function buildTranches() {
|
||||
return tranches
|
||||
}
|
||||
|
||||
onMounted(() => builderFuncs[props.builder.id] = buildTranches)
|
||||
onUnmounted(() => delete builderFuncs[props.builder.id])
|
||||
|
||||
// todo move this into a supercomponent
|
||||
let lastId = props.builder.id
|
||||
builderFuncs[props.builder.id] = buildTranches
|
||||
onUpdated(()=>{
|
||||
if (lastId !== props.builder.id ) {
|
||||
delete builderFuncs[lastId]
|
||||
builderFuncs[props.builder.id] = buildTranches
|
||||
lastId = props.builder.id
|
||||
}
|
||||
})
|
||||
onUnmounted(() => delete builderFuncs[lastId])
|
||||
|
||||
|
||||
const skew100 = computed( {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="d-flex mb-1 align-center w-100">
|
||||
<div class="d-flex align-end clickable" @click="$router.push('/place')">
|
||||
<div class="d-flex align-end clickable" @click="$router.push('/create')">
|
||||
<span class="arrow align-self-start"><v-icon icon="mdi-arrow-up-bold" :color="theme.colors.success"/></span>
|
||||
<span class="logo">dexorder</span>
|
||||
<v-chip text="ALPHA" size='x-small' color="red" class="align-self-start pr-6" variant="text"/>
|
||||
@@ -12,9 +12,12 @@
|
||||
<slot/>
|
||||
<div class="ml-auto d-flex align-center">
|
||||
<!-- <v-icon :icon="icon" size="small"/> -->
|
||||
<span class="title">{{title}}</span>
|
||||
<toolbar-button icon="mdi-currency-btc" path="/vault"/>
|
||||
<toolbar-button icon="mdi-format-list-bulleted-square" path="/orders"/>
|
||||
<span class="title mr-4">{{title}}</span>
|
||||
<toolbar-button tooltip="Create" icon="mdi-chart-timeline-variant" path="/create"/>
|
||||
<!-- mdi-currency-btc mdi-currency-eth mdi-bank-outline mdi-safe-square-outline -->
|
||||
<toolbar-button tooltip="Assets" icon="mdi-currency-btc" path="/assets"/>
|
||||
<!-- mdi-format-list-checks mdi-format-list-bulleted-square -->
|
||||
<toolbar-button tooltip="Orders" icon="mdi-format-list-checks" path="/orders"/>
|
||||
<v-btn variant="text" icon="mdi-help-circle-outline" text="Info" @click="showCorp" disabled></v-btn>
|
||||
</div>
|
||||
</div>
|
||||
@@ -23,10 +26,6 @@
|
||||
<script setup>
|
||||
import {useStore} from "@/store/store.js";
|
||||
import {useChartOrderStore} from "@/orderbuild.js";
|
||||
import {chart, drawShape} from "@/charts/chart.js";
|
||||
import {timestamp} from "@/misc.js";
|
||||
import {ShapeType} from "@/charts/shape.js";
|
||||
import {computed, ref} from "vue";
|
||||
import {useTheme} from "vuetify";
|
||||
import ToolbarButton from "@/components/chart/ToolbarButton.vue";
|
||||
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
<template>
|
||||
<v-btn :color="isCurrent?'primary':undefined" variant="text" :icon="icon" @click="$router.push(path)"/>
|
||||
<v-tooltip :text="tooltip" location="top">
|
||||
<template v-slot:activator="{ props }">
|
||||
<v-btn v-bind="props" :color="isCurrent?'primary':undefined" variant="text"
|
||||
:icon="icon" @click="$router.push(path)"/>
|
||||
</template>
|
||||
</v-tooltip>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {computed} from "vue";
|
||||
import {useRoute} from "vue-router";
|
||||
|
||||
const props = defineProps(['icon', 'path'])
|
||||
const props = defineProps(['icon', 'path', 'tooltip'])
|
||||
const isCurrent = computed(() => useRoute().path === props.path)
|
||||
</script>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<v-chip text="ALPHA" size="x-small" color="red" class="mx-1"/>
|
||||
</v-app-bar-title>
|
||||
|
||||
<v-btn icon="mdi-safe-square" color="grey-darken-2" text="Vault" @click="$router.push('/vault')"></v-btn>
|
||||
<v-btn icon="mdi-safe-square" color="grey-darken-2" text="Vault" @click="$router.push('/assets')"></v-btn>
|
||||
<v-btn icon="mdi-information-outline" text="Order Status" @click="$router.push('/orders')"></v-btn>
|
||||
|
||||
</v-app-bar>
|
||||
|
||||
@@ -31,12 +31,15 @@ export const orderFuncs = {}
|
||||
// the key is order.builder.id and the value is a function() that returns an array of tranches
|
||||
export const builderFuncs = {}
|
||||
|
||||
function newDefaultOrder() {
|
||||
return { id:uuid(), amount:1, amountIsTokenA: true, buy: true, builders:[] }
|
||||
}
|
||||
|
||||
export const useChartOrderStore = defineStore('chart_orders', () => {
|
||||
const chartReady = ref(false)
|
||||
|
||||
const orders = ref([]) // order models in UI format
|
||||
const built = ref([]) // orders in blockchain format, ready to send
|
||||
const orders = ref([newDefaultOrder()]) // order models in UI format
|
||||
const built = ref([{}]) // orders in blockchain format, ready to send
|
||||
const selectedOrder = ref(null)
|
||||
const selectedSymbol = ref(null)
|
||||
const selectedPool = ref(null)
|
||||
@@ -45,7 +48,7 @@ export const useChartOrderStore = defineStore('chart_orders', () => {
|
||||
const drawingCallbacks = ref(null) // only during draw mode
|
||||
|
||||
function newOrder() {
|
||||
const order = {id:uuid(), amount:1, amountIsTokenA: true, buy: true, builders:[] }
|
||||
const order = newDefaultOrder()
|
||||
orders.value.push(order)
|
||||
built.value.push({})
|
||||
selectedOrder.value = order
|
||||
@@ -54,15 +57,25 @@ export const useChartOrderStore = defineStore('chart_orders', () => {
|
||||
function removeOrder(order) {
|
||||
let index = orders.value.findIndex((o)=>o.id===order.id)
|
||||
if (index === -1) return
|
||||
orders.value = orders.value.filter((o)=>o.id!==order.id)
|
||||
if (orders.value.length === 0)
|
||||
selectedOrder.value = null
|
||||
const result = orders.value.filter((o)=>o.id!==order.id)
|
||||
if (result.length === 0) {
|
||||
const order = newDefaultOrder()
|
||||
result.push(order)
|
||||
selectedOrder.value = order
|
||||
}
|
||||
else
|
||||
selectedOrder.value = orders.value[Math.max(0,index-1)] // select the order above the removed one
|
||||
selectedOrder.value = result[Math.max(0,index-1)] // select the order above the removed one
|
||||
orders.value = result
|
||||
}
|
||||
|
||||
function resetOrders() {
|
||||
const order = newDefaultOrder()
|
||||
orders.value = [order]
|
||||
selectedOrder.value = order
|
||||
}
|
||||
|
||||
return {
|
||||
chartReady, selectedSymbol, selectedPool, orders, drawing, drawingCallbacks, newOrder, removeOrder,
|
||||
chartReady, selectedSymbol, selectedPool, orders, drawing, drawingCallbacks, newOrder, removeOrder, resetOrders,
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -14,16 +14,16 @@ const routes = [
|
||||
component: () => import(/* webpackChunkName: "chartorder" */ '@/components/chart/ChartPlaceOrder.vue'),
|
||||
},
|
||||
{
|
||||
path: '/place',
|
||||
name: 'Place',
|
||||
path: '/create',
|
||||
name: 'Edit',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (about.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import(/* webpackChunkName: "chartorder" */ '@/components/chart/ChartPlaceOrder.vue'),
|
||||
},
|
||||
{
|
||||
path: '/vault',
|
||||
name: 'Vault',
|
||||
path: '/assets',
|
||||
name: 'Assets',
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (about.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
|
||||
Reference in New Issue
Block a user