mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
added paperless ui
This commit is contained in:
84
src-ui/src/app/components/app-frame/app-frame.component.css
Normal file
84
src-ui/src/app/components/app-frame/app-frame.component.css
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
/*
|
||||
* Sidebar
|
||||
*/
|
||||
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 100; /* Behind the navbar */
|
||||
padding: 48px 0 0; /* Height of navbar */
|
||||
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1);
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.sidebar {
|
||||
top: 5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar-sticky {
|
||||
position: relative;
|
||||
top: 0;
|
||||
height: calc(100vh - 48px);
|
||||
padding-top: .5rem;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto; /* Scrollable contents if viewport is shorter than content. */
|
||||
}
|
||||
|
||||
@supports ((position: -webkit-sticky) or (position: sticky)) {
|
||||
.sidebar-sticky {
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar .nav-link {
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.sidebar .nav-link .sidebaricon {
|
||||
margin-right: 4px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.sidebar .nav-link.active {
|
||||
color: #007bff;
|
||||
}
|
||||
|
||||
.sidebar .nav-link:hover .sidebaricon,
|
||||
.sidebar .nav-link.active .sidebaricon {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.sidebar-heading {
|
||||
font-size: .75rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Navbar
|
||||
*/
|
||||
|
||||
.navbar-brand {
|
||||
padding-top: .75rem;
|
||||
padding-bottom: .75rem;
|
||||
font-size: 1rem;
|
||||
background-color: rgba(0, 0, 0, .25);
|
||||
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25);
|
||||
}
|
||||
|
||||
.navbar .navbar-toggler {
|
||||
top: .25rem;
|
||||
right: 1rem;
|
||||
}
|
||||
|
||||
.navbar .form-control {
|
||||
padding: .75rem 1rem;
|
||||
border-width: 0;
|
||||
border-radius: 0;
|
||||
}
|
112
src-ui/src/app/components/app-frame/app-frame.component.html
Normal file
112
src-ui/src/app/components/app-frame/app-frame.component.html
Normal file
@@ -0,0 +1,112 @@
|
||||
<nav class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
|
||||
<span class="navbar-brand col-md-3 col-lg-2 mr-0 px-3" href="#">Paperless</span>
|
||||
<button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-toggle="collapse"
|
||||
data-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<form (ngSubmit)="search()" class="w-100">
|
||||
<input class="form-control form-control-dark" type="text" placeholder="Search" aria-label="Search"
|
||||
[formControl]="searchField">
|
||||
</form>
|
||||
<ul class="navbar-nav px-3">
|
||||
<li class="nav-item text-nowrap">
|
||||
<a class="nav-link" (click)="logout()" style="cursor: pointer;">
|
||||
<svg class="buttonicon" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#door-closed"/>
|
||||
</svg>
|
||||
Logout
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<nav id="sidebarMenu" class="col-md-3 col-lg-2 d-md-block bg-light sidebar collapse">
|
||||
<div class="sidebar-sticky pt-3">
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="dashboard" routerLinkActive="active">
|
||||
<svg class="sidebaricon" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#house"/>
|
||||
</svg>
|
||||
Dashboard
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="documents" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">
|
||||
<svg class="sidebaricon" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#files"/>
|
||||
</svg>
|
||||
Documents
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted" *ngIf='openDocuments.length > 0'>
|
||||
<span>Open documents</span>
|
||||
</h6>
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item" *ngFor='let d of openDocuments'>
|
||||
<a class="nav-link" routerLink="documents/{{d.id}}" routerLinkActive="active">
|
||||
<svg class="sidebaricon" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#file-text"/>
|
||||
</svg>
|
||||
{{d.title}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
|
||||
<span>Manage</span>
|
||||
</h6>
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="correspondents" routerLinkActive="active">
|
||||
<svg class="sidebaricon" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#person"/>
|
||||
</svg>
|
||||
Correspondents
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="tags" routerLinkActive="active">
|
||||
<svg class="sidebaricon" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#tags"/>
|
||||
</svg>
|
||||
Tags
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="documenttypes" routerLinkActive="active">
|
||||
<svg class="sidebaricon" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#hash"/>
|
||||
</svg>
|
||||
Document types
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="logs" routerLinkActive="active">
|
||||
<svg class="sidebaricon" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#text-left"/>
|
||||
</svg>
|
||||
Logs
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" routerLink="settings" routerLinkActive="active">
|
||||
<svg class="sidebaricon" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#gear"/>
|
||||
</svg>
|
||||
Settings
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<main role="main" class="col-md-9 ml-sm-auto col-lg-10 px-md-4">
|
||||
<router-outlet></router-outlet>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AppFrameComponent } from './app-frame.component';
|
||||
|
||||
describe('AppFrameComponent', () => {
|
||||
let component: AppFrameComponent;
|
||||
let fixture: ComponentFixture<AppFrameComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ AppFrameComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AppFrameComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
41
src-ui/src/app/components/app-frame/app-frame.component.ts
Normal file
41
src-ui/src/app/components/app-frame/app-frame.component.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { Router } from '@angular/router';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document';
|
||||
import { AuthService } from 'src/app/services/auth.service';
|
||||
import { OpenDocumentsService } from 'src/app/services/open-documents.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-app-frame',
|
||||
templateUrl: './app-frame.component.html',
|
||||
styleUrls: ['./app-frame.component.css']
|
||||
})
|
||||
export class AppFrameComponent implements OnInit, OnDestroy {
|
||||
|
||||
constructor (public router: Router, private openDocumentsService: OpenDocumentsService, private authService: AuthService) {
|
||||
}
|
||||
|
||||
searchField = new FormControl('')
|
||||
|
||||
openDocuments: PaperlessDocument[] = []
|
||||
|
||||
openDocumentsSubscription: Subscription
|
||||
|
||||
search() {
|
||||
this.router.navigate(['search'], {queryParams: {query: this.searchField.value}})
|
||||
}
|
||||
|
||||
logout() {
|
||||
this.authService.logout()
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.openDocumentsSubscription = this.openDocumentsService.getOpenDocuments().subscribe(docs => this.openDocuments = docs)
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.openDocumentsSubscription.unsubscribe()
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user