web/satellite: dates to utc; limits bug fix;

Change-Id: I00981f62f8540e5bd8688cf4d38f75c9dfd8b820
This commit is contained in:
NikolaiYurchenko 2020-01-02 16:17:57 +02:00 committed by Nikolay Yurchenko
parent c740b82e66
commit 6a4e4e030f
15 changed files with 84 additions and 92 deletions

View File

@ -7,7 +7,7 @@
<h1 class="account-balance-area__title-area__title">Account Balance</h1>
<VInfo
class="account-balance-area__title-area__info-button"
bold-text="Prepaid STORJ token amount and any additional credits, minus current usage">
bold-text="Prepaid STORJ token amount and any additional credits.">
<svg class="account-balance-area__title-area__info-button__image" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect class="account-balance-svg-rect" x="0.5" y="0.5" width="19" height="19" rx="9.5" stroke="#AFB7C1"/>
<path class="account-balance-svg-path" d="M7 7.25177C7.00959 6.23527 7.28777 5.44177 7.83453 4.87129C8.38129 4.29043 9.1199 4 10.0504 4C10.952 4 11.6667 4.22819 12.1942 4.68458C12.7314 5.14097 13 5.79444 13 6.64498C13 7.03913 12.9376 7.38661 12.8129 7.68741C12.6882 7.98821 12.5396 8.24234 12.3669 8.44979C12.1942 8.65724 11.9592 8.90099 11.6619 9.18105C11.2686 9.54408 10.9712 9.876 10.7698 10.1768C10.5779 10.4672 10.482 10.8303 10.482 11.2659H9.04317C9.04317 10.851 9.10072 10.488 9.21583 10.1768C9.33094 9.86563 9.46523 9.6115 9.61871 9.41443C9.78177 9.20698 10.0024 8.96841 10.2806 8.69873C10.6067 8.37718 10.8465 8.09712 11 7.85856C11.1535 7.61999 11.2302 7.31919 11.2302 6.95615C11.2302 6.55163 11.1103 6.25082 10.8705 6.05375C10.6403 5.8463 10.3141 5.74257 9.89209 5.74257C9.45084 5.74257 9.10552 5.87223 8.85611 6.13154C8.60671 6.38048 8.47242 6.75389 8.45324 7.25177H7ZM9.73381 12.7595C10.0216 12.7595 10.2566 12.8633 10.4388 13.0707C10.6307 13.2782 10.7266 13.5427 10.7266 13.8642C10.7266 14.1961 10.6307 14.471 10.4388 14.6888C10.2566 14.8963 10.0216 15 9.73381 15C9.45564 15 9.22062 14.8911 9.02878 14.6733C8.84652 14.4554 8.7554 14.1858 8.7554 13.8642C8.7554 13.5427 8.84652 13.2782 9.02878 13.0707C9.22062 12.8633 9.45564 12.7595 9.73381 12.7595Z" fill="#354049"/>

View File

@ -66,7 +66,6 @@ export default class AccountDropdown extends Vue {
this.$store.dispatch(NOTIFICATION_ACTIONS.CLEAR);
this.$store.dispatch(BUCKET_ACTIONS.CLEAR);
LocalData.removeSelectedProjectId();
LocalData.removeUserId();
}
}

View File

@ -44,6 +44,7 @@ export default class ProjectSelectionArea extends Vue {
public async toggleSelection(): Promise<void> {
try {
await this.$store.dispatch(PROJECTS_ACTIONS.FETCH);
await this.$store.dispatch(PROJECTS_ACTIONS.GET_LIMITS, this.$store.getters.selectedProject.id);
} catch (error) {
await this.$notify.error(error.message);
}

View File

@ -31,7 +31,6 @@ import {
APP_STATE_ACTIONS,
PM_ACTIONS,
} from '@/utils/constants/actionNames';
import { LocalData } from '@/utils/localData';
@Component({
components: {
@ -43,7 +42,6 @@ export default class ProjectSelectionDropdown extends Vue {
public async onProjectSelected(projectID: string): Promise<void> {
this.$store.dispatch(PROJECTS_ACTIONS.SELECT, projectID);
LocalData.setSelectedProjectId(this.$store.getters.selectedProject.id);
this.$store.dispatch(APP_STATE_ACTIONS.TOGGLE_PROJECTS);
this.$store.dispatch(PM_ACTIONS.SET_SEARCH_QUERY, '');
@ -70,6 +68,12 @@ export default class ProjectSelectionDropdown extends Vue {
} catch (error) {
await this.$notify.error('Unable to fetch buckets: ' + error.message);
}
try {
await this.$store.dispatch(PROJECTS_ACTIONS.GET_LIMITS, this.$store.getters.selectedProject.id);
} catch (error) {
await this.$notify.error(`Unable to fetch project limits. ${error.message}`);
}
}
public get projects(): Project[] {

View File

@ -81,7 +81,6 @@ import { PROJECTS_ACTIONS } from '@/store/modules/projects';
import { UpdateProjectModel } from '@/types/projects';
import { APP_STATE_ACTIONS } from '@/utils/constants/actionNames';
import { SegmentEvent } from '@/utils/constants/analyticsEventNames';
import { LocalData } from '@/utils/localData';
@Component({
components: {
@ -100,6 +99,7 @@ export default class ProjectDetailsArea extends Vue {
public async mounted(): Promise<void> {
try {
await this.$store.dispatch(PROJECTS_ACTIONS.FETCH);
await this.$store.dispatch(PROJECTS_ACTIONS.GET_LIMITS, this.$store.getters.selectedProject.id);
this.$segment.track(SegmentEvent.PROJECT_VIEWED, {
project_id: this.$store.getters.selectedProject.id,
});
@ -136,7 +136,6 @@ export default class ProjectDetailsArea extends Vue {
PROJECTS_ACTIONS.UPDATE,
new UpdateProjectModel(this.$store.getters.selectedProject.id, this.newDescription),
);
LocalData.setSelectedProjectId(this.$store.getters.selectedProject.id);
} catch (error) {
await this.$notify.error(`Unable to update project description. ${error.message}`);

View File

@ -28,10 +28,6 @@ import { Dimensions, Size } from '@/utils/bytesSize';
@Component
export default class ProjectLimitsArea extends Vue {
public async mounted() {
await this.$store.dispatch(PROJECTS_ACTIONS.GET_LIMITS, this.$store.getters.selectedProject.id);
}
public get bandwidthUsed(): string {
const bandwidthUsed = new Size(this.$store.getters.selectedProject.limits.bandwidthUsed);

View File

@ -42,7 +42,11 @@
</div>
</div>
<div class="usage-report-container__main-area__footer">
<p class="usage-report-container__main-area__footer__rollup-info">Roll Up Period <b class="usage-report-container__main-area__footer__rollup-info__bold-text">{{startDate}}</b> to <b class="usage-report-container__main-area__footer__rollup-info__bold-text">{{endDate}}</b></p>
<p class="usage-report-container__main-area__footer__rollup-info">
Roll Up Period
<b class="usage-report-container__main-area__footer__rollup-info__bold-text">{{startDate}}</b> to
<b class="usage-report-container__main-area__footer__rollup-info__bold-text">{{endDate}}</b> (UTC +0)
</p>
<div class="usage-report-container__main-area__footer__report-area">
<p class="usage-report-container__main-area__footer__report-area__download-text">Download Advanced Report</p>
<DownloadReportIcon
@ -220,21 +224,12 @@ export default class UsageReport extends Vue {
}
public async getDates(datesArray: Date[]): Promise<void> {
const now = new Date();
const firstDate = new Date(datesArray[0]);
const secondDate = new Date(datesArray[1]);
const isInverted = firstDate > secondDate;
const startDate = isInverted ? secondDate : firstDate;
let endDate = isInverted ? firstDate : secondDate;
endDate = new Date(Date.UTC(endDate.getUTCFullYear(), endDate.getUTCMonth(), endDate.getUTCDate(), 23, 59, 59));
if (now.getUTCFullYear() === endDate.getUTCFullYear() &&
now.getUTCMonth() === endDate.getUTCMonth() &&
now.getUTCDate() === endDate.getUTCDate()) {
endDate = now;
}
const endDate = isInverted ? firstDate : secondDate;
const dateRange: DateRange = new DateRange(startDate, endDate);

View File

@ -114,17 +114,11 @@ export function makeProjectsModule(api: ProjectsApi): StoreModule<ProjectsState>
},
},
actions: {
[FETCH]: async function ({commit, state}: any): Promise<Project[]> {
[FETCH]: async function ({commit}: any): Promise<Project[]> {
const projects = await api.get();
commit(SET_PROJECTS, projects);
if (state.selectedProject.id) {
const limits = await api.getLimits(state.selectedProject.id);
commit(SET_LIMITS, limits);
}
return projects;
},
[CREATE]: async function ({commit}: any, createProjectModel: CreateProjectModel): Promise<Project> {
@ -134,12 +128,8 @@ export function makeProjectsModule(api: ProjectsApi): StoreModule<ProjectsState>
return project;
},
[SELECT]: async function ({commit}: any, projectID: string): Promise<void> {
[SELECT]: function ({commit}: any, projectID: string): void {
commit(SELECT_PROJECT, projectID);
const limits = await api.getLimits(projectID);
commit(SET_LIMITS, limits);
},
[UPDATE]: async function ({commit}: any, updateProjectModel: UpdateProjectModel): Promise<void> {
await api.update(updateProjectModel.id, updateProjectModel.description);

View File

@ -44,11 +44,20 @@ export function makeUsageModule(api: UsageApi): StoreModule<UsageState> {
},
actions: {
[PROJECT_USAGE_ACTIONS.FETCH]: async function({commit, rootGetters}: any, dateRange: DateRange): Promise<ProjectUsage> {
const projectID = rootGetters.selectedProject.id;
const now = new Date();
let beforeUTC = new Date(Date.UTC(dateRange.endDate.getFullYear(), dateRange.endDate.getMonth(), dateRange.endDate.getDate(), 23, 59));
const usage: ProjectUsage = await api.get(projectID, dateRange.startDate, dateRange.endDate);
if (now.getUTCFullYear() === dateRange.endDate.getUTCFullYear() &&
now.getUTCMonth() === dateRange.endDate.getUTCMonth() &&
now.getUTCDate() <= dateRange.endDate.getUTCDate()) {
beforeUTC = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getMinutes()));
}
commit(PROJECT_USAGE_MUTATIONS.SET_DATE, dateRange);
const sinceUTC = new Date(Date.UTC(dateRange.startDate.getFullYear(), dateRange.startDate.getMonth(), dateRange.startDate.getDate()));
const usage: ProjectUsage = await api.get(rootGetters.selectedProject.id, sinceUTC, beforeUTC);
commit(PROJECT_USAGE_MUTATIONS.SET_DATE, new DateRange(sinceUTC, beforeUTC));
commit(PROJECT_USAGE_MUTATIONS.SET_PROJECT_USAGE, usage);
return usage;
@ -56,13 +65,13 @@ export function makeUsageModule(api: UsageApi): StoreModule<UsageState> {
[PROJECT_USAGE_ACTIONS.FETCH_CURRENT_ROLLUP]: async function({commit, rootGetters}: any): Promise<ProjectUsage> {
const projectID: string = rootGetters.selectedProject.id;
const endDate = new Date();
const startDate = new Date(Date.UTC(endDate.getUTCFullYear(), endDate.getUTCMonth(), 1));
const dateRange = new DateRange(startDate, endDate);
const now = new Date();
const endUTC = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getMinutes()));
const startUTC = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1));
const usage: ProjectUsage = await api.get(projectID, dateRange.startDate, dateRange.endDate);
const usage: ProjectUsage = await api.get(projectID, startUTC, endUTC);
commit(PROJECT_USAGE_MUTATIONS.SET_DATE, dateRange);
commit(PROJECT_USAGE_MUTATIONS.SET_DATE, new DateRange(startUTC, endUTC));
commit(PROJECT_USAGE_MUTATIONS.SET_PROJECT_USAGE, usage);
return usage;
@ -70,14 +79,13 @@ export function makeUsageModule(api: UsageApi): StoreModule<UsageState> {
[PROJECT_USAGE_ACTIONS.FETCH_PREVIOUS_ROLLUP]: async function({commit, rootGetters}: any): Promise<ProjectUsage> {
const projectID = rootGetters.selectedProject.id;
const date = new Date();
const startDate = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() - 1, 1));
const endDate = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 0, 23, 59, 59));
const dateRange = new DateRange(startDate, endDate);
const now = new Date();
const startUTC = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() - 1, 1));
const endUTC = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 0, 23, 59, 59));
const usage: ProjectUsage = await api.get(projectID, dateRange.startDate, dateRange.endDate);
const usage: ProjectUsage = await api.get(projectID, startUTC, endUTC);
commit(PROJECT_USAGE_MUTATIONS.SET_DATE, dateRange);
commit(PROJECT_USAGE_MUTATIONS.SET_DATE, new DateRange(startUTC, endUTC));
commit(PROJECT_USAGE_MUTATIONS.SET_PROJECT_USAGE, usage);
return usage;

View File

@ -106,11 +106,11 @@ export class BillingHistoryItem {
) {}
public get quantity(): Amount {
if (this.type === BillingHistoryItemType.Invoice) {
return new Amount('USD $', this.amountDollars(this.amount));
if (this.type === BillingHistoryItemType.Transaction) {
return new Amount('USD $', this.amountDollars(this.amount), this.amountDollars(this.received));
}
return new Amount('USD $', this.amountDollars(this.amount), this.amountDollars(this.received));
return new Amount('USD $', this.amountDollars(this.amount));
}
public get formattedStatus(): string {

View File

@ -87,6 +87,7 @@ export enum DisplayedType {
export class DateGenerator {
private current: DateStamp;
private isSundayFirst: boolean;
private now = new Date();
public populateDays(current: DateStamp, isSundayFirst: boolean): DayItem[] {
this.current = current;
@ -114,17 +115,16 @@ export class DateGenerator {
private populateSelectedMonthDays(days: DayItem[]): void {
const daysInSelectedMonth = new Date(this.current.year, this.current.month + 1, 0).getDate();
const now = new Date();
const daysInCurrentMonth = now.getMonth();
const currentMonth = this.now.getMonth();
for (let i = 1; i <= daysInSelectedMonth; i++) {
const moment = new Date(this.current.year, this.current.month, this.current.day);
const moment = new Date(this.current.year, this.current.month, this.current.day, 23, 59);
moment.setDate(i);
days.push(
new DayItem(
i,
this.current.month !== daysInCurrentMonth || (this.current.month === daysInCurrentMonth && i <= now.getDate()),
this.current.month !== currentMonth || (this.current.month === currentMonth && i <= this.now.getDate()),
false,
false,
moment,
@ -145,7 +145,7 @@ export class DateGenerator {
const daysInPreviousMonth = new Date(previousMonth.getFullYear(), previousMonth.getMonth() + 1, 0).getDate();
for (let i = 0; i < firstDay - (this.isSundayFirst ? 0 : 1); i++) {
const moment = new Date(this.current.year, this.current.month, this.current.day);
const moment = new Date(this.current.year, this.current.month, this.current.day, 23, 59);
moment.setDate(1);
moment.setMonth(moment.getMonth() - 1);
moment.setDate(new Date(moment.getFullYear(), moment.getMonth() + 1, 0).getDate() - i);
@ -167,7 +167,7 @@ export class DateGenerator {
const passiveDaysAtFinal = 42 - days.length;
for (let i = 1; i <= passiveDaysAtFinal; i++) {
const moment = new Date(this.current.year, this.current.month, this.current.day);
const moment = new Date(this.current.year, this.current.month, this.current.day, 23, 59);
moment.setMonth(moment.getMonth() + 1);
moment.setDate(i);
@ -185,13 +185,12 @@ export class DateGenerator {
}
private markToday(days: DayItem[]): void {
const now = new Date();
const daysCount = days.length;
for (let i = 0; i < daysCount; i++) {
const day: DayItem = days[i];
if (day.equals(now)) {
if (day.equals(this.now)) {
day.today = true;
break;
}
@ -211,9 +210,9 @@ export class DateFormat {
* @returns formatted date string
*/
public static getUSDate(date: Date, separator: string): string {
const month = date.getMonth() + 1;
const day = date.getDate();
const year = date.getFullYear();
const month = date.getUTCMonth() + 1;
const day = date.getUTCDate();
const year = date.getUTCFullYear();
return [month, day, year].join(separator);
}

View File

@ -50,7 +50,6 @@ import {
PM_ACTIONS,
} from '@/utils/constants/actionNames';
import { AppState } from '@/utils/constants/appStateEnum';
import { LocalData } from '@/utils/localData';
const {
SETUP_ACCOUNT,
@ -124,14 +123,7 @@ export default class DashboardArea extends Vue {
return;
}
const selectedProjectId: string | null = LocalData.getSelectedProjectId();
if (selectedProjectId) {
await this.$store.dispatch(PROJECTS_ACTIONS.SELECT, selectedProjectId);
} else {
await this.$store.dispatch(PROJECTS_ACTIONS.SELECT, projects[0].id);
LocalData.setSelectedProjectId(this.$store.getters.selectedProject.id);
}
await this.$store.dispatch(PROJECTS_ACTIONS.SELECT, projects[0].id);
await this.$store.dispatch(PM_ACTIONS.SET_SEARCH_QUERY, '');
try {
@ -140,6 +132,12 @@ export default class DashboardArea extends Vue {
await this.$notify.error(`Unable to fetch project members. ${error.message}`);
}
try {
await this.$store.dispatch(PROJECTS_ACTIONS.GET_LIMITS, this.$store.getters.selectedProject.id);
} catch (error) {
await this.$notify.error(`Unable to fetch project limits. ${error.message}`);
}
try {
await this.$store.dispatch(API_KEYS_ACTIONS.FETCH, 1);
} catch (error) {

View File

@ -107,6 +107,8 @@ describe('VDatePicker.vue', () => {
it('triggers correct functionality on year selection', function () {
const wrapper = mount(VDatePicker);
const now = new Date();
const nowYear = now.getFullYear();
wrapper.vm.showCheck();
wrapper.vm.setYear(2019);
@ -117,15 +119,13 @@ describe('VDatePicker.vue', () => {
wrapper.find('.year-selection').trigger('click');
expect(wrapper.findAll('.year').length).toBe(100);
const currentYear = (new Date()).getFullYear()
expect(wrapper.findAll('.year').at(0).text()).toBe(currentYear.toString());
expect(wrapper.findAll('.year').at(0).text()).toBe(nowYear.toString());
wrapper.find('.year-selection').trigger('click');
wrapper.findAll('.year').at(1).trigger('click');
expect(wrapper.vm.selectedDateState.year).toBe(currentYear-1);
expect(wrapper.find('.year-selection').text()).toBe((currentYear-1).toString());
expect(wrapper.vm.selectedDateState.year).toBe(nowYear - 1);
expect(wrapper.find('.year-selection').text()).toBe((nowYear - 1).toString());
});
it('triggers correct functionality on month incrementation', function () {

View File

@ -21,12 +21,10 @@ const selectedProject = new Project('', '', '', '');
selectedProject.id = '1';
projectsModule.state.selectedProject = selectedProject;
const testDate1 = new Date();
testDate1.setDate(1);
const testDate2 = new Date();
testDate2.setDate(2);
const testUsage = new ProjectUsage(2, 3, 4, testDate1, testDate2);
const now = new Date();
const testDate1 = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
const testDate2 = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), 23, 59));
const testUsage = new ProjectUsage(2, 3, 4, testDate1, testDate2);
Vue.use(Vuex);
@ -86,7 +84,8 @@ describe('actions', () => {
jest.spyOn(projectUsageApi, 'get').mockReturnValue(
Promise.resolve(testUsage),
);
const dateRange: DateRange = new DateRange(testDate1, testDate2);
const startUTC = new Date(Date.UTC(1999, 1, 1, 20, 15));
const dateRange: DateRange = new DateRange(startUTC, testDate1);
await store.dispatch(PROJECT_USAGE_ACTIONS.FETCH, dateRange);
@ -97,8 +96,10 @@ describe('actions', () => {
expect(state.projectUsage.storage.label).toBe('KB');
expect(state.projectUsage.egress.label).toBe('KB');
expect(state.projectUsage.objectCount).toBe(4);
expect(state.startDate.toDateString()).toBe(testDate1.toDateString());
expect(state.endDate.toDateString()).toBe(testDate2.toDateString());
expect(state.startDate.toDateString()).toBe(startUTC.toDateString());
expect(state.endDate.getUTCFullYear()).toBe(testDate1.getUTCFullYear());
expect(state.endDate.getUTCMonth()).toBe(testDate1.getUTCMonth());
expect(state.endDate.getUTCDate()).toBe(testDate1.getUTCDate());
});
it('success fetch current project usage', async () => {
@ -106,8 +107,7 @@ describe('actions', () => {
Promise.resolve(testUsage),
);
const firstDate = new Date();
firstDate.setDate(1);
const firstDate = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1));
await store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_CURRENT_ROLLUP);
@ -119,7 +119,12 @@ describe('actions', () => {
expect(state.projectUsage.egress.label).toBe('KB');
expect(state.projectUsage.objectCount).toBe(4);
expect(state.startDate.toDateString()).toBe(firstDate.toDateString());
expect(state.endDate.toDateString()).toBe(now.toDateString());
expect(state.endDate.getUTCFullYear()).toBe(now.getUTCFullYear());
expect(state.endDate.getUTCMonth()).toBe(now.getUTCMonth());
expect(state.endDate.getUTCDate()).toBe(now.getUTCDate());
expect(state.endDate.getUTCHours()).toBe(now.getUTCHours());
expect(state.endDate.getUTCMinutes()).toBe(now.getUTCMinutes());
});
it('success fetch previous project usage', async () => {
@ -127,10 +132,8 @@ describe('actions', () => {
Promise.resolve(testUsage),
);
const date = new Date();
const firstDate = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth() - 1, 1));
const secondDate = new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), 0, 23, 59, 59));
const firstDate = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() - 1, 1));
const secondDate = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 0, 23, 59, 59));
await store.dispatch(PROJECT_USAGE_ACTIONS.FETCH_PREVIOUS_ROLLUP);

View File

@ -80,8 +80,8 @@ describe('datepicker', () => {
});
it('DateFormat formats date to string correctly', () => {
const testDate1 = new Date(2019, 10, 7);
const testDate2 = new Date(2019, 1, 1);
const testDate1 = new Date(Date.UTC(2019, 10, 7));
const testDate2 = new Date(Date.UTC(2019, 1, 1));
const expectedResult1 = '11/7/2019';
const expectedResult2 = '2-1-2019';