Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement empty state for supported ecosystem with no feeds #414

Merged
merged 7 commits into from
Jun 7, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/api/src/fetchSvgs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export const DEFAULT_SVG =
'<svg class="icon-size" width="34" height="34" viewBox="0 0 34 34" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="17" cy="17" r="17" fill="#C4C4C4"/><path d="M18.066 20.785h-2.988a9.951 9.951 0 0 1 .164-1.816c.11-.516.293-.98.551-1.395a6.466 6.466 0 0 1 1.055-1.23c.367-.328.687-.64.96-.938.274-.297.489-.601.645-.914.156-.32.235-.676.235-1.066 0-.453-.07-.828-.211-1.125a1.428 1.428 0 0 0-.61-.692c-.265-.156-.601-.234-1.008-.234-.336 0-.648.074-.937.223-.29.14-.527.359-.715.656-.18.297-.273.687-.281 1.172h-3.399c.024-1.07.27-1.953.739-2.649a4.252 4.252 0 0 1 1.91-1.558c.797-.344 1.691-.516 2.683-.516 1.094 0 2.032.18 2.813.54.781.35 1.379.87 1.793 1.558.414.68.62 1.508.62 2.484 0 .68-.132 1.285-.398 1.817a6.21 6.21 0 0 1-1.043 1.464c-.43.454-.902.922-1.417 1.407-.446.398-.75.816-.915 1.254-.156.437-.238.957-.246 1.558Zm-3.34 3.621c0-.5.172-.914.516-1.242.344-.336.805-.504 1.383-.504.57 0 1.027.168 1.371.504.352.328.527.742.527 1.242 0 .485-.175.895-.527 1.23-.344.337-.8.505-1.371.505-.578 0-1.04-.168-1.383-.504a1.655 1.655 0 0 1-.515-1.23Z" fill="#fff"/></svg>'

const STATIC_LOGOS_SVG_URL = process.env.TEST_BRANCH
? `https://raw.githubusercontent.com/witnet/data-feeds-explorer//${process.env.TEST_BRANCH}/packages/ui/assets/svg/`
? `https://raw.githubusercontent.com/witnet/data-feeds-explorer/${process.env.TEST_BRANCH}/packages/ui/assets/svg/`
: 'https://raw.githubusercontent.com/witnet/data-feeds-explorer/main/packages/ui/assets/svg/'

export async function fetchSvgs(
Expand Down
5 changes: 4 additions & 1 deletion packages/api/src/readDataFeeds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import fs from 'fs'
import { RouterDataFeedsConfig, FeedInfo, FeedInfoConfig } from '../types'
import { normalizeConfig } from './utils'

const CONFIG_URL = `https://raw.github.com/witnet/data-feeds-explorer/main/packages/api/src/dataFeedsRouter.json`
const CONFIG_URL = process.env.TEST_BRANCH
? `https://raw.github.com/witnet/data-feeds-explorer/${process.env.TEST_BRANCH}/packages/api/src/dataFeedsRouter.json`
: `https://raw.github.com/witnet/data-feeds-explorer/main/packages/api/src/dataFeedsRouter.json`

function isRouterDataFeedsConfig(val: any): val is RouterDataFeedsConfig {
return val?.contracts && val?.chains && val.conditions && val.currencies
}

export async function fetchDataFeedsRouterConfig(): Promise<RouterDataFeedsConfig | null> {
console.log('CONFIG URL', CONFIG_URL)
gabaldon marked this conversation as resolved.
Show resolved Hide resolved
return await axios
.get(CONFIG_URL)
.then((res) => {
Expand Down
22 changes: 22 additions & 0 deletions packages/ui/assets/styles/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,17 @@

//breadcrumbs
--selected-option: #4ab6a1;

//Placeholder
--placeholder-bg-color: #bebebe0d;
--placeholder-gradient: linear-gradient(
to right,
rgba(84, 84, 85, 0) 0%,
rgba(84, 84, 85, 0.07) 20%,
rgba(84, 84, 85, 0.12) 24%,
rgba(84, 84, 85, 0.17) 30%,
rgba(84, 84, 85, 0.22) 35%
);
}

.light-mode {
Expand Down Expand Up @@ -340,6 +351,17 @@

//breadcrumbs
--selected-option: #41bea5;

//Placeholder
--placeholder-bg-color: rgba(128, 128, 128, 0.051);
--placeholder-gradient: linear-gradient(
to right,
rgba(128, 128, 128, 0) 0%,
rgba(128, 128, 128, 0.001) 20%,
rgba(128, 128, 128, 0.005) 24%,
rgba(128, 128, 128, 0.008) 30%,
rgba(128, 128, 128, 0.03) 35%
);
}

body {
Expand Down
39 changes: 39 additions & 0 deletions packages/ui/components/AnimatedPlaceholder.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<template>
<div class="placeholder">&nbsp;</div>
</template>
<script setup>
defineProps({
height: {
type: String,
required: true,
},
width: {
type: String,
required: true,
},
borderRadius: {
type: String,
required: true,
},
})
</script>
<style scoped lang="scss">
@keyframes bgAnimate {
0% {
background-position: 50% 0;
}
100% {
background-position: -150% 0;
}
}
.placeholder {
background-color: var(--placeholder-bg-color);
height: v-bind(height);
width: v-bind(width);
border-radius: v-bind(borderRadius);
background-image: var(--placeholder-gradient);
background-size: 200% 200%;
box-shadow: var(--card-box-shadow);
animation: bgAnimate 1.2s linear infinite;
}
</style>
28 changes: 24 additions & 4 deletions packages/ui/components/DataFeeds.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
<template>
<div class="feeds-container">
<div v-if="noFeedsAvailable" class="empty-state">
<i18n-t keypath="empty_feeds" tag="p" scope="global">
<span class="bold">{{ network.label }}</span>
</i18n-t>
<RequestDataFeedBtn />
</div>
<div v-else-if="!loading" class="feeds-container">
<FeedCard
v-for="feed in allFeeds"
:key="feed.name + feed.network + feed.value + feed.color"
Expand All @@ -16,6 +22,9 @@
:color="feed.color"
/>
</div>
<div v-else class="feeds-container">
<FeedCard v-for="feed in ['1', '2', '3']" :key="feed" :empty="true" />
</div>
</template>

<script setup lang="ts">
Expand All @@ -32,8 +41,10 @@ const props = defineProps({
},
})
const route = useRoute()
const loading = ref(true)
const noFeedsAvailable = ref(false)
const networkFeeds: Ref<any> = ref(null)
const emit = defineEmits(['empty'])
const emptyFeeds = computed(() => allFeeds.value.length < 1)
const allFeeds = computed(() => {
if (networkFeeds.value?.total) {
const feeds = networkFeeds.value?.feeds
Expand Down Expand Up @@ -77,8 +88,9 @@ const allFeeds = computed(() => {
}
})
watch(networkFeeds, () => {
if (allFeeds.value.length < 1) {
emit('empty', props.networkIndex)
loading.value = false
if (emptyFeeds.value) {
noFeedsAvailable.value = true
}
})
onMounted(async () => {
Expand All @@ -98,6 +110,14 @@ onMounted(async () => {
justify-content: flex-start;
align-items: center;
}
.empty-state {
display: grid;
grid-gap: 16px;
width: 100%;
grid-template-rows: 1fr;
align-items: center;
padding-bottom: 16px;
}

@media screen and (max-width: 1100px) {
.feeds-container {
Expand Down
35 changes: 35 additions & 0 deletions packages/ui/components/FeedSkeleton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<template>
<div class="card-container">
<div class="title">
<AnimatedPlaceholder
class="img"
width="50px"
height="50px"
border-radius="50%"
/>
<AnimatedPlaceholder
class="name title"
width="50px"
height="16px"
border-radius="8%"
/>
</div>
<AnimatedPlaceholder
class="value"
width="100px"
height="16px"
border-radius="8%"
/>
<AnimatedPlaceholder
class="timestamp"
width="50px"
height="8px"
border-radius="8%"
/>
</div>
</template>
<style scoped>
.card-container {
background-color: var(--placeholder-bg-color);
}
</style>
11 changes: 1 addition & 10 deletions packages/ui/components/NavBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,7 @@
<NetworkOptions type="navbar" :options="navBarOptions" />
</div>
<div class="tab last-item" @click="closeMenu">
<a
class="btn-container"
:href="urls.requestDataFeed"
target="_blank"
>
<CustomButton class="btn">{{
$t('navbar.request_data_feed')
}}</CustomButton>
</a>
<RequestDataFeedBtn class="btn-container" />
</div>
</div>
</transition>
Expand All @@ -46,7 +38,6 @@
</template>

<script setup>
import { urls } from '../constants'
import { generateNavOptions } from '../utils/generateNavOptions'
import { generateSelectOptions } from '../utils/generateSelectOptions'
const store = useStore()
Expand Down
11 changes: 11 additions & 0 deletions packages/ui/components/RequestDataFeedBtn.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<template>
<a :href="urls.requestDataFeed" target="_blank" rel="nofollow">
<CustomButton class="btn">{{
$t('navbar.request_data_feed')
}}</CustomButton>
</a>
</template>

<script setup lang="ts">
import { urls } from '../constants'
</script>
29 changes: 18 additions & 11 deletions packages/ui/components/cards/FeedCard.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<BaseCard :class="dataFeedStatus.key">
<nuxt-link v-if="detailsPath.params.id" :to="localeRoute(detailsPath)">
<BaseCard v-if="!empty" :class="dataFeedStatus.key">
<nuxt-link :to="localeRoute(detailsPath)">
<div class="card-container">
<div class="title">
<SvgIcon class="img" :svg="svg" />
Expand All @@ -23,6 +23,9 @@
</div>
</nuxt-link>
</BaseCard>
<div v-else>
<FeedSkeleton />
</div>
</template>

<script>
Expand All @@ -33,45 +36,49 @@ import { getDataFeedStatus } from '@/utils/getDataFeedStatus'
export default {
name: 'FeedCard',
props: {
empty: {
type: Boolean,
default: false,
},
detailsPath: {
type: Object,
required: true,
default: () => {},
},
decimals: {
type: Number,
required: true,
default: 2,
},
name: {
type: String,
required: true,
default: 'Name',
},
svg: {
type: String,
required: true,
default: 'svg',
},
value: {
type: String,
default: null,
},
label: {
type: String,
required: true,
default: 'label',
},
lastResultTimestamp: {
type: String,
required: true,
default: 'lastResultTimestamp',
},
timeToUpdate: {
type: Number,
default: null,
},
network: {
type: String,
required: true,
default: 'Network',
},
color: {
type: String,
required: true,
default: 'color',
},
},
computed: {
Expand All @@ -96,7 +103,7 @@ export default {
}
</script>

<style lang="scss" scoped>
<style lang="scss">
.nuxt-link-exact-active {
color: var(--value-color);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const urls = {
randomness: 'https://docs.witnet.io/smart-contracts/witnet-randomness-oracle',
getPostRequest:
'https://docs.witnet.io/smart-contracts/apis-and-http-get-post-oracle',
requestDataFeed: 'https://tally.so/r/wMZDAn',
requestDataFeed: 'https://tally.so/r/mOP09R',
integrateDirectly:
'https://docs.witnet.io/smart-contracts/witnet-data-feeds/using-witnet-data-feeds#reading-last-price-and-timestamp-from-a-price-feed-contract-serving-a-specific-pair',
integrateThroughProxy:
Expand Down
1 change: 1 addition & 0 deletions packages/ui/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
"title": "Users and Partners"
}
},
"empty_feeds": "There are no active feeds in {0}. Request new price feed!",
gabaldon marked this conversation as resolved.
Show resolved Hide resolved
"feeds": "feeds",
"data_feeds": "Data feeds",
"networks": "Networks",
Expand Down
1 change: 1 addition & 0 deletions packages/ui/locales/es-ES.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
"title": "Users and Partners"
}
},
"empty_feeds": "No hay feeds activos en {0}. ¡Solicita un nuevo data feed!",
"feeds": "feeds",
"data_feeds": "Data feeds",
"networks": "Networks",
Expand Down
Loading