feature/fe-folder
This commit is contained in:
parent
aafaab0cb1
commit
11418bc4c6
@ -0,0 +1,373 @@
|
|||||||
|
import { Component, OnInit, Renderer2, ElementRef } from '@angular/core';
|
||||||
|
import { FoldersService } from 'src/app/services/rest/folders.service';
|
||||||
|
import { Document, Folders, Results } from 'src/app/data/folders';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-view-all-folder',
|
||||||
|
templateUrl: './viewall-forder.component.html',
|
||||||
|
styleUrls: ['./viewall-forder.component.scss']
|
||||||
|
})
|
||||||
|
export class ViewallForderComponent implements OnInit {
|
||||||
|
folders: Folders[] = [];
|
||||||
|
documents: Document[] = [];
|
||||||
|
results: Results[] = [];
|
||||||
|
selectedFolderId: number | null = null;
|
||||||
|
|
||||||
|
constructor(private foldersService: FoldersService, private renderer: Renderer2, private elementRef: ElementRef) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.foldersService.getFoldersAndDocuments().subscribe({
|
||||||
|
next: (data: any) => {
|
||||||
|
this.folders = data.folders;
|
||||||
|
this.documents = data.documents;
|
||||||
|
this.initializeFolders();
|
||||||
|
this.initializeDocuments();
|
||||||
|
this.addEventListeners();
|
||||||
|
},
|
||||||
|
error: error => {
|
||||||
|
console.error('Error fetching data:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.foldersService.getResults().subscribe({
|
||||||
|
next: (data: any) => {
|
||||||
|
this.results = data.results.filter(result => result.parent_folder !== null);
|
||||||
|
this.initializeFolders();
|
||||||
|
},
|
||||||
|
error: error => {
|
||||||
|
console.error('Error fetching results:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
initializeFolders(): void {
|
||||||
|
const foldersContainer = this.elementRef.nativeElement.querySelector('#folders-container');
|
||||||
|
if (foldersContainer) {
|
||||||
|
const allFolders = [...this.folders, ...this.results];
|
||||||
|
foldersContainer.innerHTML = '';
|
||||||
|
|
||||||
|
const folderMap = new Map<number, Folders[]>();
|
||||||
|
allFolders.forEach(folder => {
|
||||||
|
const parentId = folder.parent_folder ?? null;
|
||||||
|
if (!folderMap.has(parentId)) {
|
||||||
|
folderMap.set(parentId, []);
|
||||||
|
}
|
||||||
|
folderMap.get(parentId)?.push(folder);
|
||||||
|
});
|
||||||
|
|
||||||
|
const createFolders = (parentId: number | null, parentDiv: HTMLElement | null): void => {
|
||||||
|
const children = folderMap.get(parentId) || [];
|
||||||
|
children.forEach(folder => {
|
||||||
|
const folderHTML = this.createFolderHTML(folder);
|
||||||
|
if (parentDiv) {
|
||||||
|
this.renderer.appendChild(parentDiv, folderHTML);
|
||||||
|
} else {
|
||||||
|
this.renderer.appendChild(foldersContainer, folderHTML);
|
||||||
|
}
|
||||||
|
createFolders(folder.id, folderHTML.querySelector('.children-container') as HTMLElement);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
createFolders(null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
initializeDocuments(): void {
|
||||||
|
const documentsContainer = this.elementRef.nativeElement.querySelector('#documents-container');
|
||||||
|
if (documentsContainer) {
|
||||||
|
documentsContainer.innerHTML = '';
|
||||||
|
const addedDocumentFilenames = new Set<string>();
|
||||||
|
|
||||||
|
this.documents.forEach(doc => {
|
||||||
|
const folder = this.findFolderById(doc.folder_id);
|
||||||
|
if (!addedDocumentFilenames.has(doc.filename)) {
|
||||||
|
if (folder && folder.id > 0) {
|
||||||
|
const folderDiv = this.findFolderDiv(folder.id);
|
||||||
|
if (folderDiv) {
|
||||||
|
const documentsContainerInFolder = folderDiv.querySelector('.documents-container') as HTMLElement;
|
||||||
|
if (documentsContainerInFolder && !documentsContainerInFolder.querySelector(`.document[data-document-id="${doc.id}"]`)) {
|
||||||
|
const documentHTML = this.createDocumentHTML(doc);
|
||||||
|
this.renderer.appendChild(documentsContainerInFolder, documentHTML);
|
||||||
|
addedDocumentFilenames.add(doc.filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!documentsContainer.querySelector(`.document[data-document-id="${doc.id}"]`)) {
|
||||||
|
const documentHTML = this.createDocumentHTML(doc);
|
||||||
|
this.renderer.appendChild(documentsContainer, documentHTML);
|
||||||
|
addedDocumentFilenames.add(doc.filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListeners(): void {
|
||||||
|
// Handling double click for elements with class .folder-cha
|
||||||
|
const folderChaElements = this.elementRef.nativeElement.querySelectorAll('.folder-cha');
|
||||||
|
folderChaElements.forEach(item => {
|
||||||
|
this.renderer.listen(item, 'dblclick', (event: Event) => {
|
||||||
|
const target = event.currentTarget as HTMLElement;
|
||||||
|
const folderElement = target.closest('.folder') as HTMLElement;
|
||||||
|
const folderId = Number(folderElement?.dataset.folderId);
|
||||||
|
this.confirmDisplayFolderContents(folderId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove all 'click' event listeners on 'tr' elements
|
||||||
|
const folderRows = this.elementRef.nativeElement.querySelectorAll('tr[data-folder-id]');
|
||||||
|
folderRows.forEach(row => {
|
||||||
|
// Completely remove 'click' event listener
|
||||||
|
row.removeEventListener('click', this.handleRowClick);
|
||||||
|
|
||||||
|
// Use 'dblclick' instead of 'click'
|
||||||
|
this.renderer.listen(row, 'dblclick', (event: Event) => {
|
||||||
|
const target = event.currentTarget as HTMLTableRowElement;
|
||||||
|
const folderId = Number(target.dataset.folderId);
|
||||||
|
this.confirmDisplayFolderContents(folderId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Resizing folderLeft section (unchanged from original)
|
||||||
|
const folderLeft = this.elementRef.nativeElement.querySelector('#folderLeft');
|
||||||
|
if (folderLeft) {
|
||||||
|
const resizeHandle = folderLeft.querySelector('.resize-handle') as HTMLElement;
|
||||||
|
if (resizeHandle) {
|
||||||
|
let startX: number;
|
||||||
|
let startWidth: number;
|
||||||
|
|
||||||
|
const resizeWidth = (event: MouseEvent) => {
|
||||||
|
const newWidth = startWidth + (event.clientX - startX);
|
||||||
|
folderLeft.style.width = `${newWidth}px`; // Corrected template literal usage
|
||||||
|
|
||||||
|
const folderRight = this.elementRef.nativeElement.querySelector('.folder-right') as HTMLElement;
|
||||||
|
if (folderRight) {
|
||||||
|
folderRight.style.width = `calc(100% - ${newWidth}px)`; // Corrected template literal usage
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const stopResize = () => {
|
||||||
|
document.removeEventListener('mousemove', resizeWidth);
|
||||||
|
document.removeEventListener('mouseup', stopResize);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.renderer.listen(resizeHandle, 'mousedown', (event: MouseEvent) => {
|
||||||
|
startX = event.clientX;
|
||||||
|
startWidth = parseInt(window.getComputedStyle(folderLeft).width, 10);
|
||||||
|
document.addEventListener('mousemove', resizeWidth);
|
||||||
|
document.addEventListener('mouseup', stopResize);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example function for handling 'click' on rows (if necessary)
|
||||||
|
handleRowClick(event: Event) {
|
||||||
|
const target = event.currentTarget as HTMLTableRowElement;
|
||||||
|
const folderId = Number(target.dataset.folderId);
|
||||||
|
// Handle click action here if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
confirmDisplayFolderContents(folderId: number): void {
|
||||||
|
this.displayFolderContents(folderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
displayFolderContents(folderId: number, parentRow: HTMLTableRowElement | null = null): void {
|
||||||
|
const tableBody = this.elementRef.nativeElement.querySelector('.folder-contents tbody');
|
||||||
|
if (tableBody) {
|
||||||
|
const rowsToRemove = parentRow
|
||||||
|
? tableBody.querySelectorAll(`.child-of-folder-${folderId}`)
|
||||||
|
: tableBody.querySelectorAll('tr');
|
||||||
|
rowsToRemove.forEach(row => row.remove());
|
||||||
|
|
||||||
|
const childFolders = this.folders.filter(folder => folder.parent_folder === folderId);
|
||||||
|
const childResults = this.results.filter(result => result.parent_folder === folderId);
|
||||||
|
const allChildFolders = [...childFolders, ...childResults];
|
||||||
|
|
||||||
|
allChildFolders.forEach(folder => {
|
||||||
|
const row = this.createFolderRowHTML(folder, folderId);
|
||||||
|
if (parentRow) {
|
||||||
|
parentRow.insertAdjacentElement('afterend', row);
|
||||||
|
} else {
|
||||||
|
tableBody.appendChild(row);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const childDocuments = this.documents.filter(doc => doc.folder_id === folderId);
|
||||||
|
childDocuments.forEach(doc => {
|
||||||
|
const row = this.createDocumentRowHTML(doc, folderId);
|
||||||
|
if (parentRow) {
|
||||||
|
parentRow.insertAdjacentElement('afterend', row);
|
||||||
|
} else {
|
||||||
|
tableBody.appendChild(row);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addRowEventListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createFolderRowHTML(folder: Folders, parentId: number): HTMLElement {
|
||||||
|
const row = document.createElement('tr');
|
||||||
|
row.classList.add(`child-of-folder-${parentId}`);
|
||||||
|
row.dataset.folderId = folder.id.toString();
|
||||||
|
|
||||||
|
const nameCell = document.createElement('td');
|
||||||
|
const folderIcon = document.createElement('i');
|
||||||
|
folderIcon.classList.add('fa-solid', 'fa-folder');
|
||||||
|
const folderName = document.createElement('p');
|
||||||
|
folderName.textContent = folder.name;
|
||||||
|
nameCell.appendChild(folderIcon);
|
||||||
|
nameCell.appendChild(folderName);
|
||||||
|
|
||||||
|
const dateCell = document.createElement('td');
|
||||||
|
dateCell.textContent = '11/10/2002'; // Placeholder date
|
||||||
|
|
||||||
|
const typeCell = document.createElement('td');
|
||||||
|
typeCell.textContent = 'File Folder';
|
||||||
|
|
||||||
|
const sizeCell = document.createElement('td');
|
||||||
|
sizeCell.textContent = '2 KB'; // Placeholder size
|
||||||
|
|
||||||
|
row.appendChild(nameCell);
|
||||||
|
row.appendChild(dateCell);
|
||||||
|
row.appendChild(typeCell);
|
||||||
|
row.appendChild(sizeCell);
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
createDocumentRowHTML(doc: Document, parentId: number): HTMLElement {
|
||||||
|
const row = document.createElement('tr');
|
||||||
|
row.classList.add(`child-of-folder-${parentId}`);
|
||||||
|
row.dataset.documentId = doc.id.toString();
|
||||||
|
|
||||||
|
const nameCell = document.createElement('td');
|
||||||
|
const fileIcon = document.createElement('i');
|
||||||
|
fileIcon.classList.add('fa-solid', 'fa-file');
|
||||||
|
const fileName = document.createElement('p');
|
||||||
|
fileName.textContent = doc.filename;
|
||||||
|
nameCell.appendChild(fileIcon);
|
||||||
|
nameCell.appendChild(fileName);
|
||||||
|
|
||||||
|
const dateCell = document.createElement('td');
|
||||||
|
dateCell.textContent = '11/10/2002'; // Placeholder date
|
||||||
|
|
||||||
|
const typeCell = document.createElement('td');
|
||||||
|
typeCell.textContent = 'txt'; // Placeholder type
|
||||||
|
|
||||||
|
const sizeCell = document.createElement('td');
|
||||||
|
sizeCell.textContent = '2 KB'; // Placeholder size
|
||||||
|
|
||||||
|
row.appendChild(nameCell);
|
||||||
|
row.appendChild(dateCell);
|
||||||
|
row.appendChild(typeCell);
|
||||||
|
row.appendChild(sizeCell);
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
createFolderHTML(folder: Folders): HTMLElement {
|
||||||
|
const folderDiv = document.createElement('div');
|
||||||
|
folderDiv.classList.add('folder');
|
||||||
|
folderDiv.dataset.folderId = folder.id.toString();
|
||||||
|
|
||||||
|
const folderIcon = document.createElement('i');
|
||||||
|
folderIcon.classList.add('fa', 'fa-solid', 'fa-chevron-right');
|
||||||
|
|
||||||
|
const folderIconFolder = document.createElement('i');
|
||||||
|
folderIconFolder.classList.add('fa', 'fa-solid', 'fa-folder');
|
||||||
|
|
||||||
|
const folderName = document.createElement('p');
|
||||||
|
folderName.textContent = folder.name;
|
||||||
|
|
||||||
|
const folderHeader = document.createElement('div');
|
||||||
|
folderHeader.classList.add('folder-cha');
|
||||||
|
folderHeader.appendChild(folderIcon);
|
||||||
|
folderHeader.appendChild(folderIconFolder);
|
||||||
|
folderHeader.appendChild(folderName);
|
||||||
|
|
||||||
|
folderDiv.appendChild(folderHeader);
|
||||||
|
|
||||||
|
const childrenContainer = document.createElement('div');
|
||||||
|
childrenContainer.classList.add('children-container');
|
||||||
|
childrenContainer.style.display = 'none';
|
||||||
|
folderDiv.appendChild(childrenContainer);
|
||||||
|
|
||||||
|
// Variable to store the logged folder id
|
||||||
|
let loggedFolderId: number | null = null;
|
||||||
|
|
||||||
|
this.renderer.listen(folderHeader, 'click', () => {
|
||||||
|
// Check and log folder id when clicking on folderHeader
|
||||||
|
const clickedFolderId = folder.id;
|
||||||
|
if (clickedFolderId !== loggedFolderId) {
|
||||||
|
if (loggedFolderId !== null) {
|
||||||
|
console.log(`Removed log for folder ${loggedFolderId}`);
|
||||||
|
}
|
||||||
|
console.log(`Clicked folder ${clickedFolderId}`);
|
||||||
|
loggedFolderId = clickedFolderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Display contents of the folder in the tbody
|
||||||
|
this.displayFolderContents(clickedFolderId);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.renderer.listen(folderIcon, 'click', (event: Event) => {
|
||||||
|
// Prevent folderHeader click event when clicking on folderIcon
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
// Toggle display of childrenContainer
|
||||||
|
if (childrenContainer.style.display === 'none') {
|
||||||
|
childrenContainer.style.display = 'block';
|
||||||
|
folderIcon.style.transform = 'rotate(90deg)';
|
||||||
|
folderIconFolder.classList.replace('fa-folder', 'fa-folder-open');
|
||||||
|
} else {
|
||||||
|
childrenContainer.style.display = 'none';
|
||||||
|
folderIcon.style.transform = '';
|
||||||
|
folderIconFolder.classList.replace('fa-folder-open', 'fa-folder');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return folderDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
createDocumentHTML(doc: Document): HTMLElement {
|
||||||
|
const documentDiv = document.createElement('div');
|
||||||
|
documentDiv.classList.add('document');
|
||||||
|
documentDiv.dataset.documentId = doc.id.toString();
|
||||||
|
|
||||||
|
const documentName = document.createElement('p');
|
||||||
|
documentName.textContent = doc.filename;
|
||||||
|
|
||||||
|
const documentContainer = document.createElement('div');
|
||||||
|
documentContainer.classList.add('document-container');
|
||||||
|
documentContainer.appendChild(documentName);
|
||||||
|
|
||||||
|
documentDiv.appendChild(documentContainer);
|
||||||
|
return documentDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
findFolderById(folderId: number): Folders | undefined {
|
||||||
|
return this.folders.find(folder => folder.id === folderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
findFolderDiv(folderId: number): HTMLElement | null {
|
||||||
|
const foldersContainer = document.getElementById('folders-container');
|
||||||
|
return foldersContainer?.querySelector(`.folder[data-folder-id="${folderId}"]`) as HTMLElement | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
addRowEventListeners(): void {
|
||||||
|
const folderRows = this.elementRef.nativeElement.querySelectorAll('tr[data-folder-id]');
|
||||||
|
folderRows.forEach(row => {
|
||||||
|
this.renderer.listen(row, 'dblclick', (event: Event) => {
|
||||||
|
const target = event.currentTarget as HTMLTableRowElement;
|
||||||
|
const folderId = Number(target.dataset.folderId);
|
||||||
|
this.confirmDisplayFolderContents(folderId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -1,68 +1,74 @@
|
|||||||
<div class="folder-container">
|
<div class="folder-container" id="folderLeft">
|
||||||
<div class="sub-folder-container">
|
<div style="display: none;" class="sub-folder-container">
|
||||||
|
<form action="">
|
||||||
|
<input type="text">
|
||||||
|
<button>UpLoad File</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="folder-left" id="folderLeft">
|
<div id="contextMenu" class="addfolder">
|
||||||
<div class="folder-left-1">
|
<ul>
|
||||||
<div class="folder-left-search">
|
<li id="am"><a >New file...</a></li>
|
||||||
<button class="search"><i class="fa-solid fa-magnifying-glass"></i></button>
|
<li><a >New folder...</a></li>
|
||||||
<input placeholder="Tìm Kiếm" class="serch" type="text">
|
<li style="border: 1px solid black;"><a >Rename...</a></li>
|
||||||
|
<li style="border: 1px solid black;"><a >Delete...</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="folder-left" id="sss">
|
||||||
|
<div class="folder-left-1">
|
||||||
|
<div class="folder-left-search">
|
||||||
|
<button class="search"><i class="fa-solid fa-magnifying-glass"></i></button>
|
||||||
|
<input placeholder="Tìm Kiếm" class="serch" type="text">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="folders-container" class="folder">
|
||||||
|
<!-- Folders and Documents will be added dynamically here -->
|
||||||
|
</div>
|
||||||
|
<div id="documents-container" class="documents">
|
||||||
|
</div>
|
||||||
|
<div class="resize-handle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="folder-right" id="sss">
|
||||||
|
<div class="folder-search">
|
||||||
|
<div class="folder-right-tim">
|
||||||
|
<div class="logo-folder">
|
||||||
|
<i class="fa-solid fa-folder"></i> <i class="fa-solid fa-chevron-right"></i>
|
||||||
|
</div>
|
||||||
|
<div class="ten-folder">
|
||||||
|
<p>Folder 1</p>
|
||||||
|
<i class="fa-solid fa-chevron-right"></i>
|
||||||
|
</div>
|
||||||
|
<div class="ten-folder">
|
||||||
|
<p>Folder 2</p>
|
||||||
|
<i class="fa-solid fa-chevron-right"></i>
|
||||||
|
</div>
|
||||||
|
<div class="ten-folder">
|
||||||
|
<p>Folder 3</p>
|
||||||
|
<i class="fa-solid fa-chevron-right"></i>
|
||||||
|
</div>
|
||||||
|
<div class="ten-folder">
|
||||||
|
<p>Folder 4</p>
|
||||||
|
<i class="fa-solid fa-chevron-right"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div id="folders-container" class="folder">
|
|
||||||
<!-- Folders and Documents will be added dynamically here -->
|
|
||||||
</div>
|
|
||||||
<div id="documents-container" class="documents">
|
|
||||||
</div>
|
</div>
|
||||||
<div class="resize-handle"></div>
|
<div class="folder-right-search">
|
||||||
</div>
|
<button> <i class="fa-solid fa-magnifying-glass"></i> </button>
|
||||||
<div class="folder-right">
|
<input type="text">
|
||||||
<div class="folder-search">
|
</div>
|
||||||
<div class="folder-right-tim"></div>
|
</div>
|
||||||
<div class="folder-right-search">
|
<div class="folder-right-conten">
|
||||||
<button> <i class="fa-solid fa-magnifying-glass"></i> </button>
|
<table class="folder-contents">
|
||||||
<input type="text">
|
<thead>
|
||||||
</div>
|
<tr>
|
||||||
</div>
|
<td>Name</td>
|
||||||
<div class="folder-right-conten">
|
<td>Data modified</td>
|
||||||
<table>
|
<td>Type</td>
|
||||||
<thead>
|
<td>Size</td>
|
||||||
<tr>
|
</tr>
|
||||||
<td>Name</td>
|
</thead>
|
||||||
<td>Data modified</td>
|
<tbody>
|
||||||
<td>Type</td>
|
|
||||||
<td>Size</td>
|
</tbody>
|
||||||
</tr>
|
</table>
|
||||||
</thead>
|
</div>
|
||||||
<tbody>
|
</div>
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<i class="fa-solid fa-folder"></i>
|
|
||||||
<p>Folder 1</p>
|
|
||||||
</td>
|
|
||||||
<td>11/10/2002</td>
|
|
||||||
<td>
|
|
||||||
<p>File Folder</p>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<p>2 KB</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<i class="fa-solid fa-file"></i>
|
|
||||||
<p>Document</p>
|
|
||||||
</td>
|
|
||||||
<td>11/10/2002</td>
|
|
||||||
<td>
|
|
||||||
<p>txt</p>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<p>2 KB</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
@ -3,251 +3,283 @@ body {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.folder-container {
|
.folder-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
|
||||||
.folder-container .folder-left {
|
|
||||||
width: 30%;
|
|
||||||
position: relative;
|
|
||||||
min-width: 100px;
|
|
||||||
height: 100vh;
|
|
||||||
overflow-x: auto;
|
|
||||||
overflow-y: auto;
|
|
||||||
background: rgba(37, 36, 36, 0.845);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.resize-handle {
|
|
||||||
background-color: #f0f0f0;
|
|
||||||
cursor: ew-resize;
|
|
||||||
width: 2px;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
.folder-container .folder-right {
|
|
||||||
width: 70%;
|
|
||||||
height: 100vh;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
.folder-left-1 {
|
|
||||||
width: 100%;
|
|
||||||
height: 30px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
.folder-left-search {
|
|
||||||
width: 85%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-top: 10px;
|
|
||||||
box-shadow: 0 0 3px 0 gold;
|
|
||||||
}
|
|
||||||
.folder-left-search .serch {
|
|
||||||
width: 90%;
|
|
||||||
height: 100%;
|
|
||||||
border-left: none;
|
|
||||||
border-top-right-radius: 5px;
|
|
||||||
border-bottom-right-radius: 5px;
|
|
||||||
}
|
|
||||||
.folder-left-search .serch:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
.serch:focus + .folder-left-search {
|
|
||||||
border: 5px solid gold;
|
|
||||||
}
|
|
||||||
.folder-left-search .search {
|
|
||||||
width: 10%;
|
|
||||||
height: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
border-right: none;
|
|
||||||
border-top-left-radius: 5px;
|
|
||||||
border-bottom-left-radius: 5px;
|
|
||||||
}
|
|
||||||
.folder{
|
|
||||||
width: 95%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
#folders-container{
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
.documents {
|
|
||||||
width: 95%;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
.folder-cha{
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
display: flex;
|
|
||||||
cursor: pointer;
|
|
||||||
margin-top: 2%;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.folder-cha P{
|
|
||||||
color: #f0f0f0;
|
|
||||||
}
|
|
||||||
.folder-cha .fa-solid{
|
|
||||||
color: gold;
|
|
||||||
padding: 0 5px;
|
|
||||||
}
|
|
||||||
.folder-cha .fa-chevron-right{
|
|
||||||
color: #f0f0f0;
|
|
||||||
}
|
|
||||||
.folder-cha .fa-folder{
|
|
||||||
color: goldenrod;
|
|
||||||
}
|
|
||||||
.folder-con{
|
|
||||||
width: 100%;
|
|
||||||
height: auto;
|
|
||||||
display: flex;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
text-align: left;
|
.folder-left {
|
||||||
}
|
width: 30%;
|
||||||
.folder-con P{
|
position: relative;
|
||||||
color: #f0f0f0;
|
min-width: 100px;
|
||||||
}
|
height: 100vh;
|
||||||
.foder{
|
overflow-x: auto;
|
||||||
width: 100%;
|
overflow-y: auto;
|
||||||
height: auto;
|
background: rgba(37, 36, 36, 0.845);
|
||||||
position: relative;
|
display: flex;
|
||||||
text-align: left;
|
align-items: center;
|
||||||
}
|
flex-direction: column;
|
||||||
.folder-con .fa-solid{
|
overflow: hidden;
|
||||||
color: gold;
|
|
||||||
padding: 0 5px;
|
|
||||||
}
|
|
||||||
.folder-con .fa-chevron-right{
|
|
||||||
color: #f0f0f0;
|
|
||||||
}
|
|
||||||
.folder-con .fa-folder{
|
|
||||||
color: goldenrod;
|
|
||||||
}
|
|
||||||
#folders-container{
|
|
||||||
margin-left: -10%;
|
|
||||||
}
|
|
||||||
.docoment{
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.docomenta,
|
|
||||||
.document-container{
|
|
||||||
margin-left: 7%;
|
|
||||||
}
|
|
||||||
p{
|
|
||||||
color: aliceblue;
|
|
||||||
}
|
|
||||||
.folder {
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
padding-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.folder .ke {
|
.resize-handle {
|
||||||
background: #f0f0f0;
|
background-color: #f0f0f0;
|
||||||
width: 1px;
|
cursor: ew-resize;
|
||||||
height: 180%;
|
width: 2px;
|
||||||
z-index: 10000;
|
height: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 8.5%;
|
right: 0;
|
||||||
top: 60%;
|
}
|
||||||
display: none;
|
|
||||||
transform: translateY(-15%);
|
|
||||||
}
|
|
||||||
.folder-search{
|
|
||||||
width: 100%;
|
|
||||||
height: 50px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.folder-right-tim{
|
|
||||||
width: 60%;
|
|
||||||
height: 40px;
|
|
||||||
background: rgba(128, 128, 128, 0.534);
|
|
||||||
border-radius: 5px;
|
|
||||||
|
|
||||||
margin-left: 10px;
|
.folder-left-1 {
|
||||||
}
|
width: 100%;
|
||||||
.folder-right-search{
|
height: 30px;
|
||||||
width: 30%;
|
display: flex;
|
||||||
height: 40px;
|
align-items: center;
|
||||||
background: rgba(128, 128, 128, 0.449);
|
justify-content: center;
|
||||||
border-radius: 5px;
|
}
|
||||||
margin-left: 50px;
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
.folder-right-search button{
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 11px 15px;
|
|
||||||
border-right: none;
|
|
||||||
}
|
|
||||||
.folder-right-search input{
|
|
||||||
border-left: none;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.folder-right-conten{
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
margin: 20px 0;
|
|
||||||
background-color: #fff;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
table td{
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
table thead {
|
|
||||||
background-color: #007bff25;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
table thead tr {
|
.folder-left-search {
|
||||||
border-bottom: 1px solid #dee2e6;
|
width: 85%;
|
||||||
}
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
box-shadow: 0 0 3px 0 gold;
|
||||||
|
|
||||||
table thead td {
|
.serch {
|
||||||
padding: 12px 15px;
|
width: 90%;
|
||||||
text-align: left;
|
height: 100%;
|
||||||
font-weight: bold;
|
border-left: none;
|
||||||
}
|
border-top-right-radius: 5px;
|
||||||
|
border-bottom-right-radius: 5px;
|
||||||
|
|
||||||
table tbody tr {
|
&:focus {
|
||||||
border-bottom: 1px solid #dee2e6;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
table tbody tr:nth-of-type(even) {
|
&:focus + .folder-left-search {
|
||||||
background-color: #f2f2f2;
|
border: 5px solid gold;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
table tbody tr:hover {
|
.search {
|
||||||
background-color: #f1f1f1;
|
width: 10%;
|
||||||
}
|
height: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
border-right: none;
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-bottom-left-radius: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
table tbody td {
|
.folder {
|
||||||
padding: 12px 15px;
|
width: 95%;
|
||||||
text-align: left;
|
height: auto;
|
||||||
}
|
}
|
||||||
tbody td p{
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
table tbody td i {
|
#folders-container {
|
||||||
margin-right: 8px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table tbody td p {
|
.folder-cha {
|
||||||
display: inline;
|
width: 100%;
|
||||||
margin: 0;
|
height: auto;
|
||||||
}
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-top: 2%;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-solid {
|
||||||
|
color: gold;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
.fa{
|
||||||
|
color: gold;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-chevron-right {
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-folder {
|
||||||
|
color: goldenrod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-con {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-solid {
|
||||||
|
color: gold;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-chevron-right {
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fa-folder {
|
||||||
|
color: goldenrod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#folders-container {
|
||||||
|
margin-left: -10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.docoment {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.docomenta,
|
||||||
|
.document-container {
|
||||||
|
margin-left: 7%;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: aliceblue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-left: 20px;
|
||||||
|
|
||||||
|
.ke {
|
||||||
|
background: #f0f0f0;
|
||||||
|
width: 1px;
|
||||||
|
height: 180%;
|
||||||
|
z-index: 10000;
|
||||||
|
position: absolute;
|
||||||
|
left: 8.5%;
|
||||||
|
top: 60%;
|
||||||
|
display: none;
|
||||||
|
transform: translateY(-15%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-right {
|
||||||
|
width: 70%;
|
||||||
|
height: 100vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.folder-search {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.folder-right-tim {
|
||||||
|
width: 60%;
|
||||||
|
height: 40px;
|
||||||
|
background: rgba(128, 128, 128, 0.534);
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-right-search {
|
||||||
|
width: 30%;
|
||||||
|
height: 40px;
|
||||||
|
background: rgba(128, 128, 128, 0.449);
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-left: 50px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 11px 15px;
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
border-left: none;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-right-conten {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
|
||||||
|
td {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead {
|
||||||
|
background-color: #007bff25;
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
tr {
|
||||||
|
border-bottom: 1px solid #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 12px 15px;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: bold;
|
||||||
|
border-left: ăp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody {
|
||||||
|
tr {
|
||||||
|
border-bottom: 1px solid #dee2e6;
|
||||||
|
|
||||||
|
&:nth-of-type(even) {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 12px 15px;
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
display: inline;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,92 +1,213 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, Renderer2, ElementRef } from '@angular/core';
|
||||||
import { FoldersService } from 'src/app/services/rest/folders.service';
|
import { FoldersService } from 'src/app/services/rest/folders.service';
|
||||||
import { Document, Folders } from 'src/app/data/folders';
|
import { Document, Folders, Results } from 'src/app/data/folders';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-view-all-folder',
|
selector: 'app-view-all-folder',
|
||||||
templateUrl: './viewall-forder.component.html',
|
templateUrl: './viewall-forder.component.html',
|
||||||
styleUrls: ['./viewall-forder.component.scss']
|
styleUrls: ['./viewall-forder.component.scss']
|
||||||
})
|
})
|
||||||
export class ViewAllFolderComponent implements OnInit {
|
export class ViewallForderComponent implements OnInit {
|
||||||
folders: Folders[] = [];
|
folders: Folders[] = [];
|
||||||
documents: Document[] = [];
|
documents: Document[] = [];
|
||||||
|
results: Results[] = [];
|
||||||
|
selectedFolderId: number | null = null;
|
||||||
|
|
||||||
constructor(private foldersService: FoldersService) {}
|
constructor(private foldersService: FoldersService, private renderer: Renderer2, private elementRef: ElementRef) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.foldersService.getFoldersAndDocuments().subscribe({
|
this.foldersService.getFoldersAndDocuments().subscribe({
|
||||||
next: data => {
|
next: (data: any) => {
|
||||||
this.folders = data.folders;
|
this.folders = data.folders;
|
||||||
this.documents = data.documents;
|
this.documents = data.documents;
|
||||||
this.initializeFolders();
|
this.initializeFolders();
|
||||||
this.initializeDocuments();
|
this.initializeDocuments();
|
||||||
this.addEventListeners();
|
this.addEventListeners();
|
||||||
|
this.setupEventListeners();
|
||||||
},
|
},
|
||||||
error: error => {
|
error: error => {
|
||||||
console.error('Error fetching data:', error);
|
console.error('Error fetching data:', error);
|
||||||
// Xử lý lỗi theo yêu cầu của bạn
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.foldersService.getResults().subscribe({
|
||||||
|
next: (data: any) => {
|
||||||
|
this.results = data.results.filter(result => result.parent_folder !== null);
|
||||||
|
this.initializeFolders();
|
||||||
|
},
|
||||||
|
error: error => {
|
||||||
|
console.error('Error fetching results:', error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
setupEventListeners(): void {
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
const folderLeft = document.getElementById('folderLeft');
|
||||||
|
const folderright = document.getElementById('folderrightt');
|
||||||
|
const folderContainer = document.querySelector('.folder-container');
|
||||||
|
const zoom = document.getElementById("zoomImg");
|
||||||
|
const contextMenu = document.getElementById("contextMenu");
|
||||||
|
const toggleButton = document.getElementById("toggleButton");
|
||||||
|
const amButton = document.getElementById("am");
|
||||||
|
const subFolderContainer = document.querySelector('.sub-folder-container') as HTMLElement;
|
||||||
|
|
||||||
|
let eventsEnabled = false;
|
||||||
|
|
||||||
|
amButton.addEventListener("click", () => {
|
||||||
|
subFolderContainer.style.display = "block";
|
||||||
|
contextMenu.style.display = "none";
|
||||||
|
|
||||||
|
const inputInSubFolder = subFolderContainer.querySelector('input[type="text"]') as HTMLElement;
|
||||||
|
if (inputInSubFolder) {
|
||||||
|
inputInSubFolder.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
const allInputs = document.querySelectorAll('input');
|
||||||
|
allInputs.forEach((input) => {
|
||||||
|
if (input !== inputInSubFolder) {
|
||||||
|
input.blur();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('sss').addEventListener('click', () => {
|
||||||
|
const contextMenu1 = document.querySelector('.sub-folder-container') as HTMLElement;
|
||||||
|
if (contextMenu1) {
|
||||||
|
contextMenu1.style.display = 'none';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
folderLeft.addEventListener('click', () => {
|
||||||
|
hideContextMenu();
|
||||||
|
});
|
||||||
|
|
||||||
|
folderLeft.addEventListener('contextmenu', (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
showContextMenu(event.clientX, event.clientY);
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('mousedown', (event) => {
|
||||||
|
const targetElement = event.target as HTMLElement;
|
||||||
|
|
||||||
|
const clickedInsideContextMenu = contextMenu.contains(targetElement);
|
||||||
|
const clickedInsideFolderContainer = folderContainer.contains(targetElement);
|
||||||
|
const clickedInsideAddFolder = targetElement.classList.contains('addfolder') || targetElement.closest('.addfolder');
|
||||||
|
const clickedInsideAm = targetElement.id === 'am' || targetElement.closest('#am');
|
||||||
|
|
||||||
|
if (!clickedInsideContextMenu && !clickedInsideAddFolder && !clickedInsideAm) {
|
||||||
|
hideContextMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clickedInsideAm) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
toggleButton.addEventListener("click", () => {
|
||||||
|
toggleEvents();
|
||||||
|
});
|
||||||
|
|
||||||
|
function showContextMenu(x: number, y: number) {
|
||||||
|
if (contextMenu) {
|
||||||
|
contextMenu.style.display = "block";
|
||||||
|
contextMenu.style.left = x + "px";
|
||||||
|
contextMenu.style.top = y + "px";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideContextMenu() {
|
||||||
|
if (contextMenu) {
|
||||||
|
contextMenu.style.display = "none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleEvents() {
|
||||||
|
eventsEnabled = !eventsEnabled;
|
||||||
|
if (eventsEnabled) {
|
||||||
|
if (zoom) {
|
||||||
|
zoom.addEventListener("contextmenu", handleContextMenu);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (zoom) {
|
||||||
|
zoom.removeEventListener("contextmenu", handleContextMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleContextMenu(e: MouseEvent) {
|
||||||
|
e.preventDefault();
|
||||||
|
showContextMenu(e.clientX, e.clientY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zoom) {
|
||||||
|
zoom.onmouseup = () => {
|
||||||
|
if (eventsEnabled) {
|
||||||
|
hideContextMenu();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
zoom.onmousemove = (e: MouseEvent) => {
|
||||||
|
// Additional handling if needed
|
||||||
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeFolders(): void {
|
initializeFolders(): void {
|
||||||
const foldersContainer = document.getElementById('folders-container');
|
const foldersContainer = this.elementRef.nativeElement.querySelector('#folders-container');
|
||||||
if (foldersContainer) {
|
if (foldersContainer) {
|
||||||
|
const allFolders = [...this.folders, ...this.results];
|
||||||
foldersContainer.innerHTML = '';
|
foldersContainer.innerHTML = '';
|
||||||
|
|
||||||
const createFolders = (parentId: number | null, parentDiv: HTMLElement | null) => {
|
const folderMap = new Map<number, Folders[]>();
|
||||||
this.folders.forEach(folder => {
|
allFolders.forEach(folder => {
|
||||||
if (folder.parent_folder_id === parentId) {
|
const parentId = folder.parent_folder ?? null;
|
||||||
const folderHTML = this.createFolderHTML(folder, parentDiv);
|
if (!folderMap.has(parentId)) {
|
||||||
createFolders(folder.id, folderHTML.querySelector('.children-container') as HTMLElement);
|
folderMap.set(parentId, []);
|
||||||
|
}
|
||||||
|
folderMap.get(parentId)?.push(folder);
|
||||||
|
});
|
||||||
|
|
||||||
|
const createFolders = (parentId: number | null, parentDiv: HTMLElement | null): void => {
|
||||||
|
const children = folderMap.get(parentId) || [];
|
||||||
|
children.forEach(folder => {
|
||||||
|
const folderHTML = this.createFolderHTML(folder);
|
||||||
|
if (parentDiv) {
|
||||||
|
this.renderer.appendChild(parentDiv, folderHTML);
|
||||||
|
} else {
|
||||||
|
this.renderer.appendChild(foldersContainer, folderHTML);
|
||||||
}
|
}
|
||||||
|
createFolders(folder.id, folderHTML.querySelector('.children-container') as HTMLElement);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.folders.forEach(folder => {
|
createFolders(null, null);
|
||||||
if (folder.parent_folder_id === null) {
|
|
||||||
const folderHTML = this.createFolderHTML(folder);
|
|
||||||
foldersContainer.appendChild(folderHTML);
|
|
||||||
this.documents.forEach(doc => {
|
|
||||||
if (doc.folder_id === folder.id) {
|
|
||||||
const documentHTML = this.createDocumentHTML(doc);
|
|
||||||
folderHTML.querySelector('.children-container')?.appendChild(documentHTML);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
createFolders(folder.id, folderHTML.querySelector('.children-container') as HTMLElement);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeDocuments(): void {
|
initializeDocuments(): void {
|
||||||
const documentsContainer = document.getElementById('documents-container');
|
const documentsContainer = this.elementRef.nativeElement.querySelector('#documents-container');
|
||||||
const foldersContainer = document.getElementById('folders-container');
|
if (documentsContainer) {
|
||||||
|
|
||||||
if (documentsContainer && foldersContainer) {
|
|
||||||
documentsContainer.innerHTML = '';
|
documentsContainer.innerHTML = '';
|
||||||
|
|
||||||
const addedDocumentFilenames = new Set<string>();
|
const addedDocumentFilenames = new Set<string>();
|
||||||
|
|
||||||
this.documents.forEach(doc => {
|
this.documents.forEach(doc => {
|
||||||
|
const folder = this.findFolderById(doc.folder_id);
|
||||||
if (!addedDocumentFilenames.has(doc.filename)) {
|
if (!addedDocumentFilenames.has(doc.filename)) {
|
||||||
const folder = this.findFolderById(doc.folder_id);
|
if (folder && folder.id > 0) {
|
||||||
if (folder && folder.id === 71) {
|
|
||||||
const folderDiv = this.findFolderDiv(folder.id);
|
const folderDiv = this.findFolderDiv(folder.id);
|
||||||
if (folderDiv) {
|
if (folderDiv) {
|
||||||
const documentsContainerInFolder = folderDiv.querySelector('.documents-container');
|
const documentsContainerInFolder = folderDiv.querySelector('.documents-container') as HTMLElement;
|
||||||
if (documentsContainerInFolder) {
|
if (documentsContainerInFolder && !documentsContainerInFolder.querySelector(`.document[data-document-id="${doc.id}"]`)) {
|
||||||
if (!documentsContainerInFolder.querySelector(`.document[data-document-id="${doc.id}"]`)) {
|
const documentHTML = this.createDocumentHTML(doc);
|
||||||
const documentHTML = this.createDocumentHTML(doc);
|
this.renderer.appendChild(documentsContainerInFolder, documentHTML);
|
||||||
documentsContainerInFolder.appendChild(documentHTML);
|
addedDocumentFilenames.add(doc.filename);
|
||||||
addedDocumentFilenames.add(doc.filename);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!documentsContainer.querySelector(`.document[data-document-id="${doc.id}"]`)) {
|
if (!documentsContainer.querySelector(`.document[data-document-id="${doc.id}"]`)) {
|
||||||
const documentHTML = this.createDocumentHTML(doc);
|
const documentHTML = this.createDocumentHTML(doc);
|
||||||
documentsContainer.appendChild(documentHTML);
|
this.renderer.appendChild(documentsContainer, documentHTML);
|
||||||
addedDocumentFilenames.add(doc.filename);
|
addedDocumentFilenames.add(doc.filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -95,24 +216,182 @@ export class ViewAllFolderComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createFolderHTML(folder: Folders, parentDiv: HTMLElement | null = null): HTMLElement {
|
addEventListeners(): void {
|
||||||
|
// Handling double click for elements with class .folder-cha
|
||||||
|
const folderChaElements = this.elementRef.nativeElement.querySelectorAll('.folder-cha');
|
||||||
|
folderChaElements.forEach(item => {
|
||||||
|
this.renderer.listen(item, 'dblclick', (event: Event) => {
|
||||||
|
const target = event.currentTarget as HTMLElement;
|
||||||
|
const folderElement = target.closest('.folder') as HTMLElement;
|
||||||
|
const folderId = Number(folderElement?.dataset.folderId);
|
||||||
|
this.confirmDisplayFolderContents(folderId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove all 'click' event listeners on 'tr' elements
|
||||||
|
const folderRows = this.elementRef.nativeElement.querySelectorAll('tr[data-folder-id]');
|
||||||
|
folderRows.forEach(row => {
|
||||||
|
// Completely remove 'click' event listener
|
||||||
|
row.removeEventListener('click', this.handleRowClick);
|
||||||
|
|
||||||
|
// Use 'dblclick' instead of 'click'
|
||||||
|
this.renderer.listen(row, 'dblclick', (event: Event) => {
|
||||||
|
const target = event.currentTarget as HTMLTableRowElement;
|
||||||
|
const folderId = Number(target.dataset.folderId);
|
||||||
|
this.confirmDisplayFolderContents(folderId);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Resizing folderLeft section (unchanged from original)
|
||||||
|
const folderLeft = this.elementRef.nativeElement.querySelector('#folderLeft');
|
||||||
|
if (folderLeft) {
|
||||||
|
const resizeHandle = folderLeft.querySelector('.resize-handle') as HTMLElement;
|
||||||
|
if (resizeHandle) {
|
||||||
|
let startX: number;
|
||||||
|
let startWidth: number;
|
||||||
|
|
||||||
|
const resizeWidth = (event: MouseEvent) => {
|
||||||
|
const newWidth = startWidth + (event.clientX - startX);
|
||||||
|
folderLeft.style.width = `${newWidth}px`; // Corrected template literal usage
|
||||||
|
|
||||||
|
const folderRight = this.elementRef.nativeElement.querySelector('.folder-right') as HTMLElement;
|
||||||
|
if (folderRight) {
|
||||||
|
folderRight.style.width = `calc(100% - ${newWidth}px)`; // Corrected template literal usage
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const stopResize = () => {
|
||||||
|
document.removeEventListener('mousemove', resizeWidth);
|
||||||
|
document.removeEventListener('mouseup', stopResize);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.renderer.listen(resizeHandle, 'mousedown', (event: MouseEvent) => {
|
||||||
|
startX = event.clientX;
|
||||||
|
startWidth = parseInt(window.getComputedStyle(folderLeft).width, 10);
|
||||||
|
document.addEventListener('mousemove', resizeWidth);
|
||||||
|
document.addEventListener('mouseup', stopResize);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example function for handling 'click' on rows (if necessary)
|
||||||
|
handleRowClick(event: Event) {
|
||||||
|
const target = event.currentTarget as HTMLTableRowElement;
|
||||||
|
const folderId = Number(target.dataset.folderId);
|
||||||
|
// Handle click action here if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
confirmDisplayFolderContents(folderId: number): void {
|
||||||
|
this.displayFolderContents(folderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
displayFolderContents(folderId: number, parentRow: HTMLTableRowElement | null = null): void {
|
||||||
|
const tableBody = this.elementRef.nativeElement.querySelector('.folder-contents tbody');
|
||||||
|
if (tableBody) {
|
||||||
|
const rowsToRemove = parentRow
|
||||||
|
? tableBody.querySelectorAll(`.child-of-folder-${folderId}`)
|
||||||
|
: tableBody.querySelectorAll('tr');
|
||||||
|
rowsToRemove.forEach(row => row.remove());
|
||||||
|
|
||||||
|
const childFolders = this.folders.filter(folder => folder.parent_folder === folderId);
|
||||||
|
const childResults = this.results.filter(result => result.parent_folder === folderId);
|
||||||
|
const allChildFolders = [...childFolders, ...childResults];
|
||||||
|
|
||||||
|
allChildFolders.forEach(folder => {
|
||||||
|
const row = this.createFolderRowHTML(folder, folderId);
|
||||||
|
if (parentRow) {
|
||||||
|
parentRow.insertAdjacentElement('afterend', row);
|
||||||
|
} else {
|
||||||
|
tableBody.appendChild(row);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const childDocuments = this.documents.filter(doc => doc.folder_id === folderId);
|
||||||
|
childDocuments.forEach(doc => {
|
||||||
|
const row = this.createDocumentRowHTML(doc, folderId);
|
||||||
|
if (parentRow) {
|
||||||
|
parentRow.insertAdjacentElement('afterend', row);
|
||||||
|
} else {
|
||||||
|
tableBody.appendChild(row);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addRowEventListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createFolderRowHTML(folder: Folders, parentId: number): HTMLElement {
|
||||||
|
const row = document.createElement('tr');
|
||||||
|
row.classList.add(`child-of-folder-${parentId}`);
|
||||||
|
row.dataset.folderId = folder.id.toString();
|
||||||
|
|
||||||
|
const nameCell = document.createElement('td');
|
||||||
|
const folderIcon = document.createElement('i');
|
||||||
|
folderIcon.classList.add('fa-solid', 'fa-folder');
|
||||||
|
const folderName = document.createElement('p');
|
||||||
|
folderName.textContent = folder.name;
|
||||||
|
nameCell.appendChild(folderIcon);
|
||||||
|
nameCell.appendChild(folderName);
|
||||||
|
|
||||||
|
const dateCell = document.createElement('td');
|
||||||
|
dateCell.textContent = '11/10/2002'; // Placeholder date
|
||||||
|
|
||||||
|
const typeCell = document.createElement('td');
|
||||||
|
typeCell.textContent = 'File Folder';
|
||||||
|
|
||||||
|
const sizeCell = document.createElement('td');
|
||||||
|
sizeCell.textContent = '2 KB'; // Placeholder size
|
||||||
|
|
||||||
|
row.appendChild(nameCell);
|
||||||
|
row.appendChild(dateCell);
|
||||||
|
row.appendChild(typeCell);
|
||||||
|
row.appendChild(sizeCell);
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
createDocumentRowHTML(doc: Document, parentId: number): HTMLElement {
|
||||||
|
const row = document.createElement('tr');
|
||||||
|
row.classList.add(`child-of-folder-${parentId}`);
|
||||||
|
row.dataset.documentId = doc.id.toString();
|
||||||
|
|
||||||
|
const nameCell = document.createElement('td');
|
||||||
|
const fileIcon = document.createElement('i');
|
||||||
|
fileIcon.classList.add('fa-solid', 'fa-file');
|
||||||
|
const fileName = document.createElement('p');
|
||||||
|
fileName.textContent = doc.filename;
|
||||||
|
nameCell.appendChild(fileIcon);
|
||||||
|
nameCell.appendChild(fileName);
|
||||||
|
|
||||||
|
const dateCell = document.createElement('td');
|
||||||
|
dateCell.textContent = '11/10/2002'; // Placeholder date
|
||||||
|
|
||||||
|
const typeCell = document.createElement('td');
|
||||||
|
typeCell.textContent = 'txt'; // Placeholder type
|
||||||
|
|
||||||
|
const sizeCell = document.createElement('td');
|
||||||
|
sizeCell.textContent = '2 KB'; // Placeholder size
|
||||||
|
|
||||||
|
row.appendChild(nameCell);
|
||||||
|
row.appendChild(dateCell);
|
||||||
|
row.appendChild(typeCell);
|
||||||
|
row.appendChild(sizeCell);
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
createFolderHTML(folder: Folders): HTMLElement {
|
||||||
const folderDiv = document.createElement('div');
|
const folderDiv = document.createElement('div');
|
||||||
folderDiv.classList.add('folder');
|
folderDiv.classList.add('folder');
|
||||||
folderDiv.dataset.folderId = folder.id.toString();
|
folderDiv.dataset.folderId = folder.id.toString();
|
||||||
|
|
||||||
if (this.hasParentFolder(folder.id)) {
|
|
||||||
const keDiv = document.createElement('div');
|
|
||||||
keDiv.classList.add('ke');
|
|
||||||
folderDiv.appendChild(keDiv);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parentDiv) {
|
|
||||||
parentDiv.appendChild(folderDiv);
|
|
||||||
folderDiv.style.marginLeft = '0px';
|
|
||||||
}
|
|
||||||
|
|
||||||
const folderIcon = document.createElement('i');
|
const folderIcon = document.createElement('i');
|
||||||
folderIcon.classList.add('fa', 'fa-solid', 'fa-chevron-right');
|
folderIcon.classList.add('fa', 'fa-solid', 'fa-chevron-right');
|
||||||
|
|
||||||
const folderIconFolder = document.createElement('i');
|
const folderIconFolder = document.createElement('i');
|
||||||
folderIconFolder.classList.add('fa', 'fa-solid', 'fa-folder');
|
folderIconFolder.classList.add('fa', 'fa-solid', 'fa-folder');
|
||||||
|
|
||||||
@ -132,8 +411,49 @@ export class ViewAllFolderComponent implements OnInit {
|
|||||||
childrenContainer.style.display = 'none';
|
childrenContainer.style.display = 'none';
|
||||||
folderDiv.appendChild(childrenContainer);
|
folderDiv.appendChild(childrenContainer);
|
||||||
|
|
||||||
|
// Function to log folder chain recursively
|
||||||
|
const logFolderChainRecursive = (currentFolder: Folders, chain: string[] = []) => {
|
||||||
|
chain.unshift(currentFolder.id.toString()); // Prepend current folder id to the chain
|
||||||
|
|
||||||
|
if (currentFolder.parent_folder) {
|
||||||
|
const parentFolder = this.findFolderById(currentFolder.parent_folder);
|
||||||
|
if (parentFolder) {
|
||||||
|
logFolderChainRecursive(parentFolder, chain); // Recursive call to log parent folder
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(`Clicked folder ${chain.join(' > ')}`); // Log the chain when reached the root folder
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.renderer.listen(folderHeader, 'click', () => {
|
||||||
|
logFolderChainRecursive(folder); // Start logging from the clicked folder
|
||||||
|
this.displayFolderContents(folder.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.renderer.listen(folderIcon, 'click', (event: Event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
if (childrenContainer.style.display === 'none') {
|
||||||
|
childrenContainer.style.display = 'block';
|
||||||
|
folderIcon.style.transform = 'rotate(90deg)';
|
||||||
|
folderIconFolder.classList.replace('fa-folder', 'fa-folder-open');
|
||||||
|
} else {
|
||||||
|
childrenContainer.style.display = 'none';
|
||||||
|
folderIcon.style.transform = '';
|
||||||
|
folderIconFolder.classList.replace('fa-folder-open', 'fa-folder');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Recursively create HTML for child folders
|
||||||
|
const childFolders = this.folders.filter(f => f.parent_folder === folder.id);
|
||||||
|
childFolders.forEach(childFolder => {
|
||||||
|
const childFolderHTML = this.createFolderHTML(childFolder);
|
||||||
|
childrenContainer.appendChild(childFolderHTML);
|
||||||
|
});
|
||||||
|
|
||||||
return folderDiv;
|
return folderDiv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
createDocumentHTML(doc: Document): HTMLElement {
|
createDocumentHTML(doc: Document): HTMLElement {
|
||||||
const documentDiv = document.createElement('div');
|
const documentDiv = document.createElement('div');
|
||||||
@ -151,80 +471,23 @@ export class ViewAllFolderComponent implements OnInit {
|
|||||||
return documentDiv;
|
return documentDiv;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasParentFolder(folderId: number): boolean {
|
findFolderById(folderId: number): Folders | undefined {
|
||||||
return this.folders.some(folder => folder.parent_folder_id === folderId);
|
|
||||||
}
|
|
||||||
|
|
||||||
findFolderById(folderId: number | null): Folders | undefined {
|
|
||||||
return this.folders.find(folder => folder.id === folderId);
|
return this.folders.find(folder => folder.id === folderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
findFolderDiv(folderId: number): HTMLElement | null {
|
findFolderDiv(folderId: number): HTMLElement | null {
|
||||||
const foldersContainer = document.getElementById('folders-container');
|
const foldersContainer = document.getElementById('folders-container');
|
||||||
return foldersContainer?.querySelector(`.folder[data-folder-id="${folderId}"]`) as HTMLElement;
|
return foldersContainer?.querySelector(`.folder[data-folder-id="${folderId}"]`) as HTMLElement | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
addEventListeners(): void {
|
addRowEventListeners(): void {
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
const folderRows = this.elementRef.nativeElement.querySelectorAll('tr[data-folder-id]');
|
||||||
const folderLeft = document.getElementById('folderLeft');
|
folderRows.forEach(row => {
|
||||||
if (folderLeft) {
|
this.renderer.listen(row, 'dblclick', (event: Event) => {
|
||||||
const resizeHandle = folderLeft.querySelector('.resize-handle') as HTMLElement | null;
|
const target = event.currentTarget as HTMLTableRowElement;
|
||||||
if (resizeHandle) {
|
const folderId = Number(target.dataset.folderId);
|
||||||
let startX: number, startWidth: number;
|
this.confirmDisplayFolderContents(folderId);
|
||||||
|
});
|
||||||
resizeHandle.addEventListener('mousedown', (event: MouseEvent) => {
|
|
||||||
startX = event.clientX;
|
|
||||||
startWidth = parseInt(document.defaultView.getComputedStyle(folderLeft).width, 10);
|
|
||||||
|
|
||||||
document.addEventListener('mousemove', resizeWidth);
|
|
||||||
document.addEventListener('mouseup', stopResize);
|
|
||||||
});
|
|
||||||
|
|
||||||
const resizeWidth = (event: MouseEvent) => {
|
|
||||||
const newWidth = startWidth + (event.clientX - startX);
|
|
||||||
folderLeft.style.width = newWidth + 'px';
|
|
||||||
const folderRight = document.querySelector('.folder-right') as HTMLElement | null;
|
|
||||||
if (folderRight) {
|
|
||||||
folderRight.style.width = `calc(100% - ${newWidth}px)`;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const stopResize = () => {
|
|
||||||
document.removeEventListener('mousemove', resizeWidth);
|
|
||||||
document.removeEventListener('mouseup', stopResize);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle folder open/close toggle
|
|
||||||
const folderCha = document.querySelectorAll('.folder-cha');
|
|
||||||
if (folderCha.length > 0) {
|
|
||||||
folderCha.forEach(item => {
|
|
||||||
let isOpen = false; // Track whether folder is open or closed
|
|
||||||
const folderIcon = item.querySelector('.fa-folder');
|
|
||||||
const chevronIcon = item.querySelector('.fa-chevron-right') as HTMLElement;
|
|
||||||
const folder = item.closest('.folder');
|
|
||||||
const ke = folder.querySelector('.ke');
|
|
||||||
|
|
||||||
item.addEventListener('click', () => {
|
|
||||||
if (isOpen) {
|
|
||||||
const ke = folder.querySelector('.ke') as HTMLElement;
|
|
||||||
ke.style.display = 'none'; // Hide .ke when closing the folder
|
|
||||||
folderIcon.classList.remove('fa-folder-open' ) ;
|
|
||||||
folderIcon.classList.add('fa-folder');
|
|
||||||
chevronIcon.style.transform = ''; // Reset chevron rotation
|
|
||||||
} else {
|
|
||||||
const ke = folder.querySelector('.ke') as HTMLElement;
|
|
||||||
ke.style.display = 'block'; // Show .ke when opening the folder
|
|
||||||
folderIcon.classList.remove('fa-folder');
|
|
||||||
folderIcon.classList.add('fa-folder-open');
|
|
||||||
chevronIcon.style.transform = 'rotate(90deg)'; // Rotate chevron
|
|
||||||
}
|
|
||||||
|
|
||||||
isOpen = !isOpen; // Toggle isOpen state
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,7 +10,17 @@ export interface Folders extends MatchingModel {
|
|||||||
match: string;
|
match: string;
|
||||||
matching_algorithm: number;
|
matching_algorithm: number;
|
||||||
is_insensitive: boolean;
|
is_insensitive: boolean;
|
||||||
parent_folder_id: number | null;
|
parent_folder: number | null;
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
export interface Results{
|
||||||
|
id: number;
|
||||||
|
owner_id: number;
|
||||||
|
name: string;
|
||||||
|
match: string;
|
||||||
|
matching_algorithm: number;
|
||||||
|
is_insensitive: boolean;
|
||||||
|
parent_folder: number | null;
|
||||||
path: string;
|
path: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
|||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { AbstractNameFilterService } from './abstract-name-filter-service';
|
import { AbstractNameFilterService } from './abstract-name-filter-service';
|
||||||
import { Folders, Document } from 'src/app/data/folders';
|
import { Folders, Document,Results } from 'src/app/data/folders';
|
||||||
import { environment } from 'src/environments/environment';
|
import { environment } from 'src/environments/environment';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
@ -11,6 +11,10 @@ import { environment } from 'src/environments/environment';
|
|||||||
export class FoldersService extends AbstractNameFilterService<Folders> {
|
export class FoldersService extends AbstractNameFilterService<Folders> {
|
||||||
constructor(http: HttpClient) {
|
constructor(http: HttpClient) {
|
||||||
super(http, 'folders');
|
super(http, 'folders');
|
||||||
|
|
||||||
|
}
|
||||||
|
getResults(): Observable<{results: Results[]}> {
|
||||||
|
return this.http.get<{results: Results[]}>(`${environment.apiBaseUrl}folders/`);
|
||||||
}
|
}
|
||||||
|
|
||||||
getFoldersAndDocuments(): Observable<{ folders: Folders[], documents: Document[] }> {
|
getFoldersAndDocuments(): Observable<{ folders: Folders[], documents: Document[] }> {
|
||||||
|
339
src-ui/src/assets/css-folder/style.css
Normal file
339
src-ui/src/assets/css-folder/style.css
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
|
||||||
|
body {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.folder-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
z-index: 10000 !important;
|
||||||
|
}
|
||||||
|
.folder-container .folder-left {
|
||||||
|
width: 30%;
|
||||||
|
position: relative;
|
||||||
|
min-width: 100px;
|
||||||
|
height: 100vh;
|
||||||
|
overflow-x: auto;
|
||||||
|
overflow-y: auto;
|
||||||
|
background: rgba(37, 36, 36, 0.845);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.resize-handle {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
cursor: ew-resize;
|
||||||
|
width: 2px;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
.folder-container .folder-right {
|
||||||
|
width: 70%;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.folder-left-1 {
|
||||||
|
width: 100%;
|
||||||
|
height: 30px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.folder-left-search {
|
||||||
|
width: 85%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 10px;
|
||||||
|
box-shadow: 0 0 3px 0 gold;
|
||||||
|
}
|
||||||
|
.folder-left-search .serch {
|
||||||
|
width: 90%;
|
||||||
|
height: 100%;
|
||||||
|
border-left: none;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
border-bottom-right-radius: 5px;
|
||||||
|
}
|
||||||
|
.folder-left-search .serch:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.serch:focus + .folder-left-search {
|
||||||
|
border: 5px solid gold;
|
||||||
|
}
|
||||||
|
.folder-left-search .search {
|
||||||
|
width: 10%;
|
||||||
|
height: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
border-right: none;
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-bottom-left-radius: 5px;
|
||||||
|
}
|
||||||
|
.folder{
|
||||||
|
width: 95%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
#folders-container{
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.documents {
|
||||||
|
width: 95%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
.folder-cha{
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.folder-cha P{
|
||||||
|
color: #f0f0f0;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.folder-cha .fa-solid{
|
||||||
|
color: gold;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
.folder-cha .fa-chevron-right{
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
.folder-cha .fa-folder{
|
||||||
|
color: goldenrod;
|
||||||
|
}
|
||||||
|
.folder-con{
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.folder-con P{
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
.foder{
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
position: relative;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.folder-con .fa-solid{
|
||||||
|
color: gold;
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
.folder-con .fa-chevron-right{
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
.folder-con .fa-folder{
|
||||||
|
color: goldenrod;
|
||||||
|
}
|
||||||
|
#folders-container{
|
||||||
|
margin-left: -10%;
|
||||||
|
}
|
||||||
|
.docoment{
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.docomenta,
|
||||||
|
.document-container{
|
||||||
|
margin-left: 7%;
|
||||||
|
}
|
||||||
|
p{
|
||||||
|
color: aliceblue;
|
||||||
|
}
|
||||||
|
.folder {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder .ke {
|
||||||
|
background: #f0f0f0;
|
||||||
|
width: 1px;
|
||||||
|
height: 180%;
|
||||||
|
z-index: 10000;
|
||||||
|
position: absolute;
|
||||||
|
left: 8.5%;
|
||||||
|
top: 60%;
|
||||||
|
display: none;
|
||||||
|
transform: translateY(-15%);
|
||||||
|
}
|
||||||
|
.folder-search{
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.folder-right-tim{
|
||||||
|
width: 60%;
|
||||||
|
height: 40px;
|
||||||
|
background: rgba(128, 128, 128, 0.534);
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.folder-right-search{
|
||||||
|
width: 30%;
|
||||||
|
height: 40px;
|
||||||
|
background: rgba(128, 128, 128, 0.449);
|
||||||
|
border-radius: 5px;
|
||||||
|
margin-left: 50px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.folder-right-search button{
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 11px 15px;
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
.folder-right-search input{
|
||||||
|
border-left: none;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.folder-right-conten{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin: 20px 0;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
table td{
|
||||||
|
color: black;
|
||||||
|
border-left: 1px solid gray;
|
||||||
|
border-right: 1px solid gray;
|
||||||
|
}
|
||||||
|
table thead {
|
||||||
|
background-color: #007bff25;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
table thead tr {
|
||||||
|
border-bottom: 1px solid #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
table thead td {
|
||||||
|
padding: 12px 15px;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tbody tr {
|
||||||
|
border-bottom: 1px solid #dee2e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tbody tr:nth-of-type(even) {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tbody tr:hover {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tbody td {
|
||||||
|
padding: 12px 15px;
|
||||||
|
text-align: left;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
table tbody tr td .fa-folder{
|
||||||
|
color: gold;
|
||||||
|
}
|
||||||
|
table tbody tr td .fa-file{
|
||||||
|
color: rgb(79, 58, 16);
|
||||||
|
}
|
||||||
|
tbody td p{
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tbody td i {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table tbody td p {
|
||||||
|
display: inline;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.folder-cha:hover{
|
||||||
|
background: rgb(87, 87, 205);
|
||||||
|
}
|
||||||
|
.folder-right-tim {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.logo-folder,
|
||||||
|
.ten-folder{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.folder-right-tim .fa-folder{
|
||||||
|
color: gold;
|
||||||
|
margin-left: 2%;
|
||||||
|
}
|
||||||
|
.folder-right-tim .fa-chevron-right{
|
||||||
|
padding: 0 3px;
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
.logo-folder{
|
||||||
|
margin-left: 2%;
|
||||||
|
}
|
||||||
|
.ten-folder p{
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.sub-folder-container{
|
||||||
|
width: 40%;
|
||||||
|
height: 50px;
|
||||||
|
background: darkcyan;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 10000;
|
||||||
|
top: 0;
|
||||||
|
left: 30%;
|
||||||
|
}
|
||||||
|
.sub-folder-container form{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.sub-folder-container form input{
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 10px;
|
||||||
|
border: none;
|
||||||
|
border: 2px solid salmon;
|
||||||
|
}
|
||||||
|
.sub-folder-container form input:focus {
|
||||||
|
border-color: dodgerblue;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.addfolder{
|
||||||
|
position: absolute;
|
||||||
|
background: grey;
|
||||||
|
width: 200px;
|
||||||
|
height: auto;
|
||||||
|
z-index: 10000;
|
||||||
|
border: 1px solid black;
|
||||||
|
}
|
||||||
|
#contextMenu{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.addfolder ul li{
|
||||||
|
padding: 5px 5px;
|
||||||
|
list-style-type: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.addfolder ul li a{
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.addfolder ul li:hover{
|
||||||
|
background: burlywood;
|
||||||
|
}
|
||||||
|
.folder-right{
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
117
src-ui/src/assets/css-folder/zomm.js
Normal file
117
src-ui/src/assets/css-folder/zomm.js
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
var folderLeft = document.getElementById('folderLeft');
|
||||||
|
var folderright = document.getElementById('folderrightt');
|
||||||
|
var folderContainer = document.querySelector('.folder-container');
|
||||||
|
var zoom = document.getElementById("zoomImg");
|
||||||
|
var contextMenu = document.getElementById("contextMenu");
|
||||||
|
var toggleButton = document.getElementById("toggleButton");
|
||||||
|
|
||||||
|
var eventsEnabled = false;
|
||||||
|
|
||||||
|
|
||||||
|
var amButton = document.getElementById("am");
|
||||||
|
var subFolderContainer = document.querySelector('.sub-folder-container');
|
||||||
|
|
||||||
|
amButton.addEventListener("click", function() {
|
||||||
|
|
||||||
|
subFolderContainer.style.display = "block";
|
||||||
|
|
||||||
|
contextMenu.style.display = "none";
|
||||||
|
|
||||||
|
|
||||||
|
var inputInSubFolder = subFolderContainer.querySelector('input[type="text"]');
|
||||||
|
if (inputInSubFolder) {
|
||||||
|
inputInSubFolder.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var allInputs = document.querySelectorAll('input');
|
||||||
|
allInputs.forEach(function(input) {
|
||||||
|
if (input !== inputInSubFolder) {
|
||||||
|
input.blur();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
document.getElementById('sss').addEventListener('click', function() {
|
||||||
|
var contextMenu1 = document.querySelector('.sub-folder-container');
|
||||||
|
contextMenu1.style.display = 'none';
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
folderLeft.addEventListener('click', function() {
|
||||||
|
hideContextMenu();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
folderLeft.addEventListener('contextmenu', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
showContextMenu(event.clientX, event.clientY);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
folderright.addEventListener('contextmenu', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
showContextMenu(event.clientX, event.clientY);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
document.addEventListener('mousedown', function(event) {
|
||||||
|
var targetElement = event.target;
|
||||||
|
|
||||||
|
var clickedInsideContextMenu = contextMenu.contains(targetElement);
|
||||||
|
var clickedInsideFolderContainer = folderContainer.contains(targetElement);
|
||||||
|
var clickedInsideAddFolder = targetElement.classList.contains('addfolder') || targetElement.closest('.addfolder');
|
||||||
|
var clickedInsideAm = targetElement.id === 'am' || targetElement.closest('#am');
|
||||||
|
|
||||||
|
if (!clickedInsideContextMenu && !clickedInsideAddFolder && !clickedInsideAm) {
|
||||||
|
hideContextMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (clickedInsideAm) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
toggleButton.addEventListener("click", function() {
|
||||||
|
toggleEvents();
|
||||||
|
});
|
||||||
|
|
||||||
|
function showContextMenu(x, y) {
|
||||||
|
contextMenu.style.display = "block";
|
||||||
|
contextMenu.style.left = x + "px";
|
||||||
|
contextMenu.style.top = y + "px";
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideContextMenu() {
|
||||||
|
contextMenu.style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleEvents() {
|
||||||
|
eventsEnabled = !eventsEnabled;
|
||||||
|
if (eventsEnabled) {
|
||||||
|
zoom.addEventListener("contextmenu", handleContextMenu);
|
||||||
|
} else {
|
||||||
|
zoom.removeEventListener("contextmenu", handleContextMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleContextMenu(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
showContextMenu(e.clientX, e.clientY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
zoom.onmouseup = function () {
|
||||||
|
if (eventsEnabled) {
|
||||||
|
hideContextMenu();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
zoom.onmousemove = function (e) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
@ -9,6 +9,7 @@
|
|||||||
<meta name="theme-color" content="#17541f" />
|
<meta name="theme-color" content="#17541f" />
|
||||||
<link rel="manifest" href="manifest.webmanifest">
|
<link rel="manifest" href="manifest.webmanifest">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
|
||||||
|
<link rel="stylesheet" href="./assets/css-folder/style.css">
|
||||||
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
<link rel="apple-touch-icon" href="apple-touch-icon.png">
|
<link rel="apple-touch-icon" href="apple-touch-icon.png">
|
||||||
</head>
|
</head>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user