mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-01 11:08:10 +00:00
UI/Client counts view if no license (#13964)
* adds date picker if no license start date found * handle permissions denied for license endpoint * handle permissions errors if no license start date * change empty state copy for OSS * fix tests and empty state view * update nav links * remove ternary Co-authored-by: Chelsea Shaw <82459713+hashishaw@users.noreply.github.com> * simplify hbs boolean Co-authored-by: Chelsea Shaw <82459713+hashishaw@users.noreply.github.com> * organize history file * organize current file * rerun tests * fix conditional to show attribution chart * match main Co-authored-by: Chelsea Shaw <82459713+hashishaw@users.noreply.github.com>
This commit is contained in:
@@ -4,32 +4,25 @@ import { formatRFC3339 } from 'date-fns';
|
||||
export default Application.extend({
|
||||
formatTimeParams(query) {
|
||||
let { start_time, end_time } = query;
|
||||
// do not query without start_time. Otherwise returns last year data, which is not reflective of billing data.
|
||||
if (start_time) {
|
||||
// check if it's an array, if it is, it's coming from an action like selecting a new startTime or new EndTime
|
||||
if (Array.isArray(start_time)) {
|
||||
let startYear = Number(start_time[0]);
|
||||
let startMonth = Number(start_time[1]);
|
||||
start_time = formatRFC3339(new Date(startYear, startMonth));
|
||||
// check if it's an array, if it is, it's coming from an action like selecting a new startTime or new EndTime
|
||||
if (Array.isArray(start_time)) {
|
||||
let startYear = Number(start_time[0]);
|
||||
let startMonth = Number(start_time[1]);
|
||||
start_time = formatRFC3339(new Date(startYear, startMonth));
|
||||
}
|
||||
if (end_time) {
|
||||
if (Array.isArray(end_time)) {
|
||||
let endYear = Number(end_time[0]);
|
||||
let endMonth = Number(end_time[1]);
|
||||
end_time = formatRFC3339(new Date(endYear, endMonth));
|
||||
}
|
||||
if (end_time) {
|
||||
if (Array.isArray(end_time)) {
|
||||
let endYear = Number(end_time[0]);
|
||||
let endMonth = Number(end_time[1]);
|
||||
end_time = formatRFC3339(new Date(endYear, endMonth));
|
||||
}
|
||||
|
||||
return { start_time, end_time };
|
||||
} else {
|
||||
return { start_time };
|
||||
}
|
||||
return { start_time, end_time };
|
||||
} else {
|
||||
// did not have a start time, return null through to component.
|
||||
return null;
|
||||
return { start_time };
|
||||
}
|
||||
},
|
||||
|
||||
// ARG TODO current Month tab is hitting this endpoint. Need to amend so only hit on Monthly history (large payload)
|
||||
// query comes in as either: {start_time: '2021-03-17T00:00:00Z'} or
|
||||
// {start_time: Array(2), end_time: Array(2)}
|
||||
// end_time: (2) ['2022', 0]
|
||||
@@ -44,9 +37,6 @@ export default Application.extend({
|
||||
response.id = response.request_id || 'no-data';
|
||||
return response;
|
||||
});
|
||||
} else {
|
||||
// did not have a start time, return null through to component.
|
||||
return null;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -7,18 +7,28 @@ export default class Current extends Component {
|
||||
{ key: 'entity_clients', label: 'entity clients' },
|
||||
{ key: 'non_entity_clients', label: 'non-entity clients' },
|
||||
];
|
||||
@tracked firstUpgradeVersion = this.args.model.versionHistory[0].id || null; // return 1.9.0 or earliest upgrade post 1.9.0
|
||||
@tracked upgradeDate = this.args.model.versionHistory[0].timestampInstalled || null; // returns RFC3339 timestamp
|
||||
|
||||
@tracked selectedNamespace = null;
|
||||
@tracked namespaceArray = this.byNamespaceCurrent.map((namespace) => {
|
||||
return { name: namespace['label'], id: namespace['label'] };
|
||||
});
|
||||
@tracked firstUpgradeVersion = this.args.model.versionHistory[0].id || null; // return 1.9.0 or earliest upgrade post 1.9.0
|
||||
@tracked upgradeDate = this.args.model.versionHistory[0].timestampInstalled || null; // returns RFC3339 timestamp
|
||||
|
||||
// API client count data by namespace for current/partial month
|
||||
// Response client count data by namespace for current/partial month
|
||||
get byNamespaceCurrent() {
|
||||
return this.args.model.monthly?.byNamespace || [];
|
||||
}
|
||||
|
||||
get isGatheringData() {
|
||||
// return true if tracking IS enabled but no data collected yet
|
||||
return this.args.model.config?.enabled === 'On' && this.byNamespaceCurrent.length === 0;
|
||||
}
|
||||
|
||||
get hasAttributionData() {
|
||||
return this.totalUsageCounts.clients !== 0 && this.totalClientsData.length !== 0;
|
||||
}
|
||||
|
||||
get countsIncludeOlderData() {
|
||||
let firstUpgrade = this.args.model.versionHistory[0];
|
||||
if (!firstUpgrade) {
|
||||
|
||||
@@ -3,9 +3,10 @@ import { action } from '@ember/object';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
import { isSameMonth, isAfter } from 'date-fns';
|
||||
|
||||
export default class History extends Component {
|
||||
// TODO CMB alphabetize and delete unused vars (particularly @tracked)
|
||||
@service store;
|
||||
@service version;
|
||||
|
||||
arrayOfMonths = [
|
||||
'January',
|
||||
'February',
|
||||
@@ -26,7 +27,7 @@ export default class History extends Component {
|
||||
{ key: 'non_entity_clients', label: 'non-entity clients' },
|
||||
];
|
||||
|
||||
// needed for startTime modal picker
|
||||
// FOR START DATE EDIT & MODAL //
|
||||
months = Array.from({ length: 12 }, (item, i) => {
|
||||
return new Date(0, i).toLocaleString('en-US', { month: 'long' });
|
||||
});
|
||||
@@ -34,33 +35,43 @@ export default class History extends Component {
|
||||
return new Date().getFullYear() - i;
|
||||
});
|
||||
|
||||
@service store;
|
||||
|
||||
@tracked queriedActivityResponse = null;
|
||||
@tracked barChartSelection = false;
|
||||
@tracked isEditStartMonthOpen = false;
|
||||
@tracked responseRangeDiffMessage = null;
|
||||
@tracked startTimeRequested = null;
|
||||
@tracked startTimeFromResponse = this.args.model.startTimeFromLicense; // ex: ['2021', 3] is April 2021 (0 indexed)
|
||||
@tracked endTimeFromResponse = this.args.model.endTimeFromResponse;
|
||||
@tracked startMonth = null;
|
||||
@tracked startYear = null;
|
||||
|
||||
// FOR HISTORY COMPONENT //
|
||||
|
||||
// RESPONSE
|
||||
@tracked endTimeFromResponse = this.args.model.endTimeFromResponse;
|
||||
@tracked startTimeFromResponse = this.args.model.startTimeFromLicense; // ex: ['2021', 3] is April 2021 (0 indexed)
|
||||
@tracked startTimeRequested = null;
|
||||
@tracked queriedActivityResponse = null;
|
||||
|
||||
// VERSION/UPGRADE INFO
|
||||
@tracked firstUpgradeVersion = this.args.model.versionHistory[0].id || null; // return 1.9.0 or earliest upgrade post 1.9.0
|
||||
@tracked upgradeDate = this.args.model.versionHistory[0].timestampInstalled || null; // returns RFC3339 timestamp
|
||||
|
||||
// SEARCH SELECT
|
||||
@tracked selectedNamespace = null;
|
||||
@tracked noActivityDate = '';
|
||||
@tracked namespaceArray = this.getActivityResponse.byNamespace.map((namespace) => {
|
||||
return { name: namespace['label'], id: namespace['label'] };
|
||||
});
|
||||
@tracked firstUpgradeVersion = this.args.model.versionHistory[0].id || null; // return 1.9.0 or earliest upgrade post 1.9.0
|
||||
@tracked upgradeDate = this.args.model.versionHistory[0].timestampInstalled || null; // returns RFC3339 timestamp
|
||||
|
||||
// TEMPLATE MESSAGING
|
||||
@tracked noActivityDate = '';
|
||||
@tracked responseRangeDiffMessage = null;
|
||||
|
||||
// on init API response uses license start_date, getter updates when user queries dates
|
||||
get getActivityResponse() {
|
||||
return this.queriedActivityResponse || this.args.model.activity;
|
||||
}
|
||||
|
||||
get hasAttributionData() {
|
||||
return this.totalUsageCounts.clients !== 0 && this.totalClientsData.length !== 0;
|
||||
}
|
||||
|
||||
get startTimeDisplay() {
|
||||
if (!this.startTimeFromResponse) {
|
||||
// otherwise will return date of new Date(null)
|
||||
return null;
|
||||
}
|
||||
let month = this.startTimeFromResponse[1];
|
||||
@@ -70,7 +81,6 @@ export default class History extends Component {
|
||||
|
||||
get endTimeDisplay() {
|
||||
if (!this.endTimeFromResponse) {
|
||||
// otherwise will return date of new Date(null)
|
||||
return null;
|
||||
}
|
||||
let month = this.endTimeFromResponse[1];
|
||||
@@ -120,7 +130,6 @@ export default class History extends Component {
|
||||
return isAfter(versionDate, startTimeFromResponseAsDateObject) ? versionDate : false;
|
||||
}
|
||||
|
||||
// ACTIONS
|
||||
@action
|
||||
async handleClientActivityQuery(month, year, dateType) {
|
||||
if (dateType === 'cancel') {
|
||||
@@ -134,7 +143,7 @@ export default class History extends Component {
|
||||
// clicked "Edit" Billing start month in Dashboard which opens a modal.
|
||||
if (dateType === 'startTime') {
|
||||
let monthIndex = this.arrayOfMonths.indexOf(month);
|
||||
this.startTimeRequested = [year.toString(), monthIndex]; // ['2021', 0] (e.g. January 2021) // TODO CHANGE TO ARRAY
|
||||
this.startTimeRequested = [year.toString(), monthIndex]; // ['2021', 0] (e.g. January 2021)
|
||||
this.endTimeRequested = null;
|
||||
}
|
||||
// clicked "Custom End Month" from the calendar-widget
|
||||
@@ -173,7 +182,7 @@ export default class History extends Component {
|
||||
}
|
||||
this.queriedActivityResponse = response;
|
||||
} catch (e) {
|
||||
// ARG TODO handle error
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,6 +197,7 @@ export default class History extends Component {
|
||||
this.selectedNamespace = value;
|
||||
}
|
||||
|
||||
// FOR START DATE MODAL
|
||||
@action
|
||||
selectStartMonth(month) {
|
||||
this.startMonth = month;
|
||||
@@ -198,7 +208,7 @@ export default class History extends Component {
|
||||
this.startYear = year;
|
||||
}
|
||||
|
||||
// HELPERS
|
||||
// HELPERS //
|
||||
filterByNamespace(namespace) {
|
||||
return this.getActivityResponse.byNamespace.find((ns) => ns.label === namespace);
|
||||
}
|
||||
|
||||
37
ui/app/components/date-dropdown.js
Normal file
37
ui/app/components/date-dropdown.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import Component from '@glimmer/component';
|
||||
import { action } from '@ember/object';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
|
||||
/**
|
||||
* @module DateDropdown
|
||||
* DateDropdown components are used to display a dropdown of months and years to handle date selection
|
||||
*
|
||||
* @example
|
||||
* ```js
|
||||
* <DateDropdown @handleDateSelection={this.actionFromParent} @name={{"startTime"}}/>
|
||||
* ```
|
||||
* @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
|
||||
*/
|
||||
|
||||
export default class DateDropdown extends Component {
|
||||
@tracked startMonth = null;
|
||||
@tracked startYear = null;
|
||||
|
||||
months = Array.from({ length: 12 }, (item, i) => {
|
||||
return new Date(0, i).toLocaleString('en-US', { month: 'long' });
|
||||
});
|
||||
years = Array.from({ length: 5 }, (item, i) => {
|
||||
return new Date().getFullYear() - i;
|
||||
});
|
||||
|
||||
@action
|
||||
selectStartMonth(month) {
|
||||
this.startMonth = month;
|
||||
}
|
||||
|
||||
@action
|
||||
selectStartYear(year) {
|
||||
this.startYear = year;
|
||||
}
|
||||
}
|
||||
@@ -5,19 +5,24 @@ import { action } from '@ember/object';
|
||||
export default class HistoryRoute extends Route {
|
||||
async getActivity(start_time) {
|
||||
try {
|
||||
return this.store.queryRecord('clients/activity', { start_time });
|
||||
// on init ONLY make network request if we have a start time from the license
|
||||
// otherwise user needs to manually input
|
||||
return start_time
|
||||
? await this.store.queryRecord('clients/activity', { start_time })
|
||||
: { endTime: null };
|
||||
} catch (e) {
|
||||
// ARG TODO handle
|
||||
return e;
|
||||
}
|
||||
}
|
||||
|
||||
async getLicense() {
|
||||
async getLicenseStartTime() {
|
||||
try {
|
||||
return this.store.queryRecord('license', {});
|
||||
let license = await this.store.queryRecord('license', {});
|
||||
// if license.startTime is 'undefined' return 'null' for consistency
|
||||
return license.startTime || null;
|
||||
} catch (e) {
|
||||
// ARG TODO handle
|
||||
return e;
|
||||
// if error due to permission denied, return null so user can input date manually
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,18 +53,18 @@ export default class HistoryRoute extends Route {
|
||||
|
||||
async model() {
|
||||
let config = await this.store.queryRecord('clients/config', {}).catch((e) => {
|
||||
console.debug(e);
|
||||
// swallowing error so activity can show if no config permissions
|
||||
console.debug(e);
|
||||
return {};
|
||||
});
|
||||
let license = await this.getLicense();
|
||||
let activity = await this.getActivity(license.startTime);
|
||||
let licenseStart = await this.getLicenseStartTime();
|
||||
let activity = await this.getActivity(licenseStart);
|
||||
|
||||
return RSVP.hash({
|
||||
config,
|
||||
activity,
|
||||
startTimeFromLicense: this.parseRFC3339(license.startTime),
|
||||
endTimeFromResponse: activity ? this.parseRFC3339(activity.endTime) : null,
|
||||
startTimeFromLicense: this.parseRFC3339(licenseStart),
|
||||
endTimeFromResponse: this.parseRFC3339(activity?.endTime),
|
||||
versionHistory: this.getVersionHistory(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -13,46 +13,37 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if (eq @totalUsageCounts.clients 0)}}
|
||||
<div class="chart-empty-state">
|
||||
<EmptyState
|
||||
@title="No data received"
|
||||
@message="Tracking is turned on and Vault is gathering data. It should appear here within 30 minutes."
|
||||
/>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="chart-container-wide">
|
||||
<Clients::HorizontalBarChart
|
||||
@dataset={{this.barChartTotalClients}}
|
||||
@chartLegend={{@chartLegend}}
|
||||
@totalUsageCounts={{@totalUsageCounts}}
|
||||
/>
|
||||
</div>
|
||||
<div class="chart-container-wide">
|
||||
<Clients::HorizontalBarChart
|
||||
@dataset={{this.barChartTotalClients}}
|
||||
@chartLegend={{@chartLegend}}
|
||||
@totalUsageCounts={{@totalUsageCounts}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="chart-subTitle">
|
||||
<p class="chart-subtext">{{this.chartText.totalCopy}}</p>
|
||||
</div>
|
||||
<div class="chart-subTitle">
|
||||
<p class="chart-subtext">{{this.chartText.totalCopy}}</p>
|
||||
</div>
|
||||
|
||||
<div class="data-details-top">
|
||||
<h3 class="data-details">Top {{this.attributionBreakdown}}</h3>
|
||||
<p class="data-details">{{this.topClientCounts.label}}</p>
|
||||
</div>
|
||||
<div class="data-details-top">
|
||||
<h3 class="data-details">Top {{this.attributionBreakdown}}</h3>
|
||||
<p class="data-details">{{this.topClientCounts.label}}</p>
|
||||
</div>
|
||||
|
||||
<div class="data-details-bottom">
|
||||
<h3 class="data-details">Clients in {{this.attributionBreakdown}}</h3>
|
||||
<p class="data-details">{{format-number this.topClientCounts.clients}}</p>
|
||||
</div>
|
||||
<div class="data-details-bottom">
|
||||
<h3 class="data-details">Clients in {{this.attributionBreakdown}}</h3>
|
||||
<p class="data-details">{{format-number this.topClientCounts.clients}}</p>
|
||||
</div>
|
||||
|
||||
<div class="timestamp">
|
||||
Updated
|
||||
{{date-format @timestamp "MMM dd yyyy, h:mm:ss aaa"}}
|
||||
</div>
|
||||
<div class="timestamp">
|
||||
Updated
|
||||
{{date-format @timestamp "MMM dd yyyy, h:mm:ss aaa"}}
|
||||
</div>
|
||||
|
||||
<div class="legend-center">
|
||||
<span class="light-dot"></span><span class="legend-label">{{capitalize @chartLegend.0.label}}</span>
|
||||
<span class="dark-dot"></span><span class="legend-label">{{capitalize @chartLegend.1.label}}</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="legend-center">
|
||||
<span class="light-dot"></span><span class="legend-label">{{capitalize @chartLegend.0.label}}</span>
|
||||
<span class="dark-dot"></span><span class="legend-label">{{capitalize @chartLegend.1.label}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{! MODAL FOR CSV DOWNLOAD }}
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
</LinkTo>
|
||||
{{/if}}
|
||||
</EmptyState>
|
||||
{{else if this.isGatheringData}}
|
||||
<EmptyState
|
||||
@title="No data received"
|
||||
@message="Tracking is turned on and Vault is gathering data. It should appear here within 30 minutes."
|
||||
/>
|
||||
{{else}}
|
||||
<div class="is-subtitle-gray has-bottom-margin-m">
|
||||
FILTERS
|
||||
@@ -48,7 +53,7 @@
|
||||
@title={{date-format this.responseTimestamp "MMMM"}}
|
||||
@totalUsageCounts={{this.totalUsageCounts}}
|
||||
/>
|
||||
{{#if this.totalClientsData}}
|
||||
{{#if this.hasAttributionData}}
|
||||
<Clients::Attribution
|
||||
@chartLegend={{this.chartLegend}}
|
||||
@totalClientsData={{this.totalClientsData}}
|
||||
@@ -59,8 +64,6 @@
|
||||
@timestamp={{this.responseTimestamp}}
|
||||
/>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<EmptyState @title={{concat "No partial history"}} @message="There is no data in the current month yet." />
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
@@ -8,10 +8,14 @@
|
||||
Billing start month
|
||||
</h1>
|
||||
<div data-test-start-date-editor class="is-flex-align-baseline">
|
||||
<p class="is-size-6">{{this.startTimeDisplay}}</p>
|
||||
<button type="button" class="button is-link" {{on "click" (fn (mut this.isEditStartMonthOpen) true)}}>
|
||||
Edit
|
||||
</button>
|
||||
{{#if this.startTimeDisplay}}
|
||||
<p class="is-size-6">{{this.startTimeDisplay}}</p>
|
||||
<button type="button" class="button is-link" {{on "click" (fn (mut this.isEditStartMonthOpen) true)}}>
|
||||
Edit
|
||||
</button>
|
||||
{{else}}
|
||||
<DateDropdown @handleDateSelection={{this.handleClientActivityQuery}} @name={{"startTime"}} />
|
||||
{{/if}}
|
||||
</div>
|
||||
<p class="is-8 has-text-grey has-bottom-margin-xl">
|
||||
This date comes from your license, and defines when client counting starts. Without this starting point, the data shown
|
||||
@@ -106,7 +110,7 @@
|
||||
{{else}}
|
||||
{{#if this.totalUsageCounts}}
|
||||
<Clients::UsageStats @title="Total usage" @totalUsageCounts={{this.totalUsageCounts}} />
|
||||
{{#if this.totalClientsData}}
|
||||
{{#if this.hasAttributionData}}
|
||||
<Clients::Attribution
|
||||
@chartLegend={{this.chartLegend}}
|
||||
@totalClientsData={{this.totalClientsData}}
|
||||
@@ -123,10 +127,17 @@
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<EmptyState
|
||||
@title="No billing start date found"
|
||||
@message="In order to get the most from this data, please enter your billing period start month. This will ensure that the resulting data is accurate."
|
||||
/>
|
||||
{{#if this.version.isEnterprise}}
|
||||
<EmptyState
|
||||
@title="No billing start date found"
|
||||
@message="In order to get the most from this data, please enter your billing period start month. This will ensure that the resulting data is accurate."
|
||||
/>
|
||||
{{else}}
|
||||
<EmptyState
|
||||
@title="No start date found"
|
||||
@message="In order to get the most from this data, please enter a start month above. Vault will calculate new clients starting from that month."
|
||||
/>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@
|
||||
<ul class="menu-list">
|
||||
<li class="action">
|
||||
{{! template-lint-disable no-unknown-arguments-for-builtin-components }}
|
||||
<LinkTo @route="vault.cluster.clients" @query={{hash tab="current"}} @invokeAction={{@onLinkClick}}>
|
||||
<LinkTo @route="vault.cluster.clients.index" @invokeAction={{@onLinkClick}}>
|
||||
<div class="level is-mobile">
|
||||
<span class="level-left">Client count</span>
|
||||
<Chevron class="has-text-grey-light level-right" />
|
||||
|
||||
54
ui/app/templates/components/date-dropdown.hbs
Normal file
54
ui/app/templates/components/date-dropdown.hbs
Normal file
@@ -0,0 +1,54 @@
|
||||
<BasicDropdown @class="popup-menu" @horizontalPosition="auto-right" @verticalPosition="below" as |D|>
|
||||
<D.Trigger
|
||||
data-test-popup-menu-trigger="true"
|
||||
class={{concat "toolbar-link" (if D.isOpen " is-active")}}
|
||||
@htmlTag="button"
|
||||
>
|
||||
{{or this.startMonth "Month"}}
|
||||
<Chevron @direction="down" @isButton={{true}} />
|
||||
</D.Trigger>
|
||||
<D.Content class="popup-menu-content is-wide">
|
||||
<nav class="box menu scroll">
|
||||
<ul class="menu-list">
|
||||
{{#each this.months as |month|}}
|
||||
<button
|
||||
type="button"
|
||||
class="link"
|
||||
{{on "click" (queue (fn this.selectStartMonth month) (action D.actions.close))}}
|
||||
>
|
||||
{{month}}
|
||||
</button>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</nav>
|
||||
</D.Content>
|
||||
</BasicDropdown>
|
||||
<BasicDropdown @class="popup-menu" @horizontalPosition="auto-right" @verticalPosition="below" as |D|>
|
||||
<D.Trigger
|
||||
data-test-popup-menu-trigger="true"
|
||||
class={{concat "toolbar-link" (if D.isOpen " is-active")}}
|
||||
@htmlTag="button"
|
||||
>
|
||||
{{or this.startYear "Year"}}
|
||||
<Chevron @direction="down" @isButton={{true}} />
|
||||
</D.Trigger>
|
||||
<D.Content class="popup-menu-content is-wide">
|
||||
<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))}}>
|
||||
{{year}}
|
||||
</button>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</nav>
|
||||
</D.Content>
|
||||
</BasicDropdown>
|
||||
<button
|
||||
type="button"
|
||||
class="button is-primary"
|
||||
disabled={{if (and this.startMonth this.startYear) false true}}
|
||||
{{on "click" (fn @handleDateSelection this.startMonth this.startYear @name)}}
|
||||
>
|
||||
Save
|
||||
</button>
|
||||
@@ -76,9 +76,8 @@
|
||||
{{! template-lint-configure no-curly-component-invocation "warn" }}
|
||||
{{! template-lint-configure no-link-to-positional-params "warn" }}
|
||||
{{#link-to
|
||||
"vault.cluster.clients"
|
||||
(query-params tab="history")
|
||||
current-when="vault.cluster.clients"
|
||||
"vault.cluster.clients.history"
|
||||
current-when="vault.cluster.clients.history"
|
||||
data-test-navbar-item="metrics"
|
||||
}}
|
||||
Client count
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
<Clients::Dashboard @model={{@model}} />
|
||||
|
||||
<Clients::History @model={{@model}} @isLoading={{this.currentlyLoading}} />
|
||||
@@ -32,12 +32,13 @@ module('Integration | Component | client count current', function (hooks) {
|
||||
<div id="modal-wormhole"></div>
|
||||
<Clients::Current @model={{this.model}} />`);
|
||||
assert.dom('[data-test-component="empty-state"]').exists('Empty state exists');
|
||||
assert.dom('[data-test-empty-state-title]').hasText('No partial history');
|
||||
assert.dom('[data-test-empty-state-title]').hasText('No data received');
|
||||
});
|
||||
|
||||
test('it shows zeroed data when enabled but no counts', async function (assert) {
|
||||
Object.assign(this.model.config, { queriesAvailable: true, enabled: 'On' });
|
||||
Object.assign(this.model.monthly, {
|
||||
byNamespace: [{ label: 'root', clients: 0, entity_clients: 0, non_entity_clients: 0 }],
|
||||
total: { clients: 0, entity_clients: 0, non_entity_clients: 0 },
|
||||
});
|
||||
await render(hbs`
|
||||
|
||||
Reference in New Issue
Block a user