mirror of
https://github.com/hashicorp/vault.git
synced 2026-05-05 12:26:34 +02:00
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:
parent
0db8108592
commit
e801db629e
@ -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]) {
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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%);
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
29
ui/app/templates/vault/cluster/clients/error.hbs
Normal file
29
ui/app/templates/vault/cluster/clients/error.hbs
Normal 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}}
|
||||
Loading…
x
Reference in New Issue
Block a user