Browse Source

Implement suggested changes

pull/2323/head
Frane Caleta 2 years ago
committed by Thomas
parent
commit
4a9e51f9b0
  1. 5
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/file-drop.directive.ts
  2. 182
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts
  3. 8
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html
  4. 2
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.module.ts
  5. 9
      apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.scss

5
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/file-drop.directive.ts

@ -1,7 +1,7 @@
import { Directive, HostListener, Output, EventEmitter } from '@angular/core'; import { Directive, HostListener, Output, EventEmitter } from '@angular/core';
@Directive({ @Directive({
selector: '[appFileDrop]' selector: '[gfFileDrop]'
}) })
export class FileDropDirective { export class FileDropDirective {
@Output() filesDropped = new EventEmitter<FileList>(); @Output() filesDropped = new EventEmitter<FileList>();
@ -23,7 +23,6 @@ export class FileDropDirective {
// Prevent the browser's default behavior for handling the file drop // Prevent the browser's default behavior for handling the file drop
event.dataTransfer.dropEffect = 'copy'; event.dataTransfer.dropEffect = 'copy';
const files = event.dataTransfer.files; this.filesDropped.emit(event.dataTransfer.files);
this.filesDropped.emit(files);
} }
} }

182
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.component.ts

@ -175,128 +175,9 @@ export class ImportActivitiesDialog implements OnDestroy {
aStepper.reset(); aStepper.reset();
} }
public onFilesDropped(files: FileList): void { private async handleFile(file: File): Promise<void> {
if (files.length === 0) {
return;
}
const droppedFile = files[0];
// Check the file type and handle it accordingly (JSON/CSV)
if (
droppedFile.type === 'application/json' ||
droppedFile.name.endsWith('.json')
) {
// Handle JSON file
const reader = new FileReader();
reader.readAsText(droppedFile, 'UTF-8');
reader.onload = async (readerEvent) => {
const fileContent = readerEvent.target.result as string;
try {
const content = JSON.parse(fileContent);
this.accounts = content.accounts;
if (!Array.isArray(content.activities)) {
if (Array.isArray(content.orders)) {
// Handle orders (activities) data
const { activities } =
await this.importActivitiesService.importJson({
accounts: content.accounts,
activities: content.orders,
isDryRun: true
});
this.activities = activities;
} else {
throw new Error('Unexpected JSON format');
}
} else {
// Handle activities data
const { activities } =
await this.importActivitiesService.importJson({
accounts: content.accounts,
activities: content.activities,
isDryRun: true
});
this.activities = activities;
}
} catch (error) {
console.error(error);
this.handleImportError({
activities: [],
error: {
error: { message: ['Error handling JSON file'] }
}
});
} finally {
this.importStep = ImportStep.SELECT_ACTIVITIES;
this.snackBar.dismiss();
// Proceed with further steps or updates as needed
this.changeDetectorRef.markForCheck();
}
};
} else if (
droppedFile.type === 'text/csv' ||
droppedFile.name.endsWith('.csv')
) {
// Handle CSV file
const reader = new FileReader();
reader.readAsText(droppedFile, 'UTF-8');
reader.onload = async (readerEvent) => {
const fileContent = readerEvent.target.result as string;
try {
const data = await this.importActivitiesService.importCsv({
fileContent,
isDryRun: true,
userAccounts: this.data.user.accounts
});
this.activities = data.activities;
} catch (error) {
console.error(error);
this.handleImportError({
activities: error?.activities ?? [],
error: {
error: { message: error?.error?.message ?? [error?.message] }
}
});
} finally {
this.importStep = ImportStep.SELECT_ACTIVITIES;
this.snackBar.dismiss();
// Proceed with further steps or updates as needed
this.changeDetectorRef.markForCheck();
}
};
} else {
// Handle unsupported file type
console.error('Unsupported file format');
this.handleImportError({
activities: [],
error: {
error: { message: ['Unsupported file format'] }
}
});
this.importStep = ImportStep.SELECT_ACTIVITIES;
this.snackBar.dismiss();
// Proceed with further steps or updates as needed
this.changeDetectorRef.markForCheck();
}
}
public onSelectFile(aStepper: MatStepper) {
const input = document.createElement('input');
input.accept = 'application/JSON, .csv';
input.type = 'file';
input.onchange = (event) => {
this.snackBar.open('⏳ ' + $localize`Validating data...`); this.snackBar.open('⏳ ' + $localize`Validating data...`);
// Getting the file reference
const file = (event.target as HTMLInputElement).files[0];
// Setting up the reader // Setting up the reader
const reader = new FileReader(); const reader = new FileReader();
reader.readAsText(file, 'UTF-8'); reader.readAsText(file, 'UTF-8');
@ -305,13 +186,12 @@ export class ImportActivitiesDialog implements OnDestroy {
const fileContent = readerEvent.target.result as string; const fileContent = readerEvent.target.result as string;
try { try {
if (file.name.endsWith('.json')) { if (file.type === 'application/json' || file.name.endsWith('.json')) {
const content = JSON.parse(fileContent); const content = JSON.parse(fileContent);
this.accounts = content.accounts; this.accounts = content.accounts;
if (!isArray(content.activities)) { if (!Array.isArray(content.activities)) {
if (isArray(content.orders)) { if (Array.isArray(content.orders)) {
this.handleImportError({ this.handleImportError({
activities: [], activities: [],
error: { error: {
@ -326,57 +206,51 @@ export class ImportActivitiesDialog implements OnDestroy {
} }
} }
try { const { activities } = await this.importActivitiesService.importJson({
const { activities } =
await this.importActivitiesService.importJson({
accounts: content.accounts, accounts: content.accounts,
activities: content.activities, activities: content.activities,
isDryRun: true isDryRun: true
}); });
this.activities = activities; this.activities = activities;
} catch (error) { } else if (file.type === 'text/csv' || file.name.endsWith('.csv')) {
console.error(error);
this.handleImportError({ error, activities: content.activities });
}
return;
} else if (file.name.endsWith('.csv')) {
try {
const data = await this.importActivitiesService.importCsv({ const data = await this.importActivitiesService.importCsv({
fileContent, fileContent,
isDryRun: true, isDryRun: true,
userAccounts: this.data.user.accounts userAccounts: this.data.user.accounts
}); });
this.activities = data.activities; this.activities = data.activities;
} else {
throw new Error();
}
} catch (error) { } catch (error) {
console.error(error); console.error(error);
this.handleImportError({ this.handleImportError({ error, activities: [] });
activities: error?.activities ?? [], } finally {
error: { this.importStep = ImportStep.SELECT_ACTIVITIES;
error: { message: error?.error?.message ?? [error?.message] } this.snackBar.dismiss();
this.changeDetectorRef.markForCheck();
} }
}); };
} }
public onFilesDropped(files: FileList): void {
if (files.length === 0) {
return; return;
} }
throw new Error(); const droppedFile = files[0];
} catch (error) { this.handleFile(droppedFile);
console.error(error); }
this.handleImportError({
activities: [],
error: { error: { message: ['Unexpected format'] } }
});
} finally {
this.importStep = ImportStep.SELECT_ACTIVITIES;
this.snackBar.dismiss();
aStepper.next(); public onSelectFile(aStepper: MatStepper) {
const input = document.createElement('input');
input.accept = 'application/JSON, .csv';
input.type = 'file';
this.changeDetectorRef.markForCheck(); input.onchange = (event) => {
} // Getting the file reference
}; const file = (event.target as HTMLInputElement).files[0];
this.handleFile(file);
}; };
input.click(); input.click();

8
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.html

@ -70,12 +70,14 @@
<ng-template #selectFile> <ng-template #selectFile>
<div class="d-flex flex-column justify-content-center"> <div class="d-flex flex-column justify-content-center">
<button <button
appFileDrop class="drop-area cursor-pointer text-center p-4"
class="custom-button" gfFileDrop
(click)="onSelectFile(stepper)" (click)="onSelectFile(stepper)"
(filesDropped)="onFilesDropped($event)" (filesDropped)="onFilesDropped($event)"
> >
<div class="button-content"> <div
class="button-content d-flex align-items-center justify-content-center flex-column"
>
<ion-icon <ion-icon
class="cloud-icon" class="cloud-icon"
name="cloud-upload-outline" name="cloud-upload-outline"

2
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.module.ts

@ -17,7 +17,7 @@ import { FileDropDirective } from './file-drop.directive';
import { ImportActivitiesDialog } from './import-activities-dialog.component'; import { ImportActivitiesDialog } from './import-activities-dialog.component';
@NgModule({ @NgModule({
declarations: [ImportActivitiesDialog, FileDropDirective], declarations: [FileDropDirective, ImportActivitiesDialog],
imports: [ imports: [
CommonModule, CommonModule,
FormsModule, FormsModule,

9
apps/client/src/app/pages/portfolio/activities/import-activities-dialog/import-activities-dialog.scss

@ -33,21 +33,14 @@
top: calc(50% - 10px); top: calc(50% - 10px);
} }
.custom-button { .drop-area {
border: 3px dashed rgba(var(--palette-primary-500), 1); border: 3px dashed rgba(var(--palette-primary-500), 1);
border-radius: 8px; border-radius: 8px;
padding: 30px;
text-align: center;
background-color: inherit; background-color: inherit;
cursor: pointer;
transition: border-color 0.1s ease; transition: border-color 0.1s ease;
color: rgba(var(--palette-primary-500), 1); color: rgba(var(--palette-primary-500), 1);
.button-content { .button-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-weight: bolder; font-weight: bolder;
} }

Loading…
Cancel
Save