Secrets Sync UI: Hide sync client data and add beta tags to feature work (#25170)

* hide sync billing related details

* add beta tags

* add csv comments

* remaining tests

* a couple more tests!
This commit is contained in:
claire bontempo 2024-02-01 12:42:58 -08:00 committed by GitHub
parent 9d86e5e111
commit c9d0bd2c19
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 95 additions and 53 deletions

View File

@ -88,6 +88,13 @@
Export attribution data
</M.Header>
<M.Body>
<p class="has-bottom-margin-s">
This export will include the namespace path, authentication method path, and the associated total, entity, and
non-entity clients for the
{{if this.formattedEndDate "date range" "month"}}
below.
</p>
{{!-- * SYNC BETA (1.16.0) - beta removal planned for 1.16.1 release, replace copy above with the following
<p class="has-bottom-margin-s">
This export will include the namespace path, mount path and associated total, entity, non-entity and secrets sync
clients for the
@ -100,6 +107,7 @@
for secrets sync clients is the KV v2 engine path and for entity/non-entity clients is the corresponding
authentication method path.
</p>
--}}
<p class="has-bottom-margin-s is-subtitle-gray">SELECTED DATE {{if this.formattedEndDate " RANGE"}}</p>
<p class="has-bottom-margin-s" data-test-export-date-range>
{{this.formattedStartDate}}

View File

@ -48,7 +48,7 @@ export default class Attribution extends Component {
attributionLegend = [
{ key: 'entity_clients', label: 'entity clients' },
{ key: 'non_entity_clients', label: 'non-entity clients' },
{ key: 'secret_syncs', label: 'secrets sync clients' },
// { key: 'secret_syncs', label: 'secrets sync clients' }, * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
];
get formattedStartDate() {
@ -125,11 +125,15 @@ export default class Attribution extends Component {
}
}
// secrets_syncs unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
// the three necessary CSV changes to add sync data are commented below
destructureCountsToArray(object) {
// destructure the namespace object {label: 'some-namespace', entity_clients: 171, non_entity_clients: 20, secret_syncs: 10, clients: 201}
// to get integers for CSV file
const { clients, entity_clients, non_entity_clients, secret_syncs } = object;
return [clients, entity_clients, non_entity_clients, secret_syncs];
// (1) SYNC BETA - add `secrets_syncs to destructured and returned object below
const { clients, entity_clients, non_entity_clients } = object;
return [clients, entity_clients, non_entity_clients];
}
constructCsvRow(namespaceColumn, mountColumn = null, totalColumns, newColumns = null) {
@ -161,13 +165,11 @@ export default class Attribution extends Component {
'Total clients',
'Entity clients',
'Non-entity clients',
'Secrets sync clients',
// 'Secrets sync clients', * (2) SYNC BETA - add 'Secrets sync clients' as the last element of csvHeader
];
if (newAttribution) {
csvHeader.push(
'Total new clients, New entity clients, New non-entity clients, New secrets sync clients'
);
csvHeader.push('Total new clients, New entity clients, New non-entity clients'); // * (3) add 'New secrets sync clients' as last string pushed here
}
totalAttribution.forEach((totalClientsObject) => {

View File

@ -6,7 +6,8 @@
{{#if (gt @byMonthActivityData.length 1)}}
<Clients::ChartContainer
@title="Vault client counts"
@description="The total clients in the specified date range. This includes entity, non-entity, and secrets sync clients. The total client count number is an important consideration for Vault billing."
{{! * add "secrets sync" clients to list here - unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release }}
@description="The total clients in the specified date range. This includes entity and non-entity clients. The total client count number is an important consideration for Vault billing."
@timestamp={{@responseTimestamp}}
@hasChartData={{true}}
data-test-chart="running total"
@ -29,13 +30,15 @@
@size="m"
data-test-chart-stat="running total entity"
/>
{{!-- * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
<StatText
@label="Secrets sync clients"
@value={{@runningTotals.secret_syncs}}
@size="m"
class="has-left-margin-l"
data-test-chart-stat="running total sync"
/>
/>
--}}
</div>
</div>
<StatText
@ -77,9 +80,11 @@
<div class="single-month-breakdown-nonentity">
<StatText @label="Non-entity clients" @value={{singleMonthData.new_clients.non_entity_clients}} @size="m" />
</div>
{{!-- * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
<div class="single-month-breakdown-sync">
<StatText @label="Secrets sync clients" @value={{singleMonthData.new_clients.secret_syncs}} @size="m" />
</div>
--}}
</div>
<div class="single-month-stats" data-test-total>
<div class="single-month-section-title">
@ -96,9 +101,11 @@
<div class="single-month-breakdown-nonentity">
<StatText @label="Non-entity clients" @value={{singleMonthData.non_entity_clients}} @size="m" />
</div>
{{!-- * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
<div class="single-month-breakdown-sync">
<StatText @label="Secrets sync clients" @value={{singleMonthData.secret_syncs}} @size="m" />
</div>
--}}
</div>
</div>
{{else}}

View File

@ -47,6 +47,7 @@
data-test-stat-text="non-entity-clients"
/>
</div>
{{!-- * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
{{#if (gte @totalUsageCounts.secret_syncs 0)}}
<div class="column">
<StatText
@ -59,5 +60,6 @@
/>
</div>
{{/if}}
--}}
</div>
</div>

View File

@ -16,7 +16,7 @@
<Nav.Link
@route="vault.cluster.sync"
@text="Secrets Sync"
@badge={{unless this.version.isEnterprise "Enterprise"}}
@badge={{if this.version.isEnterprise "Beta" "Enterprise"}}
data-test-sidebar-nav-link="Secrets Sync"
/>
{{#if (has-permission "access")}}

View File

@ -29,7 +29,7 @@ Router.map(function () {
this.route('clients', function () {
this.route('counts', function () {
this.route('overview');
this.route('sync');
// this.route('sync'); * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
this.route('token');
});
this.route('config');

View File

@ -20,9 +20,11 @@
<LinkTo @route="vault.cluster.clients.counts.token" data-test-tab="token">
Entity/Non-entity clients
</LinkTo>
{{! * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
<LinkTo @route="vault.cluster.clients.counts.sync" data-test-tab="sync">
Secrets sync clients
</LinkTo>
}}
{{#if (or @model.config.canRead @model.canRead)}}
<LinkTo
@route="vault.cluster.clients.config"

View File

@ -138,10 +138,13 @@
</OverviewCard>
<OverviewCard
@cardTitle="Total sync associations"
@subText="The number of secrets with a configured sync destination. One secret synced to two unique destinations will count as two associations."
{{!-- * sync clients are unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
@subText="Total sync associations that count towards client count"
@actionText="View billing"
@actionText="View billing"
@actionTo="clientCountOverview"
@actionExternal={{true}}
--}}
class="is-flex-half"
>
<h2

View File

@ -17,6 +17,9 @@
{{#if this.version.isCommunity}}
<Hds::Badge @text="Enterprise feature" @color="highlight" @size="large" />
{{/if}}
{{#if this.version.isEnterprise}}
<Hds::Badge @text="Beta" @color="highlight" @size="large" />
{{/if}}
</h1>
</p.levelLeft>

View File

@ -184,9 +184,10 @@ module('Acceptance | clients | overview', function (hooks) {
`${formatNumber([topNamespace.non_entity_clients])}`,
'total non-entity clients is accurate'
);
assert
.dom(SELECTORS.charts.statTextValue('Secrets sync clients'))
.includesText(`${formatNumber([topNamespace.secret_syncs])}`, 'total sync clients is accurate');
// * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
// assert
// .dom(SELECTORS.charts.statTextValue('Secrets sync clients'))
// .includesText(`${formatNumber([topNamespace.secret_syncs])}`, 'total sync clients is accurate');
assert
.dom('[data-test-attribution-clients] p')
.includesText(`${formatNumber([topMount.clients])}`, 'top attribution clients accurate');
@ -204,9 +205,10 @@ module('Acceptance | clients | overview', function (hooks) {
assert
.dom(SELECTORS.charts.statTextValue('Non-entity clients'))
.includesText(`${formatNumber([topMount.non_entity_clients])}`, 'total non-entity clients is accurate');
assert
.dom(SELECTORS.charts.statTextValue('Secrets sync clients'))
.includesText(`${formatNumber([topMount.secret_syncs])}`, 'total sync clients is accurate');
// * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
// assert
// .dom(SELECTORS.charts.statTextValue('Secrets sync clients'))
// .includesText(`${formatNumber([topMount.secret_syncs])}`, 'total sync clients is accurate');
assert.dom(SELECTORS.attributionBlock).doesNotExist('Does not show attribution block');
await click('#namespace-search-select [data-test-selected-list-button="delete"]');
@ -224,12 +226,13 @@ module('Acceptance | clients | overview', function (hooks) {
`${formatNumber([formatNumber([response.total.non_entity_clients])])}`,
'total non-entity clients is back to unfiltered value'
);
assert
.dom(SELECTORS.charts.statTextValue('Secrets sync clients'))
.hasTextContaining(
`${formatNumber([formatNumber([response.total.secret_syncs])])}`,
'total sync clients is back to unfiltered value'
);
// * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
// assert
// .dom(SELECTORS.charts.statTextValue('Secrets sync clients'))
// .hasTextContaining(
// `${formatNumber([formatNumber([response.total.secret_syncs])])}`,
// 'total sync clients is back to unfiltered value'
// );
assert
.dom('[data-test-attribution-clients]')
.hasTextContaining(

View File

@ -57,7 +57,7 @@ module('Integration | Component | clients/running-total', function (hooks) {
test('it renders with full monthly activity data', async function (assert) {
const expectedTotalEntity = formatNumber([this.totalUsageCounts.entity_clients]);
const expectedTotalNonEntity = formatNumber([this.totalUsageCounts.non_entity_clients]);
const expectedTotalSync = formatNumber([this.totalUsageCounts.secret_syncs]);
// const expectedTotalSync = formatNumber([this.totalUsageCounts.secret_syncs]);
await render(hbs`
<Clients::RunningTotal
@ -80,9 +80,10 @@ module('Integration | Component | clients/running-total', function (hooks) {
`${expectedTotalNonEntity}`,
`renders correct total nonentity average ${expectedTotalNonEntity}`
);
assert
.dom(ts.charts.statTextValue('Secrets sync clients'))
.hasText(`${expectedTotalSync}`, `renders correct total sync ${expectedTotalSync}`);
// * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
// assert
// .dom(ts.charts.statTextValue('Secrets sync clients'))
// .hasText(`${expectedTotalSync}`, `renders correct total sync ${expectedTotalSync}`);
// assert line chart is correct
findAll(ts.charts.line.xAxisLabel).forEach((e, i) => {
@ -111,7 +112,7 @@ module('Integration | Component | clients/running-total', function (hooks) {
);
const expectedTotalEntity = formatNumber([this.totalUsageCounts.entity_clients]);
const expectedTotalNonEntity = formatNumber([this.totalUsageCounts.non_entity_clients]);
const expectedTotalSync = formatNumber([this.totalUsageCounts.secret_syncs]);
// const expectedTotalSync = formatNumber([this.totalUsageCounts.secret_syncs]);
await render(hbs`
<Clients::RunningTotal
@ -133,9 +134,10 @@ module('Integration | Component | clients/running-total', function (hooks) {
`${expectedTotalNonEntity}`,
`renders correct total nonentity average ${expectedTotalNonEntity}`
);
assert
.dom(ts.charts.statTextValue('Secrets sync clients'))
.hasText(`${expectedTotalSync}`, `renders correct total sync ${expectedTotalSync}`);
// * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
// assert
// .dom(ts.charts.statTextValue('Secrets sync clients'))
// .hasText(`${expectedTotalSync}`, `renders correct total sync ${expectedTotalSync}`);
});
test('it renders with single historical month data', async function (assert) {
@ -145,11 +147,11 @@ module('Integration | Component | clients/running-total', function (hooks) {
const expectedTotalClients = formatNumber([singleMonth.clients]);
const expectedTotalEntity = formatNumber([singleMonth.entity_clients]);
const expectedTotalNonEntity = formatNumber([singleMonth.non_entity_clients]);
const expectedTotalSync = formatNumber([singleMonth.secret_syncs]);
// const expectedTotalSync = formatNumber([singleMonth.secret_syncs]);
const expectedNewClients = formatNumber([singleMonthNew.clients]);
const expectedNewEntity = formatNumber([singleMonthNew.entity_clients]);
const expectedNewNonEntity = formatNumber([singleMonthNew.non_entity_clients]);
const expectedNewSyncs = formatNumber([singleMonthNew.secret_syncs]);
// const expectedNewSyncs = formatNumber([singleMonthNew.secret_syncs]);
const { statTextValue } = ts.charts;
await render(hbs`
@ -161,7 +163,7 @@ module('Integration | Component | clients/running-total', function (hooks) {
/>
`);
assert.dom(ts.charts.lineChart).doesNotExist('line chart does not render');
assert.dom(statTextValue()).exists({ count: 8 }, 'renders stat text containers');
assert.dom(statTextValue()).exists({ count: 6 }, 'renders 6 stat text containers'); // after SYNC BETA update to 8
assert
.dom(`[data-test-new] ${statTextValue('New clients')}`)
.hasText(`${expectedNewClients}`, `renders correct total new clients: ${expectedNewClients}`);
@ -171,9 +173,10 @@ module('Integration | Component | clients/running-total', function (hooks) {
assert
.dom(`[data-test-new] ${statTextValue('Non-entity clients')}`)
.hasText(`${expectedNewNonEntity}`, `renders correct total new non-entity: ${expectedNewNonEntity}`);
assert
.dom(`[data-test-new] ${statTextValue('Secrets sync clients')}`)
.hasText(`${expectedNewSyncs}`, `renders correct total new non-entity: ${expectedNewSyncs}`);
// * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
// assert
// .dom(`[data-test-new] ${statTextValue('Secrets sync clients')}`)
// .hasText(`${expectedNewSyncs}`, `renders correct total new non-entity: ${expectedNewSyncs}`);
assert
.dom(`[data-test-total] ${statTextValue('Total monthly clients')}`)
.hasText(`${expectedTotalClients}`, `renders correct total clients: ${expectedTotalClients}`);
@ -183,8 +186,9 @@ module('Integration | Component | clients/running-total', function (hooks) {
assert
.dom(`[data-test-total] ${statTextValue('Non-entity clients')}`)
.hasText(`${expectedTotalNonEntity}`, `renders correct total non-entity: ${expectedTotalNonEntity}`);
assert
.dom(`[data-test-total] ${statTextValue('Secrets sync clients')}`)
.hasText(`${expectedTotalSync}`, `renders correct total sync: ${expectedTotalSync}`);
// * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
// assert
// .dom(`[data-test-total] ${statTextValue('Secrets sync clients')}`)
// .hasText(`${expectedTotalSync}`, `renders correct total sync: ${expectedTotalSync}`);
});
});

View File

@ -60,7 +60,7 @@ module('Integration | Component | clients/usage-stats', function (hooks) {
await render(hbs`<Clients::UsageStats @totalUsageCounts={{this.counts}} />`);
assert.dom('[data-test-stat-text]').exists({ count: 4 }, 'Renders 4 Stat texts');
assert.dom('[data-test-stat-text]').exists({ count: 3 }, 'Renders 3 Stat texts'); // after SYNC BETA update to 4
assert
.dom('[data-test-stat-text="total-clients"] .stat-value')
.hasText('22', 'Total clients shows passed value');
@ -70,8 +70,9 @@ module('Integration | Component | clients/usage-stats', function (hooks) {
assert
.dom('[data-test-stat-text="non-entity-clients"] .stat-value')
.hasText('10', 'non entity clients shows passed value');
assert
.dom('[data-test-stat-text="secret-syncs"] .stat-value')
.hasText('5', 'secrets sync clients shows passed value');
// * unavailable during SYNC BETA (1.16.0), planned for 1.16.1 release
// assert
// .dom('[data-test-stat-text="secret-syncs"] .stat-value')
// .hasText('5', 'secrets sync clients shows passed value');
});
});

View File

@ -79,8 +79,13 @@ module('Integration | Component | sidebar-nav-cluster', function (hooks) {
.dom('[data-test-sidebar-nav-link]')
.exists({ count: links.length }, 'Correct number of links render');
links.forEach((link) => {
if (link === 'Secrets Sync') return;
assert.dom(`[data-test-sidebar-nav-link="${link}"]`).hasText(link, `${link} link renders`);
});
// after SYNC BETA - remove assertion below and return on line 82
assert
.dom('[data-test-sidebar-nav-link="Secrets Sync"]')
.hasText('Secrets Sync Beta', 'Secrets Sync nav link includes beta tag');
});
test('it should hide enterprise related links in child namespace', async function (assert) {

View File

@ -70,7 +70,7 @@ module('Integration | Component | sync | Page::Destinations', function (hooks) {
test('it should render header and tabs', async function (assert) {
await this.renderComponent();
assert.dom(breadcrumb).includesText('Secrets Sync', 'Breadcrumb renders');
assert.dom(title).hasText('Secrets Sync', 'Page title renders');
assert.dom(title).hasText('Secrets Sync Beta', 'Page title renders');
assert.dom(tab('Overview')).exists('Overview tab renders');
assert.dom(tab('Destinations')).exists('Destinations tab renders');
});

View File

@ -60,13 +60,13 @@ module('Integration | Component | sync | Page::Overview', function (hooks) {
test('it should render landing cta component for enterprise', async function (assert) {
this.set('destinations', []);
await settled();
assert.dom(title).hasText('Secrets Sync', 'Page title renders');
assert.dom(title).hasText('Secrets Sync Beta', 'Page title renders');
assert.dom(cta.button).hasText('Create first destination', 'CTA action renders');
assert.dom(cta.summary).exists('CTA renders');
});
test('it should render header, tabs and toolbar for overview state', async function (assert) {
assert.dom(title).hasText('Secrets Sync', 'Page title renders');
assert.dom(title).hasText('Secrets Sync Beta', 'Page title renders');
assert.dom(breadcrumb).exists({ count: 1 }, 'Correct number of breadcrumbs render');
assert.dom(breadcrumb).includesText('Secrets Sync', 'Top level breadcrumb renders');
assert.dom(cta.button).doesNotExist('CTA does not render');
@ -141,8 +141,9 @@ module('Integration | Component | sync | Page::Overview', function (hooks) {
},
{
cardTitle: 'Total sync associations',
subText: 'Total sync associations that count towards client count',
actionText: 'View billing',
subText:
'The number of secrets with a configured sync destination. One secret synced to two unique destinations will count as two associations.',
// actionText: 'View billing',
count: '7',
},
];
@ -150,8 +151,9 @@ module('Integration | Component | sync | Page::Overview', function (hooks) {
cardData.forEach(({ cardTitle, subText, actionText, count }) => {
assert.dom(title(cardTitle)).hasText(cardTitle, 'Overview card title renders');
assert.dom(description(cardTitle)).hasText(subText, 'Destinations overview card description renders');
assert.dom(action(cardTitle)).hasText(actionText, 'Card action renders');
assert.dom(content(cardTitle)).hasText(count, 'Total count renders');
if (cardTitle === 'Total sync associations') return; // uncomment 'actionText' above and this return after SYNC BETA
assert.dom(action(cardTitle)).hasText(actionText, 'Card action renders');
});
});
});

View File

@ -41,11 +41,11 @@ module('Integration | Component | sync | SyncHeader', function (hooks) {
test('it should just render title for enterprise version', async function (assert) {
await this.renderComponent();
assert.dom(title).hasText('Secrets Sync');
assert.dom(title).hasText('Secrets Sync Beta');
});
test('it should render title and promotional enterprise badge for community version', async function (assert) {
this.version.type = null;
this.version.type = 'community';
await this.renderComponent();
assert.dom(title).hasText('Secrets Sync Enterprise feature');
});