Skip to content

Commit

Permalink
Story #13791 cc: create project with zip file class and file selector
Browse files Browse the repository at this point in the history
  • Loading branch information
laedanrex committed Dec 23, 2024
1 parent cf02004 commit f70995a
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ import {
SearchCriteriaTypeEnum,
Transaction,
Unit,
ZipFile,
} from 'vitamui-library';
import { ArchiveCollectService } from '../archive-collect.service';
import { FormControl } from '@angular/forms';
import { ZipFile } from './zip-file';
import { last, tap } from 'rxjs/operators';
import { HttpEventType } from '@angular/common/http';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,9 @@
<span class="pb-3">{{ 'COLLECT.PROJECT_CONTEXT_ACQUISITION_INFORMATION' | translate }}</span>
</label>
<mat-select formControlName="acquisitionInformation">
<mat-option *ngFor="let acquisitionInformation of acquisitionInformationsList" [value]="acquisitionInformation">{{
acquisitionInformation
}}</mat-option>
<mat-option *ngFor="let acquisitionInformation of acquisitionInformationsList" [value]="acquisitionInformation"
>{{ acquisitionInformation }}
</mat-option>
</mat-select>
</mat-form-field>
</div>
Expand All @@ -203,7 +203,7 @@
<span class="pb-3">{{ 'COLLECT.PROJECT_CONTEXT_LEGAL_STATUS' | translate }}</span>
</label>
<mat-select formControlName="legalStatus">
<mat-option *ngFor="let legalStatus of legalStatusList" [value]="legalStatus.id">{{ legalStatus.value }}</mat-option>
<mat-option *ngFor="let legalStatus of legalStatusList" [value]="legalStatus.id">{{ legalStatus.value }} </mat-option>
</mat-select>
</mat-form-field>
</div>
Expand All @@ -225,48 +225,25 @@
</div>
</cdk-step>

<!-- ########## stepIndex 4 : workflow 1 , step 4/6 : Upload fichiers ########## -->
<!-- ########## stepIndex 4 : workflow 1 , step 4/6 : Choix des fichiers à upload ########## -->
<cdk-step *ngIf="selectedWorkflow === Workflow.MANUAL">
<div class="content">
<div class="text medium light">{{ 'COLLECT.MODAL.TITLE' | translate }}</div>
<div class="text large bold">{{ 'COLLECT.MODAL.UPLOAD_SUB_TITLE' | translate }}</div>
<div class="main-content">
<div
class="drag-and-drop-area"
(dragleave)="onDragLeave($event)"
(dragover)="onDragOver($event)"
(drop)="onDropped($event)"
[ngClass]="{ 'on-over': hasDropZoneOver }"
>
<div *ngIf="(uploadFiles$ | async)?.length > 0" class="drag-container">
<div class="file-info-class">
<div class="vitamui-chip-list">
<div *ngFor="let uploadFile of uploadFiles$ | async" class="vitamui-chip">
<div [title]="uploadFile" class="vitamui-chip-content">
{{ uploadFile?.name }}
<span class="file-size">{{ uploadFile?.size | bytes }}</span>
</div>
<div (click)="removeFolder(uploadFile)" class="vitamui-remove-chip">
<i class="material-icons">clear</i>
</div>
</div>
</div>
</div>
</div>
<input #fileSearch (change)="handleFile($event)" class="input-file" directory multiple type="file" webkitdirectory />
<div class="drop-area">
<div class="sip-drop">
<span (click)="fileSearch.click()" class="url-select">
{{ 'COLLECT.UPLOAD.DRAG_AND_DROP_OR_BROWSE' | translate }}
</span>
<span class="sip-drop-small">{{ 'COLLECT.UPLOAD.ADD_FILE_DESCRIPTION' | translate }}</span>
</div>
</div>
<div class="w-100">
<vitamui-file-selector
[multipleFiles]="true"
[maxSizeInBytes]="uploadMaxSizeInBytes"
[directoryMode]="true"
(filesChanged)="setFilesToUpload($event)"
>
</vitamui-file-selector>
</div>
</div>
<div class="actions">
<div class="line">
<button (click)="moveToNextStep()" [disabled]="(uploadFiles$ | async)?.length === 0" class="btn primary" type="button">
<button (click)="moveToNextStep()" [disabled]="filesToUpload.length < 1" class="btn primary" type="button">
{{ 'COMMON.NEXT' | translate }}
</button>
<button (click)="onClose()" class="btn link" type="button">
Expand Down Expand Up @@ -484,7 +461,7 @@
</div>
</cdk-step>

<!-- stepIndex 8 : workflow 1 , step 6/6 : Upload fichiers -->
<!-- stepIndex 8 : workflow 1 , step 6/6 : Zip des fichiers et upload -->
<cdk-step *ngIf="selectedWorkflow === Workflow.MANUAL">
<div class="content">
<div class="text medium light">{{ 'COLLECT.MODAL.TITLE' | translate }}</div>
Expand All @@ -500,7 +477,7 @@
</tr>
</thead>
<tbody>
<tr *ngIf="zippedFile$ | async as zippedFile">
<tr *ngIf="zipFileStatus$ | async as zippedFile">
<td>{{ zippedFile?.name }}</td>
<td>{{ zippedFile?.size | fileSize }}</td>
<td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
* knowledge of the CeCILL-C license and that you accept its terms.
*/
import { animate, state, style, transition, trigger } from '@angular/animations';
import { AfterViewChecked, ChangeDetectorRef, Component, Inject, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { AfterViewChecked, ChangeDetectorRef, Component, Inject, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import {
MAT_LEGACY_DIALOG_DATA as MAT_DIALOG_DATA,
Expand All @@ -45,7 +45,7 @@ import {
import { MatLegacySnackBar as MatSnackBar } from '@angular/material/legacy-snack-bar';
import { TranslateService } from '@ngx-translate/core';
import { finalize, Observable, throwError } from 'rxjs';
import { catchError, map, switchMap, tap } from 'rxjs/operators';
import { catchError, last, map, switchMap, tap } from 'rxjs/operators';
import {
FilingPlanMode,
FlowType,
Expand All @@ -59,11 +59,13 @@ import {
Transaction,
TransactionStatus,
Workflow,
ZipFile,
ZipFileStatus,
} from 'vitamui-library';
import { CollectUploadFile, CollectZippedUploadFile } from '../../shared/collect-upload/collect-upload-file';
import { CollectUploadService } from '../../shared/collect-upload/collect-upload.service';
import { ProjectsService } from '../projects.service';
import { TransactionsService } from '../transactions.service';
import { ArchiveCollectService } from '../../archive-search-collect/archive-collect.service';
import { HttpEventType } from '@angular/common/http';

@Component({
selector: 'app-create-project',
Expand All @@ -77,7 +79,8 @@ import { TransactionsService } from '../transactions.service';
]),
],
})
export class CreateProjectComponent implements OnInit, OnDestroy, AfterViewChecked {
export class CreateProjectComponent implements OnInit, AfterViewChecked {
protected readonly uploadMaxSizeInBytes = Math.pow(1024, 3); // 1 Gb
// enums for html
Workflow = Workflow;
FilingPlanMode = FilingPlanMode;
Expand All @@ -92,11 +95,10 @@ export class CreateProjectComponent implements OnInit, OnDestroy, AfterViewCheck

projectForm: FormGroup;

hasDropZoneOver = false;
hasError = false;
uploadFiles$: Observable<CollectUploadFile[]>;
zippedFile$: Observable<CollectZippedUploadFile>;
ontologies: IOntology[];
filesToUpload: File[] = [];
zipFileStatus$: Observable<ZipFileStatus>;

acquisitionInformationsList = [
this.translationService.instant('ACQUISITION_INFORMATION.PAYMENT'),
Expand All @@ -119,8 +121,6 @@ export class CreateProjectComponent implements OnInit, OnDestroy, AfterViewCheck
{ id: 'Public and Private Archive', value: this.translationService.instant('LEGAL_STATUS.PUBLIC_PRIVATE_ARCHIVE') },
];

uploadZipCompleted = false;

@ViewChild('confirmDeleteAddRuleDialog', { static: true }) confirmDeleteAddRuleDialog: TemplateRef<CreateProjectComponent>;

constructor(
Expand All @@ -130,7 +130,7 @@ export class CreateProjectComponent implements OnInit, OnDestroy, AfterViewCheck
@Inject(MAT_DIALOG_DATA) public data: any,
private projectsService: ProjectsService,
private transactionsService: TransactionsService,
private uploadService: CollectUploadService,
private archiveCollectService: ArchiveCollectService,
private snackBar: MatSnackBar,
private logger: Logger,
private cdr: ChangeDetectorRef,
Expand All @@ -145,8 +145,6 @@ export class CreateProjectComponent implements OnInit, OnDestroy, AfterViewCheck

ngOnInit(): void {
this.initForm();
this.uploadFiles$ = this.uploadService.getUploadingFiles();
this.zippedFile$ = this.uploadService.getZipFile();
this.ontologyService.getInternalOntologyFieldsList().subscribe((data) => {
this.ontologies = data;
this.ontologies.sort((a: any, b: any) => {
Expand All @@ -157,10 +155,6 @@ export class CreateProjectComponent implements OnInit, OnDestroy, AfterViewCheck
});
}

ngOnDestroy(): void {
this.uploadService.reinitializeZip();
}

ngAfterViewChecked(): void {
this.cdr.detectChanges();
}
Expand Down Expand Up @@ -192,42 +186,8 @@ export class CreateProjectComponent implements OnInit, OnDestroy, AfterViewCheck
this.stepIndex = this.stepIndex - 1;
}

// FIXME: use vitamuiCommonDragAndDrop directive?

onDragOver(event: any) {
event.preventDefault();
this.hasDropZoneOver = true;
}

onDragLeave(event: any) {
event.preventDefault();
this.hasDropZoneOver = false;
}

async onDropped(event: DragEvent) {
this.hasDropZoneOver = false;
event.preventDefault();
const items = event.dataTransfer.items;
const exists = this.uploadService.directoryExistInZipFile(items, true);
if (exists) {
this.snackBar.open(this.translationService.instant('COLLECT.UPLOAD_FILE_ALREADY_IMPORTED'), null, { duration: 3000 });
return;
}
await this.uploadService.handleDragAndDropUpload(items);
}

async handleFile(event: any) {
event.preventDefault();
const items: FileList = event.target.files;
if (this.uploadService.directoryExistInZipFile(items, false)) {
this.snackBar.open(this.translationService.instant('COLLECT.UPLOAD_FILE_ALREADY_IMPORTED'), null, { duration: 3000 });
return;
}
await this.uploadService.handleUpload(items);
}

removeFolder(file: CollectUploadFile) {
this.uploadService.removeFolder(file);
setFilesToUpload(files: File[]) {
this.filesToUpload = files;
}

/*** Form validator Step : Description du versement ***/
Expand Down Expand Up @@ -377,11 +337,12 @@ export class CreateProjectComponent implements OnInit, OnDestroy, AfterViewCheck
}

private createProjectAndTransactionAndUpload() {
this.uploadZipCompleted = false;
let transactionId: string;
this.isLoading = true;
const project: Project = this.formToProject();
this.moveToNextStep();

const zipFile = new ZipFile();
this.zipFileStatus$ = zipFile.zipFileStatus$;
this.projectsService
.create(project)
.pipe(
Expand All @@ -394,11 +355,12 @@ export class CreateProjectComponent implements OnInit, OnDestroy, AfterViewCheck
}) as Transaction,
),
switchMap((transaction) => this.transactionsService.create(transaction)),
map((createTransactionResponse) => createTransactionResponse.id as string),
switchMap((createTransactionId) => this.uploadService.uploadZip(createTransactionId)),
switchMap((uploadOperation) => uploadOperation),
tap(() => {
this.uploadZipCompleted = true;
tap((createdTransactionResponse) => (transactionId = createdTransactionResponse.id)),
switchMap(() => zipFile.addFiles(this.filesToUpload).generateZip()),
switchMap((content) => this.archiveCollectService.uploadZip(content, transactionId)),
tap((httpEvent) => zipFile.updateUploadingZipFileStatus(httpEvent)),
last((httpEvent) => httpEvent.type === HttpEventType.Response),
finalize(() => {
this.isLoading = false;
this.snackBar.open(this.translationService.instant('COLLECT.UPLOAD.TERMINATED'), null, {
panelClass: 'vitamui-snack-bar',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@
import JSZip from 'jszip';
import { ZipFileStatus } from './zip-file-status.interface';
import { HttpEvent, HttpEventType } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs';

export class ZipFile {
private zipFile: JSZip;
zipFileStatus: ZipFileStatus = null;
zipFileStatus$: BehaviorSubject<ZipFileStatus> = new BehaviorSubject<ZipFileStatus>(null);

constructor(transactionId: string) {
constructor(transactionId?: string) {
this.zipFile = new JSZip();
this.zipFileStatus = {
transactionId: transactionId,
Expand All @@ -52,9 +54,14 @@ export class ZipFile {
};
}

setTransactionId(transactionId: string) {
this.zipFileStatus.transactionId = transactionId;
return this;
}

addFiles(files: FileList | File[]) {
if (files.length === 0) {
return;
return this;
}
for (let i = 0; i < files.length; i++) {
const item = files[i];
Expand All @@ -73,6 +80,7 @@ export class ZipFile {
private updateZipFileStatus(metadataCurrentFile: string, metadataPercent: number) {
this.zipFileStatus.currentFile = metadataCurrentFile;
this.zipFileStatus.currentFileUploadedSize = metadataPercent;
this.zipFileStatus$.next(this.zipFileStatus);
}

updateUploadingZipFileStatus(data: HttpEvent<any>) {
Expand All @@ -87,5 +95,6 @@ export class ZipFile {
break;
}
this.zipFileStatus.uploadedSize = progressPercent;
this.zipFileStatus$.next(this.zipFileStatus);
}
}
2 changes: 2 additions & 0 deletions ui/ui-frontend/projects/vitamui-library/src/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ export * from './lib/models/rule';
export * from './lib/models/search-criteria.interface';
export * from './lib/models/search-query.interface';
export * from './lib/models/year-month-query.interface';
export * from './lib/models/zip/zip-file.class';
export * from './lib/models/zip/zip-file-status.interface';

/* SERVICES */
export * from './lib/components/filing-plan/filing-plan.service';
Expand Down

0 comments on commit f70995a

Please sign in to comment.