import { Component, ViewChild, OnInit, ElementRef, Inject, } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; import { ActivatedRoute, Router } from '@angular/router'; import { AlertComponent } from 'src/app/components/resources/dialogs/alert/alert.component'; import { EncService } from 'src/app/services/enc/enc.service'; import { ResourcesService } from 'src/app/services/resources/resources.service'; import { lastValueFrom } from 'rxjs'; import { WebviewerComponent } from './webviewer/webviewer.component'; import { MatSnackBar } from '@angular/material/snack-bar'; import { GdelService } from 'src/app/services/document-management/gdel.service'; import { docClassification, modules, supportedFiles } from 'src/environments/environment.prod'; import { DateRangePickerComponent } from './date-range-picker/date-range-picker.component'; import { FormControl } from '@angular/forms'; import { FindedFile, FindedFilesResponse } from 'src/app/interfaces/finded-files.interface'; import { UploadDialogComponent } from './upload-dialog/upload-dialog.component'; import { DOCUMENT } from '@angular/common'; import { ShareFileComponent } from './share-file/share-file.component'; import { AccessDialogComponent } from './access-dialog/access-dialog.component'; import { OrderAssociatonComponent } from './order-associaton/order-associaton.component'; import { Permissions } from 'src/app/interfaces/permissions.interface'; import { SocketService } from 'src/app/services/socket.service'; import { UserConsultResponse } from 'src/app/interfaces/user.interface'; import { UsersProfilesService } from 'src/app/services/users-profiles.service'; import { ProfileInterface } from 'src/app/interfaces/profile.interface'; import { FunctionsService } from 'src/app/services/functions.service'; export interface FoundedFiles{ CODIGO: string; VERSION: string; NOMBRE: string; TAMANIO: string; USRREG: string; ACCESO: UsersAccess[]; } export interface UsersAccess{ userLabel: string; userName: string; userColor: string; isTrigger: boolean; } @Component({ selector: 'app-gdel', templateUrl: './gdel.component.html', styleUrls: ['./gdel.component.css'], }) export class GDELComponent implements OnInit { public btnSmall: boolean; isLoading: boolean; hasError: boolean; errorStr: string; category: string; modulesArr = modules; clasificationsArr = docClassification; supportedFilesArr = supportedFiles; startDate: Date | null; endDate: Date | null; @ViewChild('dateRange') dateRange?: ElementRef; @ViewChild(MatPaginator) paginator!: MatPaginator; @ViewChild(MatSort) sort!: MatSort; moduleControl: FormControl; clasificationControl: FormControl; fileNameControl: FormControl; fileTypeControl: FormControl; datesRangeControl: FormControl; files: FindedFile[]; dataSource: MatTableDataSource; displayedColumns = ['CODIGO', 'VERSION', 'NOMBRE', 'TAMANIO', 'USRREG', 'ACCESO', 'ACCIONES']; avatarColors = { A: 244, B: 67, C: 54, D: 233, E: 30, F: 99, G: 156, H: 39, I: 176, J: 103, K: 58, L: 58, M: 183, N: 63, Ñ: 81, O: 181, P: 33, Q: 150, R: 243, S: 3, T: 169, U: 244, V: 76, W: 175, X: 80, Y: 255, Z: 193 }; isFromModule: boolean; module: string; documentsManagementEnabled: boolean; documentsViewerEnabled: boolean; documentsEditorEnabled: boolean; shareDocumentsEnabled: boolean; registerDocumentsEnabled: boolean; versionsHistoryEnabled: boolean; constructor( @Inject(DOCUMENT) private _document: Document, private _encService: EncService, private _dialog: MatDialog, private _gdelService: GdelService, private _activatedRoute: ActivatedRoute, private _resourcesService: ResourcesService, private _socketService: SocketService, private _usersProfilesService: UsersProfilesService, private _router: Router, private _functionsService: FunctionsService, ) { this.btnSmall = false; this.isLoading = true; this.hasError = true; this.errorStr = ''; this.category = 'my-files'; this.startDate = null; this.endDate = null; this.moduleControl = new FormControl(''); this.clasificationControl = new FormControl(''); this.fileNameControl = new FormControl(''); this.fileTypeControl = new FormControl(''); this.datesRangeControl = new FormControl(''); this.dataSource = new MatTableDataSource(); this.files = []; this.isFromModule = false; this.module = ''; this.documentsManagementEnabled = true; this.documentsViewerEnabled = true; this.documentsEditorEnabled = true; this.shareDocumentsEnabled = true; this.registerDocumentsEnabled = true; this.versionsHistoryEnabled = true; } ngOnInit(): void { this.initPermissions(); this._socketService.refreshPermissions().subscribe(async (profUpdEnc) => { try{ let idUser = localStorage.getItem('idusuario')!; let usrInfo: UserConsultResponse = await lastValueFrom(this._usersProfilesService.getUser(idUser, idUser, 1)); if(usrInfo.error){ this._resourcesService.openSnackBar('ERR_NPE000: Ocurrió un error inesperado.'); }else{ let idProfDec = await this._encService.decrypt(usrInfo.response.PERFIL); let currentProfile = await this._encService.decrypt(localStorage.getItem('perfil')!); if(idProfDec != currentProfile){ this._router.navigate(['/sam/home']); return; } let profileUpdated = await this._encService.decrypt(`${profUpdEnc}`); if(profileUpdated == currentProfile){ let profile = localStorage.getItem('perfil')!; let profInfo: ProfileInterface = await lastValueFrom(this._usersProfilesService.getProfile( profile, idUser, 1 )); let permArr = await this._functionsService.processPermissions(profInfo.response.PERMISOS.permissions); let modPerm = permArr.filter(item => item.id == 'S002V01M04GDEL'); if(modPerm.length > 0){ let funPerm = modPerm[0].children.filter(item => item.id == 'S002V01F01ADDO'); if(funPerm.length > 0){ let documentsManagementEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P01GEDO'); if(documentsManagementEnabled.length > 0){ this.documentsManagementEnabled = documentsManagementEnabled[0].access > 0; } let documentsViewerEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P02VIDO'); if(documentsViewerEnabled.length > 0){ this.documentsViewerEnabled = documentsViewerEnabled[0].access > 0; } let documentsEditorEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P03EDDO'); if(documentsEditorEnabled.length > 0){ this.documentsEditorEnabled = documentsEditorEnabled[0].access > 0; } let shareDocumentsEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P04CODO'); if(shareDocumentsEnabled.length > 0){ this.shareDocumentsEnabled = shareDocumentsEnabled[0].access > 0; } let registerDocumentsEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P05REDO'); if(registerDocumentsEnabled.length > 0){ this.registerDocumentsEnabled = registerDocumentsEnabled[0].access > 0; } let versionsHistoryEnabled = funPerm[0].children.filter(item => item.id == 'S002V01P06HIVE'); if(versionsHistoryEnabled.length > 0){ this.versionsHistoryEnabled = versionsHistoryEnabled[0].access > 0; } } } } } }catch(error: any){ if(error.error == undefined){ this._resourcesService.openSnackBar('ERR_PAD001: Ocurrió un error inesperado.'); }else if(error.error.msg == undefined){ this._resourcesService.openSnackBar('ERR_PAD002: Ocurrió un error inesperado.'); }else{ this._resourcesService.openSnackBar(`ERR_PAD003: ${error.error.msg}`); } } }); this.moduleControl.valueChanges.subscribe(mod => { let cla = this.clasificationControl.value; let sda = this.startDate; let eda = this.endDate; let dna = this.fileNameControl.value; let ext = this.fileTypeControl.value; this.getFiles(mod, cla, sda, eda, dna, ext); }); this.clasificationControl.valueChanges.subscribe(cla => { let mod = this.moduleControl.value; let sda = this.startDate; let eda = this.endDate; let dna = this.fileNameControl.value; let ext = this.fileTypeControl.value; this.getFiles(mod, cla, sda, eda, dna, ext); }); this.fileNameControl.valueChanges.subscribe(dna => { let mod = this.moduleControl.value; let cla = this.clasificationControl.value; let sda = this.startDate; let eda = this.endDate; let ext = this.fileTypeControl.value; this.getFiles(mod, cla, sda, eda, dna, ext); }); this.fileTypeControl.valueChanges.subscribe(ext => { let mod = this.moduleControl.value; let cla = this.clasificationControl.value; let sda = this.startDate; let eda = this.endDate; let dna = this.fileNameControl.value; this.getFiles(mod, cla, sda, eda, dna, ext); }); this._activatedRoute.queryParams.subscribe(params => { let module = params['module']; if(module != undefined && module != null && module != ''){ this.isFromModule = true; this.module = module; this.moduleControl.disable(); this.moduleControl.setValue(module); } this.getFiles( this.moduleControl.value, this.clasificationControl.value, this.startDate, this.endDate, this.fileNameControl.value, this.fileTypeControl.value ); }); } public onResize(): void { this.btnSmall = window.innerWidth <= 1573; } updateCategory(category: string){ let mod = this.moduleControl.value; let cla = this.clasificationControl.value; let sda = this.startDate; let eda = this.endDate; let dna = this.fileNameControl.value; let ext = this.fileTypeControl.value; this.category = category; this.getFiles(mod, cla, sda, eda, dna, ext); } openDateRangePicker(){ let dialogRef = this._dialog.open(DateRangePickerComponent, { disableClose: true, width: '480px', data: { startDate: this.startDate, endDate: this.endDate } }); dialogRef.afterClosed().subscribe(res => { if(res != null && res != undefined && res != ''){ let resObj = JSON.parse(res); let dateRange = ""; if(resObj.startDate != null || resObj.endDate != null){ if(resObj.startDate != null){ let startDateTimeArr = resObj.startDate.split('T'); let startDateArr = startDateTimeArr[0].split('-').reverse(); let startDateStr = startDateArr.join('/'); this.startDate = new Date(resObj.startDate); dateRange += `desde ${startDateStr}, `; } if(resObj.endDate != null){ let endDateTimeArr = resObj.endDate.split('T'); let endDateArr = endDateTimeArr[0].split('-').reverse(); let endDateStr = endDateArr.join('/'); this.endDate = new Date(resObj.endDate); dateRange += `hasta ${endDateStr}, `; } let fl = dateRange[0].toUpperCase(); let dateRangeArr = dateRange.split(""); dateRangeArr[0] = fl; dateRange = dateRangeArr.join(""); dateRange = dateRange.substring(0, dateRange.length - 2); this.dateRange!.nativeElement.value = dateRange; this.getFiles( this.moduleControl.value, this.clasificationControl.value, this.startDate, this.endDate, this.fileNameControl.value, this.fileTypeControl.value, ); } } }); } async initPermissions(){ try{ let permissionsEnc = localStorage.getItem('permisos'); let permissionsDec = await this._encService.decrypt(permissionsEnc!); let permissionsArr: Permissions = JSON.parse(permissionsDec); let modPerm = permissionsArr.permissions.filter(item => item.id == 'S002V01M04GDEL')[0]; let funPerm = modPerm.children.filter(item => item.id == 'S002V01F01ADDO')[0]; this.documentsManagementEnabled = funPerm.children.filter(item => item.id == 'S002V01P01GEDO')[0].access > 0; this.documentsViewerEnabled = funPerm.children.filter(item => item.id == 'S002V01P02VIDO')[0].access > 0; this.documentsEditorEnabled = funPerm.children.filter(item => item.id == 'S002V01P03EDDO')[0].access > 0; this.shareDocumentsEnabled = funPerm.children.filter(item => item.id == 'S002V01P04CODO')[0].access > 0; this.registerDocumentsEnabled = funPerm.children.filter(item => item.id == 'S002V01P05REDO')[0].access > 0; this.versionsHistoryEnabled = funPerm.children.filter(item => item.id == 'S002V01P06HIVE')[0].access > 0; console.log(this.documentsManagementEnabled); }catch(error: any){ this._resourcesService.openSnackBar('Hubo un error al obtener los permisos del módulo.'); this.documentsManagementEnabled = false; } } async getFiles(module: string | undefined, clas: string | undefined, startDate: Date | null, endDate: Date | null, name: string | undefined, type: string | undefined){ try{ this.isLoading = true; this.hasError = false; this.errorStr = ""; let mod = module == undefined || module == '' ? '-' : module; let cla = clas == undefined || clas == '' ? '-' : clas; let sda = startDate == null ? '-' : this.formatSearchDate(startDate); let eda = endDate == null ? '-' : this.formatSearchDate(endDate); let dna = name == undefined || name == '' ? '-' : name; let ext = type == undefined || type == '' ? '-' : JSON.stringify(type.split(',')); let idUser = localStorage.getItem('idusuario')!; let files: FindedFilesResponse = await lastValueFrom(this._gdelService.getFiles( mod, cla, sda, eda, dna, ext, this.category, idUser, 1 )); this.hasError = files.error; this.errorStr = files.msg; if(!this.hasError){ this.files = files.response; let filesFound: FoundedFiles[] = []; files.response.forEach(file => { let fileSize = this.formatBytes(file.TAMANIO as number); let fileAccess = this.getUsersAccess(file.ACCESO); let fileObj: FoundedFiles = { CODIGO: file.CODIGO, VERSION: file.VERSION, NOMBRE: file.NOMBRE, TAMANIO: fileSize, USRREG: file.USRREG, ACCESO: fileAccess, }; filesFound.push(fileObj); }); this.dataSource = new MatTableDataSource(filesFound); this.dataSource.paginator = this.paginator; this.dataSource.sort = this.sort; } this.isLoading = false; }catch(error: any){ if(error.error == undefined){ this.errorStr = 'Ocurrió un error inesperado.'; }else if(error.error.msg == undefined){ this.errorStr = 'Ocurrió un error inesperado.'; }else{ this.errorStr = error.error.msg; } this.hasError = true; this.isLoading = false; } } formatSearchDate(date: Date): string{ let day = date.getDate() < 10 ? `0${date.getDate()}` : `${date.getDate()}`; let month = date.getMonth() + 1 < 10 ? `0${date.getMonth() + 1}` : `${date.getMonth() + 1}`; let fullYear = `${date.getFullYear()}`; let year = fullYear.substring(2); return `${year}${month}${day}`; } formatBytes(bytes: number, decimals = 2) { if (bytes === 0) return '0 Bytes'; const k = 1024; const dm = decimals < 0 ? 0 : decimals; const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; } getUsersAccess(accessStr: string): UsersAccess[]{ let accessArr = JSON.parse(accessStr); let arrFn: UsersAccess[] = []; for(const user of accessArr){ let userNameArr = user.split(' '); let userLabel = ''; for(let i = 0; i < 2; i++){ userLabel += userNameArr[i][0]; } let userColor = "rgb("; for(let i = 0; i < 3; i++){ let char: never = user.charAt(i) as never; let code = this.avatarColors[char]; userColor += `${code}, `; } userColor = userColor.substring(0, userColor.length - 2); userColor += ")"; let userObj: UsersAccess = { userLabel: userLabel, userName: user, userColor: userColor, isTrigger: false, } arrFn.push(userObj); } let arrFnAux: UsersAccess[] = []; if(arrFn.length > 4){ for(let i = 0; i < 3; i++){ arrFnAux.push(arrFn[i]); } let moreUsers: UsersAccess = { userLabel: `${arrFn.length - 3}+`, userName: `Ver ${arrFn.length - 3} más...`, userColor: 'rgba(0,0,0,0.54)', isTrigger: true, }; arrFnAux.push(moreUsers); return arrFnAux; } return arrFn; } clearDatesRange(){ this.startDate = null; this.endDate = null; this.datesRangeControl.setValue(''); this.getFiles( this.moduleControl.value, this.clasificationControl.value, this.startDate, this.endDate, this.fileNameControl.value, this.fileTypeControl.value ); } openUploadDialog(){ if(!this.isFromModule && this.registerDocumentsEnabled){ let dialogRef = this._dialog.open(UploadDialogComponent, { width: '480px', disableClose: true, }); dialogRef.afterClosed().subscribe(res => { if(res == true){ let mod = this.moduleControl.value; let cla = this.clasificationControl.value; let sda = this.startDate; let eda = this.endDate; let dna = this.fileNameControl.value; let ext = this.fileTypeControl.value; this.getFiles(mod, cla, sda, eda, dna, ext); } }); } } async downloadFile(code: string, version: string, name: string){ try{ let idFile = `${code}=${version}=${name}`; this._resourcesService.openSnackBar(`Iniciando la descarga del archivo ${idFile}...`); let idFileEnc = await this._encService.encrypt(idFile); let download = this._document.getElementById(`download`) as HTMLAnchorElement; let idUser = localStorage.getItem('idusuario')!; let downloadToken = await lastValueFrom(this._gdelService.getDownloadToken( idFileEnc, idUser, 1 )); download.href = `http://git.ittec.mx/sam/public/api/download-file/${downloadToken.response.TOKEN}/${idUser}/1`; download.download = idFile; download.click(); }catch(error: any){ if(error.error == undefined){ this._resourcesService.openSnackBar('Ocurrió un error inesperado.'); }else if(error.error.msg == undefined){ this._resourcesService.openSnackBar('Ocurrió un error inesperado.'); }else{ this._resourcesService.openSnackBar(error.error.msg); } } } async openViewer(code: string, version: string, name: string) { try{ let idFile = `${code}=${version}=${name}`; this._resourcesService.openSnackBar(`Abriendo el archivo ${idFile}...`); let idFileEnc = await this._encService.encrypt(idFile); let idUser = localStorage.getItem('idusuario')!; let publicURL = await lastValueFrom(this._gdelService.getPublicDocumentUrl( idFileEnc, idUser, 1 )); let fileData = { url: publicURL.response.public_uri, }; this._dialog.open(WebviewerComponent, { data: fileData, width: '100%', }); }catch(error: any){ if(error.error == undefined){ this._resourcesService.openSnackBar('Ocurrió un error inesperado.'); }else if(error.error.msg == undefined){ this._resourcesService.openSnackBar('Ocurrió un error inesperado.'); }else{ this._resourcesService.openSnackBar(error.error.msg); } } } openShareDialog(code: string, version: string, name: string){ let idFile = `${code}=${version}=${name}`; let dialogRef = this._dialog.open(ShareFileComponent, { width: '720px', disableClose: true, data: { idFile: idFile, } }) dialogRef.afterClosed().subscribe((res) => { this.updateFilePermissions(idFile, res); }) } async updateFilePermissions(idFile: string, permissions: string){ try{ this._resourcesService.openSnackBar(`Actualizando permisos del archivo ${idFile}`); this.isLoading = true; this.hasError = false; this.errorStr = ''; let idFileEnc = await this._encService.encrypt(idFile); let idUser = localStorage.getItem('idusuario'); let formData = new FormData(); formData.append('id_user', idUser!); formData.append('id_file', idFileEnc); formData.append('linea', '1'); formData.append('permissions', permissions); await lastValueFrom(this._gdelService.updateFilePermissions(formData)); this._resourcesService.openSnackBar(`Los permisos se actualizaron correctamente`); let mod = this.moduleControl.value; let cla = this.clasificationControl.value; let sda = this.startDate; let eda = this.endDate; let dna = this.fileNameControl.value; let ext = this.fileTypeControl.value; this.getFiles(mod, cla, sda, eda, dna, ext); }catch(error: any){ if(error.error == undefined){ this.errorStr = 'Ocurrió un error inesperado.'; }else if(error.error.msg == undefined){ this.errorStr = 'Ocurrió un error inesperado.'; }else{ this.errorStr = error.error.msg; } this.hasError = true; this.isLoading = false; } } openAccessDialog(code: string, version: string, name: string, isTrigger: boolean, isDeleted: boolean){ if(isTrigger){ let file = this.files.filter(item => item.CODIGO == code && item.VERSION == version && item.NOMBRE == name)[0]; let accessStr = file.ACCESO; let idFile = `${code}=${version}=${name}`; let dialogRef = this._dialog.open(AccessDialogComponent, { width: '720px', data: { idFile: idFile, accessStr: accessStr, isDeleted: isDeleted } }); dialogRef.afterClosed().subscribe(res => { if(res == true){ this.openShareDialog(code, version, name); } }) } } confirmDelete(code: string, version: string, name: string){ let idFile = `${code}=${version}=${name}`; let dialogRef = this._dialog.open(AlertComponent, { disableClose: true, width: '480px', data: { title: 'Confirmar acción', icon: 'warning', description: `¿Está seguro de querer eliminar el archivo ${idFile}?`, description2: 'Esta acción no se puede deshacer' } }); dialogRef.afterClosed().subscribe(res => { if(res == true){ this.deleteFile(idFile); } }); } async deleteFile(idFile: string){ try{ let idUser = localStorage.getItem('idusuario'); let idFileEnc = await this._encService.encrypt(idFile); let formData = new FormData(); formData.append('id_user', idUser!); formData.append('id_file', idFileEnc); formData.append('linea', '1'); await lastValueFrom(this._gdelService.deleteFile(formData)); this._resourcesService.openSnackBar('El archivo se eliminó correctamente.'); let mod = this.moduleControl.value; let cla = this.clasificationControl.value; let sda = this.startDate; let eda = this.endDate; let dna = this.fileNameControl.value; let ext = this.fileTypeControl.value; this.getFiles(mod, cla, sda, eda, dna, ext); }catch(error: any){ if(error.error == undefined){ this._resourcesService.openSnackBar('Ocurrió un error inesperado.'); }else if(error.error.msg == undefined){ this._resourcesService.openSnackBar('Ocurrió un error inesperado.'); }else{ this._resourcesService.openSnackBar(error.error.msg); } } } openAssociationDialog(code: string, version: string, name: string){ let idFile = `${code}=${version}=${name}`; this._dialog.open(OrderAssociatonComponent, { width: '840px', disableClose: true, data: { idFile: idFile, } }); } goBack(steps: number){ window.history.go(steps * -1); } }