mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 18:11:36 +01:00
5edc0ff6ef
Fixes #5011
134 lines
7.0 KiB
Plaintext
134 lines
7.0 KiB
Plaintext
@using BTCPayServer.Services.Wallets
|
|
@model BTCPayServer.Components.StoreWalletBalance.StoreWalletBalanceViewModel
|
|
|
|
<div id="StoreWalletBalance-@Model.Store.Id" class="widget store-wallet-balance">
|
|
<div class="d-flex gap-3 align-items-center justify-content-between mb-2">
|
|
<h6>Wallet Balance</h6>
|
|
@if (Model.CryptoCode != Model.DefaultCurrency)
|
|
{
|
|
<div class="btn-group btn-group-sm gap-0 currency-toggle" role="group">
|
|
<input type="radio" class="btn-check" name="StoreWalletBalance-currency" id="StoreWalletBalance-currency_@Model.CryptoCode" value="@Model.CryptoCode" autocomplete="off" checked>
|
|
<label class="btn btn-outline-secondary px-2 py-1" for="StoreWalletBalance-currency_@Model.CryptoCode">@Model.CryptoCode</label>
|
|
<input type="radio" class="btn-check" name="StoreWalletBalance-currency" id="StoreWalletBalance-currency_@Model.DefaultCurrency" value="@Model.DefaultCurrency" autocomplete="off">
|
|
<label class="btn btn-outline-secondary px-2 py-1" for="StoreWalletBalance-currency_@Model.DefaultCurrency">@Model.DefaultCurrency</label>
|
|
</div>
|
|
}
|
|
</div>
|
|
<header class="mb-3">
|
|
@if (Model.Balance != null)
|
|
{
|
|
<div class="balance d-flex align-items-baseline gap-1">
|
|
<h3 class="d-inline-block me-1" data-balance="@Model.Balance" data-sensitive>@Model.Balance</h3>
|
|
<span class="text-secondary fw-semibold currency">@Model.CryptoCode</span>
|
|
</div>
|
|
}
|
|
@if (Model.Series != null)
|
|
{
|
|
<div class="btn-group only-for-js mt-1" role="group" aria-label="Period">
|
|
<input type="radio" class="btn-check" name="StoreWalletBalancePeriod-@Model.Store.Id" id="StoreWalletBalancePeriodWeek-@Model.Store.Id" value="@WalletHistogramType.Week" @(Model.Type == WalletHistogramType.Week ? "checked" : "")>
|
|
<label class="btn btn-link" for="StoreWalletBalancePeriodWeek-@Model.Store.Id">1W</label>
|
|
<input type="radio" class="btn-check" name="StoreWalletBalancePeriod-@Model.Store.Id" id="StoreWalletBalancePeriodMonth-@Model.Store.Id" value="@WalletHistogramType.Month" @(Model.Type == WalletHistogramType.Month ? "checked" : "")>
|
|
<label class="btn btn-link" for="StoreWalletBalancePeriodMonth-@Model.Store.Id">1M</label>
|
|
<input type="radio" class="btn-check" name="StoreWalletBalancePeriod-@Model.Store.Id" id="StoreWalletBalancePeriodYear-@Model.Store.Id" value="@WalletHistogramType.Year" @(Model.Type == WalletHistogramType.Year ? "checked" : "")>
|
|
<label class="btn btn-link" for="StoreWalletBalancePeriodYear-@Model.Store.Id">1Y</label>
|
|
</div>
|
|
}
|
|
</header>
|
|
@if (Model.Series != null)
|
|
{
|
|
<div class="ct-chart"></div>
|
|
}
|
|
else
|
|
{
|
|
<p>
|
|
We would like to show you a chart of your balance.
|
|
Please <a href="https://github.com/dgarage/NBXplorer/blob/master/docs/Postgres-Migration.md" target="_blank" rel="noreferrer noopener">migrate to the new NBXplorer backend</a>
|
|
for that data to become available.
|
|
</p>
|
|
}
|
|
<script>
|
|
(function () {
|
|
const storeId = @Safe.Json(Model.Store.Id);
|
|
const cryptoCode = @Safe.Json(Model.CryptoCode);
|
|
const defaultCurrency = @Safe.Json(Model.DefaultCurrency);
|
|
const divisibility = @Safe.Json(Model.CurrencyData.Divisibility);
|
|
let data = { series: @Safe.Json(Model.Series), labels: @Safe.Json(Model.Labels), balance: @Safe.Json(Model.Balance) };
|
|
let rate = null;
|
|
|
|
const id = `StoreWalletBalance-${storeId}`;
|
|
const baseUrl = @Safe.Json(Url.Action("WalletHistogram", "UIWallets", new { walletId = Model.WalletId, type = WalletHistogramType.Week }));
|
|
const chartOpts = {
|
|
fullWidth: true,
|
|
showArea: true,
|
|
axisY: {
|
|
labelInterpolationFnc: value => rate
|
|
? DashboardUtils.displayDefaultCurrency(value, rate, defaultCurrency, divisibility).toString()
|
|
: value
|
|
}
|
|
};
|
|
|
|
const render = data => {
|
|
let { series, labels } = data;
|
|
const currency = rate ? defaultCurrency : cryptoCode;
|
|
document.querySelectorAll(`#${id} .currency`).forEach(c => c.innerText = currency)
|
|
document.querySelectorAll(`#${id} [data-balance]`).forEach(c => {
|
|
const value = Number.parseFloat(c.dataset.balance);
|
|
c.innerText = rate
|
|
? DashboardUtils.displayDefaultCurrency(value, rate, currency, divisibility)
|
|
: value
|
|
});
|
|
if (!series) return;
|
|
|
|
const min = Math.min(...series);
|
|
const max = Math.max(...series);
|
|
const low = Math.max(min - ((max - min) / 5), 0);
|
|
const renderOpts = Object.assign({}, chartOpts, { low });
|
|
const chart = new Chartist.Line(`#${id} .ct-chart`, {
|
|
labels,
|
|
series: [series]
|
|
}, renderOpts);
|
|
|
|
// prevent y-axis labels from getting cut off
|
|
window.setTimeout(() => {
|
|
const yLabels = [...document.querySelectorAll('.ct-label.ct-vertical.ct-start')];
|
|
if (yLabels) {
|
|
const width = Math.max(...(yLabels.map(l => l.innerText.length * 7.5)));
|
|
const opts = Object.assign({}, renderOpts, {
|
|
axisY: Object.assign({}, renderOpts.axisY, { offset: width })
|
|
});
|
|
chart.update(null, opts);
|
|
}
|
|
}, 0)
|
|
};
|
|
|
|
const update = async type => {
|
|
const url = baseUrl.replace(/\/week$/gi, `/${type}`);
|
|
const response = await fetch(url);
|
|
if (response.ok) {
|
|
data = await response.json();
|
|
render(data);
|
|
}
|
|
};
|
|
|
|
render(data);
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
delegate('change', `#${id} [name="StoreWalletBalancePeriod-${storeId}"]`, async e => {
|
|
const type = e.target.value;
|
|
await update(type);
|
|
})
|
|
delegate('change', `#${id} .currency-toggle input`, async e => {
|
|
const { target } = e;
|
|
if (target.value === defaultCurrency) {
|
|
rate = await DashboardUtils.fetchRate(`${cryptoCode}_${defaultCurrency}`);
|
|
if (rate) render(data);
|
|
} else {
|
|
rate = null;
|
|
render(data);
|
|
}
|
|
});
|
|
});
|
|
})();
|
|
</script>
|
|
</div>
|