Skip to content

Commit

Permalink
Client count updates (#12554)
Browse files Browse the repository at this point in the history
* Client count updates

- Added Current month tab which leverages partial monthly activity api
- Refactored Vault usage to Monthly history
- New client count history component based on StatText and BarChart component
- Restrict bar chart to showcase only top 10 namespaces
- Removed config route, as config and history component will be rendered based on query param
- Updated all metrics reference to clients
- Removed old tests and added integration test for current month

* Fixed navbar permission

- Added changelog

* Updated the model for current month data

* Fixed current month tests

* Fixed indentation and chart label
  • Loading branch information
arnav28 committed Sep 16, 2021
1 parent cdecce0 commit 681a931
Show file tree
Hide file tree
Showing 36 changed files with 440 additions and 367 deletions.
3 changes: 3 additions & 0 deletions changelog/12554.txt
@@ -0,0 +1,3 @@
```release-note:feature
ui: client count monthly view
```
Expand Up @@ -5,7 +5,11 @@ export default Application.extend({
return 'internal/counters/activity';
},
queryRecord(store, type, query) {
const url = this.urlForQuery(null, type);
let url = this.urlForQuery(null, type);
if (query.tab === 'current') {
url = `${url}/monthly`;
query = null;
}
// API accepts start and end as query params
return this.ajax(url, 'GET', { data: query }).then(resp => {
let response = resp || {};
Expand Down
File renamed without changes.
@@ -1,12 +1,12 @@
/**
* @module PricingMetricsConfig
* PricingMetricsConfig components are used to show and edit the pricing metrics config information.
* @module ClientsConfig
* ClientsConfig components are used to show and edit the client count config information.
*
* @example
* ```js
* <PricingMetricsConfig @model={{model}} @mode="edit" />
* <Clients::Config @model={{model}} @mode="edit" />
* ```
* @param {object} model - model is the DS metrics/config model which should be passed in
* @param {object} model - model is the DS clients/config model which should be passed in
* @param {string} [mode=show] - mode is either show or edit. Show results in a table with the config, show has a form.
*/

Expand All @@ -16,7 +16,7 @@ import { inject as service } from '@ember/service';
import { tracked } from '@glimmer/tracking';
import { task } from 'ember-concurrency';

export default class PricingMetricsConfigComponent extends Component {
export default class ConfigComponent extends Component {
@service router;
@tracked mode = 'show';
@tracked modalOpen = false;
Expand Down Expand Up @@ -57,7 +57,7 @@ export default class PricingMetricsConfigComponent extends Component {
this.error = err.message;
return;
}
this.router.transitionTo('vault.cluster.metrics.config');
this.router.transitionTo('vault.cluster.clients.index');
}).drop())
save;

Expand Down
40 changes: 40 additions & 0 deletions ui/app/components/clients/history.js
@@ -0,0 +1,40 @@
import Component from '@glimmer/component';

export default class HistoryComponent extends Component {
max_namespaces = 10;

get hasClientData() {
if (this.args.tab === 'current') {
return this.args.model.activity && this.args.model.activity.clients;
}
return this.args.model.activity && this.args.model.activity.total;
}

get barChartDataset() {
if (!this.args.model.activity || !this.args.model.activity.byNamespace) {
return null;
}
let dataset = this.args.model.activity.byNamespace;
// Filter out root data
dataset = dataset.filter(item => {
return item.namespace_id !== 'root';
});
// Show only top 10 namespaces
dataset = dataset.slice(0, this.max_namespaces);
return dataset.map(d => {
return {
label: d['namespace_path'],
non_entity_tokens: d['counts']['non_entity_tokens'],
distinct_entities: d['counts']['distinct_entities'],
total: d['counts']['clients'],
};
});
}

get showGraphs() {
if (!this.args.model.activity || !this.args.model.activity.byNamespace) {
return null;
}
return this.args.model.activity.byNamespace.length > 1;
}
}
42 changes: 2 additions & 40 deletions ui/app/components/pricing-metrics-dates.js
Expand Up @@ -18,16 +18,7 @@
import { set, computed } from '@ember/object';
import { inject as service } from '@ember/service';
import Component from '@ember/component';
import {
differenceInSeconds,
isValid,
subMonths,
startOfToday,
format,
endOfMonth,
startOfMonth,
isBefore,
} from 'date-fns';
import { subMonths, startOfToday, format, endOfMonth, startOfMonth, isBefore } from 'date-fns';
import layout from '../templates/components/pricing-metrics-dates';
import { parseDateString } from 'vault/helpers/parse-date-string';

Expand Down Expand Up @@ -69,35 +60,6 @@ export default Component.extend({
}
}),

// We don't want the warning to show when inputs are being updated before query is made
/* eslint-disable-next-line ember/require-computed-property-dependencies */
showResultsWarning: computed('resultEnd', 'resultStart', function() {
if (!this.queryStart || !this.queryEnd || !this.resultStart || !this.resultEnd) {
return false;
}
const resultStart = new Date(this.resultStart);
const resultEnd = new Date(this.resultEnd);
let queryStart, queryEnd;
try {
queryStart = parseDateString(this.queryStart, '-');
queryEnd = parseDateString(this.queryEnd, '-');
} catch (e) {
// Log error for debugging purposes
console.debug(e);
}

if (!queryStart || !queryEnd || !isValid(resultStart) || !isValid(resultEnd)) {
return false;
}
if (Math.abs(differenceInSeconds(queryStart, resultStart)) >= 86400) {
return true;
}
if (Math.abs(differenceInSeconds(resultEnd, endOfMonth(queryEnd))) >= 86400) {
return true;
}
return false;
}),

error: computed('end', 'endDate', 'retentionMonths', 'start', 'startDate', function() {
if (!this.startDate) {
return 'Start date is invalid. Please use format MM/yyyy';
Expand Down Expand Up @@ -148,7 +110,7 @@ export default Component.extend({
handleQuery() {
const start = format(this.startDate, 'MM-yyyy');
const end = format(this.endDate, 'MM-yyyy');
this.router.transitionTo('vault.cluster.metrics', {
this.router.transitionTo('vault.cluster.clients', {
queryParams: {
start,
end,
Expand Down
8 changes: 8 additions & 0 deletions ui/app/controllers/vault/cluster/clients/index.js
@@ -0,0 +1,8 @@
import Controller from '@ember/controller';

export default class ClientsController extends Controller {
queryParams = ['tab', 'start', 'end'];
tab = null;
start = null;
end = null;
}
8 changes: 0 additions & 8 deletions ui/app/controllers/vault/cluster/metrics/index.js

This file was deleted.

Expand Up @@ -2,6 +2,10 @@ import Model, { attr } from '@ember-data/model';

export default Model.extend({
total: attr('object'),
byNamespace: attr('array'),
endTime: attr('string'),
startTime: attr('string'),
clients: attr('number'),
distinct_entities: attr('number'),
non_entity_tokens: attr('number'),
});
File renamed without changes.
3 changes: 1 addition & 2 deletions ui/app/router.js
Expand Up @@ -15,9 +15,8 @@ Router.map(function() {
this.route('logout');
this.mount('open-api-explorer', { path: '/api-explorer' });
this.route('license');
this.route('metrics', function() {
this.route('clients', function() {
this.route('index', { path: '/' });
this.route('config');
this.route('edit');
});
this.route('storage', { path: '/storage/raft' });
Expand Down
Expand Up @@ -2,6 +2,6 @@ import Route from '@ember/routing/route';

export default Route.extend({
model() {
return this.store.queryRecord('metrics/config', {});
return this.store.queryRecord('clients/config', {});
},
});
Expand Up @@ -4,30 +4,37 @@ import { hash } from 'rsvp';
import { getTime } from 'date-fns';
import { parseDateString } from 'vault/helpers/parse-date-string';

const getActivityParams = ({ start, end }) => {
const getActivityParams = ({ tab, start, end }) => {
// Expects MM-yyyy format
// TODO: minStart, maxEnd
let params = {};
if (start) {
let startDate = parseDateString(start);
if (startDate) {
// TODO: Replace with formatRFC3339 when date-fns is updated
// converts to milliseconds, divide by 1000 to get epoch
params.start_time = getTime(startDate) / 1000;
if (tab === 'current') {
params.tab = tab;
} else if (tab === 'history') {
if (start) {
let startDate = parseDateString(start);
if (startDate) {
// TODO: Replace with formatRFC3339 when date-fns is updated
// converts to milliseconds, divide by 1000 to get epoch
params.start_time = getTime(startDate) / 1000;
}
}
}
if (end) {
let endDate = parseDateString(end);
if (endDate) {
// TODO: Replace with formatRFC3339 when date-fns is updated
params.end_time = getTime(endDate) / 1000;
if (end) {
let endDate = parseDateString(end);
if (endDate) {
// TODO: Replace with formatRFC3339 when date-fns is updated
params.end_time = getTime(endDate) / 1000;
}
}
}
return params;
};

export default Route.extend(ClusterRoute, {
queryParams: {
tab: {
refreshModel: true,
},
start: {
refreshModel: true,
},
Expand All @@ -37,13 +44,13 @@ export default Route.extend(ClusterRoute, {
},

model(params) {
let config = this.store.queryRecord('metrics/config', {}).catch(e => {
let config = this.store.queryRecord('clients/config', {}).catch(e => {
console.debug(e);
// swallowing error so activity can show if no config permissions
return {};
});
const activityParams = getActivityParams(params);
let activity = this.store.queryRecord('metrics/activity', activityParams);
let activity = this.store.queryRecord('clients/activity', activityParams);

return hash({
queryStart: params.start,
Expand Down
8 changes: 0 additions & 8 deletions ui/app/routes/vault/cluster/metrics/config.js

This file was deleted.

File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion ui/app/services/permissions.js
Expand Up @@ -29,7 +29,7 @@ const API_PATHS = {
seal: 'sys/seal',
raft: 'sys/storage/raft/configuration',
},
metrics: {
clients: {
activity: 'sys/internal/counters/activity',
config: 'sys/internal/counters/config',
},
Expand Down
5 changes: 1 addition & 4 deletions ui/app/styles/components/bar-chart.scss
Expand Up @@ -7,14 +7,11 @@

> div.is-border {
border: 0.3px solid $ui-gray-200;
width: 94%;
margin-left: 3%;
margin-bottom: $spacing-xxs;
}
}

.chart-header {
margin-left: $spacing-l;
display: grid;
grid-template-columns: 3fr 1fr;

Expand Down Expand Up @@ -47,7 +44,7 @@
}

.bar-chart-container {
padding: $spacing-m $spacing-l $spacing-m $spacing-l;
padding: $spacing-m 0;
}

.bar-chart {
Expand Down
4 changes: 4 additions & 0 deletions ui/app/styles/components/stat-text.scss
@@ -1,5 +1,8 @@
.stat-text-container {
line-height: normal;
height: 100%;
display: flex;
flex-direction: column;

&.l,
&.m {
Expand All @@ -13,6 +16,7 @@
font-weight: $font-weight-normal;
color: $ui-gray-700;
line-height: inherit;
flex-grow: 1;
}
.stat-value {
font-size: $size-3;
Expand Down
Expand Up @@ -54,7 +54,8 @@
Save
</button>
<LinkTo
@route="vault.cluster.metrics.config"
@route="vault.cluster.clients.index"
@query={{hash tab="config"}}
class="button">
Cancel
</LinkTo>
Expand Down

0 comments on commit 681a931

Please sign in to comment.