Ui/ Clients error handling (#14066)

* add error message to date selection

* adds dropdown to no billing error message

* add error template

* disabled months/years not allowed

* clean up ternary statements

* remove queues
This commit is contained in:
claire bontempo 2022-02-16 11:03:34 -08:00 committed by GitHub
parent 0db8108592
commit e801db629e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 127 additions and 64 deletions

View File

@ -32,6 +32,20 @@ export default class Current extends Component {
return this.totalUsageCounts.clients !== 0 && !!this.totalClientsData && !this.selectedAuthMethod;
}
get filteredActivity() {
const namespace = this.selectedNamespace;
const auth = this.selectedAuthMethod;
if (!namespace && !auth) {
return this.getActivityResponse;
}
if (!auth) {
return this.byNamespaceCurrent.find((ns) => ns.label === namespace);
}
return this.byNamespaceCurrent
.find((ns) => ns.label === namespace)
.mounts?.find((mount) => mount.label === auth);
}
get countsIncludeOlderData() {
let firstUpgrade = this.args.model.versionHistory[0];
if (!firstUpgrade) {
@ -60,21 +74,6 @@ export default class Current extends Component {
return this.args.model.monthly?.responseTimestamp;
}
// HELPERS
get filteredActivity() {
const namespace = this.selectedNamespace;
const auth = this.selectedAuthMethod;
if (!namespace && !auth) {
return this.getActivityResponse;
}
if (!auth) {
return this.byNamespaceCurrent.find((ns) => ns.label === namespace);
}
return this.byNamespaceCurrent
.find((ns) => ns.label === namespace)
.mounts?.find((mount) => mount.label === auth);
}
// ACTIONS
@action
selectNamespace([value]) {

View File

@ -38,10 +38,15 @@ export default class History extends Component {
years = Array.from({ length: 5 }, (item, i) => {
return new Date().getFullYear() - i;
});
currentDate = new Date();
currentYear = this.currentDate.getFullYear(); // integer of year
currentMonth = this.currentDate.getMonth(); // index of month
@tracked isEditStartMonthOpen = false;
@tracked startMonth = null;
@tracked startYear = null;
@tracked allowedMonthMax = 12;
@tracked disabledYear = null;
// FOR HISTORY COMPONENT //
@ -66,6 +71,7 @@ export default class History extends Component {
@tracked noActivityDate = '';
@tracked responseRangeDiffMessage = null;
@tracked isLoadingQuery = false;
@tracked licenseStartIsCurrentMonth = this.args.model.activity?.isLicenseDateError || false;
@tracked selectedAuthMethod = null;
@tracked authMethodOptions = [];
@ -117,6 +123,20 @@ export default class History extends Component {
return `${this.arrayOfMonths[month]} ${year}`;
}
get filteredActivity() {
const namespace = this.selectedNamespace;
const auth = this.selectedAuthMethod;
if (!namespace && !auth) {
return this.getActivityResponse;
}
if (!auth) {
return this.getActivityResponse.byNamespace.find((ns) => ns.label === namespace);
}
return this.getActivityResponse.byNamespace
.find((ns) => ns.label === namespace)
.mounts?.find((mount) => mount.label === auth);
}
get isDateRange() {
return !isSameMonth(
new Date(this.getActivityResponse.startTime),
@ -158,6 +178,7 @@ export default class History extends Component {
@action
async handleClientActivityQuery(month, year, dateType) {
this.isEditStartMonthOpen = false;
if (dateType === 'cancel') {
return;
}
@ -196,6 +217,7 @@ export default class History extends Component {
this.storage().setItem(INPUTTED_START_DATE, this.startTimeFromResponse);
}
this.queriedActivityResponse = response;
this.licenseStartIsCurrentMonth = response.isLicenseDateError;
// compare if the response startTime comes after the requested startTime. If true throw a warning.
// only display if they selected a startTime
if (
@ -210,7 +232,6 @@ export default class History extends Component {
this.responseRangeDiffMessage = null;
}
} catch (e) {
// TODO CMB surface API errors when user selects start date after end date
return e;
} finally {
this.isLoadingQuery = false;
@ -246,27 +267,18 @@ export default class History extends Component {
// FOR START DATE MODAL
@action
selectStartMonth(month) {
selectStartMonth(month, event) {
this.startMonth = month;
// disables months if in the future
this.disabledYear = this.months.indexOf(month) >= this.currentMonth ? this.currentYear : null;
event.close();
}
@action
selectStartYear(year) {
selectStartYear(year, event) {
this.startYear = year;
}
get filteredActivity() {
const namespace = this.selectedNamespace;
const auth = this.selectedAuthMethod;
if (!namespace && !auth) {
return this.getActivityResponse;
}
if (!auth) {
return this.getActivityResponse.byNamespace.find((ns) => ns.label === namespace);
}
return this.getActivityResponse.byNamespace
.find((ns) => ns.label === namespace)
.mounts?.find((mount) => mount.label === auth);
this.allowedMonthMax = year === this.currentYear ? this.currentMonth : 12;
event.close();
}
storage() {

View File

@ -12,9 +12,15 @@ import { tracked } from '@glimmer/tracking';
* ```
* @param {function} handleDateSelection - is the action from the parent that the date picker triggers
* @param {string} [name] - optional argument passed from date dropdown to parent function
* @param {string} [submitText] - optional argument to change submit button text
*/
export default class DateDropdown extends Component {
currentDate = new Date();
currentYear = this.currentDate.getFullYear(); // integer of year
currentMonth = this.currentDate.getMonth(); // index of month
@tracked allowedMonthMax = 12;
@tracked disabledYear = null;
@tracked startMonth = null;
@tracked startYear = null;
@ -26,13 +32,18 @@ export default class DateDropdown extends Component {
});
@action
selectStartMonth(month) {
selectStartMonth(month, event) {
this.startMonth = month;
// disables months if in the future
this.disabledYear = this.months.indexOf(month) >= this.currentMonth ? this.currentYear : null;
event.close();
}
@action
selectStartYear(year) {
selectStartYear(year, event) {
this.startYear = year;
this.allowedMonthMax = year === this.currentYear ? this.currentMonth : 12;
event.close();
}
@action

View File

@ -8,10 +8,13 @@ export default class HistoryRoute extends Route {
try {
// on init ONLY make network request if we have a start time from the license
// otherwise user needs to manually input
// TODO CMB what to return here?
return start_time ? await this.store.queryRecord('clients/activity', { start_time }) : {};
} catch (e) {
return e;
// returns 400 when license start date is in the current month
if (e.httpStatus === 400) {
return { isLicenseDateError: true };
}
throw e;
}
}

View File

@ -54,7 +54,7 @@ $button-box-shadow-standard: 0 3px 1px 0 rgba($black, 0.12);
background-color: $color;
color: $color-invert;
&:hover,
&:hover:not([disabled]),
&.is-hovered {
background-color: darken($color, 5%);
border-color: darken($color, 5%);

View File

@ -14,13 +14,22 @@
Edit
</button>
{{else}}
<DateDropdown @handleDateSelection={{this.handleClientActivityQuery}} @name={{"startTime"}} />
<DateDropdown @handleDateSelection={{this.handleClientActivityQuery}} @name={{"startTime"}} @submitText="Save" />
{{/if}}
</div>
<p class="is-8 has-text-grey has-bottom-margin-xl">
{{this.versionText.description}}
</p>
{{#if (eq @model.config.queriesAvailable false)}}
{{#if this.licenseStartIsCurrentMonth}}
<EmptyState
@title="No data for this billing period"
@subTitle="Your billing period has just begun, so there is no data yet. Data will be available here on the first of next month."
@message="To view data from a previous billing period, you can enter your previous billing start date."
@bottomBorder={{true}}
>
<DateDropdown @handleDateSelection={{this.handleClientActivityQuery}} @name={{"startTime"}} @submitText="View" />
</EmptyState>
{{else if (eq @model.config.queriesAvailable false)}}
{{#if (eq @model.config.enabled "On")}}
<EmptyState
@title={{concat "No monthly history " (if this.noActivityDate "from ") this.noActivityDate}}
@ -138,8 +147,10 @@
<EmptyState @title="No data received" @message="No data exists for that query period. Try searching again." />
{{/if}}
{{/if}}
{{else}}
{{else if (or (not @model.startTimeFromLicense) (not this.startTimeFromResponse))}}
<EmptyState @title={{this.versionText.title}} @message={{this.versionText.message}} />
{{else}}
<EmptyState @title="No data received" @message="No data exists for that query period. Try searching again." />
{{/if}}
{{/if}}
@ -168,11 +179,12 @@
<D.Content @defaultClass="popup-menu-content is-wide">
<nav class="box menu scroll">
<ul class="menu-list">
{{#each this.months as |month|}}
{{#each this.months as |month index|}}
<button
type="button"
class="link"
{{on "click" (queue (fn this.selectStartMonth month) (action D.actions.close))}}
class="button link"
disabled={{if (lt index this.allowedMonthMax) false true}}
{{on "click" (fn this.selectStartMonth month D.actions)}}
>
{{month}}
</button>
@ -196,8 +208,9 @@
{{#each this.years as |year|}}
<button
type="button"
class="link"
{{on "click" (queue (fn this.selectStartYear year) (action D.actions.close))}}
class="button link"
disabled={{if (eq year this.disabledYear) true false}}
{{on "click" (fn this.selectStartYear year D.actions)}}
>
{{year}}
</button>
@ -212,22 +225,12 @@
<button
type="button"
class="button is-primary"
onclick={{queue
(action (mut this.isEditStartMonthOpen) false)
(action "handleClientActivityQuery" this.startMonth this.startYear "startTime")
}}
disabled={{if (and this.startMonth this.startYear) false true}}
disabled={{or (if (and this.startMonth this.startYear) false true)}}
{{on "click" (fn this.handleClientActivityQuery this.startMonth this.startYear "startTime")}}
>
Save
</button>
<button
type="button"
class="button is-secondary"
{{on
"click"
(queue (action (mut this.isEditStartMonthOpen) false) (fn this.handleClientActivityQuery 0 0 "cancel"))
}}
>
<button type="button" class="button is-secondary" {{on "click" (fn this.handleClientActivityQuery 0 0 "cancel")}}>
Cancel
</button>
</footer>

View File

@ -10,11 +10,12 @@
<D.Content @defaultClass="popup-menu-content is-wide">
<nav class="box menu scroll">
<ul class="menu-list">
{{#each this.months as |month|}}
{{#each this.months as |month index|}}
<button
type="button"
class="link"
{{on "click" (queue (fn this.selectStartMonth month) (action D.actions.close))}}
class="button link"
disabled={{if (lt index this.allowedMonthMax) false true}}
{{on "click" (fn this.selectStartMonth month D.actions)}}
>
{{month}}
</button>
@ -36,7 +37,12 @@
<nav class="box menu">
<ul class="menu-list">
{{#each this.years as |year|}}
<button type="button" class="link" {{on "click" (queue (fn this.selectStartYear year) (action D.actions.close))}}>
<button
type="button"
class="button link"
disabled={{if (eq year this.disabledYear) true false}}
{{on "click" (fn this.selectStartYear year D.actions)}}
>
{{year}}
</button>
{{/each}}
@ -50,5 +56,5 @@
disabled={{if (and this.startMonth this.startYear) false true}}
{{on "click" this.saveDateSelection}}
>
Save
{{or @submitText "Submit"}}
</button>

View File

@ -0,0 +1,29 @@
{{#if (eq @model.httpStatus 404)}}
<NotFound @model={{this.model}} />
{{else}}
<EmptyState
@title={{if (eq @model.httpStatus 403) "You are not authorized" "Error"}}
@subTitle={{concat "Error " @model.httpStatus}}
@icon="skip"
>
{{#if (eq @model.httpStatus 403)}}
<p>
You must be granted permissions to view this page. Ask your administrator if you think you should have access to the
<code>{{@model.path}}</code>
endpoint.
</p>
{{else}}
<ul>
{{#if @model.message}}
<li>{{@model.message}}</li>
{{/if}}
<hr />
{{#each @model.errors as |error|}}
<li>
{{error}}
</li>
{{/each}}
</ul>
{{/if}}
</EmptyState>
{{/if}}