mirror of
				https://github.com/richard-loafle/fuse-angular.git
				synced 2025-10-31 12:23:33 +00:00 
			
		
		
		
	(apps/file-manager) Added support for nested folder views
This commit is contained in:
		
							parent
							
								
									fc1e7b02b0
								
							
						
					
					
						commit
						11ad2c89df
					
				| @ -33,10 +33,18 @@ export class FileManagerMockApi | ||||
|         // -----------------------------------------------------------------------------------------------------
 | ||||
|         this._fuseMockApiService | ||||
|             .onGet('api/apps/file-manager') | ||||
|             .reply(() => { | ||||
|             .reply(({request}) => { | ||||
| 
 | ||||
|                 // Clone the items
 | ||||
|                 const items = cloneDeep(this._items); | ||||
|                 let items = cloneDeep(this._items); | ||||
| 
 | ||||
|                 // See if a folder id exist
 | ||||
|                 const folderId = request.params.get('folderId') ?? null; | ||||
| 
 | ||||
|                 // Filter the items by folder id. If folder id is null,
 | ||||
|                 // that means we want to root items which have folder id
 | ||||
|                 // of null
 | ||||
|                 items = items.filter(item => item.folderId === folderId); | ||||
| 
 | ||||
|                 // Separate the items by folders and files
 | ||||
|                 const folders = items.filter(item => item.type === 'folder'); | ||||
| @ -46,11 +54,38 @@ export class FileManagerMockApi | ||||
|                 folders.sort((a, b) => a.name.localeCompare(b.name)); | ||||
|                 files.sort((a, b) => a.name.localeCompare(b.name)); | ||||
| 
 | ||||
|                 // Figure out the path and attach it to the response
 | ||||
|                 // Prepare the empty paths array
 | ||||
|                 const pathItems = cloneDeep(this._items); | ||||
|                 const path = []; | ||||
| 
 | ||||
|                 // Prepare the current folder
 | ||||
|                 let currentFolder = null; | ||||
| 
 | ||||
|                 // Get the current folder and add it as the first entry
 | ||||
|                 if ( folderId ) | ||||
|                 { | ||||
|                     currentFolder = pathItems.find(item => item.id === folderId); | ||||
|                     path.push(currentFolder); | ||||
|                 } | ||||
| 
 | ||||
|                 // Start traversing and storing the folders as a path array
 | ||||
|                 // until we hit null on the folder id
 | ||||
|                 while ( currentFolder?.folderId ) | ||||
|                 { | ||||
|                     currentFolder = pathItems.find(item => item.id === currentFolder.folderId); | ||||
|                     if ( currentFolder ) | ||||
|                     { | ||||
|                         path.unshift(currentFolder); | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 return [ | ||||
|                     200, | ||||
|                     { | ||||
|                         folders, | ||||
|                         files | ||||
|                         files, | ||||
|                         path | ||||
|                     } | ||||
|                 ]; | ||||
|             }); | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
| export const items = [ | ||||
|     { | ||||
|         id         : 'cd6897cb-acfd-4016-8b53-3f66a5b5fc68', | ||||
|         folderId   : null, | ||||
|         name       : 'Personal', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'April 24, 2018', | ||||
| @ -13,6 +14,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : '6da8747f-b474-4c9a-9eba-5ef212285500', | ||||
|         folderId   : null, | ||||
|         name       : 'Photos', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'November 01, 2021', | ||||
| @ -24,6 +26,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : 'ed58add1-45a7-41db-887d-3ca7ee7f2719', | ||||
|         folderId   : null, | ||||
|         name       : 'Work', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'May 8, 2020', | ||||
| @ -35,6 +38,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : '5cb66e32-d1ac-4b9a-8c34-5991ce25add2', | ||||
|         folderId   : null, | ||||
|         name       : 'Contract #123', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'January 14, 2021', | ||||
| @ -46,6 +50,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : '3ffc3d84-8f2d-4929-903a-ef6fc21657a7', | ||||
|         folderId   : null, | ||||
|         name       : 'Estimated budget', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'December 14, 2020', | ||||
| @ -57,6 +62,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : '157adb9a-14f8-4559-ac93-8be893c9f80a', | ||||
|         folderId   : null, | ||||
|         name       : 'DMCA notice #42', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'May 8, 2021', | ||||
| @ -68,6 +74,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : '4f64597a-df7e-461c-ad60-f33e5f7e0747', | ||||
|         folderId   : null, | ||||
|         name       : 'Invoices', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'January 12, 2020', | ||||
| @ -79,6 +86,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : 'e445c445-57b2-4476-8c62-b068e3774b8e', | ||||
|         folderId   : null, | ||||
|         name       : 'Crash logs', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'June 8, 2020', | ||||
| @ -90,6 +98,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : 'b482f93e-7847-4614-ad48-b78b78309f81', | ||||
|         folderId   : null, | ||||
|         name       : 'System logs', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'June 8, 2020', | ||||
| @ -101,6 +110,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : 'ec07a98d-2e5b-422c-a9b2-b5d1c0e263f5', | ||||
|         folderId   : null, | ||||
|         name       : 'Personal projects', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'March 18, 2020', | ||||
| @ -112,6 +122,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : 'ae908d59-07da-4dd8-aba0-124e50289295', | ||||
|         folderId   : null, | ||||
|         name       : 'Biometric portrait', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'August 29, 2020', | ||||
| @ -123,6 +134,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : '4038a5b6-5b1a-432d-907c-e037aeb817a8', | ||||
|         folderId   : null, | ||||
|         name       : 'Scanned image 20201012-1', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'September 13, 2020', | ||||
| @ -134,6 +146,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : '630d2e9a-d110-47a0-ac03-256073a0f56d', | ||||
|         folderId   : null, | ||||
|         name       : 'Scanned image 20201012-2', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'September 14, 2020', | ||||
| @ -145,6 +158,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : '1417d5ed-b616-4cff-bfab-286677b69d79', | ||||
|         folderId   : null, | ||||
|         name       : 'Prices', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'April 07, 2020', | ||||
| @ -156,6 +170,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : 'bd2817c7-6751-40dc-b252-b6b5634c0689', | ||||
|         folderId   : null, | ||||
|         name       : 'Shopping list', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'March 26, 2021', | ||||
| @ -167,6 +182,7 @@ export const items = [ | ||||
|     }, | ||||
|     { | ||||
|         id         : '14fb47c9-6eeb-4070-919c-07c8133285d1', | ||||
|         folderId   : null, | ||||
|         name       : 'Summer budget', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'June 02, 2020', | ||||
| @ -175,5 +191,67 @@ export const items = [ | ||||
|         type       : 'XLS', | ||||
|         contents   : null, | ||||
|         description: null | ||||
|     }, | ||||
| 
 | ||||
|     { | ||||
|         id         : '894e8514-03d3-4f5e-bb28-f6c092501fae', | ||||
|         folderId   : 'cd6897cb-acfd-4016-8b53-3f66a5b5fc68', | ||||
|         name       : 'A personal file', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'June 02, 2020', | ||||
|         modifiedAt : 'June 02, 2020', | ||||
|         size       : '943 KB', | ||||
|         type       : 'XLS', | ||||
|         contents   : null, | ||||
|         description: null | ||||
|     }, | ||||
|     { | ||||
|         id         : '74010810-16cf-441d-a1aa-c9fb620fceea', | ||||
|         folderId   : 'cd6897cb-acfd-4016-8b53-3f66a5b5fc68', | ||||
|         name       : 'A personal folder', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'November 01, 2021', | ||||
|         modifiedAt : 'November 01, 2021', | ||||
|         size       : '3015 MB', | ||||
|         type       : 'folder', | ||||
|         contents   : '907 files', | ||||
|         description: 'Personal photos; selfies, family, vacation and etc.' | ||||
|     }, | ||||
|     { | ||||
|         id         : 'a8c73e5a-8114-436d-ab54-d900b50b3762', | ||||
|         folderId   : '74010810-16cf-441d-a1aa-c9fb620fceea', | ||||
|         name       : 'A personal file within the personal folder', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'June 02, 2020', | ||||
|         modifiedAt : 'June 02, 2020', | ||||
|         size       : '943 KB', | ||||
|         type       : 'XLS', | ||||
|         contents   : null, | ||||
|         description: null | ||||
|     }, | ||||
| 
 | ||||
|     { | ||||
|         id         : '12d851a8-4f60-473e-8a59-abe4b422ea99', | ||||
|         folderId   : '6da8747f-b474-4c9a-9eba-5ef212285500', | ||||
|         name       : 'Photos file', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'June 02, 2020', | ||||
|         modifiedAt : 'June 02, 2020', | ||||
|         size       : '943 KB', | ||||
|         type       : 'XLS', | ||||
|         contents   : null, | ||||
|         description: null | ||||
|     }, | ||||
|     { | ||||
|         id         : '2836766d-27e1-4f40-a31a-5a8419105e7e', | ||||
|         folderId   : 'ed58add1-45a7-41db-887d-3ca7ee7f2719', | ||||
|         name       : 'Work file', | ||||
|         createdBy  : 'Brian Hughes', | ||||
|         createdAt  : 'June 02, 2020', | ||||
|         modifiedAt : 'June 02, 2020', | ||||
|         size       : '943 KB', | ||||
|         type       : 'XLS', | ||||
|         contents   : null, | ||||
|         description: null | ||||
|     } | ||||
| ]; | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
|     <div class="flex items-center justify-end"> | ||||
|         <button | ||||
|             mat-icon-button | ||||
|             [routerLink]="['../']"> | ||||
|             [routerLink]="['../../']"> | ||||
|             <mat-icon [svgIcon]="'heroicons_outline:x'"></mat-icon> | ||||
|         </button> | ||||
|     </div> | ||||
|  | ||||
| @ -22,17 +22,17 @@ export class CanDeactivateFileManagerDetails implements CanDeactivate<FileManage | ||||
|             nextRoute = nextRoute.firstChild; | ||||
|         } | ||||
| 
 | ||||
|         // If the next state doesn't contain '/files'
 | ||||
|         // If the next state doesn't contain '/file-manager'
 | ||||
|         // it means we are navigating away from the
 | ||||
|         // tasks app
 | ||||
|         // file manager app
 | ||||
|         if ( !nextState.url.includes('/file-manager') ) | ||||
|         { | ||||
|             // Let it navigate
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         // If we are navigating to another task...
 | ||||
|         if ( nextRoute.paramMap.get('id') ) | ||||
|         // If we are navigating to another item...
 | ||||
|         if ( nextState.url.includes('/details') ) | ||||
|         { | ||||
|             // Just navigate
 | ||||
|             return true; | ||||
|  | ||||
| @ -33,6 +33,54 @@ export class FileManagerItemsResolver implements Resolve<any> | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @Injectable({ | ||||
|     providedIn: 'root' | ||||
| }) | ||||
| export class FileManagerFolderResolver implements Resolve<any> | ||||
| { | ||||
|     /** | ||||
|      * Constructor | ||||
|      */ | ||||
|     constructor( | ||||
|         private _router: Router, | ||||
|         private _fileManagerService: FileManagerService | ||||
|     ) | ||||
|     { | ||||
|     } | ||||
| 
 | ||||
|     // -----------------------------------------------------------------------------------------------------
 | ||||
|     // @ Public methods
 | ||||
|     // -----------------------------------------------------------------------------------------------------
 | ||||
| 
 | ||||
|     /** | ||||
|      * Resolver | ||||
|      * | ||||
|      * @param route | ||||
|      * @param state | ||||
|      */ | ||||
|     resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Item[]> | ||||
|     { | ||||
|         return this._fileManagerService.getItems(route.paramMap.get('folderId')) | ||||
|                    .pipe( | ||||
|                        // Error here means the requested task is not available
 | ||||
|                        catchError((error) => { | ||||
| 
 | ||||
|                            // Log the error
 | ||||
|                            console.error(error); | ||||
| 
 | ||||
|                            // Get the parent url
 | ||||
|                            const parentUrl = state.url.split('/').slice(0, -1).join('/'); | ||||
| 
 | ||||
|                            // Navigate to there
 | ||||
|                            this._router.navigateByUrl(parentUrl); | ||||
| 
 | ||||
|                            // Throw an error
 | ||||
|                            return throwError(error); | ||||
|                        }) | ||||
|                    ); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @Injectable({ | ||||
|     providedIn: 'root' | ||||
| }) | ||||
|  | ||||
| @ -3,13 +3,30 @@ import { CanDeactivateFileManagerDetails } from 'app/modules/admin/apps/file-man | ||||
| import { FileManagerComponent } from 'app/modules/admin/apps/file-manager/file-manager.component'; | ||||
| import { FileManagerListComponent } from 'app/modules/admin/apps/file-manager/list/list.component'; | ||||
| import { FileManagerDetailsComponent } from 'app/modules/admin/apps/file-manager/details/details.component'; | ||||
| import { FileManagerItemResolver, FileManagerItemsResolver } from 'app/modules/admin/apps/file-manager/file-manager.resolvers'; | ||||
| import { FileManagerFolderResolver, FileManagerItemResolver, FileManagerItemsResolver } from 'app/modules/admin/apps/file-manager/file-manager.resolvers'; | ||||
| 
 | ||||
| export const fileManagerRoutes: Route[] = [ | ||||
|     { | ||||
|         path     : '', | ||||
|         component: FileManagerComponent, | ||||
|         children : [ | ||||
|             { | ||||
|                 path    : 'folders/:folderId', | ||||
|                 component: FileManagerListComponent, | ||||
|                 resolve : { | ||||
|                     item: FileManagerFolderResolver | ||||
|                 }, | ||||
|                 children: [ | ||||
|                     { | ||||
|                         path         : 'details/:id', | ||||
|                         component    : FileManagerDetailsComponent, | ||||
|                         resolve      : { | ||||
|                             item: FileManagerItemResolver | ||||
|                         }, | ||||
|                         canDeactivate: [CanDeactivateFileManagerDetails] | ||||
|                     } | ||||
|                 ] | ||||
|             }, | ||||
|             { | ||||
|                 path     : '', | ||||
|                 component: FileManagerListComponent, | ||||
| @ -18,7 +35,7 @@ export const fileManagerRoutes: Route[] = [ | ||||
|                 }, | ||||
|                 children : [ | ||||
|                     { | ||||
|                         path         : ':id', | ||||
|                         path         : 'details/:id', | ||||
|                         component    : FileManagerDetailsComponent, | ||||
|                         resolve      : { | ||||
|                             item: FileManagerItemResolver | ||||
|  | ||||
| @ -47,9 +47,9 @@ export class FileManagerService | ||||
|     /** | ||||
|      * Get items | ||||
|      */ | ||||
|     getItems(): Observable<Item[]> | ||||
|     getItems(folderId: string | null = null): Observable<Item[]> | ||||
|     { | ||||
|         return this._httpClient.get<Items>('api/apps/file-manager').pipe( | ||||
|         return this._httpClient.get<Items>('api/apps/file-manager', {params: {folderId}}).pipe( | ||||
|             tap((response: any) => { | ||||
|                 this._items.next(response); | ||||
|             }) | ||||
|  | ||||
| @ -2,11 +2,13 @@ export interface Items | ||||
| { | ||||
|     folders: Item[]; | ||||
|     files: Item[]; | ||||
|     path: any[]; | ||||
| } | ||||
| 
 | ||||
| export interface Item | ||||
| { | ||||
|     id?: string; | ||||
|     folderId?: string; | ||||
|     name?: string; | ||||
|     createdBy?: string; | ||||
|     createdAt?: string; | ||||
|  | ||||
| @ -26,7 +26,32 @@ | ||||
|                     <div> | ||||
|                         <div class="text-4xl font-extrabold tracking-tight leading-none">File Manager</div> | ||||
|                         <div class="flex items-center mt-0.5 font-medium text-secondary"> | ||||
|                             {{items.folders.length}} folders, {{items.files.length}} files | ||||
|                             <ng-container *ngIf="!items.path.length"> | ||||
|                                 {{items.folders.length}} folders, {{items.files.length}} files | ||||
|                             </ng-container> | ||||
|                             <!-- Breadcrumbs --> | ||||
|                             <ng-container *ngIf="items.path.length"> | ||||
|                                 <div class="flex items-center space-x-2"> | ||||
|                                     <a | ||||
|                                         class="text-primary cursor-pointer" | ||||
|                                         [routerLink]="['/apps/file-manager']">Home | ||||
|                                     </a> | ||||
|                                     <div class="">/</div> | ||||
|                                     <ng-container *ngFor="let path of items.path; let last = last; trackBy: trackByFn"> | ||||
|                                         <ng-container *ngIf="!last"> | ||||
|                                             <a | ||||
|                                                 class="text-primary cursor-pointer" | ||||
|                                                 [routerLink]="['/apps/file-manager/folders/', path.id]">{{path.name}}</a> | ||||
|                                         </ng-container> | ||||
|                                         <ng-container *ngIf="last"> | ||||
|                                             <div>{{path.name}}</div> | ||||
|                                         </ng-container> | ||||
|                                         <ng-container *ngIf="!last"> | ||||
|                                             <div class="">/</div> | ||||
|                                         </ng-container> | ||||
|                                     </ng-container> | ||||
|                                 </div> | ||||
|                             </ng-container> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                     <!-- Actions --> | ||||
| @ -42,75 +67,95 @@ | ||||
|                 </div> | ||||
| 
 | ||||
|                 <!-- Items list --> | ||||
|                 <ng-container *ngIf="items && items.folders.length && items.files.length > 0; else noItems"> | ||||
|                     <div class="p-6 md:p-8"> | ||||
|                 <ng-container *ngIf="items && (items.folders.length > 0 || items.files.length > 0); else noItems"> | ||||
|                     <div class="p-6 md:p-8 space-y-8"> | ||||
|                         <!-- Folders --> | ||||
|                         <div class="font-medium">Folders</div> | ||||
|                         <div | ||||
|                             class="flex flex-wrap -m-2 mt-2"> | ||||
|                             <ng-container *ngFor="let folder of items.folders; trackBy:trackByFn"> | ||||
|                                 <ng-container *ngTemplateOutlet="item, context: {$implicit: folder}"></ng-container> | ||||
|                             </ng-container> | ||||
|                         </div> | ||||
| 
 | ||||
|                         <!-- Files --> | ||||
|                         <div class="font-medium mt-8">Files</div> | ||||
|                         <div | ||||
|                             class="flex flex-wrap -m-2 mt-2"> | ||||
|                             <ng-container *ngFor="let file of items.files; trackBy:trackByFn"> | ||||
|                                 <ng-container *ngTemplateOutlet="item, context: {$implicit: file}"></ng-container> | ||||
|                             </ng-container> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </ng-container> | ||||
| 
 | ||||
|                 <!-- Item template --> | ||||
|                 <ng-template | ||||
|                     #item | ||||
|                     let-item> | ||||
|                     <a | ||||
|                         class="flex flex-col w-40 h-40 m-2 p-4 shadow rounded-2xl cursor-pointer bg-card" | ||||
|                         [routerLink]="['./', item.id]"> | ||||
|                         <div class="aspect-w-9 aspect-h-6"> | ||||
|                             <div class="flex items-center justify-center"> | ||||
|                                 <!-- Icons --> | ||||
|                                 <ng-container [ngSwitch]="item.type"> | ||||
|                                     <!-- Folder --> | ||||
|                                     <ng-container *ngSwitchCase="'folder'"> | ||||
|                                         <mat-icon | ||||
|                                             class="icon-size-14 text-hint" | ||||
|                                             [svgIcon]="'iconsmind:folder'"></mat-icon> | ||||
|                                     </ng-container> | ||||
|                                     <!-- File --> | ||||
|                                     <ng-container *ngSwitchDefault> | ||||
|                                         <div class="relative"> | ||||
|                                             <mat-icon | ||||
|                                                 class="icon-size-14 text-hint" | ||||
|                                                 [svgIcon]="'iconsmind:file'"></mat-icon> | ||||
|                                             <div | ||||
|                                                 class="absolute left-0 bottom-0 px-1.5 rounded text-sm font-semibold leading-5 text-white" | ||||
|                                                 [class.bg-red-600]="item.type === 'PDF'" | ||||
|                                                 [class.bg-blue-600]="item.type === 'DOC'" | ||||
|                                                 [class.bg-green-600]="item.type === 'XLS'" | ||||
|                                                 [class.bg-gray-600]="item.type === 'TXT'" | ||||
|                                                 [class.bg-amber-600]="item.type === 'JPG'"> | ||||
|                                                 {{item.type.toUpperCase()}} | ||||
|                                             </div> | ||||
|                         <ng-container *ngIf="items.folders.length > 0"> | ||||
|                             <div> | ||||
|                                 <div class="font-medium">Folders</div> | ||||
|                                 <div | ||||
|                                     class="flex flex-wrap -m-2 mt-2"> | ||||
|                                     <ng-container *ngFor="let folder of items.folders; trackBy:trackByFn"> | ||||
|                                         <div class="relative w-40 h-40 m-2 p-4 shadow rounded-2xl bg-card"> | ||||
|                                             <a | ||||
|                                                 class="absolute z-20 top-1.5 right-1.5 w-8 h-8 min-h-8" | ||||
|                                                 (click)="$event.preventDefault()" | ||||
|                                                 [routerLink]="['./details/', folder.id]" | ||||
|                                                 mat-icon-button> | ||||
|                                                 <mat-icon | ||||
|                                                     class="icon-size-5" | ||||
|                                                     [svgIcon]="'heroicons_solid:information-circle'"></mat-icon> | ||||
|                                             </a> | ||||
|                                             <a | ||||
|                                                 class="z-10 absolute inset-0 flex flex-col p-4 cursor-pointer" | ||||
|                                                 [routerLink]="['/apps/file-manager/folders/', folder.id]"> | ||||
|                                                 <div class="aspect-w-9 aspect-h-6"> | ||||
|                                                     <div class="flex items-center justify-center"> | ||||
|                                                         <!-- Icon --> | ||||
|                                                         <mat-icon | ||||
|                                                             class="icon-size-14 text-hint" | ||||
|                                                             [svgIcon]="'iconsmind:folder'"></mat-icon> | ||||
|                                                     </div> | ||||
|                                                 </div> | ||||
|                                                 <div class="flex flex-col flex-auto justify-center text-center text-sm font-medium"> | ||||
|                                                     <div | ||||
|                                                         class="truncate" | ||||
|                                                         [matTooltip]="folder.name">{{folder.name}}</div> | ||||
|                                                     <ng-container *ngIf="folder.contents"> | ||||
|                                                         <div class="text-secondary truncate">{{folder.contents}}</div> | ||||
|                                                     </ng-container> | ||||
|                                                 </div> | ||||
|                                             </a> | ||||
|                                         </div> | ||||
|                                     </ng-container> | ||||
|                                 </ng-container> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <div class="flex flex-col flex-auto justify-center text-center text-sm font-medium"> | ||||
|                             <div | ||||
|                                 class="truncate" | ||||
|                                 [matTooltip]="item.name">{{item.name}}</div> | ||||
|                             <ng-container *ngIf="item.contents"> | ||||
|                                 <div class="text-secondary truncate">{{item.contents}}</div> | ||||
|                             </ng-container> | ||||
|                         </div> | ||||
|                     </a> | ||||
|                 </ng-template> | ||||
|                         </ng-container> | ||||
| 
 | ||||
|                         <!-- Files --> | ||||
|                         <ng-container *ngIf="items.files.length > 0"> | ||||
|                             <div> | ||||
|                                 <div class="font-medium">Files</div> | ||||
|                                 <div | ||||
|                                     class="flex flex-wrap -m-2 mt-2"> | ||||
|                                     <ng-container *ngFor="let file of items.files; trackBy:trackByFn"> | ||||
|                                         <a | ||||
|                                             class="flex flex-col w-40 h-40 m-2 p-4 shadow rounded-2xl cursor-pointer bg-card" | ||||
|                                             [routerLink]="['./details/', file.id]"> | ||||
|                                             <div class="aspect-w-9 aspect-h-6"> | ||||
|                                                 <div class="flex items-center justify-center"> | ||||
|                                                     <!-- Icons --> | ||||
|                                                     <div class="relative"> | ||||
|                                                         <mat-icon | ||||
|                                                             class="icon-size-14 text-hint" | ||||
|                                                             [svgIcon]="'iconsmind:file'"></mat-icon> | ||||
|                                                         <div | ||||
|                                                             class="absolute left-0 bottom-0 px-1.5 rounded text-sm font-semibold leading-5 text-white" | ||||
|                                                             [class.bg-red-600]="file.type === 'PDF'" | ||||
|                                                             [class.bg-blue-600]="file.type === 'DOC'" | ||||
|                                                             [class.bg-green-600]="file.type === 'XLS'" | ||||
|                                                             [class.bg-gray-600]="file.type === 'TXT'" | ||||
|                                                             [class.bg-amber-600]="file.type === 'JPG'"> | ||||
|                                                             {{file.type.toUpperCase()}} | ||||
|                                                         </div> | ||||
|                                                     </div> | ||||
|                                                 </div> | ||||
|                                             </div> | ||||
|                                             <div class="flex flex-col flex-auto justify-center text-center text-sm font-medium"> | ||||
|                                                 <div | ||||
|                                                     class="truncate" | ||||
|                                                     [matTooltip]="file.name">{{file.name}}</div> | ||||
|                                                 <ng-container *ngIf="file.contents"> | ||||
|                                                     <div class="text-secondary truncate">{{file.contents}}</div> | ||||
|                                                 </ng-container> | ||||
|                                             </div> | ||||
|                                         </a> | ||||
|                                     </ng-container> | ||||
|                                 </div> | ||||
|                             </div> | ||||
|                         </ng-container> | ||||
|                     </div> | ||||
|                 </ng-container> | ||||
| 
 | ||||
|                 <!-- No items template --> | ||||
|                 <ng-template #noItems> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user