From 5357414c60758dd3838d5d874c669bc92891dd25 Mon Sep 17 00:00:00 2001 From: hlkavya0213 <79827230+hlkavya0213@users.noreply.github.com> Date: Mon, 9 Oct 2023 18:02:20 +0530 Subject: [PATCH] feat: remove thumbnails across mobile app (#2499) --- src/app/core/mock-data/file-object.data.ts | 3 +- src/app/core/services/file.service.spec.ts | 41 +----- src/app/core/services/file.service.ts | 28 +---- .../split-expense/split-expense.page.spec.ts | 4 +- .../expense-card-lite.component.html | 14 +-- .../expense-card-lite.component.scss | 7 +- .../expense-card-lite.component.spec.ts | 69 ++++------ .../expense-card-lite.component.ts | 21 +--- .../expenses-card.component.html | 17 +-- .../expenses-card.component.scss | 7 +- .../expenses-card.component.spec.ts | 118 +----------------- .../expenses-card/expenses-card.component.ts | 61 ++------- src/assets/images/pdf-receipt-placeholder.png | Bin 0 -> 7933 bytes 13 files changed, 77 insertions(+), 313 deletions(-) create mode 100644 src/assets/images/pdf-receipt-placeholder.png diff --git a/src/app/core/mock-data/file-object.data.ts b/src/app/core/mock-data/file-object.data.ts index 8655f0fd8f..b6f37c79d9 100644 --- a/src/app/core/mock-data/file-object.data.ts +++ b/src/app/core/mock-data/file-object.data.ts @@ -78,10 +78,9 @@ export const fileObjectData5: FileObject = { purpose: '', }; -export const thumbnailUrlMockData: FileObject[] = [ +export const fileUrlMockData: FileObject[] = [ { id: 'fiwJ0nQTBpYH', - purpose: 'THUMBNAILx200x200', url: 'mock-url-1', }, ]; diff --git a/src/app/core/services/file.service.spec.ts b/src/app/core/services/file.service.spec.ts index 15cf211c74..11d50a46de 100644 --- a/src/app/core/services/file.service.spec.ts +++ b/src/app/core/services/file.service.spec.ts @@ -1,12 +1,6 @@ import { TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; -import { - fileObjectAdv, - fileObjectAdv1, - fileObjectData, - fileObjectData4, - thumbnailUrlMockData, -} from '../mock-data/file-object.data'; +import { fileObjectAdv, fileObjectAdv1, fileObjectData, fileObjectData4 } from '../mock-data/file-object.data'; import { ApiService } from './api.service'; import { DateService } from './date.service'; @@ -42,39 +36,6 @@ describe('FileService', () => { expect(fileService).toBeTruthy(); }); - it('downloadThumbnailUrl(): should return the file obj with thumbnail url', (done) => { - apiService.post.and.returnValue(of(thumbnailUrlMockData)); - - const fileId = 'fiwJ0nQTBpYH'; - fileService.downloadThumbnailUrl(fileId).subscribe((res) => { - expect(res).toEqual(thumbnailUrlMockData); - expect(apiService.post).toHaveBeenCalledOnceWith('/files/download_urls', [ - { - id: fileId, - purpose: 'THUMBNAILx200x200', - }, - ]); - done(); - }); - }); - - it('getFilesWithThumbnail(): should return files with thumbnail for the given txn ID', (done) => { - apiService.get.and.returnValue(of([fileObjectData])); - - const txnId = 'txdzGV1TZEg3'; - fileService.getFilesWithThumbnail(txnId).subscribe((res) => { - expect(res).toEqual([fileObjectData]); - expect(apiService.get).toHaveBeenCalledOnceWith('/files', { - params: { - transaction_id: txnId, - skip_html: 'true', - purpose: 'THUMBNAILx200x200', - }, - }); - done(); - }); - }); - it('base64Download(): should return the base64 encoded file content', (done) => { apiService.get.and.returnValue(of({ content: 'base64encodedcontent' })); diff --git a/src/app/core/services/file.service.ts b/src/app/core/services/file.service.ts index 937437af53..225c8c7d80 100644 --- a/src/app/core/services/file.service.ts +++ b/src/app/core/services/file.service.ts @@ -12,34 +12,12 @@ import { DateService } from './date.service'; providedIn: 'root', }) export class FileService { - constructor( - private apiService: ApiService, - private dateService: DateService, - ) {} + constructor(private apiService: ApiService, private dateService: DateService) {} downloadUrl(fileId: string): Observable { return this.apiService.post('/files/' + fileId + '/download_url').pipe(map((res) => res.url)); } - downloadThumbnailUrl(fileId: string): Observable { - return this.apiService.post('/files/download_urls', [ - { - id: fileId, - purpose: 'THUMBNAILx200x200', - }, - ]); - } - - getFilesWithThumbnail(txnId: string): Observable { - return this.apiService.get('/files', { - params: { - transaction_id: txnId, - skip_html: 'true', - purpose: 'THUMBNAILx200x200', - }, - }); - } - base64Download(fileId: string): Observable<{ content: string }> { return this.apiService.get('/files/' + fileId + '/download_b64'); } @@ -51,7 +29,7 @@ export class FileService { advance_request_id: advanceRequestId, skip_html: 'true', }, - }), + }) ).pipe( map((files) => { files.map((file) => { @@ -59,7 +37,7 @@ export class FileService { this.setFileType(file as FileObject); }); return files as unknown as FileObject[]; - }), + }) ); } diff --git a/src/app/fyle/split-expense/split-expense.page.spec.ts b/src/app/fyle/split-expense/split-expense.page.spec.ts index 492730b5f3..e7ac7feaef 100644 --- a/src/app/fyle/split-expense/split-expense.page.spec.ts +++ b/src/app/fyle/split-expense/split-expense.page.spec.ts @@ -84,7 +84,7 @@ import { splitExpFile2, splitExpFile3, splitExpFileObj, - thumbnailUrlMockData, + fileUrlMockData, fileObjectData1, } from 'src/app/core/mock-data/file-object.data'; import { @@ -632,7 +632,7 @@ describe('SplitExpensePage', () => { it('should return the attached files when the transaction id is specified', (done) => { spyOn(component, 'getAttachedFiles').and.returnValue(of(fileObject8)); - const FileObject9: FileObject[] = thumbnailUrlMockData.map((fileObject) => ({ + const FileObject9: FileObject[] = fileUrlMockData.map((fileObject) => ({ ...fileObject, id: 'fizBwnXhyZTp', })); diff --git a/src/app/shared/components/expense-card-lite/expense-card-lite.component.html b/src/app/shared/components/expense-card-lite/expense-card-lite.component.html index ae9a29ff24..afce935eb9 100644 --- a/src/app/shared/components/expense-card-lite/expense-card-lite.component.html +++ b/src/app/shared/components/expense-card-lite/expense-card-lite.component.html @@ -1,6 +1,6 @@
- +
-
+
+ +
@@ -29,7 +25,7 @@
- {{ expense.txn_dt | date: 'MMM dd, YYYY' }} + {{ expense.txn_dt | date : 'MMM dd, YYYY' }}
diff --git a/src/app/shared/components/expense-card-lite/expense-card-lite.component.scss b/src/app/shared/components/expense-card-lite/expense-card-lite.component.scss index 6a59195d44..75507b99af 100644 --- a/src/app/shared/components/expense-card-lite/expense-card-lite.component.scss +++ b/src/app/shared/components/expense-card-lite/expense-card-lite.component.scss @@ -28,7 +28,7 @@ padding: 15px; } - &--receipt-thumbnail-container { + &--receipt-image-container { background-color: $light-grey; border-radius: 8px; height: 64px; @@ -38,6 +38,11 @@ align-items: center; } + &--receipt-image { + height: 60px; + width: 80px; + } + &--with-image { background-size: cover; background-repeat: no-repeat; diff --git a/src/app/shared/components/expense-card-lite/expense-card-lite.component.spec.ts b/src/app/shared/components/expense-card-lite/expense-card-lite.component.spec.ts index 009a8fbe0f..bcb7a45cd2 100644 --- a/src/app/shared/components/expense-card-lite/expense-card-lite.component.spec.ts +++ b/src/app/shared/components/expense-card-lite/expense-card-lite.component.spec.ts @@ -1,22 +1,13 @@ -import { ComponentFixture, TestBed, async, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { FileService } from 'src/app/core/services/file.service'; import { ExpenseCardLiteComponent } from './expense-card-lite.component'; import { IonicModule } from '@ionic/angular'; import { MatIconModule } from '@angular/material/icon'; import { MatIconTestingModule } from '@angular/material/icon/testing'; import { CurrencySymbolPipe } from '../../pipes/currency-symbol.pipe'; -import { fileObjectData1 } from 'src/app/core/mock-data/file-object.data'; -import { of } from 'rxjs'; import { getElementBySelector, getTextContent } from 'src/app/core/dom-helpers'; -import { FileObject } from 'src/app/core/models/file-obj.model'; - -const thumbnailUrlMockData1: FileObject[] = [ - { - id: 'fiwJ0nQTBpYH', - purpose: 'THUMBNAILx200x200', - url: '/assets/images/add-to-list.png', - }, -]; +import { of } from 'rxjs'; +import { fileObjectData } from 'src/app/core/mock-data/file-object.data'; describe('ExpenseCardLiteComponent', () => { let expenseCardLiteComponent: ExpenseCardLiteComponent; @@ -24,9 +15,7 @@ describe('ExpenseCardLiteComponent', () => { let fileService: jasmine.SpyObj; beforeEach(waitForAsync(() => { - const fileServiceSpy = jasmine.createSpyObj('FileService', ['getFilesWithThumbnail', 'downloadThumbnailUrl']); - fileServiceSpy.getFilesWithThumbnail.and.returnValue(of(fileObjectData1)); - fileServiceSpy.downloadThumbnailUrl.and.returnValue(of(thumbnailUrlMockData1)); + const fileServiceSpy = jasmine.createSpyObj('FileService', ['findByTransactionId']); TestBed.configureTestingModule({ declarations: [ExpenseCardLiteComponent, CurrencySymbolPipe], @@ -42,58 +31,48 @@ describe('ExpenseCardLiteComponent', () => { fixture = TestBed.createComponent(ExpenseCardLiteComponent); expenseCardLiteComponent = fixture.componentInstance; - const expense = { id: 'txn1234' }; - expenseCardLiteComponent.expense = expense; - fixture.detectChanges(); })); it('should create', () => { expect(expenseCardLiteComponent).toBeTruthy(); }); - it('should call getReceipt on initialization', () => { - spyOn(expenseCardLiteComponent, 'getReceipt'); - expenseCardLiteComponent.ngOnInit(); - expect(expenseCardLiteComponent.getReceipt).toHaveBeenCalledTimes(1); - }); + const initialSetup = (fileData) => { + fileService.findByTransactionId.and.returnValue(of(fileData)); + expenseCardLiteComponent.expense = { id: 'txn1234' }; + fixture.detectChanges(); + }; describe('getReceipt():', () => { - it('should set receiptThumbnail if there is at least one thumbnail file', () => { - fixture.detectChanges(); - expect(fileService.getFilesWithThumbnail).toHaveBeenCalledOnceWith(expenseCardLiteComponent.expense.id); - expect(fileService.downloadThumbnailUrl).toHaveBeenCalledOnceWith(fileObjectData1[0].id); - expect(expenseCardLiteComponent.receiptThumbnail).toEqual(thumbnailUrlMockData1[0].url); + it('should set isReceiptPresent to true when files are present', () => { + initialSetup([fileObjectData]); + expect(fileService.findByTransactionId).toHaveBeenCalledWith('txn1234'); + expect(expenseCardLiteComponent.isReceiptPresent).toBeTruthy(); }); - it('should return an empty array if there are no thumbnail files', () => { - fileService.getFilesWithThumbnail.and.returnValue(of([])); - fixture.detectChanges(); - expenseCardLiteComponent.getReceipt(); - expect(fileService.getFilesWithThumbnail).toHaveBeenCalledWith(expenseCardLiteComponent.expense.id); - expect(expenseCardLiteComponent.receiptThumbnail).toEqual(thumbnailUrlMockData1[0].url); + it('should set isReceiptPresent to false when no files are present', () => { + initialSetup([]); + expect(fileService.findByTransactionId).toHaveBeenCalledWith('txn1234'); + expect(expenseCardLiteComponent.isReceiptPresent).toBeFalsy(); }); }); - it('should display the thumbnail when available', () => { - fixture.detectChanges(); + it('should display the receipt when available', () => { + initialSetup([fileObjectData]); const element = fixture.nativeElement; - const thumbnailContainer = element.querySelector('.expenses-card--receipt-thumbnail-container'); - const backgroundImage = thumbnailContainer.style.backgroundImage; - expect(thumbnailContainer).toBeTruthy(); - expect(backgroundImage).toContain(expenseCardLiteComponent.receiptThumbnail); + const receiptContainer = element.querySelector('.expenses-card--receipt-image-container'); + expect(receiptContainer).toBeTruthy(); }); - it('should display a default icon when no thumbnail available', () => { - expenseCardLiteComponent.receiptThumbnail = null; - fixture.detectChanges(); - + it('should display a default icon when no receipt available', () => { + initialSetup([]); const element = fixture.nativeElement; const icon = element.querySelector('.expenses-card--receipt-icon'); expect(icon).toBeTruthy(); }); it('should display "Unspecified" if purpose is not present', () => { - fixture.detectChanges(); + initialSetup([]); const purpose = getElementBySelector(fixture, '.expenses-card--category'); expect(getTextContent(purpose)).toEqual('Unspecified'); }); diff --git a/src/app/shared/components/expense-card-lite/expense-card-lite.component.ts b/src/app/shared/components/expense-card-lite/expense-card-lite.component.ts index d24e3763e8..22500e4ec2 100644 --- a/src/app/shared/components/expense-card-lite/expense-card-lite.component.ts +++ b/src/app/shared/components/expense-card-lite/expense-card-lite.component.ts @@ -1,6 +1,4 @@ import { Component, Input, OnInit } from '@angular/core'; -import { noop } from 'rxjs'; -import { map, switchMap } from 'rxjs/operators'; import { FileObject } from 'src/app/core/models/file-obj.model'; import { FileService } from 'src/app/core/services/file.service'; @@ -12,7 +10,7 @@ import { FileService } from 'src/app/core/services/file.service'; export class ExpenseCardLiteComponent implements OnInit { @Input() expense; - receiptThumbnail: string; + isReceiptPresent: boolean; constructor(private fileService: FileService) {} @@ -21,19 +19,8 @@ export class ExpenseCardLiteComponent implements OnInit { } getReceipt() { - this.fileService - .getFilesWithThumbnail(this.expense.id) - .pipe( - switchMap((ThumbFiles: FileObject[]) => { - if (ThumbFiles.length > 0) { - return this.fileService.downloadThumbnailUrl(ThumbFiles[0].id); - } else { - return []; - } - }) - ) - .subscribe((downloadUrl: FileObject[]) => { - this.receiptThumbnail = downloadUrl[0].url; - }); + this.fileService.findByTransactionId(this.expense.id).subscribe((files: FileObject[]) => { + this.isReceiptPresent = files.length > 0; + }); } } diff --git a/src/app/shared/components/expenses-card/expenses-card.component.html b/src/app/shared/components/expenses-card/expenses-card.component.html index 99c560f7f0..28bc75e0b3 100644 --- a/src/app/shared/components/expenses-card/expenses-card.component.html +++ b/src/app/shared/components/expenses-card/expenses-card.component.html @@ -26,7 +26,7 @@
- +
+
@@ -62,7 +63,9 @@ class="expenses-card--receipt-container expenses-card--with-image" *ngIf="attachmentUploadInProgress" [ngStyle]="{ - 'background-image': inlineReceiptDataUrl && imageTransperencyOverlay + 'url(' + inlineReceiptDataUrl + ')' + 'background-image': + inlineReceiptDataUrl && + imageTransperencyOverlay + 'url(' + '../../../../assets/images/pdf-receipt-placeholder.png' + ')' }" >
@@ -77,7 +80,7 @@ [ngStyle]="{ 'background-image': expense.tx_dataUrls?.length > 0 && - imageTransperencyOverlay + 'url(' + this.expense.tx_dataUrls[0].thumbnail + ')' + imageTransperencyOverlay + 'url(' + '../../../../assets/images/pdf-receipt-placeholder.png' + ')' }" >
@@ -91,7 +94,7 @@ [ngStyle]="{ 'background-image': expense.tx_dataUrls?.length > 0 && - imageTransperencyOverlay + 'url(' + this.expense.tx_dataUrls[0].thumbnail + ')' + imageTransperencyOverlay + 'url(' + '../../../../assets/images/pdf-receipt-placeholder.png' + ')' }" > { let component: ExpensesCardComponent; let fixture: ComponentFixture; @@ -79,8 +65,6 @@ describe('ExpensesCardComponent', () => { ]); const orgUserSettingsServiceSpy = jasmine.createSpyObj('OrgUserSettingsService', ['get']); const fileServiceSpy = jasmine.createSpyObj('FileService', [ - 'getFilesWithThumbnail', - 'downloadThumbnailUrl', 'downloadUrl', 'getReceiptDetails', 'readFile', @@ -89,8 +73,6 @@ describe('ExpensesCardComponent', () => { 'post', ]); - fileServiceSpy.getFilesWithThumbnail.and.returnValue(of(fileObjectData1)); - fileServiceSpy.downloadThumbnailUrl.and.returnValue(of(thumbnailUrlMockData1)); fileServiceSpy.downloadUrl.and.returnValue(of('/assets/images/add-to-list.png')); const popoverControllerSpy = jasmine.createSpyObj('PopoverController', ['create']); const networkServiceSpy = jasmine.createSpyObj('NetworkService', ['connectivityWatcher', 'isOnline']); @@ -174,7 +156,6 @@ describe('ExpensesCardComponent', () => { component.isConnected$ = of(true); component.isSycing$ = of(true); component.isPerDiem = true; - component.receiptThumbnail = 'assets/svg/pdf.svg'; component.isSelectionModeEnabled = false; component.etxnIndex = 1; componentElement = fixture.debugElement; @@ -224,69 +205,6 @@ describe('ExpensesCardComponent', () => { }); describe('getReceipt', () => { - it('should get the receipts when the file ids are present and the length of the thumbnail files array is greater that 0', fakeAsync(() => { - fileService.getFilesWithThumbnail.and.returnValue(of([fileObjectData])); - fileService.downloadThumbnailUrl.and.returnValue(of(thumbnailUrlMockData1)); - component.expense = { - ...expenseData1, - tx_file_ids: ['fiGLwwPtYD8X'], - }; - component.getReceipt(); - fixture.detectChanges(); - tick(500); - expect(component.receiptThumbnail).toEqual(thumbnailUrlMockData1[0].url); - expect(fileService.getFilesWithThumbnail).toHaveBeenCalledOnceWith(component.expense.tx_id); - expect(fileService.downloadThumbnailUrl).toHaveBeenCalledOnceWith('fiHPZUiichAS'); - })); - - it('should get the receipts when the file ids are present and there are no thumbnail files and set the icon to fy-expense when type is not pdf', fakeAsync(() => { - const mockDownloadUrl = { - url: 'mock-url', - }; - fileService.getFilesWithThumbnail.and.returnValue(of([])); - fileService.downloadUrl.and.returnValue(of(mockDownloadUrl.url)); - fileService.getReceiptDetails.and.returnValue('mock-url'); - - component.expense = { - ...expenseData1, - tx_file_ids: ['fiGLwwPtYD8X'], - }; - component.getReceipt(); - fixture.detectChanges(); - tick(500); - expect(fileService.getFilesWithThumbnail).toHaveBeenCalledOnceWith(component.expense.tx_id); - expect(fileService.downloadUrl).toHaveBeenCalledOnceWith('fiGLwwPtYD8X'); - expect(fileService.getReceiptDetails).toHaveBeenCalledOnceWith('mock-url'); - expect(component.receiptIcon).toEqual('assets/svg/fy-expense.svg'); - })); - - it('should get the receipts when the file ids are present and there are no thumbnail files and set the icon to fy-pdf when type is pdf', fakeAsync(() => { - const mockDownloadUrl = { - url: 'mock-url', - }; - - const thumbnailUrlMockRes = { - ...thumbnailUrlMockData1, - url: '/assets/mock-url.pdf', - }; - fileService.getFilesWithThumbnail.and.returnValue(of([])); - fileService.downloadThumbnailUrl.and.returnValue(of(thumbnailUrlMockRes)); - fileService.downloadUrl.and.returnValue(of(mockDownloadUrl.url)); - fileService.getReceiptDetails.and.returnValue('pdf'); - - component.expense = { - ...expenseData1, - tx_file_ids: ['fiGLwwPtYD8Y'], - }; - component.getReceipt(); - fixture.detectChanges(); - tick(500); - expect(fileService.getFilesWithThumbnail).toHaveBeenCalledOnceWith(component.expense.tx_id); - expect(fileService.downloadUrl).toHaveBeenCalledOnceWith('fiGLwwPtYD8Y'); - expect(fileService.getReceiptDetails).toHaveBeenCalledOnceWith('mock-url'); - expect(component.receiptIcon).toEqual('assets/svg/pdf.svg'); - })); - it('should set the receipt icon to fy-mileage when the fyle catergory is mileage', () => { component.expense = { ...expenseData1, @@ -742,7 +660,6 @@ describe('ExpensesCardComponent', () => { fileService.post.and.returnValue(of(fileObjectData)); spyOn(component, 'matchReceiptWithEtxn').and.callThrough(); - spyOn(component, 'setThumbnail').and.callThrough(); component.attachReceipt(receiptDetailsaRes); tick(500); @@ -751,7 +668,6 @@ describe('ExpensesCardComponent', () => { expect(transactionsOutboxService.fileUpload).toHaveBeenCalledOnceWith(dataUrl, attachmentType); expect(component.matchReceiptWithEtxn).toHaveBeenCalledOnceWith(fileObj); expect(fileService.post).toHaveBeenCalledOnceWith(fileObj); - expect(component.setThumbnail).toHaveBeenCalledOnceWith(fileObjectData.id, attachmentType); expect(component.attachmentUploadInProgress).toBeFalse(); tick(500); })); @@ -896,32 +812,6 @@ describe('ExpensesCardComponent', () => { })); }); - describe('setThumbnail():', () => { - it('should set the thumbnail', fakeAsync(() => { - const fileObjid = fileObjectData.id; - const attachmentType = 'pdf'; - fileService.downloadUrl.and.returnValue(of('mock-url')); - component.setThumbnail(fileObjid, attachmentType); - fixture.detectChanges(); - tick(500); - expect(component.receiptIcon).toEqual('assets/svg/pdf.svg'); - expect(fileService.downloadUrl).toHaveBeenCalledOnceWith(fileObjid); - })); - - it('should set the receipt thumbnail to download url when the attatchment tyoe is not pdf', fakeAsync(() => { - component.receiptIcon = undefined; - const fileObjid = fileObjectData.id; - const attachmentType = 'png'; - fileService.downloadUrl.and.returnValue(of('/assets/images/add-to-list.png')); - component.setThumbnail(fileObjid, attachmentType); - fixture.detectChanges(); - tick(500); - expect(component.receiptThumbnail).toEqual(thumbnailUrlMockData1[0].url); - expect(component.receiptIcon).toBeUndefined(); - expect(fileService.downloadUrl).toHaveBeenCalledOnceWith(fileObjid); - })); - }); - it('setupNetworkWatcher(): should setup the network watcher', fakeAsync(() => { networkService.isOnline.and.returnValue(of(true)); const eventEmitterMock = new EventEmitter(); diff --git a/src/app/shared/components/expenses-card/expenses-card.component.ts b/src/app/shared/components/expenses-card/expenses-card.component.ts index 64789dd34e..141c41bebc 100644 --- a/src/app/shared/components/expenses-card/expenses-card.component.ts +++ b/src/app/shared/components/expenses-card/expenses-card.component.ts @@ -101,7 +101,7 @@ export class ExpensesCardComponent implements OnInit { attachmentUploadInProgress = false; - receiptThumbnail: string = null; + isReceiptPresent: boolean; isConnected$: Observable; @@ -135,7 +135,7 @@ export class ExpensesCardComponent implements OnInit { private trackingService: TrackingService, private currencyService: CurrencyService, private expenseFieldsService: ExpenseFieldsService, - private orgSettingsService: OrgSettingsService, + private orgSettingsService: OrgSettingsService ) {} get isSelected(): boolean { @@ -167,36 +167,7 @@ export class ExpensesCardComponent implements OnInit { this.receiptIcon = 'assets/svg/fy-expense.svg'; } } else { - this.fileService - .getFilesWithThumbnail(this.expense.tx_id) - .pipe( - map((ThumbFiles: FileObject[]) => { - if (ThumbFiles.length > 0) { - this.fileService - .downloadThumbnailUrl(ThumbFiles[0].id) - .pipe( - map((downloadUrl: FileObject[]) => { - this.receiptThumbnail = downloadUrl[0].url; - }), - ) - .subscribe(noop); - } else { - this.fileService - .downloadUrl(this.expense.tx_file_ids[0]) - .pipe( - map((downloadUrl: string) => { - if (this.fileService.getReceiptDetails(downloadUrl) === 'pdf') { - this.receiptIcon = 'assets/svg/pdf.svg'; - } else { - this.receiptIcon = 'assets/svg/fy-expense.svg'; - } - }), - ) - .subscribe(noop); - } - }), - ) - .subscribe(noop); + this.isReceiptPresent = true; } } } @@ -281,7 +252,7 @@ export class ExpensesCardComponent implements OnInit { const orgSettings$ = this.orgSettingsService.get().pipe(shareReplay(1)); this.isSycing$ = this.isConnected$.pipe( - map((isConnected) => isConnected && this.transactionOutboxService.isSyncInProgress() && this.isOutboxExpense), + map((isConnected) => isConnected && this.transactionOutboxService.isSyncInProgress() && this.isOutboxExpense) ); this.isMileageExpense = this.expense.tx_org_category && this.expense.tx_org_category?.toLowerCase() === 'mileage'; @@ -301,13 +272,13 @@ export class ExpensesCardComponent implements OnInit { .pipe( map((homeCurrency) => { this.homeCurrency = homeCurrency; - }), + }) ) .subscribe(noop); this.isProjectEnabled$ = orgSettings$.pipe( map((orgSettings) => orgSettings.projects && orgSettings.projects.allowed && orgSettings.projects.enabled), - shareReplay(1), + shareReplay(1) ); if (!this.expense.tx_id) { @@ -315,7 +286,7 @@ export class ExpensesCardComponent implements OnInit { } else if (this.previousExpenseTxnDate || this.previousExpenseCreatedAt) { const currentDate = this.expense && new Date(this.expense.tx_txn_dt || this.expense.tx_created_at).toDateString(); const previousDate = new Date( - (this.previousExpenseTxnDate || this.previousExpenseCreatedAt) as string, + (this.previousExpenseTxnDate || this.previousExpenseCreatedAt) as string ).toDateString(); this.showDt = currentDate !== previousDate; } @@ -453,16 +424,6 @@ export class ExpensesCardComponent implements OnInit { } } - setThumbnail(fileObjId: string, attachmentType: string): void { - this.fileService.downloadUrl(fileObjId).subscribe((downloadUrl) => { - if (attachmentType === 'pdf') { - this.receiptIcon = 'assets/svg/pdf.svg'; - } else { - this.receiptThumbnail = downloadUrl; - } - }); - } - matchReceiptWithEtxn(fileObj: FileObject): void { this.expense.tx_file_ids = []; this.expense.tx_file_ids.push(fileObj.id); @@ -482,17 +443,17 @@ export class ExpensesCardComponent implements OnInit { }), finalize(() => { this.attachmentUploadInProgress = false; - }), + }) ) - .subscribe((fileObj: FileObject) => { - this.setThumbnail(fileObj.id, attachmentType); + .subscribe(() => { + this.isReceiptPresent = true; }); } setupNetworkWatcher(): void { const networkWatcherEmitter = this.networkService.connectivityWatcher(new EventEmitter()); this.isConnected$ = concat(this.networkService.isOnline(), networkWatcherEmitter.asObservable()).pipe( - startWith(true), + startWith(true) ); } diff --git a/src/assets/images/pdf-receipt-placeholder.png b/src/assets/images/pdf-receipt-placeholder.png new file mode 100644 index 0000000000000000000000000000000000000000..619061247bb2fcd87058fce92722a83328bd839f GIT binary patch literal 7933 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 literal 0 HcmV?d00001