mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	Merge pull request #240 from shamoon/feature/updated-nav-bar
Feature: updated main navbar
This commit is contained in:
		| @@ -9,8 +9,8 @@ import { AppViewService } from './services/app-view.service'; | ||||
| export class AppComponent { | ||||
|  | ||||
|   constructor (appViewService: AppViewService) { | ||||
|     appViewService.updateDarkModeSettings() | ||||
|     (window as any).pdfWorkerSrc = '/assets/js/pdf.worker.min.js'; | ||||
|     appViewService.updateDarkModeSettings() | ||||
|   } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,19 +1,52 @@ | ||||
| <nav class="navbar navbar-dark sticky-top bg-primary flex-md-nowrap p-0 shadow"> | ||||
|   <a class="navbar-brand col-md-3 col-lg-2 mr-0 px-3" routerLink="/dashboard"> | ||||
|     <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 198.43 238.91" width="16px" class="mr-2" fill="currentColor"> | ||||
|       <path d="M194.7,0C164.22,70.94,17.64,79.74,64.55,194.06c.58,1.47-10.85,17-18.47,29.9-1.76-6.45-3.81-13.48-3.52-14.07,38.11-45.14-27.26-70.65-30.78-107.58C-4.64,131.62-10.5,182.92,39,212.53c.3,0,2.64,11.14,3.81,16.71a58.55,58.55,0,0,0-2.93,6.45c-1.17,2.93,7.62,2.64,7.62,3.22.88-.29,21.7-36.93,22.28-37.23C187.67,174.72,208.48,68.6,194.7,0ZM134.61,74.75C79.5,124,70.12,160.64,71.88,178.53,53.41,134.85,107.64,86.77,134.61,74.75ZM28.2,145.11c10.55,9.67,28.14,39.28,13.19,56.57C44.91,193.77,46.08,175.89,28.2,145.11Z" transform="translate(0 0)"/> | ||||
|     </svg> | ||||
|     <ng-container i18n="app title">Paperless-ng</ng-container> | ||||
|   </a> | ||||
|   <button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-toggle="collapse" | ||||
|   <button class="navbar-toggler d-md-none collapsed border-0" type="button" data-toggle="collapse" | ||||
|     data-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation" | ||||
|     (click)="isMenuCollapsed = !isMenuCollapsed"> | ||||
|     <span class="navbar-toggler-icon"></span> | ||||
|   </button> | ||||
|   <form (ngSubmit)="search()" class="w-100 m-1"> | ||||
|     <input class="form-control form-control-dark" type="text" placeholder="Search for documents" aria-label="Search" | ||||
|       [formControl]="searchField" [ngbTypeahead]="searchAutoComplete" (selectItem)="itemSelected($event)" i18n-placeholder> | ||||
|   </form> | ||||
|   <a class="navbar-brand col-auto col-md-3 col-lg-2 mr-0 px-3 py-3 order-sm-0" routerLink="/dashboard"> | ||||
|     <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 198.43 238.91" width="1rem" class="mr-2" fill="currentColor"> | ||||
|       <path d="M194.7,0C164.22,70.94,17.64,79.74,64.55,194.06c.58,1.47-10.85,17-18.47,29.9-1.76-6.45-3.81-13.48-3.52-14.07,38.11-45.14-27.26-70.65-30.78-107.58C-4.64,131.62-10.5,182.92,39,212.53c.3,0,2.64,11.14,3.81,16.71a58.55,58.55,0,0,0-2.93,6.45c-1.17,2.93,7.62,2.64,7.62,3.22.88-.29,21.7-36.93,22.28-37.23C187.67,174.72,208.48,68.6,194.7,0ZM134.61,74.75C79.5,124,70.12,160.64,71.88,178.53,53.41,134.85,107.64,86.77,134.61,74.75ZM28.2,145.11c10.55,9.67,28.14,39.28,13.19,56.57C44.91,193.77,46.08,175.89,28.2,145.11Z" transform="translate(0 0)"/> | ||||
|     </svg> | ||||
|     <ng-container i18n="app title">Paperless-ng</ng-container> | ||||
|   </a> | ||||
|   <div class="search-form-container flex-grow-1 py-2 pb-3 pb-sm-2 px-3 pl-md-4 mr-sm-auto order-3 order-sm-1"> | ||||
|     <form (ngSubmit)="search()" class="form-inline flex-grow-1"> | ||||
|       <input class="form-control form-control-sm" type="text" placeholder="Search documents" aria-label="Search" | ||||
|         [formControl]="searchField" [ngbTypeahead]="searchAutoComplete" (selectItem)="itemSelected($event)" i18n-placeholder> | ||||
|       <svg width="1em" height="1em"> | ||||
|         <use xlink:href="assets/bootstrap-icons.svg#search"/> | ||||
|       </svg> | ||||
|     </form> | ||||
|   </div> | ||||
|   <ul ngbNav class="order-sm-3"> | ||||
|     <li ngbDropdown class="nav-item dropdown"> | ||||
|       <button class="btn text-light" id="userDropdown" ngbDropdownToggle> | ||||
|         <span *ngIf="displayName" class="navbar-text small mr-2 text-light d-none d-sm-inline"> | ||||
|           {{displayName}} | ||||
|         </span> | ||||
|         <svg width="1.3em" height="1.3em"> | ||||
|           <use xlink:href="assets/bootstrap-icons.svg#person-circle"/> | ||||
|         </svg> | ||||
|       </button> | ||||
|       <div ngbDropdownMenu class="dropdown-menu-right shadow mr-2" aria-labelledby="userDropdown"> | ||||
|         <div *ngIf="displayName" class="d-sm-none"> | ||||
|           <p class="small mb-0 px-3" i18n>Logged in as {{displayName}}</p> | ||||
|           <div class="dropdown-divider"></div> | ||||
|         </div> | ||||
|         <a ngbDropdownItem class="nav-link" routerLink="settings" routerLinkActive="active" (click)="closeMenu()"> | ||||
|           <svg class="sidebaricon mr-2" fill="currentColor"> | ||||
|             <use xlink:href="assets/bootstrap-icons.svg#gear"/> | ||||
|           </svg><ng-container i18n>Settings</ng-container> | ||||
|         </a> | ||||
|         <a ngbDropdownItem class="nav-link" href="accounts/logout/"> | ||||
|           <svg class="sidebaricon mr-2" fill="currentColor"> | ||||
|             <use xlink:href="assets/bootstrap-icons.svg#door-open"/> | ||||
|           </svg><ng-container i18n>Logout</ng-container> | ||||
|         </a> | ||||
|       </div> | ||||
|     </li> | ||||
|   </ul> | ||||
| </nav> | ||||
|  | ||||
| <div class="container-fluid"> | ||||
| @@ -107,13 +140,6 @@ | ||||
|               </svg> <ng-container i18n>Logs</ng-container> | ||||
|             </a> | ||||
|           </li> | ||||
|           <li class="nav-item"> | ||||
|             <a class="nav-link" routerLink="settings" routerLinkActive="active" (click)="closeMenu()"> | ||||
|               <svg class="sidebaricon" fill="currentColor"> | ||||
|                 <use xlink:href="assets/bootstrap-icons.svg#gear"/> | ||||
|               </svg> <ng-container i18n>Settings</ng-container> | ||||
|             </a> | ||||
|           </li> | ||||
|           <li class="nav-item"> | ||||
|             <a class="nav-link" href="admin/"> | ||||
|               <svg class="sidebaricon" fill="currentColor"> | ||||
| @@ -141,13 +167,6 @@ | ||||
|               </svg> <ng-container i18n>GitHub</ng-container> | ||||
|             </a> | ||||
|           </li> | ||||
|           <li class="nav-item"> | ||||
|             <a class="nav-link" href="accounts/logout/"> | ||||
|               <svg class="sidebaricon" fill="currentColor"> | ||||
|                 <use xlink:href="assets/bootstrap-icons.svg#door-open"/> | ||||
|               </svg> <ng-container i18n>Logout</ng-container> | ||||
|             </a> | ||||
|           </li> | ||||
|         </ul> | ||||
|       </div> | ||||
|     </nav> | ||||
|   | ||||
| @@ -1,36 +1,30 @@ | ||||
|  | ||||
| @import "/src/theme"; | ||||
|  | ||||
|   /* | ||||
| /* | ||||
|  * Sidebar | ||||
|  */ | ||||
|  | ||||
|  .sidebar { | ||||
| .sidebar { | ||||
|   position: fixed; | ||||
|   top: 0; | ||||
|   bottom: 0; | ||||
|   left: 0; | ||||
|   z-index: 100; /* Behind the navbar */ | ||||
|   padding: 48px 0 0; /* Height of navbar */ | ||||
|   padding: 50px 0 0; /* Height of navbar */ | ||||
|   box-shadow: inset -1px 0 0 rgba(0, 0, 0, .1); | ||||
| } | ||||
|  | ||||
| @media (max-width: 767.98px) { | ||||
|   .sidebar { | ||||
|     top: 3rem; | ||||
|     top: 3.5rem; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .sidebar-sticky { | ||||
|   position: relative; | ||||
|   top: 0; | ||||
|   /* height: calc(100vh - 48px); */ | ||||
|   height: 100%; | ||||
|   padding-top: .5rem; | ||||
|   padding-top: 0.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; | ||||
| @@ -53,36 +47,85 @@ | ||||
|   font-weight: bold; | ||||
| } | ||||
|  | ||||
| .sidebar .nav-link:hover .sidebaricon, | ||||
| .sidebar .nav-link.active .sidebaricon { | ||||
| .sidebar .nav-link.active .sidebaricon, | ||||
| .sidebar .nav-link:hover .sidebaricon { | ||||
|   color: inherit; | ||||
| } | ||||
|  | ||||
| .sidebar-heading { | ||||
|   font-size: .75rem; | ||||
|   font-size: 0.75rem; | ||||
|   text-transform: uppercase; | ||||
| } | ||||
|  | ||||
|  | ||||
| /* | ||||
|  * Navbar | ||||
|  */ | ||||
|  | ||||
|  .navbar-brand { | ||||
|   padding-top: .75rem; | ||||
|   padding-bottom: .75rem; | ||||
| .navbar-brand { | ||||
|   padding-top: 0.75rem; | ||||
|   padding-bottom: 0.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; | ||||
| .dropdown.show .dropdown-toggle, | ||||
| .dropdown-toggle:hover { | ||||
|   opacity: 0.7; | ||||
| } | ||||
|  | ||||
| .navbar .form-control { | ||||
|   padding: .75rem 1rem; | ||||
|   border-width: 0; | ||||
|   border-radius: 0; | ||||
| .dropdown-toggle::after { | ||||
|   margin-left: 0.4em; | ||||
|   vertical-align: 0.155em; | ||||
| } | ||||
|  | ||||
| .navbar .dropdown-menu { | ||||
|   font-size: 0.875rem; // body size | ||||
|  | ||||
|   a svg { | ||||
|     opacity: 0.6; | ||||
|   } | ||||
| } | ||||
|  | ||||
| .navbar .search-form-container { | ||||
|   max-width: 550px; | ||||
|  | ||||
|   form { | ||||
|     position: relative; | ||||
|   } | ||||
|  | ||||
|   svg { | ||||
|     position: absolute; | ||||
|     left: 0.6rem; | ||||
|     color: rgba(255, 255, 255, 0.6); | ||||
|   } | ||||
|  | ||||
|   &:focus-within { | ||||
|     svg { | ||||
|       display: none; | ||||
|     } | ||||
|  | ||||
|     .form-control::placeholder { | ||||
|       color: rgba(255, 255, 255, 0); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .form-control { | ||||
|     color: rgba(255, 255, 255, 0.3); | ||||
|     background-color: rgba(0, 0, 0, 0.15); | ||||
|     padding-left: 1.8rem; | ||||
|     border-color: rgba(255, 255, 255, 0.2); | ||||
|     transition: flex 0.3s ease; | ||||
|     max-width: 600px; | ||||
|     min-width: 300px; // 1/2 max | ||||
|  | ||||
|     &::placeholder { | ||||
|       color: rgba(255, 255, 255, 0.4); | ||||
|     } | ||||
|  | ||||
|     &:focus { | ||||
|       background-color: #fff; | ||||
|       color: #212529; | ||||
|       flex-grow: 1; | ||||
|       padding-left: 0.5rem; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -9,7 +9,8 @@ import { SavedViewService } from 'src/app/services/rest/saved-view.service'; | ||||
| import { SearchService } from 'src/app/services/rest/search.service'; | ||||
| import { environment } from 'src/environments/environment'; | ||||
| import { DocumentDetailComponent } from '../document-detail/document-detail.component'; | ||||
|    | ||||
| import { Meta } from '@angular/platform-browser'; | ||||
|  | ||||
| @Component({ | ||||
|   selector: 'app-app-frame', | ||||
|   templateUrl: './app-frame.component.html', | ||||
| @@ -22,8 +23,11 @@ export class AppFrameComponent implements OnInit, OnDestroy { | ||||
|     private activatedRoute: ActivatedRoute, | ||||
|     private openDocumentsService: OpenDocumentsService, | ||||
|     private searchService: SearchService, | ||||
|     public savedViewService: SavedViewService | ||||
|     public savedViewService: SavedViewService, | ||||
|     private meta: Meta | ||||
|     ) { | ||||
|       console.log(meta); | ||||
|  | ||||
|   } | ||||
|  | ||||
|   versionString = `${environment.appTitle} ${environment.version}` | ||||
| @@ -55,7 +59,7 @@ export class AppFrameComponent implements OnInit, OnDestroy { | ||||
|         term.length < 2 ? from([[]]) : this.searchService.autocomplete(term) | ||||
|       ) | ||||
|     ) | ||||
|    | ||||
|  | ||||
|   itemSelected(event) { | ||||
|     event.preventDefault() | ||||
|     let currentSearch: string = this.searchField.value | ||||
| @@ -98,4 +102,17 @@ export class AppFrameComponent implements OnInit, OnDestroy { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   get displayName() { | ||||
|     // TODO: taken from dashboard component, is this the best way to pass around username? | ||||
|     let tagFullName = this.meta.getTag('name=full_name') | ||||
|     let tagUsername = this.meta.getTag('name=username') | ||||
|     if (tagFullName && tagFullName.content) { | ||||
|       return tagFullName.content | ||||
|     } else if (tagUsername && tagUsername.content) { | ||||
|       return tagUsername.content | ||||
|     } else { | ||||
|       return null | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,7 @@ | ||||
| table { | ||||
|   overflow-wrap: anywhere; | ||||
| } | ||||
|  | ||||
| th:first-child { | ||||
|   min-width: 5rem; | ||||
| } | ||||
|   | ||||
| @@ -18,7 +18,7 @@ export class AppViewService { | ||||
|     this.updateDarkModeSettings() | ||||
|   } | ||||
|  | ||||
|   updateDarkModeSettings() { | ||||
|   updateDarkModeSettings(): void { | ||||
|     let darkModeUseSystem = this.settings.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM) | ||||
|     let darkModeEnabled = this.settings.get(SETTINGS_KEYS.DARK_MODE_ENABLED) | ||||
|  | ||||
|   | ||||
| @@ -36,6 +36,10 @@ $border-color-dark-mode: #47494f; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .text-light { | ||||
|     color: $text-color-dark-mode !important; | ||||
|   } | ||||
|  | ||||
|   .border { | ||||
|     border-color: $border-color-dark-mode !important; | ||||
|   } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jonas Winkler
					Jonas Winkler