mirror of
https://github.com/hashicorp/vault.git
synced 2025-09-18 12:21:07 +02:00
* rename query params to match keys from api response * move type guard check to util * update color scheme * remove passing selected namespace to export activity data request * remove namespace and mount filter toolbar * update response, sort by client count number * remove default page size for testing * implement table and filters in overview tab * remove old query params * cleanup unused args * revert page header changes * update mirage, remove month from utils * update client count utils * one more color! * reset table to page 1; * workaround to force Hds::Pagination::Numbered to update when currentPage changes * add empty state test for no attribution * delete unused methods * add test for new utils * add changelog * rename changelog --------- Co-authored-by: claire bontempo <cbontempo@hashicorp.com>
144 lines
4.9 KiB
JavaScript
144 lines
4.9 KiB
JavaScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
import { action } from '@ember/object';
|
|
import { service } from '@ember/service';
|
|
import { waitFor } from '@ember/test-waiters';
|
|
import Component from '@glimmer/component';
|
|
import { tracked } from '@glimmer/tracking';
|
|
import { parseAPITimestamp } from 'core/utils/date-formatters';
|
|
import { sanitizePath } from 'core/utils/sanitize-path';
|
|
import { isSameMonth } from 'date-fns';
|
|
import { task } from 'ember-concurrency';
|
|
|
|
/**
|
|
* @module ClientsPageHeader
|
|
* ClientsPageHeader components are used to render a header and check for export capabilities before rendering an export button.
|
|
*
|
|
* @example
|
|
* ```js
|
|
* <Clients::PageHeader @startTimestamp="2022-06-01T23:00:11.050Z" @endTimestamp="2022-12-01T23:00:11.050Z" @namespace="foo" @upgradesDuringActivity={{array (hash version="1.10.1" previousVersion="1.9.1" timestampInstalled= "2021-11-18T10:23:16Z") }} />
|
|
* ```
|
|
* @param {string} [billingStartTime] - ISO timestamp of billing start date, to be passed to date picker
|
|
* @param {string} [activityTimestamp] - ISO timestamp created in serializer to timestamp the response to be displayed in page header
|
|
* @param {string} [startTimestamp] - ISO timestamp of start time, to be passed to export request
|
|
* @param {string} [endTimestamp] - ISO timestamp of end time, to be passed to export request
|
|
* @param {number} [retentionMonths = 48] - number of months for historical billing, to be passed to date picker
|
|
* @param {string} [upgradesDuringActivity] - array of objects containing version history upgrade data
|
|
* @param {boolean} [noData = false] - when true, export button will hide regardless of capabilities
|
|
* @param {function} [onChange] - callback when a new date range is saved, to be passed to date picker
|
|
*/
|
|
export default class ClientsPageHeaderComponent extends Component {
|
|
@service download;
|
|
@service namespace;
|
|
@service store;
|
|
@service version;
|
|
|
|
@tracked canDownload = false;
|
|
@tracked showEditModal = false;
|
|
@tracked showExportModal = false;
|
|
@tracked exportFormat = 'csv';
|
|
@tracked downloadError = '';
|
|
|
|
constructor() {
|
|
super(...arguments);
|
|
this.getExportCapabilities();
|
|
}
|
|
|
|
get showExportButton() {
|
|
if (this.args.noData === true) return false;
|
|
return this.canDownload;
|
|
}
|
|
|
|
@waitFor
|
|
async getExportCapabilities() {
|
|
const ns = this.namespace.path;
|
|
try {
|
|
// selected namespace usually ends in /
|
|
const url = ns
|
|
? `${sanitizePath(ns)}/sys/internal/counters/activity/export`
|
|
: 'sys/internal/counters/activity/export';
|
|
const cap = await this.store.findRecord('capabilities', url);
|
|
this.canDownload = cap.canSudo;
|
|
} catch (e) {
|
|
// if we can't read capabilities, default to show
|
|
this.canDownload = true;
|
|
}
|
|
}
|
|
|
|
get formattedStartDate() {
|
|
if (!this.args.startTimestamp) return null;
|
|
return parseAPITimestamp(this.args.startTimestamp, 'MMMM yyyy');
|
|
}
|
|
|
|
get formattedEndDate() {
|
|
if (!this.args.endTimestamp) return null;
|
|
return parseAPITimestamp(this.args.endTimestamp, 'MMMM yyyy');
|
|
}
|
|
|
|
get showEndDate() {
|
|
// displays on CSV export modal, no need to display duplicate months and years
|
|
if (!this.args.endTimestamp) return false;
|
|
const startDateObject = parseAPITimestamp(this.args.startTimestamp);
|
|
const endDateObject = parseAPITimestamp(this.args.endTimestamp);
|
|
return !isSameMonth(startDateObject, endDateObject);
|
|
}
|
|
|
|
get formattedCsvFileName() {
|
|
const endRange = this.showEndDate ? `-${this.formattedEndDate}` : '';
|
|
const csvDateRange = this.formattedStartDate ? `_${this.formattedStartDate + endRange}` : '';
|
|
const ns = this.namespace.path ? `_${this.namespace.path}` : '';
|
|
return `clients_export${ns}${csvDateRange}`;
|
|
}
|
|
|
|
get showCommunity() {
|
|
return this.version.isCommunity && !!this.formattedStartDate && !!this.formattedEndDate;
|
|
}
|
|
|
|
async getExportData() {
|
|
const adapter = this.store.adapterFor('clients/activity');
|
|
const { startTimestamp, endTimestamp } = this.args;
|
|
return adapter.exportData({
|
|
// the API only accepts json or csv
|
|
format: this.exportFormat === 'jsonl' ? 'json' : 'csv',
|
|
start_time: startTimestamp,
|
|
end_time: endTimestamp,
|
|
namespace: this.namespace.path,
|
|
});
|
|
}
|
|
|
|
exportChartData = task({ drop: true }, async (filename) => {
|
|
try {
|
|
const contents = await this.getExportData();
|
|
this.download.download(filename, contents, this.exportFormat);
|
|
this.showExportModal = false;
|
|
} catch (e) {
|
|
this.downloadError = e.message;
|
|
}
|
|
});
|
|
|
|
@action
|
|
setExportFormat(evt) {
|
|
const { value } = evt.target;
|
|
this.exportFormat = value;
|
|
}
|
|
|
|
@action
|
|
resetModal() {
|
|
this.showExportModal = false;
|
|
this.downloadError = '';
|
|
}
|
|
|
|
@action
|
|
setEditModalVisible(visible) {
|
|
this.showEditModal = visible;
|
|
}
|
|
|
|
// LOCAL TEMPLATE HELPERS
|
|
parseAPITimestamp = (timestamp, format) => {
|
|
return parseAPITimestamp(timestamp, format);
|
|
};
|
|
}
|