web/satellite/vuetify-poc: list invoices
This change lists invoices on the vuetifypoc billing history tab. It also removes invoice filtering on the main app. Issue: https://github.com/storj/storj/issues/6099 Change-Id: Id4cc2db003a0208775ddaefc87abf26f4b05106c
This commit is contained in:
parent
775db4aa3c
commit
3f1ea4a0b9
@ -58,9 +58,7 @@ const historyPage = computed((): PaymentHistoryPage => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const historyItems = computed((): PaymentsHistoryItem[] => {
|
const historyItems = computed((): PaymentsHistoryItem[] => {
|
||||||
return historyPage.value.items.filter((item: PaymentsHistoryItem) => {
|
return historyPage.value.items;
|
||||||
return item.status !== PaymentsHistoryItemStatus.Draft;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async function fetchHistory(endingBefore = '', startingAfter = ''): Promise<void> {
|
async function fetchHistory(endingBefore = '', startingAfter = ''): Promise<void> {
|
||||||
@ -81,18 +79,18 @@ async function sizeChanged(size: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function nextClicked(): Promise<void> {
|
async function nextClicked(): Promise<void> {
|
||||||
const length = historyPage.value.items.length;
|
const length = historyItems.value.length;
|
||||||
if (!historyPage.value.hasNext || !length) {
|
if (!historyPage.value.hasNext || !length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await fetchHistory('', historyPage.value.items[length - 1].id);
|
await fetchHistory('', historyItems.value[length - 1].id);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function previousClicked(): Promise<void> {
|
async function previousClicked(): Promise<void> {
|
||||||
if (!historyPage.value.hasPrevious || !historyPage.value.items.length) {
|
if (!historyPage.value.hasPrevious || !historyItems.value.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
await fetchHistory(historyPage.value.items[0].id, '');
|
await fetchHistory(historyItems.value[0].id, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
@ -0,0 +1,140 @@
|
|||||||
|
// Copyright (C) 2023 Storj Labs, Inc.
|
||||||
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<v-card variant="flat" :border="true" rounded="xlg">
|
||||||
|
<v-data-table
|
||||||
|
:loading="isLoading"
|
||||||
|
:headers="headers"
|
||||||
|
:items="historyItems"
|
||||||
|
:must-sort="false"
|
||||||
|
class="elevation-1"
|
||||||
|
hover
|
||||||
|
>
|
||||||
|
<template #item.amount="{ item }">
|
||||||
|
<span>
|
||||||
|
{{ centsToDollars(item.raw.amount) }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #item.formattedStart="{ item }">
|
||||||
|
<span class="font-weight-bold">
|
||||||
|
{{ item.raw.formattedStart }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #item.formattedStatus="{ item }">
|
||||||
|
<v-chip :color="getColor(item.raw.formattedStatus)" variant="tonal" size="small" rounded="xl" class="font-weight-bold">
|
||||||
|
{{ item.raw.formattedStatus }}
|
||||||
|
</v-chip>
|
||||||
|
</template>
|
||||||
|
<template #item.link="{ item }">
|
||||||
|
<v-btn v-if="item.raw.link" variant="flat" size="small" :href="item.raw.link">
|
||||||
|
Download
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #bottom>
|
||||||
|
<div class="v-data-table-footer">
|
||||||
|
<v-row justify="end" align="center" class="pa-2">
|
||||||
|
<v-col cols="auto">
|
||||||
|
<v-btn-group density="compact">
|
||||||
|
<v-btn :disabled="!historyPage.hasPrevious" icon="mdi-chevron-left" @click="previousClicked" />
|
||||||
|
<v-btn :disabled="!historyPage.hasNext" icon="mdi-chevron-right" @click="nextClicked" />
|
||||||
|
</v-btn-group>
|
||||||
|
</v-col>
|
||||||
|
<v-col cols="auto">
|
||||||
|
<v-select
|
||||||
|
v-model="limit"
|
||||||
|
density="compact"
|
||||||
|
:items="pageSizes"
|
||||||
|
variant="outlined"
|
||||||
|
@update:model-value="sizeChanged"
|
||||||
|
/>
|
||||||
|
</v-col>
|
||||||
|
</v-row>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</v-data-table>
|
||||||
|
</v-card>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
|
||||||
|
import { VBtn, VBtnGroup, VCard, VChip, VCol, VRow, VSelect, VWindowItem } from 'vuetify/components';
|
||||||
|
import { computed, onMounted, ref } from 'vue';
|
||||||
|
import { VDataTable } from 'vuetify/labs/components';
|
||||||
|
|
||||||
|
import { centsToDollars } from '@/utils/strings';
|
||||||
|
import { useBillingStore } from '@/store/modules/billingStore';
|
||||||
|
import { useNotify } from '@/utils/hooks';
|
||||||
|
import { AnalyticsErrorEventSource } from '@/utils/constants/analyticsEventNames';
|
||||||
|
import { PaymentHistoryPage, PaymentsHistoryItem, PaymentsHistoryItemStatus } from '@/types/payments';
|
||||||
|
import { useLoading } from '@/composables/useLoading';
|
||||||
|
import { DEFAULT_PAGE_LIMIT } from '@/types/pagination';
|
||||||
|
|
||||||
|
const billingStore = useBillingStore();
|
||||||
|
const notify = useNotify();
|
||||||
|
|
||||||
|
const { isLoading, withLoading } = useLoading();
|
||||||
|
|
||||||
|
const limit = ref(DEFAULT_PAGE_LIMIT);
|
||||||
|
const headers = [
|
||||||
|
{ title: 'Date', key: 'formattedStart', sortable: false },
|
||||||
|
{ title: 'Amount', key: 'amount', sortable: false },
|
||||||
|
{ title: 'Status', key: 'formattedStatus', sortable: false },
|
||||||
|
{ title: '', key: 'link', sortable: false, width: 0 },
|
||||||
|
];
|
||||||
|
const pageSizes = [DEFAULT_PAGE_LIMIT, 25, 50, 100];
|
||||||
|
|
||||||
|
const historyPage = computed((): PaymentHistoryPage => {
|
||||||
|
return billingStore.state.paymentsHistory;
|
||||||
|
});
|
||||||
|
|
||||||
|
const historyItems = computed((): PaymentsHistoryItem[] => {
|
||||||
|
return historyPage.value.items;
|
||||||
|
});
|
||||||
|
|
||||||
|
function getColor(status: string): string {
|
||||||
|
if (status === 'Paid') return 'success';
|
||||||
|
if (status === 'Open') return 'warning';
|
||||||
|
if (status === 'Pending') return 'warning';
|
||||||
|
return 'error';
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchHistory(endingBefore = '', startingAfter = ''): void {
|
||||||
|
withLoading(async () => {
|
||||||
|
try {
|
||||||
|
await billingStore.getPaymentsHistory({
|
||||||
|
limit: limit.value,
|
||||||
|
startingAfter,
|
||||||
|
endingBefore,
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
notify.notifyError(error, AnalyticsErrorEventSource.BILLING_HISTORY_TAB);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function nextClicked(): Promise<void> {
|
||||||
|
const length = historyItems.value.length;
|
||||||
|
if (!historyPage.value.hasNext || !length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fetchHistory('', historyItems.value[length - 1].id);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function previousClicked(): Promise<void> {
|
||||||
|
if (!historyPage.value.hasPrevious || !historyItems.value.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fetchHistory(historyItems.value[0].id, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function sizeChanged(size: number) {
|
||||||
|
limit.value = size;
|
||||||
|
fetchHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
fetchHistory();
|
||||||
|
});
|
||||||
|
</script>
|
@ -173,37 +173,7 @@
|
|||||||
</v-window-item>
|
</v-window-item>
|
||||||
|
|
||||||
<v-window-item>
|
<v-window-item>
|
||||||
<v-card variant="flat" :border="true" rounded="xlg">
|
<billing-history-tab />
|
||||||
<v-text-field
|
|
||||||
v-model="search"
|
|
||||||
label="Search"
|
|
||||||
prepend-inner-icon="mdi-magnify"
|
|
||||||
single-line
|
|
||||||
hide-details
|
|
||||||
/>
|
|
||||||
|
|
||||||
<v-data-table
|
|
||||||
v-model="selected"
|
|
||||||
:sort-by="sortBy"
|
|
||||||
:headers="headers"
|
|
||||||
:items="invoices"
|
|
||||||
:search="search"
|
|
||||||
class="elevation-1"
|
|
||||||
show-select
|
|
||||||
hover
|
|
||||||
>
|
|
||||||
<template #item.date="{ item }">
|
|
||||||
<span class="font-weight-bold">
|
|
||||||
{{ item.raw.date }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
<template #item.status="{ item }">
|
|
||||||
<v-chip :color="getColor(item.raw.status)" variant="tonal" size="small" rounded="xl" class="font-weight-bold">
|
|
||||||
{{ item.raw.status }}
|
|
||||||
</v-chip>
|
|
||||||
</template>
|
|
||||||
</v-data-table>
|
|
||||||
</v-card>
|
|
||||||
</v-window-item>
|
</v-window-item>
|
||||||
|
|
||||||
<v-window-item>
|
<v-window-item>
|
||||||
@ -256,6 +226,7 @@ import { useProjectsStore } from '@/store/modules/projectsStore';
|
|||||||
|
|
||||||
import CreditCardComponent from '@poc/components/CreditCardComponent.vue';
|
import CreditCardComponent from '@poc/components/CreditCardComponent.vue';
|
||||||
import AddCreditCardComponent from '@poc/components/AddCreditCardComponent.vue';
|
import AddCreditCardComponent from '@poc/components/AddCreditCardComponent.vue';
|
||||||
|
import BillingHistoryTab from '@poc/components/billing/BillingHistoryTab.vue';
|
||||||
import UsageAndChargesComponent from '@poc/components/billing/UsageAndChargesComponent.vue';
|
import UsageAndChargesComponent from '@poc/components/billing/UsageAndChargesComponent.vue';
|
||||||
import StorjTokenCardComponent from '@poc/components/StorjTokenCardComponent.vue';
|
import StorjTokenCardComponent from '@poc/components/StorjTokenCardComponent.vue';
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user