Update account details component on meta update.

This commit is contained in:
Spencer Ofwiti 2021-08-30 15:31:37 +00:00 committed by Blair Vanderlugt
parent e79afe3e88
commit 565dd5c719
3 changed files with 129 additions and 74 deletions

View File

@ -82,7 +82,7 @@ export class UserService {
location: string, location: string,
locationType: string, locationType: string,
oldPhoneNumber: string oldPhoneNumber: string
): Promise<any> { ): Promise<boolean> {
const accountInfo = await this.loadChangesToAccountStructure( const accountInfo = await this.loadChangesToAccountStructure(
name, name,
phoneNumber, phoneNumber,
@ -96,53 +96,64 @@ export class UserService {
locationType locationType
); );
const accountKey: string = await User.toKey(address); const accountKey: string = await User.toKey(address);
this.getAccountDetailsFromMeta(accountKey) return new Promise((resolve) => {
.pipe(first()) let status: boolean = false;
.subscribe( this.getAccountDetailsFromMeta(accountKey)
async (res) => { .pipe(first())
const syncableAccount: Syncable = Envelope.fromJSON(JSON.stringify(res)).unwrap(); .subscribe(
const update: Array<ArgPair> = []; async (res) => {
for (const prop of Object.keys(accountInfo)) { const syncableAccount: Syncable = Envelope.fromJSON(JSON.stringify(res)).unwrap();
update.push(new ArgPair(prop, accountInfo[prop])); const update: Array<ArgPair> = [];
for (const prop of Object.keys(accountInfo)) {
update.push(new ArgPair(prop, accountInfo[prop]));
}
updateSyncable(update, 'client-branch', syncableAccount);
await personValidation(syncableAccount.m.data);
status = await this.updateMeta(syncableAccount, accountKey, this.headers);
if (status && phoneNumber !== oldPhoneNumber) {
await this.updatePhonePointers(address, oldPhoneNumber, phoneNumber);
}
resolve(status);
},
async (error) => {
this.loggingService.sendErrorLevelMessage(
'Cannot find account info in meta service',
this,
{ error }
);
const syncableAccount: Syncable = new Syncable(accountKey, accountInfo);
status = await this.updateMeta(syncableAccount, accountKey, this.headers);
if (status && phoneNumber !== oldPhoneNumber) {
await this.updatePhonePointers(address, oldPhoneNumber, phoneNumber);
}
resolve(status);
} }
updateSyncable(update, 'client-branch', syncableAccount); );
await personValidation(syncableAccount.m.data); });
await this.updateMeta(syncableAccount, accountKey, this.headers);
},
async (error) => {
this.loggingService.sendErrorLevelMessage(
'Cannot find account info in meta service',
this,
{ error }
);
const syncableAccount: Syncable = new Syncable(accountKey, accountInfo);
await this.updateMeta(syncableAccount, accountKey, this.headers);
}
);
if (phoneNumber !== oldPhoneNumber) {
const oldPhoneKey: string = await Phone.toKey(oldPhoneNumber);
const newPhoneKey: string = await Phone.toKey(phoneNumber);
const newPhoneData: Syncable = new Syncable(newPhoneKey, strip0x(address));
await this.updateMeta(newPhoneData, newPhoneKey, this.headers);
const oldPhoneData: Syncable = new Syncable(oldPhoneKey, '');
await this.updateMeta(oldPhoneData, oldPhoneKey, this.headers);
}
return accountKey;
} }
async updateMeta( async updateMeta(
syncableAccount: Syncable, syncableAccount: Syncable,
accountKey: string, accountKey: string,
headers: HttpHeaders headers: HttpHeaders
): Promise<any> { ): Promise<boolean> {
const envelope: Envelope = await this.wrap(syncableAccount, this.signer); const envelope: Envelope = await this.wrap(syncableAccount, this.signer);
const reqBody: string = envelope.toJSON(); const reqBody: string = envelope.toJSON();
this.httpClient return new Promise((resolve) => {
.put(`${environment.cicMetaUrl}/${accountKey}`, reqBody, { headers }) this.httpClient
.pipe(first()) .put(`${environment.cicMetaUrl}/${accountKey}`, reqBody, { headers })
.subscribe((res) => { .pipe(first())
this.loggingService.sendInfoLevelMessage(`Response: ${res}`); .subscribe(
}); (res) => {
this.loggingService.sendInfoLevelMessage(`Response: ${res}`);
resolve(true);
},
(error) => {
this.loggingService.sendErrorLevelMessage('Metadata update failed!', this, { error });
resolve(false);
}
);
});
} }
getActions(): void { getActions(): void {
@ -198,7 +209,7 @@ export class UserService {
); );
} }
}); });
this.addAccount(data, limit); this.addAccount(data, limit, false);
} }
}; };
worker.postMessage({ worker.postMessage({
@ -211,7 +222,7 @@ export class UserService {
'Web workers are not supported in this environment' 'Web workers are not supported in this environment'
); );
for (const accountAddress of accountAddresses.slice(offset, offset + limit)) { for (const accountAddress of accountAddresses.slice(offset, offset + limit)) {
await this.getAccountByAddress(accountAddress, limit); await this.getAccountByAddress(accountAddress, limit, false, false);
} }
} }
} catch (error) { } catch (error) {
@ -223,7 +234,8 @@ export class UserService {
async getAccountByAddress( async getAccountByAddress(
accountAddress: string, accountAddress: string,
limit: number = 100, limit: number = 100,
history: boolean = false history: boolean = false,
top: boolean = true
): Promise<Observable<AccountDetails>> { ): Promise<Observable<AccountDetails>> {
const accountSubject: Subject<any> = new Subject<any>(); const accountSubject: Subject<any> = new Subject<any>();
this.getAccountDetailsFromMeta(await User.toKey(add0x(accountAddress))) this.getAccountDetailsFromMeta(await User.toKey(add0x(accountAddress)))
@ -249,7 +261,7 @@ export class UserService {
}); });
accountInfo.vcard = vCard.parse(atob(accountInfo.vcard)); accountInfo.vcard = vCard.parse(atob(accountInfo.vcard));
await vcardValidation(accountInfo.vcard); await vcardValidation(accountInfo.vcard);
this.addAccount(accountInfo, limit); this.addAccount(accountInfo, limit, top);
accountSubject.next(accountInfo); accountSubject.next(accountInfo);
}); });
return accountSubject.asObservable(); return accountSubject.asObservable();
@ -310,21 +322,34 @@ export class UserService {
return this.httpClient.get(`${environment.cicMetaUrl}/genders`); return this.httpClient.get(`${environment.cicMetaUrl}/genders`);
} }
addAccount(account: AccountDetails, cacheSize: number): void { addAccount(account: AccountDetails, cacheSize: number, top: boolean = true): void {
const savedIndex = this.accounts.findIndex( const savedIndex = this.accounts.findIndex(
(acc) => (acc) =>
acc.identities.evm[`bloxberg:${environment.bloxbergChainId}`][0] === acc.identities.evm[`bloxberg:${environment.bloxbergChainId}`][0] ===
account.identities.evm[`bloxberg:${environment.bloxbergChainId}`][0] account.identities.evm[`bloxberg:${environment.bloxbergChainId}`][0]
); );
if (savedIndex === 0) { if (top) {
return; if (savedIndex === 0) {
} return;
if (savedIndex > 0) { }
this.accounts.splice(savedIndex, 1); if (savedIndex > 0) {
} this.accounts.splice(savedIndex, 1);
this.accounts.unshift(account); }
if (this.accounts.length > cacheSize) { this.accounts.unshift(account);
this.accounts.length = Math.min(this.accounts.length, cacheSize); if (this.accounts.length > cacheSize) {
this.accounts.length = Math.min(this.accounts.length, cacheSize);
}
} else {
if (
this.accounts.length >= cacheSize ||
(savedIndex !== -1 && savedIndex === this.accounts.length - 1)
) {
return;
}
if (savedIndex !== -1 && savedIndex < this.accounts.length - 1) {
this.accounts.splice(savedIndex, 1);
}
this.accounts.push(account);
} }
this.accountsList.next(this.accounts); this.accountsList.next(this.accounts);
} }
@ -384,4 +409,26 @@ export class UserService {
accountInfo.vcard = btoa(vCard.generate(accountInfo.vcard)); accountInfo.vcard = btoa(vCard.generate(accountInfo.vcard));
return accountInfo; return accountInfo;
} }
async updatePhonePointers(
address: string,
oldPhoneNumber: string,
newPhoneNumber: string
): Promise<void> {
const oldPhoneKey: string = await Phone.toKey(oldPhoneNumber);
const newPhoneKey: string = await Phone.toKey(newPhoneNumber);
const newPhoneData: Syncable = new Syncable(newPhoneKey, strip0x(address));
const newPhoneSetStatus = await this.updateMeta(newPhoneData, newPhoneKey, this.headers);
if (!newPhoneSetStatus) {
const error = `Failed to update new phone number pointer: ${newPhoneNumber}`;
this.loggingService.sendErrorLevelMessage(error, this, { error });
} else {
const oldPhoneData: Syncable = new Syncable(oldPhoneKey, '');
const oldPhoneSetStatus = await this.updateMeta(oldPhoneData, oldPhoneKey, this.headers);
if (!oldPhoneSetStatus) {
const error = `Failed to update old phone number pointer: ${oldPhoneNumber}`;
this.loggingService.sendErrorLevelMessage(error, this, { error });
}
}
}
} }

View File

@ -32,8 +32,9 @@ async function getAccountByAddress(
token: string token: string
): Promise<any> { ): Promise<any> {
const userKey = await User.toKey(add0x(accountAddress)); const userKey = await User.toKey(add0x(accountAddress));
if (token) {
headers['Authorization'] = 'Bearer ' + token; headers['Authorization'] = 'Bearer ' + token;
}
const response = await fetch(`${metaUrl}/${userKey}`, options) const response = await fetch(`${metaUrl}/${userKey}`, options)
.then((res) => { .then((res) => {
if (res.ok) { if (res.ok) {

View File

@ -56,8 +56,8 @@ export class AccountDetailsComponent implements OnInit, AfterViewInit {
'dependencies', 'dependencies',
'timestamp', 'timestamp',
]; ];
historyDefaultPageSize: number = 10; historyDefaultPageSize: number = 5;
historyPageSizeOptions: Array<number> = [10, 20, 50, 100]; historyPageSizeOptions: Array<number> = [5, 10, 20, 50, 100];
@ViewChild('HistoryTablePaginator', { static: true }) historyTablePaginator: MatPaginator; @ViewChild('HistoryTablePaginator', { static: true }) historyTablePaginator: MatPaginator;
@ViewChild('HistoryTableSort', { static: true }) historyTableSort: MatSort; @ViewChild('HistoryTableSort', { static: true }) historyTableSort: MatSort;
@ -114,22 +114,7 @@ export class AccountDetailsComponent implements OnInit, AfterViewInit {
this.transactionService.resetTransactionsList(); this.transactionService.resetTransactionsList();
await this.blockSyncService.blockSync(this.accountAddress); await this.blockSyncService.blockSync(this.accountAddress);
this.userService.resetAccountsList(); this.userService.resetAccountsList();
(await this.userService.getAccountByAddress(this.accountAddress, 100, true)).subscribe( await this.loadAccount();
async (res) => {
if (res !== undefined) {
this.account = res;
this.cdr.detectChanges();
this.queryLocationAndCategory(this.account);
this.populateAccountsInfoForm(this.account);
this.userService
.getAccountStatus(this.account.vcard?.tel[0].value)
.pipe(first())
.subscribe((response) => (this.accountStatus = response.status));
} else {
alert('Account not found!');
}
}
);
this.populateDataTables(); this.populateDataTables();
this.loadSearchData(); this.loadSearchData();
this.tokenService.load.subscribe(async (status: boolean) => { this.tokenService.load.subscribe(async (status: boolean) => {
@ -185,7 +170,7 @@ export class AccountDetailsComponent implements OnInit, AfterViewInit {
if (this.accountInfoForm.invalid || !confirm(`Change user's profile information?`)) { if (this.accountInfoForm.invalid || !confirm(`Change user's profile information?`)) {
return; return;
} }
const accountKey = await this.userService.changeAccountInfo( const status = await this.userService.changeAccountInfo(
this.accountAddress, this.accountAddress,
this.accountInfoFormStub.firstName.value + ', ' + this.accountInfoFormStub.lastName.value, this.accountInfoFormStub.firstName.value + ', ' + this.accountInfoFormStub.lastName.value,
this.accountInfoFormStub.phoneNumber.value, this.accountInfoFormStub.phoneNumber.value,
@ -199,6 +184,9 @@ export class AccountDetailsComponent implements OnInit, AfterViewInit {
this.accountInfoFormStub.locationType.value, this.accountInfoFormStub.locationType.value,
this.account.vcard?.tel[0].value this.account.vcard?.tel[0].value
); );
if (status) {
await this.loadAccount();
}
this.submitted = false; this.submitted = false;
} }
@ -374,4 +362,23 @@ export class AccountDetailsComponent implements OnInit, AfterViewInit {
.pipe(first()) .pipe(first())
.subscribe((res) => (this.genders = res)); .subscribe((res) => (this.genders = res));
} }
async loadAccount(): Promise<void> {
(await this.userService.getAccountByAddress(this.accountAddress, 100, true)).subscribe(
async (res) => {
if (res !== undefined) {
this.account = res;
this.cdr.detectChanges();
this.queryLocationAndCategory(this.account);
this.populateAccountsInfoForm(this.account);
this.userService
.getAccountStatus(this.account.vcard?.tel[0].value)
.pipe(first())
.subscribe((response) => (this.accountStatus = response.status));
} else {
alert('Account not found!');
}
}
);
}
} }