Commit 841660b6 authored by sinopsysHK's avatar sinopsysHK Committed by Benjamin Bouvier
Browse files

[client] add 2 periods in category chart and in/out chart frequency

- add in by category chart two new periods to choose: current year + last year
- add capability to switch In/Out chart from monthly to yearly balance view

Default frequency for In/Out chart can be changed from default parametrs
parent 4db10bf5
Pipeline #319528 failed with stages
in 2 minutes
......@@ -36,13 +36,19 @@ export const PeriodSelect = props => {
<option key="6-months" value="6-months">
{$t('client.charts.six_months')}
</option>
<option key="current-year" value="current-year">
{$t('client.charts.current_year')}
</option>
<option key="last-year" value="last-year">
{$t('client.charts.last_year')}
</option>
</select>
);
};
PeriodSelect.propTypes = {
// Initial value.
defaultValue: PropTypes.oneOf(['all', 'current-month', 'last-month', '3-months', '6-months']),
defaultValue: PropTypes.oneOf(['all', 'current-month', 'last-month', '3-months', '6-months', 'current-year', 'last-year']),
// Callback getting the id of the selected option whenever it changes.
onChange: PropTypes.func.isRequired,
......@@ -161,7 +167,8 @@ class BarChart extends C3Component {
});
monthLabels.push(str);
}
let date = new Date();
let month = date.getMonth();
let xAxisExtent;
switch (this.props.period) {
case 'current-month':
......@@ -176,6 +183,15 @@ class BarChart extends C3Component {
case '3-months':
xAxisExtent = [Math.max(0, monthLabels.length - 3), monthLabels.length];
break;
case 'current-year':
xAxisExtent = [Math.max(0, monthLabels.length - month - 1), monthLabels.length];
break;
case 'last-year':
xAxisExtent = [
Math.max(0, monthLabels.length - month - 13),
Math.max(0, monthLabels.length - month - 1)
];
break;
default:
// All times or last 6 months: only show 6 months at a time.
xAxisExtent = [Math.max(0, monthLabels.length - 6), monthLabels.length];
......@@ -470,6 +486,12 @@ class CategorySection extends React.Component {
(d.getMonth() >= previous && d.getFullYear() === year - 1) ||
(d.getMonth() <= month && d.getFullYear() === year);
case 'current-year':
return d => d.getFullYear() === year;
case 'last-year':
return d => d.getFullYear() === year - 1;
default:
assert(false, 'unexpected option for date filter');
}
......
......@@ -9,6 +9,7 @@ import ModalContent from '../ui/modal/content';
import CancelAndSubmit from '../ui/modal/cancel-and-submit-buttons';
import { PeriodSelect, AmountKindSelect } from './category-charts';
import { FrequencySelect } from './in-out-chart';
export const MODAL_SLUG = 'charts-default-params';
......@@ -17,10 +18,12 @@ const DefaultParamsModal = connect(
let amountKind = get.setting(state, 'default-chart-type');
let displayType = get.setting(state, 'default-chart-display-type');
let period = get.setting(state, 'default-chart-period');
let frequency = get.setting(state, 'default-chart-frequency');
return {
amountKind,
displayType,
period,
frequency,
};
},
......@@ -38,6 +41,10 @@ const DefaultParamsModal = connect(
actions.setSetting(dispatch, 'default-chart-period', val);
},
setFrequency(val) {
actions.setSetting(dispatch, 'default-chart-frequency', val);
},
handleClose() {
actions.hideModal(dispatch);
},
......@@ -50,13 +57,15 @@ const DefaultParamsModal = connect(
amountKind: this.props.amountKind,
displayType: this.props.displayType,
period: this.props.period,
frequency: this.props.frequency,
};
isSubmitDisabled() {
return (
this.state.amountKind === this.props.amountKind &&
this.state.displayType === this.props.displayType &&
this.state.period === this.props.period
this.state.period === this.props.period &&
this.state.frequency === this.props.frequency
);
}
......@@ -73,6 +82,10 @@ const DefaultParamsModal = connect(
this.props.setPeriod(this.state.period);
}
if (this.state.frequency !== this.props.frequency) {
this.props.setFrequency(this.state.frequency);
}
// TODO create a chain of promises and close only if all the
// backend actions have succeeded.
this.props.handleClose();
......@@ -86,6 +99,10 @@ const DefaultParamsModal = connect(
this.setState({ period });
};
handleFrequencyChange = frequency => {
this.setState({ frequency });
};
handleChangeAmountKind = amountKind => {
this.setState({ amountKind });
};
......@@ -130,6 +147,19 @@ const DefaultParamsModal = connect(
htmlId="defaultChartPeriod"
/>
</div>
<h5>{$t('client.charts.in_out_chart')}</h5>
<div className="cols-with-label">
<label htmlFor="defaultChartFrequency">
{$t('client.charts.default_frequency')}
</label>
<FrequencySelect
defaultValue={this.state.frequency}
onChange={this.handleFrequencyChange}
htmlId="defaultChartFrequency"
/>
</div>
</form>
);
......
......@@ -4,23 +4,84 @@ import PropTypes from 'prop-types';
import c3 from 'c3';
import { get } from '../../store';
import { translate as $t, round2, getWellsColors, INTERNAL_TRANSFER_TYPE } from '../../helpers';
import { assert, translate as $t, round2, getWellsColors, INTERNAL_TRANSFER_TYPE } from '../../helpers';
import ChartComponent from './chart-base';
import DisplayIf from '../ui/display-if';
import DiscoveryMessage from '../ui/discovery-message';
export const FrequencySelect = props => {
let onChange = event => {
props.onChange(event.target.value);
};
return (
<select
className="form-element-block"
defaultValue={props.defaultValue}
onChange={onChange}
id={props.htmlId}>
<option key="monthly" value="monthly">
{$t('client.charts.monthly')}
</option>
<option key="yearly" value="yearly">
{$t('client.charts.yearly')}
</option>
</select>
);
};
FrequencySelect.propTypes = {
// Initial value.
defaultValue: PropTypes.oneOf(['monthly', 'yearly']),
// Callback getting the id of the selected option whenever it changes.
onChange: PropTypes.func.isRequired,
// CSS unique id.
htmlId: PropTypes.string.isRequired,
};
const CHART_SIZE = 600;
const SUBCHART_SIZE = 100;
// Initial subchart extent, in months.
const SUBCHART_EXTENT = 3;
function createChartPositiveNegative(chartId, operations, theme, chartSize, subchartSize) {
function datekey(op) {
function createChartPositiveNegative(chartId, frequency, operations, theme, chartSize, subchartSize) {
function datekey_monthly(op) {
let d = op.budgetDate;
return `${d.getFullYear()} - ${d.getMonth()}`;
}
function datekey_yearly(op) {
let d = op.budgetDate;
return `${d.getFullYear()}`;
}
function formatLabel_monthly(date) {
// Undefined means the default locale
let defaultLocale;
return date.toLocaleDateString(defaultLocale, {
year: '2-digit',
month: 'short',
});
}
function formatLabel_yearly(date) {
return `${date.getFullYear()}`;
}
let datekey;
let formatLabel;
switch (frequency) {
case 'monthly':
datekey = datekey_monthly;
formatLabel = formatLabel_monthly;
break;
case 'yearly':
datekey = datekey_yearly;
formatLabel = formatLabel_yearly;
break;
default:
assert(false, `unexpected frequency [${frequency}]`);
}
const POS = 0,
NEG = 1,
......@@ -72,12 +133,7 @@ function createChartPositiveNegative(chartId, operations, theme, chartSize, subc
let categories = [];
for (let i = 0; i < dates.length; i++) {
let date = new Date(dates[i][1]);
// Undefined means the default locale
let defaultLocale;
let str = date.toLocaleDateString(defaultLocale, {
year: '2-digit',
month: 'short',
});
let str = formatLabel(date);
categories.push(str);
}
......@@ -151,6 +207,7 @@ class BarChart extends ChartComponent {
redraw() {
this.container = createChartPositiveNegative(
`#${this.props.chartId}`,
this.props.frequency,
this.props.operations,
this.props.theme,
this.props.chartSize,
......@@ -170,9 +227,14 @@ class InOutChart extends React.Component {
super(props);
this.state = {
currency: props.initialView,
frequency: props.defaultFrequency,
};
}
handleChangeFrequency = frequency => {
this.setState({ frequency });
};
handleCurrencyChange = event => {
this.setState({ currency: event.target.value });
};
......@@ -210,6 +272,7 @@ class InOutChart extends React.Component {
theme={this.props.theme}
chartSize={this.props.chartSize}
subchartSize={this.props.subchartSize}
frequency={this.state.frequency}
/>
</div>
);
......@@ -221,6 +284,15 @@ class InOutChart extends React.Component {
<DiscoveryMessage message={$t('client.charts.differences_all_desc')} />
</DisplayIf>
<p>
<label htmlFor="frequency">{$t('client.charts.frequency')}</label>
<FrequencySelect
defaultValue={this.props.defaultFrequency}
onChange={this.handleChangeFrequency}
htmlId="frequency"
/>
</p>
<DisplayIf condition={currenciesOptions.length > 1}>
<p>
<select
......@@ -273,6 +345,7 @@ InOutChart.defaultProps = {
};
const Export = connect((state, ownProps) => {
let defaultFrequency = get.setting(state, 'default-chart-frequency');
let currentAccountIds = get.accountIdsByAccessId(state, ownProps.accessId);
let currencyToTransactions = new Map();
......@@ -305,6 +378,7 @@ const Export = connect((state, ownProps) => {
return {
chartIdPrefix: `barchart-${ownProps.accessId}`,
defaultFrequency,
currencyToTransactions,
initialView,
};
......
......@@ -15,6 +15,7 @@ DefaultSettings.set('budget-display-no-threshold', 'true');
DefaultSettings.set('default-account-id', '');
DefaultSettings.set('default-chart-display-type', 'all');
DefaultSettings.set('default-chart-type', 'all');
DefaultSettings.set('default-chart-frequency', 'monthly');
DefaultSettings.set('default-chart-period', 'current-month');
DefaultSettings.set('default-currency', 'EUR');
DefaultSettings.set('duplicate-ignore-different-custom-fields', 'true');
......
......@@ -126,6 +126,9 @@
"all_types": "All types",
"positive": "Income",
"negative": "Expenses",
"frequency": "Frequency",
"monthly": "Monthly",
"yearly": "Yearly",
"period": "Period",
"all_periods": "All times",
"all_currencies": "All currencies",
......@@ -133,10 +136,14 @@
"last_month": "Last month",
"three_months": "Last three months",
"six_months": "Last six months",
"current_year": "Current year",
"last_year": "Last year",
"category_chart": "Category chart",
"in_out_chart": "In & Out chart",
"default_display": "Default display type",
"default_amount_type": "Default amount type",
"default_period": "Default period",
"default_frequency": "Default frequency",
"incomes_and_expenses": "Incomes and expenses",
"incomes": "Incomes",
"expenses": "Expenses",
......
......@@ -126,6 +126,9 @@
"all_types": "Les deux",
"positive": "Revenus",
"negative": "Dépenses",
"frequency": "Fréquence",
"monthly": "Mensuelle",
"yearly": "Annuelle",
"period": "Période",
"all_periods": "Tout le temps",
"all_currencies": "Toutes les devises",
......@@ -133,10 +136,14 @@
"last_month": "Mois précédent",
"three_months": "Trois derniers mois",
"six_months": "Six derniers mois",
"current_year": "Année courante",
"last_year": "Année précédente",
"category_chart": "Graphique par catégories",
"in_out_chart": "Graphique des Balances",
"default_display": "Type d'affichage par défaut",
"default_amount_type": "Type d'opérations par défaut",
"default_period": "Période par défaut",
"default_frequency": "Fréquence par défaut",
"incomes_and_expenses": "Revenus et dépenses",
"incomes": "Revenus",
"expenses": "Dépenses",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment