-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Sync Overview #24340
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sync Overview #24340
Changes from 7 commits
0a8e114
2b6aaff
f5d0bc1
d9ab933
23dc99c
f751ca3
3c5cf39
3df671e
ede00a2
277bef5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| */ | ||
|
|
||
| import ApplicationSerializer from 'vault/serializers/application'; | ||
| import { findDestination } from 'core/helpers/sync-destinations'; | ||
|
|
||
| export default class SyncAssociationSerializer extends ApplicationSerializer { | ||
| attrs = { | ||
|
|
@@ -31,4 +32,32 @@ export default class SyncAssociationSerializer extends ApplicationSerializer { | |
| } | ||
| return payload; | ||
| } | ||
|
|
||
| normalizeFetchByDestinations(payload) { | ||
| const { store_name, store_type, associated_secrets } = payload.data; | ||
| const unsynced = []; | ||
| let lastSync; | ||
|
|
||
| for (const key in associated_secrets) { | ||
| const association = associated_secrets[key]; | ||
| // for display purposes, any status other than SYNCED is considered unsynced | ||
| if (association.sync_status !== 'SYNCED') { | ||
| unsynced.push(association.sync_status); | ||
| } | ||
| // use the most recent updated_at value as the last synced date | ||
| const updated = new Date(association.updated_at); | ||
| if (!lastSync || updated > lastSync) { | ||
| lastSync = updated; | ||
| } | ||
| } | ||
|
|
||
| return { | ||
| icon: findDestination(store_type).icon, | ||
| name: store_name, | ||
| type: store_type, | ||
| associationCount: Object.entries(associated_secrets).length, | ||
| status: unsynced.length ? `${unsynced.length} Unsynced` : 'All synced', | ||
|
||
| lastSync, | ||
| }; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| /** | ||
| * Copyright (c) HashiCorp, Inc. | ||
| * SPDX-License-Identifier: BUSL-1.1 | ||
| */ | ||
|
|
||
| import Component from '@glimmer/component'; | ||
| import { tracked } from '@glimmer/tracking'; | ||
| import { service } from '@ember/service'; | ||
| import { task } from 'ember-concurrency'; | ||
| import Ember from 'ember'; | ||
|
|
||
| import type RouterService from '@ember/routing/router-service'; | ||
| import type StoreService from 'vault/services/store'; | ||
| import type FlashMessageService from 'vault/services/flash-messages'; | ||
| import type { SyncDestinationAssociationMetrics } from 'vault/vault/adapters/sync/association'; | ||
| import type SyncDestinationModel from 'vault/vault/models/sync/destination'; | ||
|
|
||
| interface Args { | ||
| destinations: Array<SyncDestinationModel>; | ||
| totalAssociations: number; | ||
| } | ||
|
|
||
| export default class SyncSecretsDestinationsPageComponent extends Component<Args> { | ||
| @service declare readonly router: RouterService; | ||
| @service declare readonly store: StoreService; | ||
| @service declare readonly flashMessages: FlashMessageService; | ||
|
|
||
| @tracked destinationMetrics: SyncDestinationAssociationMetrics[] = []; | ||
| @tracked page = 1; | ||
|
|
||
| pageSize = Ember.testing ? 3 : 5; // lower in tests to test pagination without seeding more data | ||
|
|
||
| constructor(owner: unknown, args: Args) { | ||
| super(owner, args); | ||
| if (this.args.destinations.length) { | ||
| this.fetchAssociationsForDestinations.perform(); | ||
| } | ||
| } | ||
|
|
||
| fetchAssociationsForDestinations = task(this, {}, async (page = 1) => { | ||
| try { | ||
| const total = page * this.pageSize; | ||
| const paginatedDestinations = this.args.destinations.slice(total - this.pageSize, total); | ||
| this.destinationMetrics = await this.store | ||
| .adapterFor('sync/association') | ||
| .fetchByDestinations(paginatedDestinations); | ||
| this.page = page; | ||
| } catch (error) { | ||
| this.destinationMetrics = []; | ||
| } | ||
| }); | ||
| } |

Uh oh!
There was an error while loading. Please reload this page.