UI/Clients monthly usage component (#15012)

* clarify timestamp in jsdocs

* make title bottom margin smaller

* add monthly usage component

* fix doubled up css

* clean up average helpers

* copy update

* change arg to component variable

* fix awkward grammar

* clean up mirage handler

* address comments

* remove prop
This commit is contained in:
claire bontempo 2022-04-12 17:49:35 -05:00 committed by GitHub
parent 112d622b40
commit 85b2263dce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 757 additions and 766 deletions

View File

@ -27,7 +27,7 @@ import { inject as service } from '@ember/service';
* @param {string} startTimeDisplay - start date for CSV modal * @param {string} startTimeDisplay - start date for CSV modal
* @param {string} endTimeDisplay - end date for CSV modal * @param {string} endTimeDisplay - end date for CSV modal
* @param {boolean} isDateRange - getter calculated in parent to relay if dataset is a date range or single month * @param {boolean} isDateRange - getter calculated in parent to relay if dataset is a date range or single month
* @param {string} timestamp - timestamp response was received from API * @param {string} timestamp - ISO timestamp created in serializer to timestamp the response
*/ */
export default class Attribution extends Component { export default class Attribution extends Component {

View File

@ -22,7 +22,6 @@ import { LIGHT_AND_DARK_BLUE, SVG_DIMENSIONS, formatNumbers } from '../../utils/
*/ */
export default class LineChart extends Component { export default class LineChart extends Component {
// TODO CMB make just one tracked variable tooltipText?
@tracked tooltipTarget = ''; @tracked tooltipTarget = '';
@tracked tooltipMonth = ''; @tracked tooltipMonth = '';
@tracked tooltipTotal = ''; @tracked tooltipTotal = '';

View File

@ -9,10 +9,12 @@ import { mean } from 'd3-array';
* ```js * ```js
<Clients::MonthlyUsage <Clients::MonthlyUsage
@chartLegend={{this.chartLegend}} @chartLegend={{this.chartLegend}}
@verticalBarChartData={{this.byMonth}} @timestamp={{this.responseTimestamp}}
@verticalBarChartData={{this.byMonthTotalClients}}
/> />
* ``` * ```
* @param {array} chartLegend - array of objects with key names 'key' and 'label' so data can be stacked
* @param {string} timestamp - ISO timestamp created in serializer to timestamp the response
* @param {array} verticalBarChartData - array of flattened objects * @param {array} verticalBarChartData - array of flattened objects
sample object = sample object =
{ {
@ -31,13 +33,15 @@ import { mean } from 'd3-array';
* @param {array} chartLegend - array of objects with key names 'key' and 'label' so data can be stacked * @param {array} chartLegend - array of objects with key names 'key' and 'label' so data can be stacked
*/ */
export default class MonthlyUsage extends Component { export default class MonthlyUsage extends Component {
barChartData = this.args.verticalBarChartData;
get averageTotalClients() { get averageTotalClients() {
let average = mean(this.args.verticalBarChartData?.map((d) => d.total)); let average = mean(this.barChartData?.map((d) => d.total));
return Math.round(average) || null; return Math.round(average) || null;
} }
get averageNewClients() { get averageNewClients() {
let average = mean(this.args.verticalBarChartData?.map((d) => d.new_clients)); let average = mean(this.barChartData?.map((d) => d.new_clients.total));
return Math.round(average) || null; return Math.round(average) || null;
} }
} }

View File

@ -34,30 +34,21 @@ import { mean } from 'd3-array';
* @param {array} barChartData - array of objects, object example: { month: '1/22', entity_clients: 11, non_entity_clients: 36, total: 47, namespaces: [] }; * @param {array} barChartData - array of objects, object example: { month: '1/22', entity_clients: 11, non_entity_clients: 36, total: 47, namespaces: [] };
* @param {array} chartLegend - array of objects with key names 'key' and 'label' so data can be stacked * @param {array} chartLegend - array of objects with key names 'key' and 'label' so data can be stacked
* @param {object} runningTotals - top level totals from /activity response { clients: 3517, entity_clients: 1593, non_entity_clients: 1924 } * @param {object} runningTotals - top level totals from /activity response { clients: 3517, entity_clients: 1593, non_entity_clients: 1924 }
* @param {string} timestamp - ISO timestamp created in serializer to timestamp the response
* *
*/ */
export default class RunningTotal extends Component { export default class RunningTotal extends Component {
get getTotalClients() { get entityClientData() {
return ( return {
this.args.chartLegend?.map((legend) => { runningTotal: this.args.runningTotals.entity_clients,
return { averageNewClients: Math.round(mean(this.args.barChartData?.map((d) => d.entity_clients))),
label: legend.label, };
total: this.args.runningTotals[legend.key],
};
}) || null
);
} }
get getAverageNewClients() { get nonEntityClientData() {
// maps through legend and creates array of objects return {
// e.g. {label: 'unique entities', average: 43} runningTotal: this.args.runningTotals.non_entity_clients,
return ( averageNewClients: Math.round(mean(this.args.barChartData?.map((d) => d.non_entity_clients))),
this.args.chartLegend?.map((legend) => { };
return {
label: legend.label,
average: Math.round(mean(this.args.barChartData?.map((d) => d[legend.key]))),
};
}) || null
);
} }
} }

View File

@ -91,7 +91,7 @@ export default class VerticalBarChart extends Component {
.nice(); .nice();
let yAxis = axisLeft(yAxisScale) let yAxis = axisLeft(yAxisScale)
.ticks(6) .ticks(4)
.tickPadding(10) .tickPadding(10)
.tickSizeInner(-SVG_DIMENSIONS.width) .tickSizeInner(-SVG_DIMENSIONS.width)
.tickFormat(formatNumbers); .tickFormat(formatNumbers);

View File

@ -30,10 +30,6 @@
grid-column-end: span col4-end; grid-column-end: span col4-end;
grid-row-start: 1; grid-row-start: 1;
box-shadow: inset 0 -1px 0 $vault-gray-200; box-shadow: inset 0 -1px 0 $vault-gray-200;
> h2 {
padding-bottom: $spacing-xs;
}
} }
.has-header-link { .has-header-link {
@ -165,7 +161,7 @@ h2.chart-title {
font-weight: $font-weight-bold; font-weight: $font-weight-bold;
font-size: $size-5; font-size: $size-5;
line-height: $spacing-l; line-height: $spacing-l;
margin-bottom: $spacing-xs; margin-bottom: $spacing-xxs;
} }
p.chart-description { p.chart-description {

View File

@ -131,15 +131,18 @@
<LayoutLoading /> <LayoutLoading />
{{else}} {{else}}
{{#if this.totalUsageCounts}} {{#if this.totalUsageCounts}}
<Clients::RunningTotal {{#unless this.byMonthTotalClients}}
@chartLegend={{this.chartLegend}} <Clients::UsageStats @title="Total usage" @totalUsageCounts={{this.totalUsageCounts}} />
@barChartData={{this.byMonthNewClients}} {{/unless}}
@lineChartData={{this.byMonthTotalClients}} {{#if this.byMonthTotalClients}}
@runningTotals={{this.totalUsageCounts}} <Clients::RunningTotal
@timestamp={{this.responseTimestamp}} @chartLegend={{this.chartLegend}}
/> @lineChartData={{this.byMonthTotalClients}}
{{! TODO CMB: remove UsageStats component from history tab (and update associated tests) }} @barChartData={{this.byMonthNewClients}}
<Clients::UsageStats @title="Total usage" @totalUsageCounts={{this.totalUsageCounts}} /> @runningTotals={{this.totalUsageCounts}}
@timestamp={{this.responseTimestamp}}
/>
{{/if}}
{{#if this.hasAttributionData}} {{#if this.hasAttributionData}}
<Clients::Attribution <Clients::Attribution
@chartLegend={{this.chartLegend}} @chartLegend={{this.chartLegend}}
@ -152,6 +155,13 @@
@timestamp={{this.responseTimestamp}} @timestamp={{this.responseTimestamp}}
/> />
{{/if}} {{/if}}
{{#if this.byMonthTotalClients}}
<Clients::MonthlyUsage
@chartLegend={{this.chartLegend}}
@verticalBarChartData={{this.byMonthTotalClients}}
@timestamp={{this.responseTimestamp}}
/>
{{/if}}
{{/if}} {{/if}}
{{/if}} {{/if}}
{{else if (and (not @model.startTimeFromLicense) (not this.startTimeFromResponse))}} {{else if (and (not @model.startTimeFromLicense) (not this.startTimeFromResponse))}}

View File

@ -2,8 +2,7 @@
<div class="chart-header has-bottom-margin-xl"> <div class="chart-header has-bottom-margin-xl">
<h2 class="chart-title">Vault usage</h2> <h2 class="chart-title">Vault usage</h2>
<p class="chart-description"> <p class="chart-description">
This data can be used to understand how many total clients are using Vault each month for the time period selected This data can be used to understand how many total clients are using Vault each month for this date range.
above.
</p> </p>
</div> </div>
@ -14,38 +13,29 @@
<div class="chart-subTitle"> <div class="chart-subTitle">
<h2 class="chart-title">Total monthly clients</h2> <h2 class="chart-title">Total monthly clients</h2>
<p class="chart-subtext"> <p class="chart-subtext">
Each unique client is counted once per month. This can help with capacity planning. Each client is counted once per month. This can help with capacity planning.
</p> </p>
</div> </div>
<div class="data-details-top"> <div class="data-details-top">
<h3 class="data-details">Average total clients per month</h3> <h3 class="data-details">Average total clients per month</h3>
<p class="data-details"> <p class="data-details">
{{#if this.averageTotalClients}} {{format-number this.averageTotalClients}}
{{format-number this.averageTotalClients}}
{{else}}
<span class="has-text-danger is-size-8">
<Icon @name="x-square-fill" />Average cannot be calculated
</span>
{{/if}}
</p> </p>
</div> </div>
<div class="data-details-bottom"> <div class="data-details-bottom">
<h3 class="data-details">Average new clients per month</h3> <h3 class="data-details">Average new clients per month</h3>
<p class="data-details"> <p class="data-details">
{{#if this.averageNewClients}} {{format-number this.averageNewClients}}
{{format-number this.averageNewClients}}
{{else}}
<span class="has-text-danger is-size-8">
<Icon @name="x-square-fill" />Average cannot be calculated
</span>
{{/if}}
</p> </p>
</div> </div>
<div class="timestamp"> <div class="timestamp">
Updated Nov 15 2021, 4:07:32 pm {{#if @timestamp}}
Updated
{{date-format @timestamp "MMM d yyyy, h:mm:ss aaa"}}
{{/if}}
</div> </div>
<div class="legend-right"> <div class="legend-right">

View File

@ -16,23 +16,18 @@
<h2 class="chart-title">Running client total</h2> <h2 class="chart-title">Running client total</h2>
<p class="chart-subtext">The number of clients which interacted with Vault during this date range. </p> <p class="chart-subtext">The number of clients which interacted with Vault during this date range. </p>
</div> </div>
<div class="data-details-top"> <div class="data-details-top">
{{#let (get this.getTotalClients 0) as |stat|}} <h3 class="data-details">Entity clients</h3>
<h3 class="data-details">Entity clients</h3> <p class="data-details">
<p class="data-details"> {{format-number this.entityClientData.runningTotal}}
{{format-number stat.total}} </p>
</p>
{{/let}}
</div> </div>
<div class="data-details-bottom"> <div class="data-details-bottom">
{{#let (get this.getTotalClients 1) as |stat|}} <h3 class="data-details">Non-entity clients</h3>
<h3 class="data-details">Non-entity clients</h3> <p class="data-details">
<p class="data-details"> {{format-number this.nonEntityClientData.runningTotal}}
{{format-number stat.total}} </p>
</p>
{{/let}}
</div> </div>
<div class="legend-right"> <div class="legend-right">
@ -54,21 +49,17 @@
</div> </div>
<div class="data-details-top"> <div class="data-details-top">
{{#let (get this.getAverageNewClients 0) as |stat|}} <h3 class="data-details">Average new entity clients per month</h3>
<h3 class="data-details">Average new entity clients per month</h3> <p class="data-details">
<p class="data-details"> {{format-number this.entityClientData.averageNewClients}}
{{format-number stat.average}} </p>
</p>
{{/let}}
</div> </div>
<div class="data-details-bottom"> <div class="data-details-bottom">
{{#let (get this.getAverageNewClients 1) as |stat|}} <h3 class="data-details">Average new non-entity clients per month</h3>
<h3 class="data-details">Average new non-entity clients per month</h3> <p class="data-details">
<p class="data-details"> {{format-number this.nonEntityClientData.averageNewClients}}
{{format-number stat.average}} </p>
</p>
{{/let}}
</div> </div>
<div class="timestamp"> <div class="timestamp">

View File

@ -1,7 +1,7 @@
<div class="chart-wrapper" data-test-usage-stats> <div class="chart-wrapper" data-test-usage-stats>
<div class="chart-header has-header-link has-bottom-margin-m"> <div class="chart-header has-header-link has-bottom-margin-m">
<div class="header-left"> <div class="header-left">
<h2 class="chart-title has-bottom-margin-xs">{{@title}}</h2> <h2 class="chart-title">{{@title}}</h2>
<p class="chart-description"> These totals are within this namespace and all its children. </p> <p class="chart-description"> These totals are within this namespace and all its children. </p>
</div> </div>
<div class="header-right"> <div class="header-right">

File diff suppressed because it is too large Load Diff