mirror of
https://github.com/logos-storage/ethcc-demo.git
synced 2026-01-05 22:53:06 +00:00
Add slots inside of storage request details
This commit is contained in:
parent
552cc2705b
commit
83ab353038
@ -1,124 +1,52 @@
|
||||
<script setup>
|
||||
import { onMounted } from 'vue'
|
||||
import { initModals } from 'flowbite'
|
||||
import { useRequestsStore } from '@/stores/requests'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
const requestsStore = useRequestsStore()
|
||||
|
||||
// const ethProvider = inject('ethProvider')
|
||||
// const marketplace = inject('marketplace')
|
||||
// const codexApi = inject('codexApi')
|
||||
// const token = inject('token')
|
||||
// const blockNumber = ref(0)
|
||||
// const requests = ref([])
|
||||
|
||||
// const onStorageRequested = async ({requestId, ask, expiry, blockNumber}) => {
|
||||
// let request = await marketplace.getRequest(requestId)
|
||||
// let stateIdx = await marketplace.requestState(requestId)
|
||||
// let cid = request[2][0]
|
||||
// let state = requestState[stateIdx]
|
||||
// var imgSrc = ""
|
||||
// var error = ""
|
||||
// if (state == "New" || state == "Fulfilled"){
|
||||
// try {
|
||||
// let res = await codexApi.download(cid)
|
||||
// try{
|
||||
// const blob = await res.blob()
|
||||
// imgSrc = URL.createObjectURL(blob)
|
||||
// } catch (e) {
|
||||
// error = `not an image (error: ${error.message})`
|
||||
// }
|
||||
// } catch(error) {
|
||||
// error = `failed to download cid data: ${error}`
|
||||
// }
|
||||
// }
|
||||
// requests.value.push({
|
||||
// blockNumber,
|
||||
// cid,
|
||||
// requestId,
|
||||
// ask,
|
||||
// expiry,
|
||||
// state,
|
||||
// imgSrc,
|
||||
// error
|
||||
// })
|
||||
// }
|
||||
// onMounted(async () => {
|
||||
// await requestsStore.fetch()
|
||||
// await requestsStore.listenForNewEvents()
|
||||
// })
|
||||
// let storageRequestedFilter = marketplace.filters.StorageRequested
|
||||
// marketplace.on(storageRequestedFilter, async (requestId, ask, expiry, event) => {
|
||||
// let {blockNumber} = event
|
||||
// // onStorageRequested({
|
||||
// // blockNumber,
|
||||
// // requestId,
|
||||
// // ask,
|
||||
// // expiry,
|
||||
// // })
|
||||
// let request = await marketplace.getRequest(requestId)
|
||||
// let state = await getRequestState(requestId)
|
||||
// onStorageRequested(blockNumber, request, state)
|
||||
// })
|
||||
|
||||
// // query past events
|
||||
// let requests = (await marketplace.queryFilter(storageRequestedFilter))
|
||||
// requests.forEach(async (event) => {
|
||||
// let {requestId, ask, expiry} = event.args
|
||||
// let {blockNumber} = event
|
||||
// // onStorageRequested({
|
||||
// // blockNumber,
|
||||
// // requestId,
|
||||
// // ask,
|
||||
// // expiry
|
||||
// // })
|
||||
// let request = await marketplace.getRequest(requestId)
|
||||
// let state = await getRequestState(requestId)
|
||||
// onStorageRequested(blockNumber, request, state)
|
||||
// })
|
||||
|
||||
// let slotFreedFilter = marketplace.filters.SlotFreed
|
||||
// marketplace.on(slotFreedFilter, (requestId, ask, expiry, event) => {
|
||||
// let {blockNumber} = event
|
||||
// onSlotFreed({
|
||||
// blockNumber,
|
||||
// requestId,
|
||||
// ask,
|
||||
// expiry,
|
||||
// })
|
||||
// })
|
||||
|
||||
// let slotsFreed = (await marketplace.queryFilter(slotFreedFilter))
|
||||
// slotsFreed.forEach(event => {
|
||||
// let {requestId, ask, expiry} = event.args
|
||||
// let {blockNumber} = event
|
||||
// onSlotFreed({
|
||||
// blockNumber,
|
||||
// requestId,
|
||||
// ask,
|
||||
// expiry
|
||||
// })
|
||||
// })
|
||||
|
||||
// })
|
||||
// console.log(await ethProvider.getBlockNumber())
|
||||
const { requests } = storeToRefs(requestsStore)
|
||||
import { getStateColour } from '@/utils/slots'
|
||||
import { shortHex } from '@/utils/ids'
|
||||
import StateIndicator from '@/components/StateIndicator.vue'
|
||||
defineProps({
|
||||
slots: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- <span>asdf{{ blockNumber.value }}</span> -->
|
||||
<!-- <span>Yo yo yo yo yo {{ blockNumber }}</span> -->
|
||||
<ul class="requests">
|
||||
<!-- <li v-for="(request, idx) in requestsStore.requests" :key="{requestId}"> WORKS! -->
|
||||
<li v-for="([requestId, { request, state }], idx) in requests" :key="{ requestId }">
|
||||
{{ idx }}.
|
||||
<div>CID: {{ request[2][0] }}</div>
|
||||
<div>RequestID: {{ requestId }}</div>
|
||||
<div>State: {{ state }}</div>
|
||||
<CodexImage v-if="state == 'New' || state == 'Fulfilled'" cid="cid" />
|
||||
<!-- <div v-if="error">{{error}}</div>
|
||||
<img v-else-if="imgSrc" :src="imgSrc" width="100%"/> -->
|
||||
</li>
|
||||
</ul>
|
||||
<div
|
||||
class="relative overflow-x-auto overflow-y-auto max-h-screen shadow-md sm:rounded-lg border-t border-gray-50"
|
||||
>
|
||||
<table class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400">
|
||||
<thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
|
||||
<tr>
|
||||
<th scope="col" class="px-6 py-3">SlotID</th>
|
||||
<th scope="col" class="px-6 py-3">Index</th>
|
||||
<th scope="col" class="px-6 py-3">Proofs Missed</th>
|
||||
<th scope="col" class="px-6 py-3">Provider</th>
|
||||
<th scope="col" class="px-6 py-3">State</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="({ slotId, slotIdx, state, proofsMissed, provider }, idx) in slots"
|
||||
:key="{ slotId }"
|
||||
class="bg-white dark:bg-gray-800 hover:bg-gray-50 dark:hover:bg-gray-600"
|
||||
>
|
||||
<th
|
||||
scope="row"
|
||||
class="flex items-center px-6 py-4 font-medium text-gray-900 whitespace-nowrap dark:text-white"
|
||||
>
|
||||
<div class="text-base font-semibold">{{ shortHex(slotId) }}</div>
|
||||
</th>
|
||||
<td class="px-6 py-4">{{ slotIdx }}</td>
|
||||
<td class="px-6 py-4">{{ proofsMissed }}</td>
|
||||
<td class="px-6 py-4">{{ shortHex(provider) }}</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center">
|
||||
<StateIndicator :text="state" :color="getStateColour(state)"></StateIndicator>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
72
src/components/StateIndicator.vue
Normal file
72
src/components/StateIndicator.vue
Normal file
@ -0,0 +1,72 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
color: {
|
||||
type: String,
|
||||
required: true,
|
||||
validator(value, props) {
|
||||
// The value must match one of these strings
|
||||
return ['green', 'blue', 'gray', 'yellow', 'red'].includes(value)
|
||||
}
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
|
||||
const theme = computed(() => {
|
||||
if (props.color == 'blue') {
|
||||
return {
|
||||
bg: 'bg-blue-100',
|
||||
bgDark: 'dark:bg-blue-900',
|
||||
bgDot: 'bg-blue-500',
|
||||
text: 'text-blue-800',
|
||||
textDark: 'dark:text-blue-300'
|
||||
}
|
||||
} else if (props.color === 'gray') {
|
||||
return {
|
||||
bg: 'bg-gray-100',
|
||||
bgDark: 'dark:bg-gray-900',
|
||||
bgDot: 'bg-gray-500',
|
||||
text: 'text-gray-800',
|
||||
textDark: 'dark:text-gray-300'
|
||||
}
|
||||
} else if (props.color === 'yellow') {
|
||||
return {
|
||||
bg: 'bg-yellow-100',
|
||||
bgDark: 'dark:bg-yellow-900',
|
||||
bgDot: 'bg-yellow-500',
|
||||
text: 'text-yellow-800',
|
||||
textDark: 'dark:text-yellow-300'
|
||||
}
|
||||
} else if (props.color === 'red') {
|
||||
return {
|
||||
bg: 'bg-red-100',
|
||||
bgDark: 'dark:bg-red-900',
|
||||
bgDot: 'bg-red-500',
|
||||
text: 'text-red-800',
|
||||
textDark: 'dark:text-red-300'
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
bg: 'bg-green-100',
|
||||
bgDark: 'dark:bg-green-900',
|
||||
bgDot: 'bg-green-500',
|
||||
text: 'text-green-800',
|
||||
textDark: 'dark:text-green-300'
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span
|
||||
class="inline-flex items-center text-xs font-medium px-2.5 py-0.5 rounded-full"
|
||||
:class="[theme.bg, theme.text, theme.bgDark, theme.textDark]"
|
||||
>
|
||||
<span class="w-2 h-2 me-1 rounded-full" :class="theme.bgDot"></span>
|
||||
{{ text }}
|
||||
</span>
|
||||
</template>
|
||||
@ -1,9 +1,11 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { price } from '@/utils/requests'
|
||||
import { getStateColour, price } from '@/utils/requests'
|
||||
|
||||
import CodexImage from '@/components/CodexImage.vue'
|
||||
import StateIndicator from '@/components/StateIndicator.vue'
|
||||
import { shortHex } from '@/utils/ids'
|
||||
import Slots from './Slots.vue'
|
||||
|
||||
const props = defineProps({
|
||||
requestId: {
|
||||
@ -21,77 +23,107 @@ const totalPrice = computed(() => price(props.request))
|
||||
|
||||
<template>
|
||||
<div class="flex">
|
||||
<CodexImage class="flex-2" :cid="props.request.content.cid"></CodexImage>
|
||||
<CodexImage class="flex-2" :cid="request.content.cid"></CodexImage>
|
||||
<div class="py-8 px-4 mx-auto max-w-2xl lg:py-16">
|
||||
<h2 class="mb-2 text-xl font-semibold leading-none text-gray-900 md:text-2xl dark:text-white">
|
||||
{{ shortHex(requestId) }}
|
||||
{{ shortHex(requestId, 12) }}
|
||||
</h2>
|
||||
<p class="mb-4 text-xl font-extrabold leading-none text-gray-900 md:text-2xl dark:text-white">
|
||||
{{ totalPrice }} CDX
|
||||
</p>
|
||||
<StateIndicator
|
||||
class="mb-4"
|
||||
:text="request.state"
|
||||
:color="getStateColour(request.state)"
|
||||
></StateIndicator>
|
||||
<dl>
|
||||
<dt class="mb-2 font-semibold leading-none text-gray-900 dark:text-white">Dataset CID</dt>
|
||||
<dd class="mb-4 font-light text-gray-500 sm:mb-5 dark:text-gray-400">
|
||||
{{ request.content.cid }}
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="flex items-center space-x-6">
|
||||
<div>
|
||||
<dt class="mb-2 font-semibold leading-none text-gray-900 dark:text-white">Expiry</dt>
|
||||
<dd class="mb-4 font-light text-gray-500 sm:mb-5 dark:text-gray-400">
|
||||
{{ request.expiry }}s
|
||||
</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt class="mb-2 font-semibold leading-none text-gray-900 dark:text-white">Duration</dt>
|
||||
<dd class="mb-4 font-light text-gray-500 sm:mb-5 dark:text-gray-400">
|
||||
{{ request.ask.duration }}s
|
||||
</dd>
|
||||
</div>
|
||||
<dl>
|
||||
<dt class="mb-2 font-semibold leading-none text-gray-900 dark:text-white">Client</dt>
|
||||
<dd class="mb-4 font-light text-gray-500 sm:mb-5 dark:text-gray-400">
|
||||
{{ request.client }}
|
||||
</dd>
|
||||
</dl>
|
||||
<div class="flex items-center space-x-4">
|
||||
<button
|
||||
type="button"
|
||||
class="text-white inline-flex items-center bg-primary-700 hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-primary-600 dark:hover:bg-primary-700 dark:focus:ring-primary-800"
|
||||
<dl>
|
||||
<dt class="mb-2 font-semibold leading-none text-gray-900 dark:text-white">Merkle root</dt>
|
||||
<dd class="mb-4 font-light text-gray-500 sm:mb-5 dark:text-gray-400">
|
||||
{{ request.content.merkleRoot }}
|
||||
</dd>
|
||||
</dl>
|
||||
<div class="relative overflow-x-auto overflow-y-auto max-h-screen mb-10">
|
||||
<table
|
||||
class="w-full text-sm text-left rtl:text-right text-gray-500 dark:text-gray-400 mx-auto"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="mr-1 -ml-1 w-5 h-5"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"
|
||||
></path>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||
clip-rule="evenodd"
|
||||
></path>
|
||||
</svg>
|
||||
Edit
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center text-white bg-red-600 hover:bg-red-700 focus:ring-4 focus:outline-none focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-red-500 dark:hover:bg-red-600 dark:focus:ring-red-900"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="w-5 h-5 mr-1.5 -ml-1"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fill-rule="evenodd"
|
||||
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
|
||||
clip-rule="evenodd"
|
||||
></path>
|
||||
</svg>
|
||||
Delete
|
||||
</button>
|
||||
<tbody>
|
||||
<tr class="bg-white dark:bg-transparent hover:bg-gray-50 dark:hover:bg-gray-600 text-base">
|
||||
<td
|
||||
class="flex items-center pr-1 py-2 font-medium text-gray-900 whitespace-nowrap dark:text-white border-r"
|
||||
>
|
||||
Expiry
|
||||
</td>
|
||||
<td class="px-6 py-2 font-light">{{ request.expiry }} seconds</td>
|
||||
</tr>
|
||||
<tr class="bg-white dark:bg-transparent hover:bg-gray-50 dark:hover:bg-gray-600 text-base">
|
||||
<td
|
||||
class="flex items-center pr-1 py-2 font-medium text-gray-900 whitespace-nowrap dark:text-white border-r"
|
||||
>
|
||||
Duration
|
||||
</td>
|
||||
<td class="px-6 py-2 font-light">{{ request.ask.duration }} seconds</td>
|
||||
</tr>
|
||||
<tr class="bg-white dark:bg-transparent hover:bg-gray-50 dark:hover:bg-gray-600 text-base">
|
||||
<td
|
||||
class="flex items-center pr-1 py-2 font-medium text-gray-900 whitespace-nowrap dark:text-white border-r"
|
||||
>
|
||||
Slot size
|
||||
</td>
|
||||
<td class="px-6 py-2 font-light">{{ request.ask.slotSize }} bytes</td>
|
||||
</tr>
|
||||
<tr class="bg-white dark:bg-transparent hover:bg-gray-50 dark:hover:bg-gray-600 text-base">
|
||||
<td
|
||||
class="flex items-center pr-1 py-2 font-medium text-gray-900 whitespace-nowrap dark:text-white border-r"
|
||||
>
|
||||
Proof probability
|
||||
</td>
|
||||
<td class="px-6 py-2 font-light">{{ request.ask.proofProbability }}</td>
|
||||
</tr>
|
||||
<tr class="bg-white dark:bg-transparent hover:bg-gray-50 dark:hover:bg-gray-600 text-base">
|
||||
<td
|
||||
class="flex items-center pr-1 py-2 font-medium text-gray-900 whitespace-nowrap dark:text-white border-r"
|
||||
>
|
||||
Reward
|
||||
</td>
|
||||
<td class="px-6 py-2 font-light">{{ request.ask.reward }} CDX</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="bg-white dark:bg-transparent hover:bg-gray-50 dark:hover:tbg-gray-600 text-base"
|
||||
>
|
||||
<td
|
||||
class="flex items-center pr-1 py-2 font-medium text-gray-900 whitespace-nowrap dark:text-white border-r"
|
||||
>
|
||||
Collateral
|
||||
</td>
|
||||
<td class="px-6 py-2 font-light">{{ request.ask.collateral }} CDX</td>
|
||||
</tr>
|
||||
<tr class="bg-white dark:bg-transparent hover:bg-gray-50 dark:hover:bg-gray-600 text-base">
|
||||
<td
|
||||
class="flex items-center pr-1 py-2 font-medium text-gray-900 whitespace-nowrap dark:text-white border-r"
|
||||
>
|
||||
Max slot loss
|
||||
</td>
|
||||
<td class="px-6 py-2 font-light">
|
||||
{{ request.ask.maxSlotLoss }} {{ request.ask.maxSlotLoss == 1 ? 'slot' : 'slots' }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<Slots :slots="request.slots"></Slots>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -5,21 +5,13 @@ import { useRouter } from 'vue-router'
|
||||
import { useRequestsStore } from '@/stores/requests'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import CodexImage from '@/components/CodexImage.vue'
|
||||
import StateIndicator from '@/components/StateIndicator.vue'
|
||||
import { shortHex } from '@/utils/ids'
|
||||
import { getStateColour } from '@/utils/requests'
|
||||
|
||||
const requestsStore = useRequestsStore()
|
||||
const { requests } = storeToRefs(requestsStore)
|
||||
const router = useRouter()
|
||||
|
||||
function getStateColour(state) {
|
||||
if (state === 'New') {
|
||||
return 'bg-yellow-200'
|
||||
} else if (state === 'Fulfilled') {
|
||||
return 'bg-green-500'
|
||||
} else {
|
||||
return 'bg-red-500'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -159,8 +151,7 @@ function getStateColour(state) {
|
||||
<td class="px-6 py-4">{{ shortHex(content.cid) }}</td>
|
||||
<td class="px-6 py-4">
|
||||
<div class="flex items-center">
|
||||
<div :class="`h-2.5 w-2.5 rounded-full ${getStateColour(state)} me-2`"></div>
|
||||
{{ state }}
|
||||
<StateIndicator :text="state" :color="getStateColour(state)"></StateIndicator>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-6 py-4">
|
||||
|
||||
@ -1,7 +1,8 @@
|
||||
import { ref, computed, inject } from 'vue'
|
||||
import { ref, inject } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import { slotId } from '../utils/ids'
|
||||
import { arrayToObject } from '@/utils/requests'
|
||||
import { arrayToObject, requestState } from '@/utils/requests'
|
||||
import { slotState } from '@/utils/slots'
|
||||
|
||||
export const useRequestsStore = defineStore('request', () => {
|
||||
// let fetched = false
|
||||
@ -50,36 +51,31 @@ export const useRequestsStore = defineStore('request', () => {
|
||||
// onSlotFreed => update slots[slotId].state with getSlotState
|
||||
// => add to slotFreedEvents {blockNumber, slotId, slotIdx}
|
||||
// => add blockNumber to blockNumbers
|
||||
const requestState = [
|
||||
'New', // [default] waiting to fill slots
|
||||
'Fulfilled', // all slots filled, accepting regular proofs
|
||||
'Cancelled', // not enough slots filled before expiry
|
||||
'Finished', // successfully completed
|
||||
'Failed' // too many nodes have failed to provide proofs, data lost
|
||||
]
|
||||
|
||||
const getRequestState = async (requestId) => {
|
||||
let stateIdx = await marketplace.requestState(requestId)
|
||||
return requestState[stateIdx]
|
||||
}
|
||||
|
||||
const getSlotState = async (slotId) => {
|
||||
let stateIdx = await marketplace.slotState(slotId)
|
||||
return slotState[stateIdx]
|
||||
}
|
||||
|
||||
const getSlots = async (requestId, numSlots) => {
|
||||
// storageRequestedEvents.value.push({ blockNumber, requestId })
|
||||
let slots = []
|
||||
for (let i = 0; i < numSlots; i++) {
|
||||
let id = slotId(requestId, i)
|
||||
let state = await marketplace.slotState(id)
|
||||
slots.push({ slotId: id, slotIdx: i, state })
|
||||
for (let slotIdx = 0; slotIdx < numSlots; slotIdx++) {
|
||||
let id = slotId(requestId, slotIdx)
|
||||
let state = await getSlotState(id)
|
||||
let proofsMissed = await marketplace.missingProofs(id)
|
||||
let provider = await marketplace.getHost(id)
|
||||
slots.push({ slotId: id, slotIdx, state, proofsMissed, provider })
|
||||
}
|
||||
return slots
|
||||
// blockNumbers.value.add(blockNumber)
|
||||
}
|
||||
|
||||
async function fetch() {
|
||||
// if (fetched) {
|
||||
// // allow multiple calls without re-fetching
|
||||
// return
|
||||
// }
|
||||
// query past events
|
||||
loading.value = true
|
||||
try {
|
||||
|
||||
@ -33,14 +33,14 @@ export function short(long, ellipses = '*', start = 3, stop = 6) {
|
||||
return short
|
||||
}
|
||||
|
||||
export function shortHex(long) {
|
||||
export function shortHex(long, chars = 4) {
|
||||
let shortened = ''
|
||||
let rest = long
|
||||
if (long.substring(0, 2) === '0x') {
|
||||
shortened = '0x'
|
||||
rest = long.substring(2)
|
||||
}
|
||||
shortened += short(rest, '..', 4, 4)
|
||||
shortened += short(rest, '..', chars, chars)
|
||||
return shortened
|
||||
}
|
||||
|
||||
|
||||
@ -28,3 +28,23 @@ export function price(request) {
|
||||
}
|
||||
return request.ask.reward * request.ask.duration * request.ask.slots
|
||||
}
|
||||
|
||||
export function getStateColour(state) {
|
||||
if (state === 'New') {
|
||||
return 'yellow'
|
||||
} else if (state === 'Fulfilled') {
|
||||
return 'green'
|
||||
} else if (state === 'Finished') {
|
||||
return 'gray'
|
||||
} else {
|
||||
return 'red'
|
||||
}
|
||||
}
|
||||
|
||||
export const requestState = [
|
||||
'New', // [default] waiting to fill slots
|
||||
'Fulfilled', // all slots filled, accepting regular proofs
|
||||
'Cancelled', // not enough slots filled before expiry
|
||||
'Finished', // successfully completed
|
||||
'Failed' // too many nodes have failed to provide proofs, data lost
|
||||
]
|
||||
|
||||
22
src/utils/slots.js
Normal file
22
src/utils/slots.js
Normal file
@ -0,0 +1,22 @@
|
||||
export const slotState = [
|
||||
'Free', // [default] not filled yet, or host has vacated the slot
|
||||
'Filled', // host has filled slot
|
||||
'Finished', // successfully completed
|
||||
'Failed', // the request has failed
|
||||
'Paid', // host has been paid
|
||||
'Cancelled' // when request was cancelled then slot is cancelled as well
|
||||
]
|
||||
|
||||
export function getStateColour(state) {
|
||||
if (state === 'Free') {
|
||||
return 'yellow'
|
||||
} else if (state === 'Filled') {
|
||||
return 'green'
|
||||
} else if (state === 'Finished') {
|
||||
return 'blue'
|
||||
} else if (state === 'Paid') {
|
||||
return 'gray'
|
||||
} else {
|
||||
return 'red'
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user