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:
		
						commit
						974f9c3264
					
				@ -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 });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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) {
 | 
			
		||||
 | 
			
		||||
@ -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!');
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user