show year-over-year and period-over-period in trends chart
This commit is contained in:
@@ -42,6 +42,7 @@ interface AxisChartDataItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface AxisChartTooltipItem extends SortableTransactionStatisticDataItem {
|
interface AxisChartTooltipItem extends SortableTransactionStatisticDataItem {
|
||||||
|
readonly id: string;
|
||||||
readonly name: string;
|
readonly name: string;
|
||||||
readonly color: unknown;
|
readonly color: unknown;
|
||||||
readonly displayOrders: number[];
|
readonly displayOrders: number[];
|
||||||
@@ -71,6 +72,9 @@ const props = defineProps<{
|
|||||||
amountValue?: boolean;
|
amountValue?: boolean;
|
||||||
defaultCurrency?: string;
|
defaultCurrency?: string;
|
||||||
enableClickItem?: boolean;
|
enableClickItem?: boolean;
|
||||||
|
tooltipExtraColumnNames?: string[];
|
||||||
|
tooltipExtraColumnTotalValues?: (categoryIndex: number, totalValue: number, visibleSeriesIds: string[]) => string[];
|
||||||
|
tooltipExtraColumnValues?: (seriesId: string, categoryIndex: number, currentValue: number) => string[];
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -290,6 +294,8 @@ const chartOptions = computed<object>(() => {
|
|||||||
let totalAmount = 0;
|
let totalAmount = 0;
|
||||||
let actualDisplayItemCount = 0;
|
let actualDisplayItemCount = 0;
|
||||||
const displayItems: AxisChartTooltipItem[] = [];
|
const displayItems: AxisChartTooltipItem[] = [];
|
||||||
|
const categoryIndex = params.length > 0 && params[0] ? (params[0].dataIndex ?? 0) : 0;
|
||||||
|
const visibleSeriesIds: string[] = [];
|
||||||
|
|
||||||
for (const param of params) {
|
for (const param of params) {
|
||||||
const id = param.seriesId as string;
|
const id = param.seriesId as string;
|
||||||
@@ -299,38 +305,111 @@ const chartOptions = computed<object>(() => {
|
|||||||
const amount = param.data as number;
|
const amount = param.data as number;
|
||||||
|
|
||||||
displayItems.push({
|
displayItems.push({
|
||||||
|
id: id,
|
||||||
name: name,
|
name: name,
|
||||||
color: color,
|
color: color,
|
||||||
displayOrders: displayOrders,
|
displayOrders: displayOrders,
|
||||||
totalAmount: amount
|
totalAmount: amount
|
||||||
});
|
});
|
||||||
|
|
||||||
|
visibleSeriesIds.push(id);
|
||||||
totalAmount += amount;
|
totalAmount += amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
sortStatisticsItems(displayItems, props.sortingType);
|
sortStatisticsItems(displayItems, props.sortingType);
|
||||||
|
|
||||||
for (const item of displayItems) {
|
const extraColumnValuesMap: Record<number, string[]> = {};
|
||||||
|
const extraColumnTotalValues: string[] = [];
|
||||||
|
const hasExtraColumnIndexes: Record<number, boolean> = {};
|
||||||
|
|
||||||
|
if (props.tooltipExtraColumnNames) {
|
||||||
|
if (props.tooltipExtraColumnValues) {
|
||||||
|
for (const [item, index] of itemAndIndex(displayItems)) {
|
||||||
|
const values = props.tooltipExtraColumnValues(item.id, categoryIndex, item.totalAmount);
|
||||||
|
extraColumnValuesMap[index] = values;
|
||||||
|
|
||||||
|
for (const [value, columnIndex] of itemAndIndex(values)) {
|
||||||
|
if (value && value !== '-') {
|
||||||
|
hasExtraColumnIndexes[columnIndex] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.tooltipExtraColumnTotalValues) {
|
||||||
|
const values = props.tooltipExtraColumnTotalValues(categoryIndex, totalAmount, visibleSeriesIds);
|
||||||
|
extraColumnTotalValues.push(...values);
|
||||||
|
|
||||||
|
for (const [value, columnIndex] of itemAndIndex(values)) {
|
||||||
|
if (value && value !== '-') {
|
||||||
|
hasExtraColumnIndexes[columnIndex] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [item, index] of itemAndIndex(displayItems)) {
|
||||||
if (displayItems.length === 1 || item.totalAmount !== 0) {
|
if (displayItems.length === 1 || item.totalAmount !== 0) {
|
||||||
const value = getDisplayValue(item.totalAmount);
|
const value = getDisplayValue(item.totalAmount);
|
||||||
tooltip += '<div><span class="chart-pointer" style="background-color: ' + item.color + '"></span>';
|
tooltip += '<tr><td><span class="chart-pointer" style="background-color: ' + item.color + '"></span>';
|
||||||
tooltip += `<span>${item.name}</span><span class="ms-5" style="float: inline-end">${value}</span>`;
|
tooltip += `<span>${item.name}</span></td><td><span class="ms-5" style="float: inline-end">${value}</span></td>`;
|
||||||
tooltip += '</div>';
|
|
||||||
|
if (props.tooltipExtraColumnNames) {
|
||||||
|
const values = extraColumnValuesMap[index] ?? [];
|
||||||
|
|
||||||
|
for (let i = 0; i < props.tooltipExtraColumnNames.length; i++) {
|
||||||
|
if (!hasExtraColumnIndexes[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const value = values[i] ?? '-';
|
||||||
|
tooltip += `<td><span class="ms-5" style="float: inline-end">${value}</span></td>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip += '</tr>';
|
||||||
actualDisplayItemCount++;
|
actualDisplayItemCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (props.showTotalAmountInTooltip && !props.oneHundredPercentStacked) {
|
if (props.showTotalAmountInTooltip && !props.oneHundredPercentStacked) {
|
||||||
const displayTotalAmount = getDisplayValue(totalAmount);
|
const displayTotalAmount = getDisplayValue(totalAmount);
|
||||||
tooltip = '<div><span class="chart-pointer" style="background-color: ' + (isDarkMode.value ? '#eee' : '#333') + '"></span>'
|
let totalColumnCount = 2;
|
||||||
+ `<span>${props.totalNameInTooltip}</span><span class="ms-5" style="float: inline-end">${displayTotalAmount}</span>`
|
|
||||||
+ '</div>'
|
let totalTooltip = `<tr><td><span class="chart-pointer" style="background-color: ${isDarkMode.value ? '#eee' : '#333'}"></span>`
|
||||||
+ (actualDisplayItemCount > 0 ? '<div style="border-bottom: ' + (isDarkMode.value ? '#eee' : '#333') + ' dashed 1px"></div>' : '')
|
+ `<span>${props.totalNameInTooltip}</span></td><td><span class="ms-5" style="float: inline-end">${displayTotalAmount}</span></td>`;
|
||||||
+ tooltip;
|
|
||||||
|
if (props.tooltipExtraColumnNames) {
|
||||||
|
for (let i = 0; i < props.tooltipExtraColumnNames.length; i++) {
|
||||||
|
if (!hasExtraColumnIndexes[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const value = extraColumnTotalValues[i] ?? '-';
|
||||||
|
totalTooltip += `<td><span class="ms-5" style="float: inline-end">${value}</span></td>`;
|
||||||
|
totalColumnCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
totalTooltip += '</tr>';
|
||||||
|
totalTooltip += `<tr><td colspan="${totalColumnCount}" ${actualDisplayItemCount > 0 ? 'style="border-bottom: ' + (isDarkMode.value ? '#eee' : '#333') + ' dashed 1px"' : ''}></td></tr>`;
|
||||||
|
tooltip = totalTooltip + tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.length && params[0] && params[0].name) {
|
if (params.length && params[0] && params[0].name) {
|
||||||
tooltip = `${params[0].name}<br/>` + tooltip;
|
let tooltipHeader = `<td>${params[0].name}</td><td></td>`;
|
||||||
|
|
||||||
|
if (props.tooltipExtraColumnNames) {
|
||||||
|
for (const [columnName, columnIndex] of itemAndIndex(props.tooltipExtraColumnNames)) {
|
||||||
|
if (!hasExtraColumnIndexes[columnIndex]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltipHeader += `<td><span class="ms-5" style="float: inline-end">${columnName}</span></td>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tooltip = `<table class="chart-tooltip-table"><tbody><tr>${tooltipHeader}</tr>${tooltip}</tbody></table>`
|
||||||
}
|
}
|
||||||
|
|
||||||
return tooltip;
|
return tooltip;
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
:translate-name="translateName"
|
:translate-name="translateName"
|
||||||
:amount-value="true" :default-currency="defaultCurrency"
|
:amount-value="true" :default-currency="defaultCurrency"
|
||||||
:enable-click-item="enableClickItem"
|
:enable-click-item="enableClickItem"
|
||||||
|
:tooltip-extra-column-names="allTooltipExtraColumnNames"
|
||||||
|
:tooltip-extra-column-total-values="showYearOverYear || showPeriodOverPeriod ? getTooltipExtraColumnTotalValues : undefined"
|
||||||
|
:tooltip-extra-column-values="showYearOverYear || showPeriodOverPeriod ? getTooltipExtraColumnValues : undefined"
|
||||||
@click="clickItem"
|
@click="clickItem"
|
||||||
v-if="chartDisplayType"
|
v-if="chartDisplayType"
|
||||||
/>
|
/>
|
||||||
@@ -29,18 +32,31 @@ import {
|
|||||||
|
|
||||||
import { useUserStore } from '@/stores/user.ts';
|
import { useUserStore } from '@/stores/user.ts';
|
||||||
|
|
||||||
|
import {
|
||||||
|
itemAndIndex
|
||||||
|
} from '@/core/base.ts';
|
||||||
import {
|
import {
|
||||||
type Year1BasedMonth,
|
type Year1BasedMonth,
|
||||||
type YearMonthDay,
|
type YearMonthDay,
|
||||||
|
type YearUnixTime,
|
||||||
|
type YearQuarterUnixTime,
|
||||||
|
type YearMonthUnixTime,
|
||||||
|
type YearMonthDayUnixTime,
|
||||||
DateRangeScene
|
DateRangeScene
|
||||||
} from '@/core/datetime.ts';
|
} from '@/core/datetime.ts';
|
||||||
|
import {
|
||||||
|
type FiscalYearUnixTime
|
||||||
|
} from '@/core/fiscalyear.ts';
|
||||||
import {
|
import {
|
||||||
ChartDataAggregationType,
|
ChartDataAggregationType,
|
||||||
TrendChartType,
|
TrendChartType,
|
||||||
ChartDateAggregationType
|
ChartDateAggregationType
|
||||||
} from '@/core/statistics.ts';
|
} from '@/core/statistics.ts';
|
||||||
|
|
||||||
import { isArray, isNumber } from '@/lib/common.ts';
|
import {
|
||||||
|
isArray,
|
||||||
|
isNumber
|
||||||
|
} from '@/lib/common.ts';
|
||||||
import {
|
import {
|
||||||
parseDateTimeFromUnixTime,
|
parseDateTimeFromUnixTime,
|
||||||
getYearMonthFirstUnixTime,
|
getYearMonthFirstUnixTime,
|
||||||
@@ -56,6 +72,8 @@ interface DesktopTrendsChartProps<T extends TrendsChartDateType> extends CommonT
|
|||||||
type?: number;
|
type?: number;
|
||||||
showValue?: boolean;
|
showValue?: boolean;
|
||||||
showTotalAmountInTooltip?: boolean;
|
showTotalAmountInTooltip?: boolean;
|
||||||
|
showYearOverYear?: boolean;
|
||||||
|
showPeriodOverPeriod?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<DesktopTrendsChartProps<TrendsChartDateType>>();
|
const props = defineProps<DesktopTrendsChartProps<TrendsChartDateType>>();
|
||||||
@@ -70,7 +88,8 @@ const {
|
|||||||
formatDateTimeToGregorianLikeShortYear,
|
formatDateTimeToGregorianLikeShortYear,
|
||||||
formatDateTimeToGregorianLikeShortYearMonth,
|
formatDateTimeToGregorianLikeShortYearMonth,
|
||||||
formatYearQuarterToGregorianLikeYearQuarter,
|
formatYearQuarterToGregorianLikeYearQuarter,
|
||||||
formatDateTimeToGregorianLikeFiscalYear
|
formatDateTimeToGregorianLikeFiscalYear,
|
||||||
|
formatPercentToLocalizedNumerals
|
||||||
} = useI18n();
|
} = useI18n();
|
||||||
|
|
||||||
const { allDateRanges } = useTrendsChartBase(props);
|
const { allDateRanges } = useTrendsChartBase(props);
|
||||||
@@ -91,6 +110,20 @@ const chartDisplayType = computed<AxisChartDisplayType | undefined>(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const allTooltipExtraColumnNames = computed<string[]>(() => {
|
||||||
|
const extraColumnNames: string[] = [];
|
||||||
|
|
||||||
|
if (props.showYearOverYear) {
|
||||||
|
extraColumnNames.push(tt('Year-over-Year'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.showPeriodOverPeriod) {
|
||||||
|
extraColumnNames.push(tt('Period-over-Period'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return extraColumnNames;
|
||||||
|
});
|
||||||
|
|
||||||
const allDisplayDateRanges = computed<string[]>(() => {
|
const allDisplayDateRanges = computed<string[]>(() => {
|
||||||
const allDisplayDateRanges: string[] = [];
|
const allDisplayDateRanges: string[] = [];
|
||||||
|
|
||||||
@@ -188,22 +221,9 @@ const allSeriesData = computed<Record<string, unknown>[]>(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const dateRange of allDateRanges.value) {
|
for (const dateRange of allDateRanges.value) {
|
||||||
let dateRangeKey = '';
|
const dateRangeKey = getDateRangeKey(dateRange) ?? '';
|
||||||
|
|
||||||
if (props.dateAggregationType === ChartDateAggregationType.Year.type) {
|
|
||||||
dateRangeKey = dateRange.year.toString();
|
|
||||||
} else if (props.dateAggregationType === ChartDateAggregationType.FiscalYear.type && 'year' in dateRange) {
|
|
||||||
dateRangeKey = dateRange.year.toString();
|
|
||||||
} else if (props.dateAggregationType === ChartDateAggregationType.Quarter.type && 'quarter' in dateRange) {
|
|
||||||
dateRangeKey = `${dateRange.year}-${dateRange.quarter}`;
|
|
||||||
} else if (props.dateAggregationType === ChartDateAggregationType.Month.type && 'month0base' in dateRange) {
|
|
||||||
dateRangeKey = `${dateRange.year}-${dateRange.month0base + 1}`;
|
|
||||||
} else if (props.dateAggregationType === ChartDateAggregationType.Day.type && 'day' in dateRange && props.chartMode === 'daily') {
|
|
||||||
dateRangeKey = `${dateRange.year}-${dateRange.month}-${dateRange.day}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
let amount = 0;
|
|
||||||
const dataItems = dateRangeAmountMap[dateRangeKey];
|
const dataItems = dateRangeAmountMap[dateRangeKey];
|
||||||
|
let amount = 0;
|
||||||
|
|
||||||
if (isArray(dataItems)) {
|
if (isArray(dataItems)) {
|
||||||
for (const dataItem of dataItems) {
|
for (const dataItem of dataItems) {
|
||||||
@@ -229,6 +249,172 @@ const allSeriesData = computed<Record<string, unknown>[]>(() => {
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const seriesIdValuesMap = computed<Record<string, number[]>>(() => {
|
||||||
|
const result: Record<string, number[]> = {};
|
||||||
|
|
||||||
|
for (const item of allSeriesData.value) {
|
||||||
|
const id = getSeriesId(item);
|
||||||
|
const values = item['values'] as number[];
|
||||||
|
|
||||||
|
if (id && values) {
|
||||||
|
result[id] = values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
|
const yoyIndexMap = computed<Record<number, number>>(() => {
|
||||||
|
const result: Record<number, number> = {};
|
||||||
|
const dateKeyToIndex: Record<string, number> = {};
|
||||||
|
|
||||||
|
for (const [dateRange, index] of itemAndIndex(allDateRanges.value)) {
|
||||||
|
const key = getDateRangeKey(dateRange);
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
dateKeyToIndex[key] = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [dateRange, index] of itemAndIndex(allDateRanges.value)) {
|
||||||
|
const yoyKey = getDateRangeKey(dateRange, -1);
|
||||||
|
|
||||||
|
if (yoyKey && isNumber(dateKeyToIndex[yoyKey])) {
|
||||||
|
result[index] = dateKeyToIndex[yoyKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
|
function getSeriesId(item: Record<string, unknown>): string {
|
||||||
|
if (props.idField && item[props.idField]) {
|
||||||
|
return item[props.idField] as string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const name = item[props.nameField] as string;
|
||||||
|
return props.translateName ? tt(name) : name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDateRangeKey(dateRange: YearUnixTime | FiscalYearUnixTime | YearQuarterUnixTime | YearMonthUnixTime | YearMonthDayUnixTime, yearOffset?: number): string | undefined {
|
||||||
|
if (props.dateAggregationType === ChartDateAggregationType.Year.type) {
|
||||||
|
return (dateRange.year + (yearOffset ?? 0)).toString();
|
||||||
|
} else if (props.dateAggregationType === ChartDateAggregationType.FiscalYear.type && 'year' in dateRange) {
|
||||||
|
return (dateRange.year + (yearOffset ?? 0)).toString();
|
||||||
|
} else if (props.dateAggregationType === ChartDateAggregationType.Quarter.type && 'quarter' in dateRange) {
|
||||||
|
return `${dateRange.year + (yearOffset ?? 0)}-${dateRange.quarter}`;
|
||||||
|
} else if (props.dateAggregationType === ChartDateAggregationType.Month.type && 'month0base' in dateRange) {
|
||||||
|
return `${dateRange.year + (yearOffset ?? 0)}-${dateRange.month0base + 1}`;
|
||||||
|
} else if (props.dateAggregationType === ChartDateAggregationType.Day.type && 'day' in dateRange && props.chartMode === 'daily') {
|
||||||
|
return `${dateRange.year + (yearOffset ?? 0)}-${dateRange.month}-${dateRange.day}`;
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDisplayChangeRate(current: number, reference: number): string {
|
||||||
|
if (reference === 0 && current === 0) {
|
||||||
|
return formatPercentToLocalizedNumerals(0, 2, '<0.01');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reference === 0) {
|
||||||
|
return '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
const rate = (current - reference) / reference * 100;
|
||||||
|
return formatPercentToLocalizedNumerals(rate, 2, '<0.01');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTooltipExtraColumnTotalValues(categoryIndex: number, totalValue: number, visibleSeriesIds: string[]): string[] {
|
||||||
|
const extraColumnValues: string[] = [];
|
||||||
|
|
||||||
|
if (!props.showYearOverYear && !props.showPeriodOverPeriod) {
|
||||||
|
return extraColumnValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.showYearOverYear) {
|
||||||
|
const yoyReferenceIndex = yoyIndexMap.value[categoryIndex];
|
||||||
|
let displayChangeRate = '-';
|
||||||
|
|
||||||
|
if (isNumber(yoyReferenceIndex)) {
|
||||||
|
let referenceTotalValue = 0;
|
||||||
|
|
||||||
|
for (const seriesId of visibleSeriesIds) {
|
||||||
|
const values = seriesIdValuesMap.value[seriesId];
|
||||||
|
|
||||||
|
if (values) {
|
||||||
|
referenceTotalValue += values[yoyReferenceIndex] ?? 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
displayChangeRate = formatDisplayChangeRate(totalValue, referenceTotalValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
extraColumnValues.push(displayChangeRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.showPeriodOverPeriod) {
|
||||||
|
const popReferenceIndex = categoryIndex - 1;
|
||||||
|
let displayChangeRate = '-';
|
||||||
|
|
||||||
|
if (popReferenceIndex >= 0) {
|
||||||
|
let referenceTotalValue = 0;
|
||||||
|
|
||||||
|
for (const seriesId of visibleSeriesIds) {
|
||||||
|
const values = seriesIdValuesMap.value[seriesId];
|
||||||
|
|
||||||
|
if (values) {
|
||||||
|
referenceTotalValue += values[popReferenceIndex] ?? 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
displayChangeRate = formatDisplayChangeRate(totalValue, referenceTotalValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
extraColumnValues.push(displayChangeRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return extraColumnValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTooltipExtraColumnValues(seriesId: string, categoryIndex: number, currentValue: number): string[] {
|
||||||
|
const extraColumnValues: string[] = [];
|
||||||
|
|
||||||
|
if (!props.showYearOverYear && !props.showPeriodOverPeriod) {
|
||||||
|
return extraColumnValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
const values = seriesIdValuesMap.value[seriesId];
|
||||||
|
|
||||||
|
if (!values) {
|
||||||
|
return extraColumnValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.showYearOverYear) {
|
||||||
|
const yoyReferenceIndex = yoyIndexMap.value[categoryIndex];
|
||||||
|
let displayChangeRate = '-';
|
||||||
|
|
||||||
|
if (isNumber(yoyReferenceIndex) && yoyReferenceIndex >= 0 && yoyReferenceIndex < values.length) {
|
||||||
|
displayChangeRate = formatDisplayChangeRate(currentValue, values[yoyReferenceIndex] ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
extraColumnValues.push(displayChangeRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.showPeriodOverPeriod) {
|
||||||
|
const popReferenceIndex = categoryIndex - 1;
|
||||||
|
let displayChangeRate = '-';
|
||||||
|
|
||||||
|
if (popReferenceIndex >= 0 && popReferenceIndex < values.length) {
|
||||||
|
displayChangeRate = formatDisplayChangeRate(currentValue, values[popReferenceIndex] ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
extraColumnValues.push(displayChangeRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
return extraColumnValues;
|
||||||
|
}
|
||||||
|
|
||||||
function clickItem(itemId: string, categoryIndex: number): void {
|
function clickItem(itemId: string, categoryIndex: number): void {
|
||||||
const dateRange = allDateRanges.value[categoryIndex];
|
const dateRange = allDateRanges.value[categoryIndex];
|
||||||
|
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "Nach Quartal aggregieren",
|
"Aggregate by Quarter": "Nach Quartal aggregieren",
|
||||||
"Aggregate by Year": "Nach Jahr aggregieren",
|
"Aggregate by Year": "Nach Jahr aggregieren",
|
||||||
"Aggregate by Fiscal Year": "Aggregate by Fiscal Year",
|
"Aggregate by Fiscal Year": "Aggregate by Fiscal Year",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "Konten filtern",
|
"Filter Accounts": "Konten filtern",
|
||||||
"Filter Transaction Categories": "Transaktionskategorien filtern",
|
"Filter Transaction Categories": "Transaktionskategorien filtern",
|
||||||
"Filter Transaction Tags": "Transaktions-Tags filtern",
|
"Filter Transaction Tags": "Transaktions-Tags filtern",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "Aggregate by Quarter",
|
"Aggregate by Quarter": "Aggregate by Quarter",
|
||||||
"Aggregate by Year": "Aggregate by Year",
|
"Aggregate by Year": "Aggregate by Year",
|
||||||
"Aggregate by Fiscal Year": "Aggregate by Fiscal Year",
|
"Aggregate by Fiscal Year": "Aggregate by Fiscal Year",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "Filter Accounts",
|
"Filter Accounts": "Filter Accounts",
|
||||||
"Filter Transaction Categories": "Filter Transaction Categories",
|
"Filter Transaction Categories": "Filter Transaction Categories",
|
||||||
"Filter Transaction Tags": "Filter Transaction Tags",
|
"Filter Transaction Tags": "Filter Transaction Tags",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "Agregado por Trimestre",
|
"Aggregate by Quarter": "Agregado por Trimestre",
|
||||||
"Aggregate by Year": "Agregado por Año",
|
"Aggregate by Year": "Agregado por Año",
|
||||||
"Aggregate by Fiscal Year": "Agregado por Año Fiscal",
|
"Aggregate by Fiscal Year": "Agregado por Año Fiscal",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "Filtrar cuentas",
|
"Filter Accounts": "Filtrar cuentas",
|
||||||
"Filter Transaction Categories": "Filtrar categorías de transacciones",
|
"Filter Transaction Categories": "Filtrar categorías de transacciones",
|
||||||
"Filter Transaction Tags": "Filtrar etiquetas de transacciones",
|
"Filter Transaction Tags": "Filtrar etiquetas de transacciones",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "Agréger par trimestre",
|
"Aggregate by Quarter": "Agréger par trimestre",
|
||||||
"Aggregate by Year": "Agréger par année",
|
"Aggregate by Year": "Agréger par année",
|
||||||
"Aggregate by Fiscal Year": "Agréger par année fiscale",
|
"Aggregate by Fiscal Year": "Agréger par année fiscale",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "Filtrer les comptes",
|
"Filter Accounts": "Filtrer les comptes",
|
||||||
"Filter Transaction Categories": "Filtrer les catégories de transaction",
|
"Filter Transaction Categories": "Filtrer les catégories de transaction",
|
||||||
"Filter Transaction Tags": "Filtrer les étiquettes de transaction",
|
"Filter Transaction Tags": "Filtrer les étiquettes de transaction",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "Aggrega per trimestre",
|
"Aggregate by Quarter": "Aggrega per trimestre",
|
||||||
"Aggregate by Year": "Aggrega per anno",
|
"Aggregate by Year": "Aggrega per anno",
|
||||||
"Aggregate by Fiscal Year": "Aggregate by Fiscal Year",
|
"Aggregate by Fiscal Year": "Aggregate by Fiscal Year",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "Filtra conti",
|
"Filter Accounts": "Filtra conti",
|
||||||
"Filter Transaction Categories": "Filtra categorie transazione",
|
"Filter Transaction Categories": "Filtra categorie transazione",
|
||||||
"Filter Transaction Tags": "Filtra tag transazione",
|
"Filter Transaction Tags": "Filtra tag transazione",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "四半期ごとに集計",
|
"Aggregate by Quarter": "四半期ごとに集計",
|
||||||
"Aggregate by Year": "年ごとに集計",
|
"Aggregate by Year": "年ごとに集計",
|
||||||
"Aggregate by Fiscal Year": "Aggregate by Fiscal Year",
|
"Aggregate by Fiscal Year": "Aggregate by Fiscal Year",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "口座で絞り込み",
|
"Filter Accounts": "口座で絞り込み",
|
||||||
"Filter Transaction Categories": "取引カテゴリで絞り込み",
|
"Filter Transaction Categories": "取引カテゴリで絞り込み",
|
||||||
"Filter Transaction Tags": "取引タグで絞り込み",
|
"Filter Transaction Tags": "取引タグで絞り込み",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "ತ್ರೈಮಾಸಿಕ ಒಕ್ಕೂಟ",
|
"Aggregate by Quarter": "ತ್ರೈಮಾಸಿಕ ಒಕ್ಕೂಟ",
|
||||||
"Aggregate by Year": "ವರ್ಷವಾರು ಒಕ್ಕೂಟ",
|
"Aggregate by Year": "ವರ್ಷವಾರು ಒಕ್ಕೂಟ",
|
||||||
"Aggregate by Fiscal Year": "ಹಣಕಾಸು ವರ್ಷವಾರು ಒಕ್ಕೂಟ",
|
"Aggregate by Fiscal Year": "ಹಣಕಾಸು ವರ್ಷವಾರು ಒಕ್ಕೂಟ",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "ಖಾತೆಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಿ",
|
"Filter Accounts": "ಖಾತೆಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಿ",
|
||||||
"Filter Transaction Categories": "ವಹಿವಾಟು ವರ್ಗಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಿ",
|
"Filter Transaction Categories": "ವಹಿವಾಟು ವರ್ಗಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಿ",
|
||||||
"Filter Transaction Tags": "ವಹಿವಾಟು ಟ್ಯಾಗ್ಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಿ",
|
"Filter Transaction Tags": "ವಹಿವಾಟು ಟ್ಯಾಗ್ಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಿ",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "분기별 집계",
|
"Aggregate by Quarter": "분기별 집계",
|
||||||
"Aggregate by Year": "연도별 집계",
|
"Aggregate by Year": "연도별 집계",
|
||||||
"Aggregate by Fiscal Year": "회계 연도별 집계",
|
"Aggregate by Fiscal Year": "회계 연도별 집계",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "계좌 필터",
|
"Filter Accounts": "계좌 필터",
|
||||||
"Filter Transaction Categories": "거래 범주 필터",
|
"Filter Transaction Categories": "거래 범주 필터",
|
||||||
"Filter Transaction Tags": "거래 태그 필터",
|
"Filter Transaction Tags": "거래 태그 필터",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "Groeperen per kwartaal",
|
"Aggregate by Quarter": "Groeperen per kwartaal",
|
||||||
"Aggregate by Year": "Groeperen per jaar",
|
"Aggregate by Year": "Groeperen per jaar",
|
||||||
"Aggregate by Fiscal Year": "Groeperen per boekjaar",
|
"Aggregate by Fiscal Year": "Groeperen per boekjaar",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "Rekeningen filteren",
|
"Filter Accounts": "Rekeningen filteren",
|
||||||
"Filter Transaction Categories": "Transactiecategorieën filteren",
|
"Filter Transaction Categories": "Transactiecategorieën filteren",
|
||||||
"Filter Transaction Tags": "Transactietags filteren",
|
"Filter Transaction Tags": "Transactietags filteren",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "Agregar por Trimestre",
|
"Aggregate by Quarter": "Agregar por Trimestre",
|
||||||
"Aggregate by Year": "Agregar por Ano",
|
"Aggregate by Year": "Agregar por Ano",
|
||||||
"Aggregate by Fiscal Year": "Agregar por Ano Fiscal",
|
"Aggregate by Fiscal Year": "Agregar por Ano Fiscal",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "Filtrar Contas",
|
"Filter Accounts": "Filtrar Contas",
|
||||||
"Filter Transaction Categories": "Filtrar Categorias de Transações",
|
"Filter Transaction Categories": "Filtrar Categorias de Transações",
|
||||||
"Filter Transaction Tags": "Filtrar Tags de Transações",
|
"Filter Transaction Tags": "Filtrar Tags de Transações",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "Агрегировать по кварталам",
|
"Aggregate by Quarter": "Агрегировать по кварталам",
|
||||||
"Aggregate by Year": "Агрегировать по годам",
|
"Aggregate by Year": "Агрегировать по годам",
|
||||||
"Aggregate by Fiscal Year": "Агрегировать по фискальным годам",
|
"Aggregate by Fiscal Year": "Агрегировать по фискальным годам",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "Фильтровать счета",
|
"Filter Accounts": "Фильтровать счета",
|
||||||
"Filter Transaction Categories": "Фильтровать категории транзакций",
|
"Filter Transaction Categories": "Фильтровать категории транзакций",
|
||||||
"Filter Transaction Tags": "Фильтровать теги транзакций",
|
"Filter Transaction Tags": "Фильтровать теги транзакций",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "Združi po četrtletjih",
|
"Aggregate by Quarter": "Združi po četrtletjih",
|
||||||
"Aggregate by Year": "Združi po letih",
|
"Aggregate by Year": "Združi po letih",
|
||||||
"Aggregate by Fiscal Year": "Združi po fiskalnih letih",
|
"Aggregate by Fiscal Year": "Združi po fiskalnih letih",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "Filtriraj račune",
|
"Filter Accounts": "Filtriraj račune",
|
||||||
"Filter Transaction Categories": "Filtriraj kategorije transakcij",
|
"Filter Transaction Categories": "Filtriraj kategorije transakcij",
|
||||||
"Filter Transaction Tags": "Filtriraj oznake transakcij",
|
"Filter Transaction Tags": "Filtriraj oznake transakcij",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "காலாண்டு கூட்டமைப்பு",
|
"Aggregate by Quarter": "காலாண்டு கூட்டமைப்பு",
|
||||||
"Aggregate by Year": "ஆண்டுவாரி கூட்டமைப்பு",
|
"Aggregate by Year": "ஆண்டுவாரி கூட்டமைப்பு",
|
||||||
"Aggregate by Fiscal Year": "நிதி ஆண்டுவாரி கூட்டமைப்பு",
|
"Aggregate by Fiscal Year": "நிதி ஆண்டுவாரி கூட்டமைப்பு",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "கணக்குகளை வடிகட்டி செய்",
|
"Filter Accounts": "கணக்குகளை வடிகட்டி செய்",
|
||||||
"Filter Transaction Categories": "பரிவர்த்தனை வகைகளை வடிகட்டி செய்",
|
"Filter Transaction Categories": "பரிவர்த்தனை வகைகளை வடிகட்டி செய்",
|
||||||
"Filter Transaction Tags": "பரிவர்த்தனை குறிச்சொல்களை வடிகட்டி செய்",
|
"Filter Transaction Tags": "பரிவர்த்தனை குறிச்சொல்களை வடிகட்டி செய்",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "รวมตามไตรมาส",
|
"Aggregate by Quarter": "รวมตามไตรมาส",
|
||||||
"Aggregate by Year": "รวมตามปี",
|
"Aggregate by Year": "รวมตามปี",
|
||||||
"Aggregate by Fiscal Year": "รวมตามปีงบประมาณ",
|
"Aggregate by Fiscal Year": "รวมตามปีงบประมาณ",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "กรองบัญชี",
|
"Filter Accounts": "กรองบัญชี",
|
||||||
"Filter Transaction Categories": "กรองหมวดรายการ",
|
"Filter Transaction Categories": "กรองหมวดรายการ",
|
||||||
"Filter Transaction Tags": "กรองแท็กรายการ",
|
"Filter Transaction Tags": "กรองแท็กรายการ",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "Çeyreğe Göre Topla",
|
"Aggregate by Quarter": "Çeyreğe Göre Topla",
|
||||||
"Aggregate by Year": "Yıla Göre Topla",
|
"Aggregate by Year": "Yıla Göre Topla",
|
||||||
"Aggregate by Fiscal Year": "Mali Yıla Göre Topla",
|
"Aggregate by Fiscal Year": "Mali Yıla Göre Topla",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "Hesapları Filtrele",
|
"Filter Accounts": "Hesapları Filtrele",
|
||||||
"Filter Transaction Categories": "İşlem Kategorilerini Filtrele",
|
"Filter Transaction Categories": "İşlem Kategorilerini Filtrele",
|
||||||
"Filter Transaction Tags": "İşlem Etiketlerini Filtrele",
|
"Filter Transaction Tags": "İşlem Etiketlerini Filtrele",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "Агрегувати за кварталами",
|
"Aggregate by Quarter": "Агрегувати за кварталами",
|
||||||
"Aggregate by Year": "Агрегувати за роками",
|
"Aggregate by Year": "Агрегувати за роками",
|
||||||
"Aggregate by Fiscal Year": "Aggregate by Fiscal Year",
|
"Aggregate by Fiscal Year": "Aggregate by Fiscal Year",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "Фільтрувати рахунки",
|
"Filter Accounts": "Фільтрувати рахунки",
|
||||||
"Filter Transaction Categories": "Фільтрувати категорії транзакцій",
|
"Filter Transaction Categories": "Фільтрувати категорії транзакцій",
|
||||||
"Filter Transaction Tags": "Фільтрувати теги транзакцій",
|
"Filter Transaction Tags": "Фільтрувати теги транзакцій",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "Tổng hợp theo quý",
|
"Aggregate by Quarter": "Tổng hợp theo quý",
|
||||||
"Aggregate by Year": "Tổng hợp theo năm",
|
"Aggregate by Year": "Tổng hợp theo năm",
|
||||||
"Aggregate by Fiscal Year": "Aggregate by Fiscal Year",
|
"Aggregate by Fiscal Year": "Aggregate by Fiscal Year",
|
||||||
|
"Year-over-Year": "Year-over-Year",
|
||||||
|
"Period-over-Period": "Period-over-Period",
|
||||||
"Filter Accounts": "Lọc tài khoản",
|
"Filter Accounts": "Lọc tài khoản",
|
||||||
"Filter Transaction Categories": "Lọc danh mục giao dịch",
|
"Filter Transaction Categories": "Lọc danh mục giao dịch",
|
||||||
"Filter Transaction Tags": "Lọc thẻ giao dịch",
|
"Filter Transaction Tags": "Lọc thẻ giao dịch",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "按季度聚合",
|
"Aggregate by Quarter": "按季度聚合",
|
||||||
"Aggregate by Year": "按年聚合",
|
"Aggregate by Year": "按年聚合",
|
||||||
"Aggregate by Fiscal Year": "按财年聚合",
|
"Aggregate by Fiscal Year": "按财年聚合",
|
||||||
|
"Year-over-Year": "同比",
|
||||||
|
"Period-over-Period": "环比",
|
||||||
"Filter Accounts": "过滤账户",
|
"Filter Accounts": "过滤账户",
|
||||||
"Filter Transaction Categories": "过滤交易分类",
|
"Filter Transaction Categories": "过滤交易分类",
|
||||||
"Filter Transaction Tags": "过滤交易标签",
|
"Filter Transaction Tags": "过滤交易标签",
|
||||||
|
|||||||
@@ -2210,6 +2210,8 @@
|
|||||||
"Aggregate by Quarter": "依季度彙整",
|
"Aggregate by Quarter": "依季度彙整",
|
||||||
"Aggregate by Year": "依年份彙整",
|
"Aggregate by Year": "依年份彙整",
|
||||||
"Aggregate by Fiscal Year": "依財年彙整",
|
"Aggregate by Fiscal Year": "依財年彙整",
|
||||||
|
"Year-over-Year": "同比",
|
||||||
|
"Period-over-Period": "環比",
|
||||||
"Filter Accounts": "篩選帳戶",
|
"Filter Accounts": "篩選帳戶",
|
||||||
"Filter Transaction Categories": "篩選交易分類",
|
"Filter Transaction Categories": "篩選交易分類",
|
||||||
"Filter Transaction Tags": "篩選交易標籤",
|
"Filter Transaction Tags": "篩選交易標籤",
|
||||||
|
|||||||
@@ -174,6 +174,11 @@ html[dir="rtl"] .bidirectional-switch {
|
|||||||
background-color: #2f2f2f;
|
background-color: #2f2f2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chart-tooltip-table {
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** Common class for replacing the default style of vuetify **/
|
/** Common class for replacing the default style of vuetify **/
|
||||||
.v-input.v-input--readonly input,
|
.v-input.v-input--readonly input,
|
||||||
.v-input.v-input--readonly textarea,
|
.v-input.v-input--readonly textarea,
|
||||||
|
|||||||
@@ -400,6 +400,8 @@
|
|||||||
:default-currency="defaultCurrency"
|
:default-currency="defaultCurrency"
|
||||||
:stacked="showStackedInTrendsChart"
|
:stacked="showStackedInTrendsChart"
|
||||||
:show-total-amount-in-tooltip="showTotalAmountInTrendsChart"
|
:show-total-amount-in-tooltip="showTotalAmountInTrendsChart"
|
||||||
|
:show-year-over-year="true"
|
||||||
|
:show-period-over-period="trendDateAggregationType === ChartDateAggregationType.Month.type || trendDateAggregationType === ChartDateAggregationType.Quarter.type"
|
||||||
ref="monthlyTrendsChart"
|
ref="monthlyTrendsChart"
|
||||||
id-field="id"
|
id-field="id"
|
||||||
name-field="name"
|
name-field="name"
|
||||||
@@ -449,6 +451,8 @@
|
|||||||
:default-currency="defaultCurrency"
|
:default-currency="defaultCurrency"
|
||||||
:stacked="showStackedInTrendsChart"
|
:stacked="showStackedInTrendsChart"
|
||||||
:show-total-amount-in-tooltip="showTotalAmountInTrendsChart"
|
:show-total-amount-in-tooltip="showTotalAmountInTrendsChart"
|
||||||
|
:show-year-over-year="true"
|
||||||
|
:show-period-over-period="assetTrendsDateAggregationType === ChartDateAggregationType.Day.type || assetTrendsDateAggregationType === ChartDateAggregationType.Month.type || assetTrendsDateAggregationType === ChartDateAggregationType.Quarter.type"
|
||||||
ref="dailyTrendsChart"
|
ref="dailyTrendsChart"
|
||||||
id-field="id"
|
id-field="id"
|
||||||
name-field="name"
|
name-field="name"
|
||||||
|
|||||||
Reference in New Issue
Block a user