Merge branch 'spencer/update-details-component-on-meta-update' into 'master'

Update account details component on meta update.

See merge request grassrootseconomics/cic-staff-client!47
This commit is contained in:
Blair Vanderlugt 2021-08-30 15:31:37 +00:00
commit 0567b9b729
3 changed files with 129 additions and 74 deletions

View File

@ -82,7 +82,7 @@ export class UserService {
location: string,
locationType: string,
oldPhoneNumber: string
): Promise<any> {
): Promise<boolean> {
const accountInfo = await this.loadChangesToAccountStructure(
name,
phoneNumber,
@ -96,53 +96,64 @@ export class UserService {
locationType
);
const accountKey: string = await User.toKey(address);
this.getAccountDetailsFromMeta(accountKey)
.pipe(first())
.subscribe(
async (res) => {
const syncableAccount: Syncable = Envelope.fromJSON(JSON.stringify(res)).unwrap();
const update: Array<ArgPair> = [];
for (const prop of Object.keys(accountInfo)) {
update.push(new ArgPair(prop, accountInfo[prop]));
return new Promise((resolve) => {
let status: boolean = false;
this.getAccountDetailsFromMeta(accountKey)
.pipe(first())
.subscribe(
async (res) => {
const syncableAccount: Syncable = Envelope.fromJSON(JSON.stringify(res)).unwrap();
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(
syncableAccount: Syncable,
accountKey: string,
headers: HttpHeaders
): Promise<any> {
): Promise<boolean> {
const envelope: Envelope = await this.wrap(syncableAccount, this.signer);
const reqBody: string = envelope.toJSON();
this.httpClient
.put(`${environment.cicMetaUrl}/${accountKey}`, reqBody, { headers })
.pipe(first())
.subscribe((res) => {
this.loggingService.sendInfoLevelMessage(`Response: ${res}`);
});
return new Promise((resolve) => {
this.httpClient
.put(`${environment.cicMetaUrl}/${accountKey}`, reqBody, { headers })
.pipe(first())
.subscribe(
(res) => {
this.loggingService.sendInfoLevelMessage(`Response: ${res}`);
resolve(true);
},
(error) => {
this.loggingService.sendErrorLevelMessage('Metadata update failed!', this, { error });
resolve(false);
}
);
});
}
getActions(): void {
@ -198,7 +209,7 @@ export class UserService {
);
}
});
this.addAccount(data, limit);
this.addAccount(data, limit, false);
}
};
worker.postMessage({
@ -211,7 +222,7 @@ export class UserService {
'Web workers are not supported in this environment'
);
for (const accountAddress of accountAddresses.slice(offset, offset + limit)) {
await this.getAccountByAddress(accountAddress, limit);
await this.getAccountByAddress(accountAddress, limit, false, false);
}
}
} catch (error) {
@ -223,7 +234,8 @@ export class UserService {
async getAccountByAddress(
accountAddress: string,
limit: number = 100,
history: boolean = false
history: boolean = false,
top: boolean = true
): Promise<Observable<AccountDetails>> {
const accountSubject: Subject<any> = new Subject<any>();
this.getAccountDetailsFromMeta(await User.toKey(add0x(accountAddress)))
@ -249,7 +261,7 @@ export class UserService {
});
accountInfo.vcard = vCard.parse(atob(accountInfo.vcard));
await vcardValidation(accountInfo.vcard);
this.addAccount(accountInfo, limit);
this.addAccount(accountInfo, limit, top);
accountSubject.next(accountInfo);
});
return accountSubject.asObservable();
@ -310,21 +322,34 @@ export class UserService {
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(
(acc) =>
acc.identities.evm[`bloxberg:${environment.bloxbergChainId}`][0] ===
account.identities.evm[`bloxberg:${environment.bloxbergChainId}`][0]
);
if (savedIndex === 0) {
return;
}
if (savedIndex > 0) {
this.accounts.splice(savedIndex, 1);
}
this.accounts.unshift(account);
if (this.accounts.length > cacheSize) {
this.accounts.length = Math.min(this.accounts.length, cacheSize);
if (top) {
if (savedIndex === 0) {
return;
}
if (savedIndex > 0) {
this.accounts.splice(savedIndex, 1);
}
this.accounts.unshift(account);
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);
}
@ -384,4 +409,26 @@ export class UserService {
accountInfo.vcard = btoa(vCard.generate(accountInfo.vcard));
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
): Promise<any> {
const userKey = await User.toKey(add0x(accountAddress));
headers['Authorization'] = 'Bearer ' + token;
if (token) {
headers['Authorization'] = 'Bearer ' + token;
}
const response = await fetch(`${metaUrl}/${userKey}`, options)
.then((res) => {
if (res.ok) {

View File

@ -56,8 +56,8 @@ export class AccountDetailsComponent implements OnInit, AfterViewInit {
'dependencies',
'timestamp',
];
historyDefaultPageSize: number = 10;
historyPageSizeOptions: Array<number> = [10, 20, 50, 100];
historyDefaultPageSize: number = 5;
historyPageSizeOptions: Array<number> = [5, 10, 20, 50, 100];
@ViewChild('HistoryTablePaginator', { static: true }) historyTablePaginator: MatPaginator;
@ViewChild('HistoryTableSort', { static: true }) historyTableSort: MatSort;
@ -114,22 +114,7 @@ export class AccountDetailsComponent implements OnInit, AfterViewInit {
this.transactionService.resetTransactionsList();
await this.blockSyncService.blockSync(this.accountAddress);
this.userService.resetAccountsList();
(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!');
}
}
);
await this.loadAccount();
this.populateDataTables();
this.loadSearchData();
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?`)) {
return;
}
const accountKey = await this.userService.changeAccountInfo(
const status = await this.userService.changeAccountInfo(
this.accountAddress,
this.accountInfoFormStub.firstName.value + ', ' + this.accountInfoFormStub.lastName.value,
this.accountInfoFormStub.phoneNumber.value,
@ -199,6 +184,9 @@ export class AccountDetailsComponent implements OnInit, AfterViewInit {
this.accountInfoFormStub.locationType.value,
this.account.vcard?.tel[0].value
);
if (status) {
await this.loadAccount();
}
this.submitted = false;
}
@ -374,4 +362,23 @@ export class AccountDetailsComponent implements OnInit, AfterViewInit {
.pipe(first())
.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!');
}
}
);
}
}