This commit is contained in:
Khaiyb949 2024-06-22 09:56:37 +07:00
parent 80f033ff18
commit aafaab0cb1
11 changed files with 589 additions and 404 deletions

View File

@ -117,13 +117,13 @@ export const routes: Routes = [
},
},
{
path: 'Viewallforder',
path: 'viewallfolder',
component: ViewallForderComponent,
canActivate: [PermissionsGuard],
data: {
requiredPermission: {
action: PermissionAction.View,
type: PermissionType.Viewallforder,
type: PermissionType.Viewallfolder,
},
},
},

View File

@ -340,6 +340,8 @@ import localeTr from '@angular/common/locales/tr'
import localeUk from '@angular/common/locales/uk'
import localeZh from '@angular/common/locales/zh'
import localeVi from '@angular/common/locales/vi'
import { CommonModule } from '@angular/common';
import { ViewallForderComponent } from './components/folder-management/viewall-forder/viewall-forder.component'
registerLocaleData(localeAf)
registerLocaleData(localeAr)
@ -382,6 +384,7 @@ function initializeApp(settings: SettingsService) {
@NgModule({
declarations: [
ViewallForderComponent,
AppComponent,
DocumentListComponent,
DocumentDetailComponent,
@ -493,6 +496,7 @@ function initializeApp(settings: SettingsService) {
DragDropModule,
NgxBootstrapIconsModule.pick(icons),
NgxFilesizeModule,
CommonModule,
],
providers: [
{

View File

@ -173,11 +173,11 @@
</h6>
<ul class="nav flex-column mb-2">
<li class="nav-item app-link"
*pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Viewallforder }">
<a class="nav-link" routerLink="Viewallforder" routerLinkActive="active" (click)="closeMenu()"
ngbPopover="viewallforder" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end"
*pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Viewallfolder }">
<a class="nav-link" routerLink="viewallfolder" routerLinkActive="active" (click)="closeMenu()"
ngbPopover="viewallfolder" i18n-ngbPopover [disablePopover]="!slimSidebarEnabled" placement="end"
container="body" triggers="mouseenter:mouseleave" popoverClass="popover-slim">
<i-bs class="me-1" name="Personal"></i-bs><span>&nbsp;<ng-container i18n>Personal document</ng-container></span>
<i class="fa-regular fa-folder-open"></i><span>&nbsp;<ng-container i18n>Personal document</ng-container></span>
</a>
</li>
<li class="nav-item app-link"

View File

@ -1,156 +1,68 @@
<div class="viewforder-header">
<div class="search-new">
<form class="myform" action="">
<button><i class="fa-solid fa-magnifying-glass"></i></button>
<input type="text" placeholder="Search">
</form>
<div class="add-viewforder">
<button class="addforder"><i class="fa-solid fa-folder-plus"></i> Tạo thư mục mới</button>
</div>
<div class="folder-container">
<div class="sub-folder-container">
</div>
<div class="titel">
<p>Show</p>
<select name="Show" id="showSelect">
<option value="16" >16</option>
<option value="36">36</option>
<option value="66">66</option>
</select>
<script>
document.addEventListener('DOMContentLoaded', function() {
const defaultOption = document.querySelector('#showSelect option[selected]');
if (defaultOption) {
defaultOption.textContent = 'Show ' + defaultOption.value;
}
});
</script>
<h1 style="margin-left: 10px;">Forder</h1>
</div>
<div class="conten">
<div *ngFor="let folder of folders" class="product-forder">
<i class="fa-solid fa-folder"></i>
<p>{{ folder.name }}</p>
<i class="fa-solid fa-ellipsis-vertical" onclick="toggleDropdown(this)"></i>
<div class="submenu">
<ul>
<li><a href="#">Delete</a></li>
<li><a href="#">Reaname</a></li>
</ul>
<div class="folder-left" id="folderLeft">
<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>
<script>
document.addEventListener('click', function(event) {
const submenus = document.querySelectorAll('.submenu');
const dropdownIcons = document.querySelectorAll('.fa-ellipsis-vertical');
for (let i = 0; i < submenus.length; i++) {
const submenu = submenus[i];
const dropdownIcon = dropdownIcons[i];
const isClickInside = dropdownIcon.contains(event.target);
if (!isClickInside) {
submenu.classList.remove('active');
}
}
});
function toggleDropdown(icon) {
const submenu = icon.nextElementSibling;
submenu.classList.toggle('active');
event.stopPropagation();
}
</script>
</div>
<div style="margin-top: 20px;" class="titel">
<p>Show</p>
<select name="Show" id="showSelect">
<option value="16" >16</option>
<option value="36">36</option>
<option value="66">66</option>
</select>
<script>
document.addEventListener('DOMContentLoaded', function() {
const defaultOption = document.querySelector('#showSelect option[selected]');
if (defaultOption) {
defaultOption.textContent = 'Show ' + defaultOption.value;
}
});
</script>
<h2 style="margin-left: 10px;">Documents</h2>
</div>
<div class="conten-tailieu">
<div style="display: none;" class="conten-tailieu-submenu">
<ul>
<li><a href="#"><i class="fa-solid fa-folder"></i></a></li>
<li><a href="#"><i class="fa-solid fa-trash"></i></a></li>
</ul>
<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">
<div class="folder-search">
<div class="folder-right-tim"></div>
<div class="folder-right-search">
<button> <i class="fa-solid fa-magnifying-glass"></i> </button>
<input type="text">
</div>
</div>
<div class="folder-right-conten">
<table>
<thead>
<tr>
<td>Name</td>
<td>Data modified</td>
<td>Type</td>
<td>Size</td>
</tr>
</thead>
<tbody>
<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>
<table id="myTable">
<thead>
<tr>
<th>Document name</th>
<th>Last modified <i class="fa-solid fa-caret-down"></i><i class="fa-solid fa-arrow-right-long"></i></th>
<th>File size</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let document of documents">
<td>{{ document.original_filename }}</td>
<td>{{ document.modified | date:'medium' }}</td>
<td>{{ calculateFileSize(document.archive_checksum) }}</td>
</tr>
</tbody>
</table>
<script>
document.addEventListener('DOMContentLoaded', function() {
const table = document.getElementById('myTable');
let selectedRows = [];
table.addEventListener('click', function(event) {
const target = event.target.closest('tr'); // Find closest parent <tr>
if (!target) return;
const isCtrlPressed = event.ctrlKey || event.metaKey; // Check if Ctrl or Cmd key is pressed
if (isCtrlPressed) {
if (selectedRows.includes(target)) {
// Deselect row
selectedRows = selectedRows.filter(row => row !== target);
target.classList.remove('selected');
} else {
// Select row
selectedRows.push(target);
target.classList.add('selected');
}
} else {
// Clear all selections
selectedRows.forEach(row => row.classList.remove('selected'));
selectedRows = [target];
target.classList.add('selected');
}
// Show or hide .conten-tailieu-submenu based on selection
const submenu = document.querySelector('.conten-tailieu-submenu');
if (selectedRows.length > 0) {
submenu.style.display = 'block';
} else {
submenu.style.display = 'none';
}
});
// Hide submenu if user clicks outside
document.addEventListener('click', function(event) {
if (!event.target.closest('.conten-tailieu-submenu') && !event.target.closest('table')) {
// Clear all selections and hide submenu
selectedRows.forEach(row => row.classList.remove('selected'));
selectedRows = [];
const submenu = document.querySelector('.conten-tailieu-submenu');
submenu.style.display = 'none';
}
});
});
</script>
</div>
</div>

View File

@ -1,224 +1,253 @@
.viewforder-header {
width: 100%;
}
.search-new {
width: 100%;
height: 100px;
margin: 5px;
display: flex;
align-items: center;
.myform {
margin-top: 10px;
height: 100%;
display: flex;
align-items: center;
button {
padding: 10px 15px;
cursor: pointer;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
&:active {
cursor: progress;
}
}
input {
padding: 10px 10px;
width: 400px;
margin-left: -6px;
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
}
}
.add-viewforder {
margin-top: 10px;
height: 100%;
display: flex;
align-items: center;
}
.viewforder-header .addforder {
padding: 10px 10px;
margin-left: 50px;
color: aliceblue;
background-color: rgb(236, 72, 72);
border: none;
border-radius: 5px;
cursor: pointer;
&:active {
cursor: progress;
}
}
.fa-folder-plus {
padding: 0 5px;
}
.conten {
width: 100%;
height: auto;
margin-top: 20px;
display: flex;
gap: 1em;
flex-wrap: wrap;
margin-left: 10px;
position: relative;
cursor: pointer;
.product-forder {
width: 200px;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 10px;
padding: 0 10px;
height: 50px;
cursor: pointer;
background-color: rgba(128, 128, 128, 0.585);
p {
margin-left: -40%;
}
&:active {
cursor: progress;
}
}
.fa-ellipsis-vertical {
cursor: wait;
padding: 3px 3px;
}
.submenu {
position: absolute;
width: 100px;
height: auto;
margin-left: 190px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
overflow: hidden;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s, transform 0.3s;
transform: translateY(-100%);
ul li {
list-style-type: none;
padding: 5px 5px;
border: 1px solid gray;
background-color: rgba(0, 0, 0, 0.804);
a {
color: aliceblue;
text-decoration: none;
&:hover {
border-bottom: 1px solid white;
}
}
}
&.active {
opacity: 1;
visibility: visible;
transform: translateY(0%);
}
.product-forder & {
transform-origin: top;
}
.product-forder ul {
transform-origin: bottom;
}
}
}
.titel {
display: flex;
align-items: center;
}
#showSelect {
padding: 5px 5px;
}
.conten-tailieu{
width: 100%;
margin-top: 10px;
height: auto;
background-color: rgb(204, 202, 202);
body {
width: 100%;
height: 100%;
overflow: hidden;
}
.conten-tailieu {
width: 100%;
table {
width: 100%;
border-collapse: collapse;
th, td {
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
position: relative;
}
td:first-child {
width: 50%;
}
td:nth-child(2),
td:nth-child(3) {
text-align: right;
}
th:nth-child(2),
th:nth-child(3) {
text-align: center;
}
tbody th:nth-child(2),
tbody th:nth-child(3),
tbody td:nth-child(2),
tbody td:nth-child(3) {
text-align: center;
}
}
.folder-container {
width: 100%;
height: 100%;
display: flex;
}
.selected {
background-color: lightblue;
.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;
}
.fa-arrow-right-long {
display: inline-block;
transform: rotate(90deg);
.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;
padding: 0 15px;
text-align: left;
}
.conten-tailieu-submenu{
position: fixed;
display: none;
z-index: 10000;
right: 0;
top: 40%;
width: 40px;
height: auto;
background-color: white;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 1px 0px 1px 1px black;
.folder-con P{
color: #f0f0f0;
}
.conten-tailieu-submenu ul li{
list-style-type: none;
.foder{
width: 100%;
height: auto;
position: relative;
text-align: left;
}
.conten-tailieu-submenu .fa-solid{
padding: 5px 12px;
font-size: 18px;
.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;
}
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;
}
tbody td p{
color: black;
}
table tbody td i {
margin-right: 8px;
}
table tbody td p {
display: inline;
margin: 0;
}

View File

@ -1,26 +1,230 @@
import { Component } from '@angular/core';
import { Component, OnInit } from '@angular/core';
import { FoldersService } from 'src/app/services/rest/folders.service';
import { Document, Folders } from 'src/app/data/folders';
@Component({
selector: 'pngx-viewall-forder',
standalone: true,
imports: [],
selector: 'app-view-all-folder',
templateUrl: './viewall-forder.component.html',
styleUrl: './viewall-forder.component.scss'
styleUrls: ['./viewall-forder.component.scss']
})
export class ViewallForderComponent {
folders: any[] = [];
documents: any[] = [];
export class ViewAllFolderComponent implements OnInit {
folders: Folders[] = [];
documents: Document[] = [];
constructor(private foldersService: FoldersService) { }
constructor(private foldersService: FoldersService) {}
ngOnInit(): void {
this.foldersService.getFoldersAndDocuments().subscribe(data => {
this.folders = data.folders;
this.documents = data.documents;
this.foldersService.getFoldersAndDocuments().subscribe({
next: data => {
this.folders = data.folders;
this.documents = data.documents;
this.initializeFolders();
this.initializeDocuments();
this.addEventListeners();
},
error: error => {
console.error('Error fetching data:', error);
// Xử lý lỗi theo yêu cầu của bạn
}
});
}
calculateFileSize(checksum: string): string {
return checksum.length.toString() + ' bytes';
initializeFolders(): void {
const foldersContainer = document.getElementById('folders-container');
if (foldersContainer) {
foldersContainer.innerHTML = '';
const createFolders = (parentId: number | null, parentDiv: HTMLElement | null) => {
this.folders.forEach(folder => {
if (folder.parent_folder_id === parentId) {
const folderHTML = this.createFolderHTML(folder, parentDiv);
createFolders(folder.id, folderHTML.querySelector('.children-container') as HTMLElement);
}
});
};
this.folders.forEach(folder => {
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 {
const documentsContainer = document.getElementById('documents-container');
const foldersContainer = document.getElementById('folders-container');
if (documentsContainer && foldersContainer) {
documentsContainer.innerHTML = '';
const addedDocumentFilenames = new Set<string>();
this.documents.forEach(doc => {
if (!addedDocumentFilenames.has(doc.filename)) {
const folder = this.findFolderById(doc.folder_id);
if (folder && folder.id === 71) {
const folderDiv = this.findFolderDiv(folder.id);
if (folderDiv) {
const documentsContainerInFolder = folderDiv.querySelector('.documents-container');
if (documentsContainerInFolder) {
if (!documentsContainerInFolder.querySelector(`.document[data-document-id="${doc.id}"]`)) {
const documentHTML = this.createDocumentHTML(doc);
documentsContainerInFolder.appendChild(documentHTML);
addedDocumentFilenames.add(doc.filename);
}
}
}
} else {
if (!documentsContainer.querySelector(`.document[data-document-id="${doc.id}"]`)) {
const documentHTML = this.createDocumentHTML(doc);
documentsContainer.appendChild(documentHTML);
addedDocumentFilenames.add(doc.filename);
}
}
}
});
}
}
createFolderHTML(folder: Folders, parentDiv: HTMLElement | null = null): HTMLElement {
const folderDiv = document.createElement('div');
folderDiv.classList.add('folder');
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');
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);
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;
}
hasParentFolder(folderId: number): boolean {
return this.folders.some(folder => folder.parent_folder_id === folderId);
}
findFolderById(folderId: number | null): 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;
}
addEventListeners(): void {
document.addEventListener('DOMContentLoaded', () => {
const folderLeft = document.getElementById('folderLeft');
if (folderLeft) {
const resizeHandle = folderLeft.querySelector('.resize-handle') as HTMLElement | null;
if (resizeHandle) {
let startX: number, startWidth: number;
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
});
});
}
});
}
}

View File

@ -1,10 +1,38 @@
import { MatchingModel } from './matching-model'
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { MatchingModel } from './matching-model';
export interface folders extends MatchingModel {
type?: string
parent_warehouse?: number
path?: string
export interface Folders extends MatchingModel {
id: number;
owner_id: number;
name: string;
match: string;
matching_algorithm: number;
is_insensitive: boolean;
parent_folder_id: number | null;
path: string;
}
export interface Document {
id: number;
owner_id: number;
correspondent_id: number | null;
storage_path_id: number | null;
folder_id: number | null;
warehouse_id: number | null;
title: string;
document_type_id: number | null;
content: string;
mime_type: string;
checksum: string;
archive_checksum: string;
created: string;
modified: string;
storage_type: string;
added: string;
filename: string;
archive_filename: string;
original_filename: string;
archive_serial_number: number | null;
}

View File

@ -14,7 +14,7 @@ export enum PermissionType {
Tag = '%s_tag',
Warehouse = '%s_warehouse',
Correspondent = '%s_correspondent',
Viewallforder = '%s_viewallforder',
Viewallfolder = '%s_viewallfolder',
DocumentType = '%s_documenttype',
StoragePath = '%s_storagepath',
SavedView = '%s_savedview',

View File

@ -1,14 +1,19 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Warehouse } from 'src/app/data/warehouse'
import { AbstractNameFilterService } from './abstract-name-filter-service';
import { Folders, Document } from 'src/app/data/folders';
import { environment } from 'src/environments/environment';
@Injectable({
providedIn: 'root'
})
export class FoldersService extends AbstractNameFilterService<folders> {
export class FoldersService extends AbstractNameFilterService<Folders> {
constructor(http: HttpClient) {
super(http, 'folders')
super(http, 'folders');
}
getFoldersAndDocuments(): Observable<{ folders: Folders[], documents: Document[] }> {
return this.http.get<{ folders: Folders[], documents: Document[] }>(`${environment.apiBaseUrl}folders/folders_documents/`);
}
}

View File

@ -8,6 +8,7 @@
<meta name="color-scheme" content="dark light">
<meta name="theme-color" content="#17541f" />
<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="icon" type="image/x-icon" href="favicon.ico">
<link rel="apple-touch-icon" href="apple-touch-icon.png">
</head>

View File

@ -2069,10 +2069,11 @@ class FolderViewSet(ModelViewSet, PermissionsAwareDocumentCountMixin):
def getFolderDoc(self, request):
currentUser = request.user
documents = list(Document.objects.filter(folder=None, owner=currentUser).order_by("-created").values())
folders = list(Folder.objects.filter(parent_folder=None, owner=currentUser).order_by("name").values())
folders = list(Folder.objects.filter(parent_folder=None, owner=currentUser).order_by("name"))
folders_serialisers = FolderSerializer(folders, many = True)
return {
"documents": documents,
"folders": folders,
"folders": folders_serialisers.data,
}
@action(methods=["get"], detail=False)
@ -2089,12 +2090,13 @@ class FolderViewSet(ModelViewSet, PermissionsAwareDocumentCountMixin):
def getFolderDocById(self, fol):
documents = list(Document.objects.filter(folder=fol).order_by("-created").values())
child_folders = list(Folder.objects.filter(parent_folder=fol).order_by("name").values())
currentUser = self.request.user
documents = list(Document.objects.filter(folder=fol, owner=currentUser).order_by("-created").values())
child_folders = list(Folder.objects.filter(parent_folder=fol, owner=currentUser).order_by("name"))
folders_serialisers = FolderSerializer(child_folders, many=True)
return {
"documents": documents,
"folders": child_folders,
"folders": folders_serialisers.data,
}
@action(methods=["get"], detail=True)