From 34ad4ca9f15ee43e72075b4c0b9b63b3bb63c7b2 Mon Sep 17 00:00:00 2001 From: claire bontempo <68122737+hellobontempo@users.noreply.github.com> Date: Thu, 27 Jan 2022 10:59:08 -0800 Subject: [PATCH] UI/Current month view (#13788) * add timestamp to attribution * create usage stat component * updates stat text boxes * remove flex-header css * remove comment * add empty state if no data * update monthly serializer * remove empty state - unnecessary --- ui/app/components/clients/attribution.js | 2 + ui/app/components/clients/current.js | 22 +++++++ ui/app/components/clients/dashboard.js | 11 +++- ui/app/models/clients/activity.js | 1 + ui/app/models/clients/monthly.js | 10 +-- ui/app/serializers/clients/activity.js | 4 +- ui/app/serializers/clients/monthly.js | 16 ++--- ui/app/styles/components/stat-text.scss | 12 ---- ui/app/styles/core/charts.scss | 18 +++++- .../components/clients/attribution.hbs | 45 ++++++------- .../templates/components/clients/current.hbs | 64 +++---------------- .../components/clients/dashboard.hbs | 1 + .../components/clients/single-month.hbs | 33 ---------- .../components/clients/usage-stats.hbs | 42 ++++++++++++ 14 files changed, 134 insertions(+), 147 deletions(-) create mode 100644 ui/app/components/clients/current.js delete mode 100644 ui/app/templates/components/clients/single-month.hbs create mode 100644 ui/app/templates/components/clients/usage-stats.hbs diff --git a/ui/app/components/clients/attribution.js b/ui/app/components/clients/attribution.js index 17da0f897..f9a0816d4 100644 --- a/ui/app/components/clients/attribution.js +++ b/ui/app/components/clients/attribution.js @@ -16,6 +16,7 @@ import { tracked } from '@glimmer/tracking'; * @startTimeDisplay={{this.startTimeDisplay}} * @endTimeDisplay={{this.endTimeDisplay}} * @isDateRange={{this.isDateRange}} + * @timestamp={{this.responseTimestamp}} * /> * ``` * @param {array} chartLegend - (passed to child) array of objects with key names 'key' and 'label' so data can be stacked @@ -25,6 +26,7 @@ import { tracked } from '@glimmer/tracking'; * @param {string} startTimeDisplay - start 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 {string} timestamp - timestamp response was received from API */ export default class Attribution extends Component { diff --git a/ui/app/components/clients/current.js b/ui/app/components/clients/current.js new file mode 100644 index 000000000..8f0f36281 --- /dev/null +++ b/ui/app/components/clients/current.js @@ -0,0 +1,22 @@ +import Component from '@glimmer/component'; + +export default class Current extends Component { + chartLegend = [ + { key: 'entity_clients', label: 'entity clients' }, + { key: 'non_entity_clients', label: 'non-entity clients' }, + ]; + + // data for horizontal bar chart in attribution component + get topTenNamespaces() { + return this.args.model.monthly?.byNamespace; + } + + // top level TOTAL client counts from response for given month + get runningTotals() { + return this.args.model.monthly?.total; + } + + get responseTimestamp() { + return this.args.model.monthly?.responseTimestamp; + } +} diff --git a/ui/app/components/clients/dashboard.js b/ui/app/components/clients/dashboard.js index b978c8d71..e1e890c7e 100644 --- a/ui/app/components/clients/dashboard.js +++ b/ui/app/components/clients/dashboard.js @@ -21,8 +21,8 @@ export default class Dashboard extends Component { ]; maxNamespaces = 10; chartLegend = [ - { key: 'entity_clients', label: 'unique entities' }, - { key: 'non_entity_clients', label: 'non-entity tokens' }, + { key: 'entity_clients', label: 'entity clients' }, + { key: 'non_entity_clients', label: 'non-entity clients' }, ]; // TODO remove this adapter variable? or set to /clients/activity ? adapter = this.store.adapterFor('clients/new-init-activity'); @@ -85,6 +85,13 @@ export default class Dashboard extends Component { return this.args.model.activity.byNamespace; } + get responseTimestamp() { + if (!this.args.model.activity || !this.args.model.activity.responseTimestamp) { + return null; + } + return this.args.model.activity.responseTimestamp; + } + @action async handleClientActivityQuery(month, year, dateType) { if (dateType === 'cancel') { diff --git a/ui/app/models/clients/activity.js b/ui/app/models/clients/activity.js index 6af8c8f07..d2cee5b50 100644 --- a/ui/app/models/clients/activity.js +++ b/ui/app/models/clients/activity.js @@ -1,5 +1,6 @@ import Model, { attr } from '@ember-data/model'; export default class Activity extends Model { + @attr('string') responseTimestamp; @attr('array') byNamespace; @attr('string') endTime; @attr('string') startTime; diff --git a/ui/app/models/clients/monthly.js b/ui/app/models/clients/monthly.js index 1aaef4a8b..0c9c15af7 100644 --- a/ui/app/models/clients/monthly.js +++ b/ui/app/models/clients/monthly.js @@ -1,15 +1,7 @@ import Model, { attr } from '@ember-data/model'; // ARG TODO copied from before, modify for what you need export default class Monthly extends Model { + @attr('string') responseTimestamp; @attr('array') byNamespace; @attr('object') total; - @attr('string') timestamp; - // TODO CMB remove 'clients' and use 'total' object? - @attr('number') clients; - // new names - @attr('number') entityClients; - @attr('number') nonEntityClients; - // old names - @attr('number') distinctEntities; - @attr('number') nonEntityTokens; } diff --git a/ui/app/serializers/clients/activity.js b/ui/app/serializers/clients/activity.js index c032430b6..e1f561d6c 100644 --- a/ui/app/serializers/clients/activity.js +++ b/ui/app/serializers/clients/activity.js @@ -1,4 +1,5 @@ import ApplicationSerializer from '../application'; +import { formatISO } from 'date-fns'; /* SAMPLE PAYLOAD BEFORE/AFTER: @@ -109,9 +110,10 @@ export default ApplicationSerializer.extend({ }, normalizeResponse(store, primaryModelClass, payload, id, requestType) { + let response_timestamp = formatISO(new Date()); let transformedPayload = { ...payload, - // TODO CMB should these be nested under "data" to go to model correctly?) + response_timestamp, by_namespace: this.flattenDataset(payload.data.by_namespace), }; delete payload.data.by_namespace; diff --git a/ui/app/serializers/clients/monthly.js b/ui/app/serializers/clients/monthly.js index 5cbc47b72..67e8cd03a 100644 --- a/ui/app/serializers/clients/monthly.js +++ b/ui/app/serializers/clients/monthly.js @@ -1,14 +1,14 @@ -import { formatISO } from 'date-fns'; import ApplicationSerializer from '../application'; +import { formatISO } from 'date-fns'; export default ApplicationSerializer.extend({ flattenDataset(payload) { - let topTen = payload.slice(0, 10); + let topTen = payload ? payload.slice(0, 10) : []; return topTen.map((ns) => { // 'namespace_path' is an empty string for root if (ns['namespace_id'] === 'root') ns['namespace_path'] = 'root'; - let label = ns['namespace_path'] || ns['namespace_id']; // TODO CMB will namespace_path ever be empty? + let label = ns['namespace_path']; let flattenedNs = {}; // we don't want client counts nested within the 'counts' object for stacked charts Object.keys(ns['counts']).forEach((key) => (flattenedNs[key] = ns['counts'][key])); @@ -39,16 +39,16 @@ export default ApplicationSerializer.extend({ normalizeResponse(store, primaryModelClass, payload, id, requestType) { let { data } = payload; let { clients, distinct_entities, non_entity_tokens } = data; - let timestamp = formatISO(new Date()); + let response_timestamp = formatISO(new Date()); let transformedPayload = { ...payload, - // TODO CMB should these be nested under "data" to go to model correctly?) - timestamp, + response_timestamp, by_namespace: this.flattenDataset(data.by_namespace), + // nest within 'total' object to mimic /activity response shape total: { clients, - entity_clients: distinct_entities, - non_entity_clients: non_entity_tokens, + entityClients: distinct_entities, + nonEntityClients: non_entity_tokens, }, }; delete payload.data.by_namespace; diff --git a/ui/app/styles/components/stat-text.scss b/ui/app/styles/components/stat-text.scss index 4059545ad..abe206db1 100644 --- a/ui/app/styles/components/stat-text.scss +++ b/ui/app/styles/components/stat-text.scss @@ -103,15 +103,3 @@ } } } - -.has-gap { - gap: $spacing-xxl; -} - -.stat-text-flex-wrapper { - display: flex; - justify-content: flex-start; - flex-wrap: wrap; - column-gap: 70px; - row-gap: 20px; -} diff --git a/ui/app/styles/core/charts.scss b/ui/app/styles/core/charts.scss index 6bda0f123..f2a0d752e 100644 --- a/ui/app/styles/core/charts.scss +++ b/ui/app/styles/core/charts.scss @@ -38,14 +38,23 @@ } } -.has-export { +.has-header-link { display: grid; grid-template-columns: 4fr 1fr; .header-right { text-align: right; > button { - font-size: $size-8; + &:hover, + &.is-hovered, + &:focus, + &.is-focused { + background-color: transparent; + background-color: darken($ui-gray-050, 5%); + border-color: darken($ui-gray-300, 5%); + } + } + > a { &:hover { text-decoration: underline; } @@ -102,6 +111,11 @@ } } +.chart-empty-state { + grid-column-start: 1; + grid-column-end: -1; +} + .chart-subTitle { grid-column-start: 1; grid-column-end: 3; diff --git a/ui/app/templates/components/clients/attribution.hbs b/ui/app/templates/components/clients/attribution.hbs index b1f2f2478..c2da6989f 100644 --- a/ui/app/templates/components/clients/attribution.hbs +++ b/ui/app/templates/components/clients/attribution.hbs @@ -1,5 +1,5 @@
-
+ - {{#if this.totalClientsData}} -
- -
+
+ +
-
-

{{this.chartText.totalCopy}}

-
+
+

{{this.chartText.totalCopy}}

+
-
-

Top {{lowercase this.attributionBreakdown}}

-

{{this.topClientCounts.label}}

-
+
+

Top {{lowercase this.attributionBreakdown}}

+

{{this.topClientCounts.label}}

+
-
-

Clients in {{lowercase this.attributionBreakdown}}

-

{{this.topClientCounts.clients}}

-
- {{else}} - - {{/if}} +
+

Clients in {{lowercase this.attributionBreakdown}}

+

{{this.topClientCounts.clients}}

+
- Updated Nov 15 2021, 4:07:32 pm + Updated + {{date-format @timestamp "MMM dd yyyy, h:mm:ss aaa"}}
diff --git a/ui/app/templates/components/clients/current.hbs b/ui/app/templates/components/clients/current.hbs index 141008392..1946a4afd 100644 --- a/ui/app/templates/components/clients/current.hbs +++ b/ui/app/templates/components/clients/current.hbs @@ -18,64 +18,16 @@ {{#if @isLoading}} {{else}} -
-
-
-
-

- Total usage -

-

- These totals are within this namespace and all its children. -

-
- - Learn more - -
-
-
-
- -
-
- -
-
- -
-
-
-
+ + {{/if}}
\ No newline at end of file diff --git a/ui/app/templates/components/clients/dashboard.hbs b/ui/app/templates/components/clients/dashboard.hbs index 4f72885b0..38336dad0 100644 --- a/ui/app/templates/components/clients/dashboard.hbs +++ b/ui/app/templates/components/clients/dashboard.hbs @@ -74,6 +74,7 @@ @startTimeDisplay={{this.startTimeDisplay}} @endTimeDisplay={{this.endTimeDisplay}} @isDateRange={{this.isDateRange}} + @timestamp={{this.responseTimestamp}} /> {{else}} {{! ARG TODO remove once we have this dialed }} diff --git a/ui/app/templates/components/clients/single-month.hbs b/ui/app/templates/components/clients/single-month.hbs deleted file mode 100644 index 49ce09a17..000000000 --- a/ui/app/templates/components/clients/single-month.hbs +++ /dev/null @@ -1,33 +0,0 @@ -
-
-

{{@month}}

-
- -
-
- -
- - -
-
- -
- -
- - -
-
-
-
\ No newline at end of file diff --git a/ui/app/templates/components/clients/usage-stats.hbs b/ui/app/templates/components/clients/usage-stats.hbs new file mode 100644 index 000000000..d6182c570 --- /dev/null +++ b/ui/app/templates/components/clients/usage-stats.hbs @@ -0,0 +1,42 @@ +
+ + +
+
+ +
+
+ +
+
+ +
+
+
\ No newline at end of file