mirror of
https://github.com/hashicorp/vault.git
synced 2026-02-03 20:40:45 -05:00
UI: CE Datepicker (#30488)
* CE date picker and header changes * update test * add changelog and update empty component css * update modal values from args * update modal copy * header changes to add docs and move edit button * move + update test * Update ui/app/components/clients/date-range.ts Co-authored-by: Angel Garbarino <Monkeychip@users.noreply.github.com> * Update ui/app/components/clients/date-range.ts Co-authored-by: Angel Garbarino <Monkeychip@users.noreply.github.com> * refactor modal state and update docs * update tests * update modal copy * Update changelog/30488.txt Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com> * update date parsing, docs link copy and tidy * update var name for clarity * add date range test to check for disallowing current month selection * update tests to reflect disallowal of current month (or beyond) date selection * move ce header into page header comp and update tests --------- Co-authored-by: Angel Garbarino <Monkeychip@users.noreply.github.com> Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com>
This commit is contained in:
parent
0920108754
commit
ddd34fdbc5
11 changed files with 255 additions and 138 deletions
3
changelog/30488.txt
Normal file
3
changelog/30488.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
```release-note:improvement
|
||||
ui: Update date selector in client count usage page to disable current month selection for Vault clusters without a license.
|
||||
```
|
||||
|
|
@ -2,96 +2,112 @@
|
|||
Copyright (c) HashiCorp, Inc.
|
||||
SPDX-License-Identifier: BUSL-1.1
|
||||
}}
|
||||
|
||||
<div ...attributes>
|
||||
<div class="is-flex-column align-items-end">
|
||||
<Hds::Text::Display @tag="p" @size="100" class="has-bottom-margin-xs">
|
||||
Change billing period
|
||||
</Hds::Text::Display>
|
||||
<div class="is-flex">
|
||||
{{#if this.version.isEnterprise}}
|
||||
<Hds::Dropdown class="has-left-margin-xs" @matchToggleWidth={{true}} as |D|>
|
||||
<D.ToggleButton @text="Billing start date" @color="secondary" data-test-date-range-edit />
|
||||
<D.Description @text="Current period" />
|
||||
<D.Checkmark
|
||||
{{on "click" (fn this.updateEnterpriseDateRange @billingStartTime)}}
|
||||
@selected={{eq this.selectedStart (this.formattedDate @billingStartTime)}}
|
||||
data-test-date-range-billing-start="0"
|
||||
>
|
||||
{{this.formattedDate @billingStartTime}}
|
||||
</D.Checkmark>
|
||||
{{#if this.historicalBillingPeriods.length}}
|
||||
<D.Separator />
|
||||
<D.Description @text="Historical periods" />
|
||||
{{#each this.historicalBillingPeriods as |period idx|}}
|
||||
<D.Checkmark
|
||||
{{on "click" (fn this.updateEnterpriseDateRange period)}}
|
||||
data-test-date-range-billing-start={{add idx 1}}
|
||||
@selected={{eq this.selectedStart (this.formattedDate period)}}
|
||||
>
|
||||
{{this.formattedDate period}}
|
||||
</D.Checkmark>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</Hds::Dropdown>
|
||||
{{else}}
|
||||
{{#if this.version.isEnterprise}}
|
||||
<Hds::Text::Display @tag="p" @size="100" class="has-bottom-margin-xs">
|
||||
Change billing period
|
||||
</Hds::Text::Display>
|
||||
<Hds::Dropdown class="has-left-margin-xs" @matchToggleWidth={{true}} as |D|>
|
||||
<D.ToggleButton @text="Billing start date" @color="secondary" data-test-date-range-edit />
|
||||
<D.Description @text="Current period" />
|
||||
<D.Checkmark
|
||||
{{on "click" (fn this.updateEnterpriseDateRange @billingStartTime)}}
|
||||
@selected={{eq this.selectedStart (this.formattedDate @billingStartTime)}}
|
||||
data-test-date-range-billing-start="0"
|
||||
>
|
||||
{{this.formattedDate @billingStartTime}}
|
||||
</D.Checkmark>
|
||||
{{#if this.historicalBillingPeriods.length}}
|
||||
<D.Separator />
|
||||
<D.Description @text="Historical periods" />
|
||||
{{#each this.historicalBillingPeriods as |period idx|}}
|
||||
<D.Checkmark
|
||||
{{on "click" (fn this.updateEnterpriseDateRange period)}}
|
||||
data-test-date-range-billing-start={{add idx 1}}
|
||||
@selected={{eq this.selectedStart (this.formattedDate period)}}
|
||||
>
|
||||
{{this.formattedDate period}}
|
||||
</D.Checkmark>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</Hds::Dropdown>
|
||||
{{else}}
|
||||
{{#unless (and this.startDate this.endDate)}}
|
||||
<Hds::Button
|
||||
class="has-left-margin-xs"
|
||||
@text="Set date range"
|
||||
@icon="edit"
|
||||
{{on "click" (fn (mut this.showEditModal) true)}}
|
||||
{{on "click" (fn @setEditModalVisible true)}}
|
||||
data-test-date-range-edit
|
||||
/>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
|
||||
{{#if this.showEditModal}}
|
||||
{{#if @showEditModal}}
|
||||
<Hds::Modal data-test-date-range-edit-modal @onClose={{this.onClose}} as |M|>
|
||||
<M.Header>
|
||||
Edit date range
|
||||
</M.Header>
|
||||
<M.Body>
|
||||
<p class="has-bottom-margin-s">
|
||||
The start date will be used as the client counting start time and all clients in that month will be considered new.
|
||||
</p>
|
||||
<div class="clients-date-range-display">
|
||||
<div>
|
||||
<Hds::Form::TextInput::Field
|
||||
@type="month"
|
||||
@value={{this.startDate}}
|
||||
max={{this.currentMonth}}
|
||||
id="start-month"
|
||||
name="start"
|
||||
{{on "change" this.updateDate}}
|
||||
data-test-date-edit="start"
|
||||
as |F|
|
||||
>
|
||||
<F.Label>Start</F.Label>
|
||||
</Hds::Form::TextInput::Field>
|
||||
<Hds::Text::Body @tag="div">
|
||||
<p class="has-bottom-margin-s">
|
||||
Use custom date ranges to query historic client count data. Query results do not include the current month.
|
||||
</p>
|
||||
<ul class="has-bottom-margin-s">
|
||||
<li>
|
||||
<strong>Start</strong>
|
||||
sets the month and year (inclusive) for the first month of client counting.
|
||||
</li>
|
||||
<li>
|
||||
<strong>End</strong>
|
||||
sets the month and year (inclusive) for the final month of client counting.
|
||||
</li>
|
||||
</ul>
|
||||
<p class="has-bottom-margin-s">
|
||||
We recommend setting
|
||||
<strong>Start</strong>
|
||||
to your Vault deploy date to get the most accurate new and total client count estimations.</p>
|
||||
|
||||
<div class="clients-date-range-display">
|
||||
<div>
|
||||
<Hds::Form::TextInput::Field
|
||||
@type="month"
|
||||
@value={{this.modalStart}}
|
||||
max={{this.previousMonth}}
|
||||
id="start-month"
|
||||
name="start"
|
||||
{{on "change" this.updateDate}}
|
||||
data-test-date-edit="start"
|
||||
as |F|
|
||||
>
|
||||
<F.Label>Start</F.Label>
|
||||
</Hds::Form::TextInput::Field>
|
||||
</div>
|
||||
<div>
|
||||
<Hds::Form::TextInput::Field
|
||||
@type="month"
|
||||
@value={{this.modalEnd}}
|
||||
max={{this.previousMonth}}
|
||||
id="end-month"
|
||||
name="end"
|
||||
{{on "change" this.updateDate}}
|
||||
data-test-date-edit="end"
|
||||
as |F|
|
||||
>
|
||||
<F.Label>End</F.Label>
|
||||
</Hds::Form::TextInput::Field>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Hds::Form::TextInput::Field
|
||||
@type="month"
|
||||
@value={{this.endDate}}
|
||||
max={{this.currentMonth}}
|
||||
id="end-month"
|
||||
name="end"
|
||||
{{on "change" this.updateDate}}
|
||||
data-test-date-edit="end"
|
||||
as |F|
|
||||
>
|
||||
<F.Label>End</F.Label>
|
||||
</Hds::Form::TextInput::Field>
|
||||
</div>
|
||||
</div>
|
||||
{{#if this.validationError}}
|
||||
<Hds::Form::Error
|
||||
class="has-top-margin-xs"
|
||||
data-test-date-range-validation
|
||||
>{{this.validationError}}</Hds::Form::Error>
|
||||
{{/if}}
|
||||
{{#if this.validationError}}
|
||||
<Hds::Form::Error
|
||||
class="has-top-margin-xs"
|
||||
data-test-date-range-validation
|
||||
>{{this.validationError}}</Hds::Form::Error>
|
||||
{{/if}}
|
||||
</Hds::Text::Body>
|
||||
</M.Body>
|
||||
<M.Footer as |F|>
|
||||
<Hds::Button data-test-save @text="Save" {{on "click" this.handleSave}} />
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ interface OnChangeParams {
|
|||
}
|
||||
interface Args {
|
||||
onChange: (callback: OnChangeParams) => void;
|
||||
setEditModalVisible: (visible: boolean) => void;
|
||||
showEditModal: boolean;
|
||||
startTime: string;
|
||||
endTime: string;
|
||||
billingStartTime: string;
|
||||
|
|
@ -34,6 +36,8 @@ interface Args {
|
|||
* <Clients::DateRange @startTime="2018-01-01T14:15:30Z" @endTime="2019-01-31T14:15:30Z" @onChange={{this.handleDateChange}} />
|
||||
*
|
||||
* @param {function} onChange - callback when a new range is saved.
|
||||
* @param {function} setEditModalVisible - callback to tell parent header when modal is opened/closed
|
||||
* @param {boolean} showEditModal - boolean for when parent header triggers the modal open
|
||||
* @param {string} [startTime] - ISO string timestamp of the current start date
|
||||
* @param {string} [endTime] - ISO string timestamp of the current end date
|
||||
* @param {int} [retentionMonths=48] - number of months for historical billing
|
||||
|
|
@ -43,11 +47,17 @@ interface Args {
|
|||
export default class ClientsDateRangeComponent extends Component<Args> {
|
||||
@service declare readonly version: VersionService;
|
||||
|
||||
@tracked showEditModal = false;
|
||||
@tracked startDate = ''; // format yyyy-MM
|
||||
@tracked endDate = ''; // format yyyy-MM
|
||||
@tracked selectedStart = this.args.billingStartTime;
|
||||
currentMonth = format(timestamp.now(), 'yyyy-MM');
|
||||
@tracked modalStart = ''; // format yyyy-MM
|
||||
@tracked modalEnd = ''; // format yyyy-MM
|
||||
|
||||
currentMonth = timestamp.now();
|
||||
previousMonth = format(
|
||||
new Date(this.currentMonth.getFullYear(), this.currentMonth.getMonth() - 1, 1),
|
||||
'yyyy-MM'
|
||||
);
|
||||
|
||||
constructor(owner: unknown, args: Args) {
|
||||
super(owner, args);
|
||||
|
|
@ -57,10 +67,12 @@ export default class ClientsDateRangeComponent extends Component<Args> {
|
|||
setTrackedFromArgs() {
|
||||
if (this.args.startTime) {
|
||||
this.startDate = parseAPITimestamp(this.args.startTime, 'yyyy-MM') as string;
|
||||
this.modalStart = this.startDate;
|
||||
this.selectedStart = this.formattedDate(this.args.startTime) as string;
|
||||
}
|
||||
if (this.args.endTime) {
|
||||
this.endDate = parseAPITimestamp(this.args.endTime, 'yyyy-MM') as string;
|
||||
this.modalEnd = this.endDate;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -96,19 +108,21 @@ export default class ClientsDateRangeComponent extends Component<Args> {
|
|||
// this means we want to reset, which is fine for ent only
|
||||
return null;
|
||||
}
|
||||
if (!this.startDate || !this.endDate) {
|
||||
if (!this.modalStart || !this.modalEnd) {
|
||||
return 'You must supply both start and end dates.';
|
||||
}
|
||||
if (this.startDate > this.endDate) {
|
||||
if (this.modalStart > this.modalEnd) {
|
||||
return 'Start date must be before end date.';
|
||||
}
|
||||
if (this.modalStart > this.previousMonth || this.modalEnd > this.previousMonth)
|
||||
return 'You cannot select the current month or beyond.';
|
||||
return null;
|
||||
}
|
||||
|
||||
@action onClose() {
|
||||
// since the component never gets torn down, we have to manually re-set this on close
|
||||
this.setTrackedFromArgs();
|
||||
this.showEditModal = false;
|
||||
this.args.setEditModalVisible(false);
|
||||
}
|
||||
|
||||
@action resetDates() {
|
||||
|
|
@ -119,9 +133,9 @@ export default class ClientsDateRangeComponent extends Component<Args> {
|
|||
@action updateDate(evt: HTMLElementEvent<HTMLInputElement>) {
|
||||
const { name, value } = evt.target;
|
||||
if (name === 'end') {
|
||||
this.endDate = value;
|
||||
this.modalEnd = value;
|
||||
} else {
|
||||
this.startDate = value;
|
||||
this.modalStart = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -132,17 +146,17 @@ export default class ClientsDateRangeComponent extends Component<Args> {
|
|||
start_time: undefined,
|
||||
end_time: undefined,
|
||||
};
|
||||
if (this.startDate) {
|
||||
const [year, month] = this.startDate.split('-');
|
||||
if (year && month) {
|
||||
params.start_time = formatDateObject({ monthIdx: parseInt(month) - 1, year: parseInt(year) }, false);
|
||||
}
|
||||
this.startDate = this.modalStart;
|
||||
this.endDate = this.modalEnd;
|
||||
|
||||
let year, month;
|
||||
[year, month] = this.startDate.split('-');
|
||||
if (year && month) {
|
||||
params.start_time = formatDateObject({ monthIdx: Number(month) - 1, year: Number(year) }, false);
|
||||
}
|
||||
if (this.endDate) {
|
||||
const [year, month] = this.endDate.split('-');
|
||||
if (year && month) {
|
||||
params.end_time = formatDateObject({ monthIdx: parseInt(month) - 1, year: parseInt(year) }, true);
|
||||
}
|
||||
[year, month] = this.endDate.split('-');
|
||||
if (year && month) {
|
||||
params.end_time = formatDateObject({ monthIdx: Number(month) - 1, year: Number(year) }, true);
|
||||
}
|
||||
|
||||
this.args.onChange(params);
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
<PH.Title>
|
||||
Client Usage
|
||||
</PH.Title>
|
||||
{{#if (and this.formattedStartDate this.formattedEndDate)}}
|
||||
<PH.Description class="has-text-weight-semibold">
|
||||
{{#if this.version.isEnterprise}}
|
||||
<PH.Description class="has-text-weight-semibold flex">
|
||||
<p>
|
||||
For billing period:
|
||||
<span data-test-date-range="start">{{this.formattedStartDate}}</span>
|
||||
|
|
@ -17,7 +17,36 @@
|
|||
</p>
|
||||
</PH.Description>
|
||||
{{/if}}
|
||||
<PH.Actions class="align-items-end">
|
||||
<PH.Description>
|
||||
This is the dashboard for your overall client count usages. Review Vault's
|
||||
<Hds::Link::Inline @href={{doc-link "/vault/docs/concepts/client-count"}}>client counting documentation
|
||||
</Hds::Link::Inline>for more information.
|
||||
|
||||
{{#if this.showCommunity}}
|
||||
<div class="has-top-padding-m">
|
||||
<Hds::Text::Display @tag="h3">Client counting period</Hds::Text::Display>
|
||||
<Hds::Text::Body @tag="p" class="has-text-grey">Specify a date range to view within that timeframe. Click 'Edit' to
|
||||
choose a different date range.</Hds::Text::Body>
|
||||
<Hds::Text::Body @tag="p">
|
||||
<span data-test-date-range="start">{{this.formattedStartDate}}</span>
|
||||
-
|
||||
<span data-test-date-range="end">{{this.formattedEndDate}}</span>
|
||||
<Hds::Button
|
||||
@size="small"
|
||||
@text="Edit"
|
||||
@isInline="true"
|
||||
@color="tertiary"
|
||||
@icon="edit"
|
||||
@iconPosition="trailing"
|
||||
data-test-date-range-edit
|
||||
{{on "click" (fn (mut this.showEditModal) true)}}
|
||||
/>
|
||||
</Hds::Text::Body>
|
||||
</div>
|
||||
{{/if}}
|
||||
</PH.Description>
|
||||
|
||||
<PH.Actions class="align-items-end align-self-end">
|
||||
{{#if this.showExportButton}}
|
||||
<Hds::Button
|
||||
class="has-font-weight-normal"
|
||||
|
|
@ -34,8 +63,12 @@
|
|||
@billingStartTime={{@billingStartTime}}
|
||||
@retentionMonths={{@retentionMonths}}
|
||||
@onChange={{@onChange}}
|
||||
@showEditModal={{this.showEditModal}}
|
||||
@setEditModalVisible={{this.setEditModalVisible}}
|
||||
class={{if (and this.version.isCommunity this.startDate this.endDate) "position-absolute"}}
|
||||
/>
|
||||
</PH.Actions>
|
||||
|
||||
</Hds::PageHeader>
|
||||
|
||||
{{#if this.showExportModal}}
|
||||
|
|
|
|||
|
|
@ -21,11 +21,14 @@ import { task } from 'ember-concurrency';
|
|||
* ```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 string timestamp of billing start date, to be passed to datepicker
|
||||
* @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 datepicker
|
||||
* @param {string} [namespace] - namespace filter. Will be appended to the current namespace in the export request.
|
||||
* @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 range is saved, to be passed to datepicker
|
||||
*/
|
||||
export default class ClientsPageHeaderComponent extends Component {
|
||||
@service download;
|
||||
|
|
@ -34,6 +37,7 @@ export default class ClientsPageHeaderComponent extends Component {
|
|||
@service version;
|
||||
|
||||
@tracked canDownload = false;
|
||||
@tracked showEditModal = false;
|
||||
@tracked showExportModal = false;
|
||||
@tracked exportFormat = 'csv';
|
||||
@tracked downloadError = '';
|
||||
|
|
@ -94,6 +98,10 @@ export default class ClientsPageHeaderComponent extends Component {
|
|||
return namespace ? sanitizePath(`${currentNs}/${namespace}`) : sanitizePath(currentNs);
|
||||
}
|
||||
|
||||
get showCommunity() {
|
||||
return this.version.isCommunity && !!this.formattedStartDate && !!this.formattedEndDate;
|
||||
}
|
||||
|
||||
async getExportData() {
|
||||
const adapter = this.store.adapterFor('clients/activity');
|
||||
const { startTimestamp, endTimestamp } = this.args;
|
||||
|
|
@ -120,13 +128,20 @@ export default class ClientsPageHeaderComponent extends Component {
|
|||
}
|
||||
});
|
||||
|
||||
@action setExportFormat(evt) {
|
||||
@action
|
||||
setExportFormat(evt) {
|
||||
const { value } = evt.target;
|
||||
this.exportFormat = value;
|
||||
}
|
||||
|
||||
@action resetModal() {
|
||||
@action
|
||||
resetModal() {
|
||||
this.showExportModal = false;
|
||||
this.downloadError = '';
|
||||
}
|
||||
|
||||
@action
|
||||
setEditModalVisible(visible) {
|
||||
this.showEditModal = visible;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ export default class ClientsCountsPageComponent extends Component<Args> {
|
|||
return this.args.startTimestamp ? parseAPITimestamp(this.args.startTimestamp, 'MMMM yyyy') : null;
|
||||
}
|
||||
|
||||
get formattedEndDate() {
|
||||
return this.args.endTimestamp ? parseAPITimestamp(this.args.endTimestamp, 'MMMM yyyy') : null;
|
||||
}
|
||||
|
||||
get formattedBillingStartDate() {
|
||||
return this.args.config.billingStartTimestamp.toISOString();
|
||||
}
|
||||
|
|
@ -200,7 +204,8 @@ export default class ClientsCountsPageComponent extends Component<Args> {
|
|||
this.args.onFilterChange(params);
|
||||
}
|
||||
|
||||
@action resetFilters() {
|
||||
@action
|
||||
resetFilters() {
|
||||
this.args.onFilterChange({
|
||||
start_time: undefined,
|
||||
end_time: undefined,
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.position-absolute {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.top-xxs {
|
||||
top: size_variables.$spacing-4;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ HOW TO ADD NEW TYPES:
|
|||
*/
|
||||
export const LICENSE_START = new Date('2023-07-02T00:00:00Z');
|
||||
export const STATIC_NOW = new Date('2024-01-25T23:59:59Z');
|
||||
export const STATIC_PREVIOUS_MONTH = new Date('2023-12-25T23:59:59Z');
|
||||
const COUNTS_START = subMonths(STATIC_NOW, 12); // user started Vault cluster on 2023-01-25
|
||||
// upgrade happened 2 month after license start
|
||||
export const UPGRADE_DATE = addMonths(LICENSE_START, 2); // monthly attribution added
|
||||
|
|
|
|||
|
|
@ -6,7 +6,12 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupApplicationTest } from 'ember-qunit';
|
||||
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||
import clientsHandler, { STATIC_NOW, LICENSE_START, UPGRADE_DATE } from 'vault/mirage/handlers/clients';
|
||||
import clientsHandler, {
|
||||
STATIC_NOW,
|
||||
LICENSE_START,
|
||||
UPGRADE_DATE,
|
||||
STATIC_PREVIOUS_MONTH,
|
||||
} from 'vault/mirage/handlers/clients';
|
||||
import syncHandler from 'vault/mirage/handlers/sync';
|
||||
import sinon from 'sinon';
|
||||
import { visit, click, findAll, fillIn, currentURL } from '@ember/test-helpers';
|
||||
|
|
@ -63,11 +68,14 @@ module('Acceptance | clients | overview', function (hooks) {
|
|||
assert.dom(CHARTS.xAxisLabel).exists({ count: 7 }, 'chart months matches query');
|
||||
});
|
||||
|
||||
// TODO revisit once CE changes are finalized
|
||||
test.skip('it should update charts when querying date ranges', async function (assert) {
|
||||
test('it should update charts when querying date ranges', async function (assert) {
|
||||
// query for single, historical month with no new counts (July 2023)
|
||||
const service = this.owner.lookup('service:version');
|
||||
service.type = 'community';
|
||||
|
||||
const licenseStartMonth = format(LICENSE_START, 'yyyy-MM');
|
||||
const upgradeMonth = format(UPGRADE_DATE, 'yyyy-MM');
|
||||
const endMonth = format(STATIC_PREVIOUS_MONTH, 'yyyy-MM');
|
||||
await click(CLIENT_COUNT.dateRange.edit);
|
||||
await fillIn(CLIENT_COUNT.dateRange.editDate('start'), licenseStartMonth);
|
||||
await fillIn(CLIENT_COUNT.dateRange.editDate('end'), licenseStartMonth);
|
||||
|
|
@ -83,22 +91,14 @@ module('Acceptance | clients | overview', function (hooks) {
|
|||
assert.dom(CHARTS.container('namespace')).exists('namespace attribution chart shows');
|
||||
assert.dom(CHARTS.container('mount')).exists('mount attribution chart shows');
|
||||
|
||||
// reset to billing period
|
||||
await click(CLIENT_COUNT.dateRange.edit);
|
||||
await click(CLIENT_COUNT.dateRange.reset);
|
||||
await click(GENERAL.saveButton);
|
||||
|
||||
// change to start on month/year of upgrade to 1.10
|
||||
await click(CLIENT_COUNT.dateRange.edit);
|
||||
await fillIn(CLIENT_COUNT.dateRange.editDate('start'), upgradeMonth);
|
||||
await fillIn(CLIENT_COUNT.dateRange.editDate('end'), endMonth);
|
||||
await click(GENERAL.saveButton);
|
||||
|
||||
assert
|
||||
.dom(CLIENT_COUNT.dateRange.dateDisplay('start'))
|
||||
.hasText('September 2023', 'billing start month is correctly parsed from license');
|
||||
assert
|
||||
.dom(CLIENT_COUNT.dateRange.dateDisplay('end'))
|
||||
.hasText('January 2024', 'billing start month is correctly parsed from license');
|
||||
assert.dom(CLIENT_COUNT.attributionBlock()).exists({ count: 2 });
|
||||
assert
|
||||
.dom(CHARTS.container('Vault client counts'))
|
||||
|
|
@ -106,7 +106,7 @@ module('Acceptance | clients | overview', function (hooks) {
|
|||
assert
|
||||
.dom(`${CHARTS.container('Vault client counts')} ${CHARTS.xAxisLabel}`)
|
||||
.hasText('9/23', 'x-axis labels start with queried start month (upgrade date)');
|
||||
assert.dom(CHARTS.xAxisLabel).exists({ count: 5 }, 'chart months matches query');
|
||||
assert.dom(CHARTS.xAxisLabel).exists({ count: 4 }, 'chart months matches query');
|
||||
|
||||
// query for single, historical month (upgrade month)
|
||||
await click(CLIENT_COUNT.dateRange.edit);
|
||||
|
|
@ -147,16 +147,10 @@ module('Acceptance | clients | overview', function (hooks) {
|
|||
.dom(xAxisLabels[xAxisLabels.length - 1])
|
||||
.hasText('12/23', 'x-axis labels end with queried end month');
|
||||
|
||||
// reset to billing period
|
||||
await click(CLIENT_COUNT.dateRange.edit);
|
||||
await click(CLIENT_COUNT.dateRange.reset);
|
||||
await click(GENERAL.saveButton);
|
||||
|
||||
// query month older than count start date
|
||||
await click(CLIENT_COUNT.dateRange.edit);
|
||||
await fillIn(CLIENT_COUNT.dateRange.editDate('start'), '2020-07');
|
||||
await click(GENERAL.saveButton);
|
||||
|
||||
assert
|
||||
.dom(CLIENT_COUNT.counts.startDiscrepancy)
|
||||
.hasTextContaining(
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { click, fillIn, render } from '@ember/test-helpers';
|
|||
import { hbs } from 'ember-cli-htmlbars';
|
||||
import Sinon from 'sinon';
|
||||
import timestamp from 'core/utils/timestamp';
|
||||
import { format } from 'date-fns';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
import { CLIENT_COUNT } from 'vault/tests/helpers/clients/client-count-selectors';
|
||||
|
||||
|
|
@ -24,9 +25,13 @@ module('Integration | Component | clients/date-range', function (hooks) {
|
|||
this.billingStartTime = '2018-01-01T14:15:30';
|
||||
this.retentionMonths = 48;
|
||||
this.onChange = Sinon.spy();
|
||||
this.setEditModalVisible = Sinon.stub().callsFake((visible) => {
|
||||
this.set('showEditModal', visible);
|
||||
});
|
||||
this.showEditModal = false;
|
||||
this.renderComponent = async () => {
|
||||
await render(
|
||||
hbs`<Clients::DateRange @startTime={{this.startTime}} @endTime={{this.endTime}} @onChange={{this.onChange}} @billingStartTime={{this.billingStartTime}} @retentionMonths={{this.retentionMonths}}/>`
|
||||
hbs`<Clients::DateRange @startTime={{this.startTime}} @endTime={{this.endTime}} @onChange={{this.onChange}} @billingStartTime={{this.billingStartTime}} @retentionMonths={{this.retentionMonths}} @setEditModalVisible={{this.setEditModalVisible}} @showEditModal={{this.showEditModal}}/>`
|
||||
);
|
||||
};
|
||||
});
|
||||
|
|
@ -43,11 +48,11 @@ module('Integration | Component | clients/date-range', function (hooks) {
|
|||
assert.dom(DATE_RANGE.editModal).exists();
|
||||
assert.dom(DATE_RANGE.editDate('start')).hasValue('');
|
||||
await fillIn(DATE_RANGE.editDate('start'), '2018-01');
|
||||
await fillIn(DATE_RANGE.editDate('end'), '2019-01');
|
||||
await fillIn(DATE_RANGE.editDate('end'), '2018-03');
|
||||
await click(GENERAL.saveButton);
|
||||
assert.deepEqual(this.onChange.args[0], [
|
||||
{
|
||||
end_time: 1548892800,
|
||||
end_time: 1522454400,
|
||||
start_time: 1514764800,
|
||||
},
|
||||
]);
|
||||
|
|
@ -56,8 +61,8 @@ module('Integration | Component | clients/date-range', function (hooks) {
|
|||
|
||||
test('it does not trigger onChange if date range invalid', async function (assert) {
|
||||
this.owner.lookup('service:version').type = 'community';
|
||||
this.endTime = undefined;
|
||||
await this.renderComponent();
|
||||
|
||||
await click(DATE_RANGE.edit);
|
||||
await fillIn(DATE_RANGE.editDate('end'), '');
|
||||
assert.dom(DATE_RANGE.validation).hasText('You must supply both start and end dates.');
|
||||
|
|
@ -75,16 +80,26 @@ module('Integration | Component | clients/date-range', function (hooks) {
|
|||
assert.dom(DATE_RANGE.editModal).doesNotExist();
|
||||
});
|
||||
|
||||
test('it resets the tracked values on close', async function (assert) {
|
||||
test('it does not allow the current month to be selected as a start date or as an end date', async function (assert) {
|
||||
this.owner.lookup('service:version').type = 'community';
|
||||
this.endTime = undefined;
|
||||
const currentMonth = format(timestamp.now(), 'yyyy-MM');
|
||||
|
||||
await this.renderComponent();
|
||||
|
||||
await click(DATE_RANGE.edit);
|
||||
await fillIn(DATE_RANGE.editDate('start'), '2017-04');
|
||||
await fillIn(DATE_RANGE.editDate('end'), '2018-05');
|
||||
await click(GENERAL.cancelButton);
|
||||
await fillIn(DATE_RANGE.editDate('start'), currentMonth);
|
||||
await fillIn(DATE_RANGE.editDate('end'), currentMonth);
|
||||
|
||||
await click(DATE_RANGE.edit);
|
||||
assert.dom(DATE_RANGE.editDate('start')).hasValue('2018-01');
|
||||
assert.dom(DATE_RANGE.editDate('end')).hasValue('2019-01');
|
||||
assert.dom(DATE_RANGE.validation).hasText('You cannot select the current month or beyond.');
|
||||
await click(GENERAL.saveButton);
|
||||
assert.false(this.onChange.called);
|
||||
|
||||
// This tests validation when the end date is the current month and start is valid.
|
||||
// If start is current month and end is a valid prior selection, it will run into the validation error of start being after end date
|
||||
// which is covered by prior tests.
|
||||
await fillIn(DATE_RANGE.editDate('start'), '2018-01');
|
||||
await fillIn(DATE_RANGE.editDate('end'), currentMonth);
|
||||
await click(GENERAL.saveButton);
|
||||
assert.false(this.onChange.called);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,7 +8,11 @@ import { setupRenderingTest } from 'ember-qunit';
|
|||
import { setupMirage } from 'ember-cli-mirage/test-support';
|
||||
import { render, click, findAll, fillIn } from '@ember/test-helpers';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import clientsHandler, { LICENSE_START, STATIC_NOW } from 'vault/mirage/handlers/clients';
|
||||
import clientsHandler, {
|
||||
LICENSE_START,
|
||||
STATIC_NOW,
|
||||
STATIC_PREVIOUS_MONTH,
|
||||
} from 'vault/mirage/handlers/clients';
|
||||
import { fromUnixTime, getUnixTime } from 'date-fns';
|
||||
import { GENERAL } from 'vault/tests/helpers/general-selectors';
|
||||
import { CLIENT_COUNT } from 'vault/tests/helpers/clients/client-count-selectors';
|
||||
|
|
@ -18,9 +22,9 @@ import sinon from 'sinon';
|
|||
import { allowAllCapabilitiesStub } from 'vault/tests/helpers/stubs';
|
||||
|
||||
const START_TIME = getUnixTime(LICENSE_START);
|
||||
const END_TIME = getUnixTime(STATIC_NOW);
|
||||
const END_TIME = getUnixTime(STATIC_PREVIOUS_MONTH);
|
||||
const START_ISO = LICENSE_START.toISOString();
|
||||
const END_ISO = STATIC_NOW.toISOString();
|
||||
const END_ISO = STATIC_PREVIOUS_MONTH.toISOString();
|
||||
|
||||
module('Integration | Component | clients | Page::Counts', function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
|
@ -62,7 +66,7 @@ module('Integration | Component | clients | Page::Counts', function (hooks) {
|
|||
await this.renderComponent();
|
||||
|
||||
assert.dom(CLIENT_COUNT.dateRange.dateDisplay('start')).hasText('July 2023', 'Start month renders');
|
||||
assert.dom(CLIENT_COUNT.dateRange.dateDisplay('end')).hasText('January 2024', 'End month renders');
|
||||
assert.dom(CLIENT_COUNT.dateRange.dateDisplay('end')).hasText('December 2023', 'End month renders');
|
||||
});
|
||||
|
||||
test('it should render no data empty state', async function (assert) {
|
||||
|
|
@ -72,7 +76,7 @@ module('Integration | Component | clients | Page::Counts', function (hooks) {
|
|||
|
||||
assert
|
||||
.dom(GENERAL.emptyStateTitle)
|
||||
.hasText('No data received from July 2023 to January 2024', 'No data empty state renders');
|
||||
.hasText('No data received from July 2023 to December 2023', 'No data empty state renders');
|
||||
});
|
||||
|
||||
test('it should render activity error', async function (assert) {
|
||||
|
|
@ -100,14 +104,13 @@ module('Integration | Component | clients | Page::Counts', function (hooks) {
|
|||
// license start is July 2, 2024 on date change it recalculates start to beginning of the month
|
||||
const july23start = getUnixTime(new Date('2023-07-01T00:00:00Z'));
|
||||
const dec23end = getUnixTime(new Date('2023-12-31T00:00:00Z'));
|
||||
const jan24end = getUnixTime(new Date('2024-01-31T00:00:00Z'));
|
||||
[
|
||||
{
|
||||
scenario: 'changing start only',
|
||||
expected: { start_time: jan23start, end_time: jan24end },
|
||||
expected: { start_time: jan23start, end_time: dec23end },
|
||||
editStart: '2023-01',
|
||||
expectedStart: 'January 2023',
|
||||
expectedEnd: 'January 2024',
|
||||
expectedEnd: 'December 2023',
|
||||
},
|
||||
{
|
||||
scenario: 'changing end only',
|
||||
|
|
@ -142,9 +145,9 @@ module('Integration | Component | clients | Page::Counts', function (hooks) {
|
|||
await this.renderComponent();
|
||||
await click(CLIENT_COUNT.dateRange.edit);
|
||||
|
||||
// page starts with default billing dates, which are july 23 - jan 24
|
||||
// page starts with default billing dates, which are july 23 - dec 23
|
||||
assert.dom(CLIENT_COUNT.dateRange.editDate('start')).hasValue('2023-07');
|
||||
assert.dom(CLIENT_COUNT.dateRange.editDate('end')).hasValue('2024-01');
|
||||
assert.dom(CLIENT_COUNT.dateRange.editDate('end')).hasValue('2023-12');
|
||||
|
||||
if (testCase.editStart) {
|
||||
await fillIn(CLIENT_COUNT.dateRange.editDate('start'), testCase.editStart);
|
||||
|
|
@ -275,6 +278,20 @@ module('Integration | Component | clients | Page::Counts', function (hooks) {
|
|||
|
||||
assert
|
||||
.dom(GENERAL.emptyStateTitle)
|
||||
.hasText('No data received from July 2023 to January 2024', 'Empty state renders');
|
||||
.hasText('No data received from July 2023 to December 2023', 'Empty state renders');
|
||||
});
|
||||
|
||||
test('it resets the tracked values on close', async function (assert) {
|
||||
await this.renderComponent();
|
||||
const DATE_RANGE = CLIENT_COUNT.dateRange;
|
||||
|
||||
await click(DATE_RANGE.edit);
|
||||
await fillIn(DATE_RANGE.editDate('start'), '2017-04');
|
||||
await fillIn(DATE_RANGE.editDate('end'), '2018-05');
|
||||
await click(GENERAL.cancelButton);
|
||||
|
||||
await click(DATE_RANGE.edit);
|
||||
assert.dom(DATE_RANGE.editDate('start')).hasValue('2023-07');
|
||||
assert.dom(DATE_RANGE.editDate('end')).hasValue('2023-12');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue