Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client count updates #12554

Merged
merged 5 commits into from Sep 16, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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';
arnav28 marked this conversation as resolved.
Show resolved Hide resolved
});
// 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() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does changing the route names affect the picker at all on the Status menu? E.g. can you still navigate to the page the same way as before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated all the references which were pointing to metrics route, so it will work fine.

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.

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