mirror of
https://github.com/hashicorp/vault.git
synced 2025-08-25 00:21:07 +02:00
* cleanup namespaceArrayToObject method * WIP typescript conversion * WIP typescripted destructured block * slowly making progress.... * WIP move all types to util type file, separate returns in formatByMonths * namespaceArrayToObject is working?!? * fix mirage handler not generating months when queries are after upgrade * wow, the types are actually working omg * add comments and update client-count-utils test * delete old js file * remove types from activity model * remove comment * reuse totalclients type to minimize places we add types * commit file with type changes for git diff * delete util file again * address PR feedback and move type declarations to util file * remove unused types * update tests, use client helper in dashboard clients test * remove typo * make modifications with updated combined activity response from the backend
170 lines
5.2 KiB
TypeScript
170 lines
5.2 KiB
TypeScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
// base component for counts child routes that can be extended as needed
|
|
// contains getters that filter and extract data from activity model for use in charts
|
|
|
|
import Component from '@glimmer/component';
|
|
import { isSameMonth, fromUnixTime } from 'date-fns';
|
|
import { parseAPITimestamp } from 'core/utils/date-formatters';
|
|
import { calculateAverage } from 'vault/utils/chart-helpers';
|
|
import { filterVersionHistory, hasMountsKey, hasNamespacesKey } from 'core/utils/client-count-utils';
|
|
|
|
import type ClientsActivityModel from 'vault/models/clients/activity';
|
|
import type ClientsVersionHistoryModel from 'vault/models/clients/version-history';
|
|
import type {
|
|
ByMonthNewClients,
|
|
MountNewClients,
|
|
NamespaceByKey,
|
|
NamespaceNewClients,
|
|
} from 'core/utils/client-count-utils';
|
|
|
|
interface Args {
|
|
isSecretsSyncActivated?: boolean;
|
|
activity: ClientsActivityModel;
|
|
versionHistory: ClientsVersionHistoryModel[];
|
|
startTimestamp: number;
|
|
endTimestamp: number;
|
|
namespace: string;
|
|
mountPath: string;
|
|
}
|
|
|
|
export default class ClientsActivityComponent extends Component<Args> {
|
|
average = (
|
|
data:
|
|
| (ByMonthNewClients | NamespaceNewClients | MountNewClients | undefined)[]
|
|
| (NamespaceByKey | undefined)[],
|
|
key: string
|
|
) => {
|
|
return calculateAverage(data, key);
|
|
};
|
|
|
|
get startTimeISO() {
|
|
return fromUnixTime(this.args.startTimestamp).toISOString();
|
|
}
|
|
|
|
get endTimeISO() {
|
|
return fromUnixTime(this.args.endTimestamp).toISOString();
|
|
}
|
|
|
|
get byMonthActivityData() {
|
|
const { activity, namespace } = this.args;
|
|
return namespace ? this.filteredActivityByMonth : activity.byMonth;
|
|
}
|
|
|
|
get byMonthNewClients() {
|
|
return this.byMonthActivityData ? this.byMonthActivityData?.map((m) => m?.new_clients) : [];
|
|
}
|
|
|
|
get filteredActivityByMonth() {
|
|
const { namespace, mountPath, activity } = this.args;
|
|
if (!namespace && !mountPath) {
|
|
return activity.byMonth;
|
|
}
|
|
const namespaceData = activity.byMonth
|
|
?.map((m) => m.namespaces_by_key[namespace])
|
|
.filter((d) => d !== undefined);
|
|
|
|
if (!mountPath) {
|
|
return namespaceData || [];
|
|
}
|
|
|
|
const mountData = namespaceData
|
|
?.map((namespace) => namespace?.mounts_by_key[mountPath])
|
|
.filter((d) => d !== undefined);
|
|
|
|
return mountData || [];
|
|
}
|
|
|
|
get filteredActivityByNamespace() {
|
|
const { namespace, activity } = this.args;
|
|
return activity.byNamespace.find((ns) => ns.label === namespace);
|
|
}
|
|
|
|
get filteredActivityByAuthMount() {
|
|
return this.filteredActivityByNamespace?.mounts?.find((mount) => mount.label === this.args.mountPath);
|
|
}
|
|
|
|
get filteredActivity() {
|
|
return this.args.mountPath ? this.filteredActivityByAuthMount : this.filteredActivityByNamespace;
|
|
}
|
|
|
|
get isCurrentMonth() {
|
|
const { activity } = this.args;
|
|
const current = parseAPITimestamp(activity.responseTimestamp) as Date;
|
|
const start = parseAPITimestamp(activity.startTime) as Date;
|
|
const end = parseAPITimestamp(activity.endTime) as Date;
|
|
return isSameMonth(start, current) && isSameMonth(end, current);
|
|
}
|
|
|
|
get isDateRange() {
|
|
const { activity } = this.args;
|
|
return !isSameMonth(
|
|
parseAPITimestamp(activity.startTime) as Date,
|
|
parseAPITimestamp(activity.endTime) as Date
|
|
);
|
|
}
|
|
|
|
// (object) top level TOTAL client counts for given date range
|
|
get totalUsageCounts() {
|
|
const { namespace, activity } = this.args;
|
|
return namespace ? this.filteredActivity : activity.total;
|
|
}
|
|
|
|
get upgradesDuringActivity() {
|
|
const { versionHistory, activity } = this.args;
|
|
return filterVersionHistory(versionHistory, activity.startTime, activity.endTime);
|
|
}
|
|
|
|
// (object) single month new client data with total counts and array of
|
|
// either namespaces or mounts
|
|
get newClientCounts() {
|
|
if (this.isDateRange || this.byMonthActivityData.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
return this.byMonthActivityData[0]?.new_clients;
|
|
}
|
|
|
|
// total client data for horizontal bar chart in attribution component
|
|
get totalClientAttribution() {
|
|
const { namespace, activity } = this.args;
|
|
if (namespace) {
|
|
return this.filteredActivityByNamespace?.mounts || null;
|
|
} else {
|
|
return activity.byNamespace || null;
|
|
}
|
|
}
|
|
|
|
// new client data for horizontal bar chart
|
|
get newClientAttribution() {
|
|
// new client attribution only available in a single, historical month (not a date range or current month)
|
|
if (this.isDateRange || this.isCurrentMonth || !this.newClientCounts) return null;
|
|
|
|
const newCounts = this.newClientCounts;
|
|
if (this.args.namespace && hasMountsKey(newCounts)) return newCounts?.mounts;
|
|
|
|
if (hasNamespacesKey(newCounts)) return newCounts?.namespaces;
|
|
|
|
return null;
|
|
}
|
|
|
|
get hasAttributionData() {
|
|
const { mountPath, namespace } = this.args;
|
|
if (!mountPath) {
|
|
if (namespace) {
|
|
const mounts = this.filteredActivityByNamespace?.mounts?.map((mount) => ({
|
|
id: mount.label,
|
|
name: mount.label,
|
|
}));
|
|
return mounts && mounts.length > 0;
|
|
}
|
|
return !!this.totalClientAttribution && this.totalUsageCounts && this.totalUsageCounts.clients !== 0;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|