web/storagenode: payout info month range selection logic
Change-Id: Ibb8ab24475212bed5fe8790a317f2d9f4e4105dd
This commit is contained in:
parent
0c18ecf32e
commit
3a1b71a757
@ -5,28 +5,29 @@
|
|||||||
<div class="payout-period-calendar">
|
<div class="payout-period-calendar">
|
||||||
<div class="payout-period-calendar__header">
|
<div class="payout-period-calendar__header">
|
||||||
<div class="payout-period-calendar__header__year-selection">
|
<div class="payout-period-calendar__header__year-selection">
|
||||||
<div class="payout-period-calendar__header__year-selection__prev">
|
<div class="payout-period-calendar__header__year-selection__prev" @click="decrementYear">
|
||||||
<GrayArrowLeftIcon />
|
<GrayArrowLeftIcon />
|
||||||
</div>
|
</div>
|
||||||
<p class="payout-period-calendar__header__year-selection__year">2020</p>
|
<p class="payout-period-calendar__header__year-selection__year">{{ displayedYear }}</p>
|
||||||
<div class="payout-period-calendar__header__year-selection__next">
|
<div class="payout-period-calendar__header__year-selection__next" @click="incrementYear">
|
||||||
<GrayArrowLeftIcon />
|
<GrayArrowLeftIcon />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="payout-period-calendar__header__all-time">All time</p>
|
<p class="payout-period-calendar__header__all-time" @click="selectAllTime">All time</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="payout-period-calendar__months-area">
|
<div class="payout-period-calendar__months-area">
|
||||||
<div
|
<div
|
||||||
class="month-item"
|
class="month-item"
|
||||||
:class="{ selected: item.selected, disabled: !item.active }"
|
:class="{ selected: item.selected, disabled: !item.active }"
|
||||||
v-for="item in displayedMonths"
|
v-for="item in currentDisplayedMonths"
|
||||||
:key="item.name"
|
:key="item.name"
|
||||||
|
@click="checkMonth(item)"
|
||||||
>
|
>
|
||||||
<p class="month-item__label">{{ item.name }}</p>
|
<p class="month-item__label">{{ item.name }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="payout-period-calendar__footer-area">
|
<div class="payout-period-calendar__footer-area">
|
||||||
<p class="payout-period-calendar__footer-area__period">Jan - Apr, 2019</p>
|
<p class="payout-period-calendar__footer-area__period">{{ period }}</p>
|
||||||
<p class="payout-period-calendar__footer-area__ok-button">OK</p>
|
<p class="payout-period-calendar__footer-area__ok-button">OK</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -37,6 +38,10 @@ import { Component, Vue } from 'vue-property-decorator';
|
|||||||
|
|
||||||
import GrayArrowLeftIcon from '@/../static/images/payments/GrayArrowLeft.svg';
|
import GrayArrowLeftIcon from '@/../static/images/payments/GrayArrowLeft.svg';
|
||||||
|
|
||||||
|
interface StoredMonthsByYear {
|
||||||
|
[key: number]: MonthButton[];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds all months names.
|
* Holds all months names.
|
||||||
*/
|
*/
|
||||||
@ -51,6 +56,7 @@ const monthNames = [
|
|||||||
*/
|
*/
|
||||||
class MonthButton {
|
class MonthButton {
|
||||||
public constructor(
|
public constructor(
|
||||||
|
public year: number = 0,
|
||||||
public index: number = 0,
|
public index: number = 0,
|
||||||
public active: boolean = false,
|
public active: boolean = false,
|
||||||
public selected: boolean = false,
|
public selected: boolean = false,
|
||||||
@ -59,7 +65,7 @@ class MonthButton {
|
|||||||
/**
|
/**
|
||||||
* Returns month label depends on index.
|
* Returns month label depends on index.
|
||||||
*/
|
*/
|
||||||
public get name() {
|
public get name(): string {
|
||||||
return monthNames[this.index].slice(0, 3);
|
return monthNames[this.index].slice(0, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,14 +79,171 @@ export default class PayoutPeriodCalendar extends Vue {
|
|||||||
/**
|
/**
|
||||||
* Contains current months list depends on active and selected month state.
|
* Contains current months list depends on active and selected month state.
|
||||||
*/
|
*/
|
||||||
public displayedMonths: MonthButton[] = [];
|
public currentDisplayedMonths: MonthButton[] = [];
|
||||||
|
public displayedYear: number;
|
||||||
|
public period: string;
|
||||||
|
|
||||||
public constructor() {
|
private displayedMonths: StoredMonthsByYear = {};
|
||||||
super();
|
private now: Date;
|
||||||
|
private firstSelectedMonth: MonthButton | null;
|
||||||
|
private secondSelectedMonth: MonthButton | null;
|
||||||
|
|
||||||
for (let i = 0; i < monthNames.length; i++) {
|
/**
|
||||||
this.displayedMonths.push(new MonthButton(i, true, false));
|
* Lifecycle hook after initial render.
|
||||||
|
* Sets up current calendar state.
|
||||||
|
*/
|
||||||
|
public mounted(): void {
|
||||||
|
this.now = new Date();
|
||||||
|
this.displayedYear = this.now.getUTCFullYear();
|
||||||
|
this.populateMonths(this.displayedYear);
|
||||||
|
this.currentDisplayedMonths = this.displayedMonths[this.displayedYear];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates selected period label.
|
||||||
|
*/
|
||||||
|
public updatePeriod(): void {
|
||||||
|
if (!this.firstSelectedMonth) {
|
||||||
|
this.period = '';
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.period = this.secondSelectedMonth ?
|
||||||
|
`${this.firstSelectedMonth.name}, ${this.firstSelectedMonth.year} - ${this.secondSelectedMonth.name}, ${this.secondSelectedMonth.year}`
|
||||||
|
: `${monthNames[this.firstSelectedMonth.index]}, ${this.firstSelectedMonth.year}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects period between node start and now.
|
||||||
|
*/
|
||||||
|
public selectAllTime(): void {
|
||||||
|
const nodeStartedAt = this.$store.state.node.info.startedAt;
|
||||||
|
|
||||||
|
this.firstSelectedMonth = new MonthButton(nodeStartedAt.getUTCFullYear(), nodeStartedAt.getUTCMonth());
|
||||||
|
this.secondSelectedMonth = new MonthButton(this.now.getUTCFullYear(), this.now.getUTCMonth());
|
||||||
|
this.updateMonthsSelection(true);
|
||||||
|
this.updatePeriod();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates first and second selected month on click.
|
||||||
|
*/
|
||||||
|
public checkMonth(month: MonthButton): void {
|
||||||
|
if (this.firstSelectedMonth && this.secondSelectedMonth) {
|
||||||
|
this.updateMonthsSelection(false);
|
||||||
|
this.firstSelectedMonth = this.secondSelectedMonth = null;
|
||||||
|
|
||||||
|
if (month.active) {
|
||||||
|
this.firstSelectedMonth = month;
|
||||||
|
month.selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updatePeriod();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!month.active) return;
|
||||||
|
|
||||||
|
if (!this.firstSelectedMonth) {
|
||||||
|
this.firstSelectedMonth = month;
|
||||||
|
month.selected = true;
|
||||||
|
this.updatePeriod();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.firstSelectedMonth === month) {
|
||||||
|
this.firstSelectedMonth = null;
|
||||||
|
month.selected = false;
|
||||||
|
this.updatePeriod();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.secondSelectedMonth = month;
|
||||||
|
if ((this.secondSelectedMonth && this.firstSelectedMonth) && new Date(this.secondSelectedMonth.year, this.secondSelectedMonth.index) < new Date(this.firstSelectedMonth.year, this.firstSelectedMonth.index)) {
|
||||||
|
[this.secondSelectedMonth, this.firstSelectedMonth] = [this.firstSelectedMonth, this.secondSelectedMonth];
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updatePeriod();
|
||||||
|
this.updateMonthsSelection(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increments year and updates current months set.
|
||||||
|
*/
|
||||||
|
public incrementYear(): void {
|
||||||
|
if (this.displayedYear === this.now.getUTCFullYear()) return;
|
||||||
|
|
||||||
|
this.displayedYear += 1;
|
||||||
|
this.populateMonths(this.displayedYear);
|
||||||
|
this.currentDisplayedMonths = this.displayedMonths[this.displayedYear];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement year and updates current months set.
|
||||||
|
*/
|
||||||
|
public decrementYear(): void {
|
||||||
|
if (this.displayedYear === this.$store.state.node.info.startedAt.getUTCFullYear()) return;
|
||||||
|
|
||||||
|
this.displayedYear -= 1;
|
||||||
|
this.populateMonths(this.displayedYear);
|
||||||
|
this.currentDisplayedMonths = this.displayedMonths[this.displayedYear];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks all months between first and second selected as selected/unselected.
|
||||||
|
*/
|
||||||
|
private updateMonthsSelection(value: boolean): void {
|
||||||
|
if (!this.secondSelectedMonth || !this.firstSelectedMonth) return;
|
||||||
|
|
||||||
|
for (let i = this.firstSelectedMonth.year; i <= this.secondSelectedMonth.year; i++) {
|
||||||
|
if (!this.displayedMonths[i]) {
|
||||||
|
this.populateMonths(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.displayedMonths[i].forEach(month => {
|
||||||
|
const date = new Date(month.year, month.index);
|
||||||
|
|
||||||
|
if (
|
||||||
|
(this.secondSelectedMonth && this.firstSelectedMonth)
|
||||||
|
&& new Date(this.firstSelectedMonth.year, this.firstSelectedMonth.index) <= date
|
||||||
|
&& date <= new Date(this.secondSelectedMonth.year, this.secondSelectedMonth.index)
|
||||||
|
) {
|
||||||
|
month.selected = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets months set in displayedMonths with year as key.
|
||||||
|
*/
|
||||||
|
private populateMonths(year: number): void {
|
||||||
|
if (this.displayedMonths[year]) {
|
||||||
|
this.currentDisplayedMonths = this.displayedMonths[year];
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const months: MonthButton[] = [];
|
||||||
|
const isCurrentYear = year === this.now.getUTCFullYear();
|
||||||
|
const nowMonth = this.now.getUTCMonth();
|
||||||
|
const nodeStartedAt = this.$store.state.node.info.startedAt;
|
||||||
|
|
||||||
|
for (let i = 0; i < 12; i++) {
|
||||||
|
const notBeforeNodeStart =
|
||||||
|
(nodeStartedAt.getUTCFullYear() === year && nodeStartedAt.getUTCMonth() <= i)
|
||||||
|
|| nodeStartedAt.getUTCFullYear() < year;
|
||||||
|
const inFuture = isCurrentYear && i > nowMonth;
|
||||||
|
|
||||||
|
const isMonthActive = notBeforeNodeStart && !inFuture;
|
||||||
|
months.push(new MonthButton(year, i, isMonthActive, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.displayedMonths[year] = months;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -98,6 +261,7 @@ export default class PayoutPeriodCalendar extends Vue {
|
|||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
font-family: 'font_regular', sans-serif;
|
font-family: 'font_regular', sans-serif;
|
||||||
|
cursor: default;
|
||||||
|
|
||||||
&__header {
|
&__header {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
Loading…
Reference in New Issue
Block a user