mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-10-30 03:56:23 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			364 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			364 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
| <pngx-page-header
 | |
|   title="Settings"
 | |
|   i18n-title
 | |
|   info="Options to customize appearance, notifications and more. Settings apply to the <strong>current user only</strong>."
 | |
|   i18n-info
 | |
|   >
 | |
|   <button class="btn btn-sm btn-outline-primary" (click)="tourService.start()">
 | |
|     <i-bs class="me-1" name="airplane"></i-bs> <ng-container i18n>Start tour</ng-container>
 | |
|   </button>
 | |
|   @if (permissionsService.isAdmin()) {
 | |
|     <button class="btn btn-sm btn-outline-primary position-relative ms-md-5 me-1" (click)="showSystemStatus()"
 | |
|       [disabled]="!systemStatus">
 | |
|       @if (!systemStatus) {
 | |
|         <div class="spinner-border spinner-border-sm me-1 h-75" role="status"></div>
 | |
|       } @else {
 | |
|         <i-bs class="me-2" name="card-checklist"></i-bs>
 | |
|         @if (systemStatusHasErrors) {
 | |
|           <span class="badge bg-body position-absolute top-0 start-100 translate-middle rounded-pill p-0">
 | |
|             <i-bs name="exclamation-circle-fill" class="text-danger" width="1.75em" height="1.75em"></i-bs>
 | |
|           </span>
 | |
|         } @else {
 | |
|           <span class="badge bg-body position-absolute top-0 start-100 translate-middle rounded-pill p-0">
 | |
|             <i-bs name="check-circle-fill" class="text-primary" width="1.75em" height="1.75em"></i-bs>
 | |
|           </span>
 | |
|         }
 | |
|       }
 | |
|       <ng-container i18n>System Status</ng-container>
 | |
|     </button>
 | |
|     <a class="btn btn-sm btn-primary" href="admin/" target="_blank">
 | |
|       <ng-container i18n>Open Django Admin</ng-container>
 | |
|        <i-bs name="arrow-up-right"></i-bs>
 | |
|     </a>
 | |
|   }
 | |
| </pngx-page-header>
 | |
| 
 | |
| <form [formGroup]="settingsForm" (ngSubmit)="saveSettings()">
 | |
| 
 | |
|   <ul ngbNav #nav="ngbNav" (navChange)="onNavChange($event)" [(activeId)]="activeNavID" class="nav-tabs">
 | |
|     <li [ngbNavItem]="SettingsNavIDs.General">
 | |
|       <a ngbNavLink i18n>General</a>
 | |
|       <ng-template ngbNavContent>
 | |
|         <div class="row">
 | |
|           <div class="col-xl-6 pe-xl-5">
 | |
|             <h5 i18n>Appearance</h5>
 | |
|             <div class="row mb-3">
 | |
|               <div class="col-md-3 col-form-label pt-0">
 | |
|                 <span i18n>Display language</span>
 | |
|               </div>
 | |
|               <div class="col">
 | |
| 
 | |
|                 <select class="form-select" formControlName="displayLanguage">
 | |
|                   @for (lang of displayLanguageOptions; track lang) {
 | |
|                     <option [ngValue]="lang.code">{{lang.name}}@if (lang.code && currentLocale !== 'en-US') {
 | |
|                       <span> - {{lang.englishName}}</span>
 | |
|                     }</option>
 | |
|                   }
 | |
|                 </select>
 | |
| 
 | |
|                 @if (displayLanguageIsDirty) {
 | |
|                   <small class="form-text text-primary" i18n>You need to reload the page after applying a new language.</small>
 | |
|                 }
 | |
| 
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <div class="row mb-3">
 | |
|               <div class="col-md-3 col-form-label pt-0">
 | |
|                 <span i18n>Date display</span>
 | |
|               </div>
 | |
|               <div class="col">
 | |
| 
 | |
|                 <select class="form-select" formControlName="dateLocale">
 | |
|                   @for (lang of dateLocaleOptions; track lang) {
 | |
|                     <option [ngValue]="lang.code">{{lang.name}}@if (lang.code) {
 | |
|                       <span> - {{today | customDate:'shortDate':null:lang.code}}</span>
 | |
|                     }</option>
 | |
|                   }
 | |
|                 </select>
 | |
| 
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <div class="row mb-3">
 | |
|               <div class="col-md-3 col-form-label pt-0">
 | |
|                 <span i18n>Date format</span>
 | |
|               </div>
 | |
|               <div class="col">
 | |
| 
 | |
|                 <div class="form-check">
 | |
|                   <input type="radio" id="dateFormatShort" name="dateFormat" class="form-check-input" formControlName="dateFormat" value="shortDate">
 | |
|                   <label class="form-check-label" for="dateFormatShort" i18n>Short: {{today | customDate:'shortDate':null:computedDateLocale}}</label>
 | |
|                 </div>
 | |
|                 <div class="form-check">
 | |
|                   <input type="radio" id="dateFormatMedium" name="dateFormat" class="form-check-input" formControlName="dateFormat" value="mediumDate">
 | |
|                   <label class="form-check-label" for="dateFormatMedium" i18n>Medium: {{today | customDate:'mediumDate':null:computedDateLocale}}</label>
 | |
|                 </div>
 | |
|                 <div class="form-check">
 | |
|                   <input type="radio" id="dateFormatLong" name="dateFormat" class="form-check-input" formControlName="dateFormat" value="longDate">
 | |
|                   <label class="form-check-label" for="dateFormatLong" i18n>Long: {{today | customDate:'longDate':null:computedDateLocale}}</label>
 | |
|                 </div>
 | |
| 
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <div class="row mb-3">
 | |
|               <div class="col-md-3 col-form-label pt-0">
 | |
|                 <span i18n>Items per page</span>
 | |
|               </div>
 | |
|               <div class="col">
 | |
| 
 | |
|                 <select class="form-select" formControlName="documentListItemPerPage">
 | |
|                   <option [ngValue]="10">10</option>
 | |
|                   <option [ngValue]="25">25</option>
 | |
|                   <option [ngValue]="50">50</option>
 | |
|                   <option [ngValue]="100">100</option>
 | |
|                 </select>
 | |
| 
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <div class="row">
 | |
|               <div class="col-md-3 col-form-label pt-0">
 | |
|                 <span i18n>Sidebar</span>
 | |
|               </div>
 | |
|               <div class="col">
 | |
| 
 | |
|                 <pngx-input-check i18n-title title="Use 'slim' sidebar (icons only)" formControlName="slimSidebarEnabled"></pngx-input-check>
 | |
| 
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <div class="row">
 | |
|               <div class="col-md-3 col-form-label pt-0">
 | |
|                 <span i18n>Dark mode</span>
 | |
|               </div>
 | |
|               <div class="col">
 | |
|                 <pngx-input-check i18n-title title="Use system settings" formControlName="darkModeUseSystem"></pngx-input-check>
 | |
|                 <pngx-input-check [hidden]="settingsForm.value.darkModeUseSystem" i18n-title title="Enable dark mode" formControlName="darkModeEnabled"></pngx-input-check>
 | |
|                 <pngx-input-check i18n-title title="Invert thumbnails in dark mode" formControlName="darkModeInvertThumbs"></pngx-input-check>
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <div class="row mb-3">
 | |
|               <div class="col-md-3 col-form-label pt-0">
 | |
|                 <span i18n>Theme Color</span>
 | |
|               </div>
 | |
|               <div class="col col-md-4">
 | |
|                 <pngx-input-color i18n-title formControlName="themeColor" [error]="error?.color"></pngx-input-color>
 | |
|               </div>
 | |
|               <div class="col-2">
 | |
|                 <button class="btn btn-link btn-sm pt-2 ps-0" [disabled]="!this.settingsForm.get('themeColor').value" (click)="clearThemeColor()">
 | |
|                   <i-bs width="1em" height="1em" name="x"></i-bs><ng-container i18n>Reset</ng-container>
 | |
|                 </button>
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <h5 class="mt-3" id="update-checking" i18n>Update checking</h5>
 | |
|             <div class="row mb-3">
 | |
|               <div class="col d-flex flex-row align-items-start">
 | |
|                 <pngx-input-check i18n-title title="Enable update checking" formControlName="updateCheckingEnabled"></pngx-input-check>
 | |
|                 <button class="btn btn-sm btn-link text-muted me-auto p-0 ms-2" title="What's this?" i18n-title type="button" triggers="mouseenter:mouseleave" [ngbPopover]="updatesPopover" [autoClose]="true">
 | |
|                   <i-bs name="question-circle"></i-bs>
 | |
|                 </button>
 | |
|                 <ng-template #updatesPopover>
 | |
|                   <p i18n>
 | |
|                     Update checking works by pinging the public GitHub API for the latest release to determine whether a new version is available. Actual updating of the app must still be performed manually.
 | |
|                   </p>
 | |
|                   <p class="mb-0">
 | |
|                     <em i18n>No tracking data is collected by the app in any way.</em>
 | |
|                   </p>
 | |
|                 </ng-template>
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <h5 class="mt-3" i18n>Saved Views</h5>
 | |
|             <div class="row">
 | |
|               <div class="col">
 | |
|                 <pngx-input-check i18n-title title="Show warning when closing saved views with unsaved changes" formControlName="savedViewsWarnOnUnsavedChange"></pngx-input-check>
 | |
|                 <pngx-input-check i18n-title title="Show document counts in sidebar saved views" formControlName="sidebarViewsShowCount"></pngx-input-check>
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|           </div>
 | |
|           <div class="col-xl-6 ps-xl-5">
 | |
|             <h5 class="mt-3 mt-md-0" i18n>Document editing</h5>
 | |
| 
 | |
|             <div class="row">
 | |
|               <div class="col">
 | |
|                 <pngx-input-check i18n-title title="Use PDF viewer provided by the browser" i18n-hint hint="This is usually faster for displaying large PDF documents, but it might not work on some browsers." formControlName="useNativePdfViewer"></pngx-input-check>
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <div class="row">
 | |
|               <div class="col-md-3 col-form-label pt-0">
 | |
|                 <span i18n>Default zoom</span>
 | |
|               </div>
 | |
|               <div class="col">
 | |
|                 <select class="form-select" formControlName="pdfViewerDefaultZoom">
 | |
|                   <option [ngValue]="ZoomSetting.PageWidth" i18n>Fit width</option>
 | |
|                   <option [ngValue]="ZoomSetting.PageFit" i18n>Fit page</option>
 | |
|                 </select>
 | |
|                 <p class="small text-muted mt-1" i18n>Only applies to the Paperless-ngx PDF viewer.</p>
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <div class="row">
 | |
|               <div class="col">
 | |
|                 <pngx-input-check i18n-title title="Automatically remove inbox tag(s) on save" formControlName="documentEditingRemoveInboxTags"></pngx-input-check>
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <div class="row mb-3">
 | |
|               <div class="col">
 | |
|                 <pngx-input-check i18n-title title="Show document thumbnail during loading" formControlName="documentEditingOverlayThumbnail"></pngx-input-check>
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <h5 class="mt-3" i18n>Global search</h5>
 | |
|             <div class="row">
 | |
|               <div class="col">
 | |
|                 <pngx-input-check i18n-title title="Do not include advanced search results" formControlName="searchDbOnly"></pngx-input-check>
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <div class="row mb-3">
 | |
|               <div class="col-md-3 col-form-label pt-0">
 | |
|                 <span i18n>Full search links to</span>
 | |
|               </div>
 | |
|               <div class="col mb-3">
 | |
|                 <select class="form-select" formControlName="searchLink">
 | |
|                   <option [ngValue]="GlobalSearchType.TITLE_CONTENT" i18n>Title and content search</option>
 | |
|                   <option [ngValue]="GlobalSearchType.ADVANCED" i18n>Advanced search</option>
 | |
|                 </select>
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <h5 class="mt-3" i18n>Bulk editing</h5>
 | |
|             <div class="row mb-3">
 | |
|               <div class="col">
 | |
|                 <pngx-input-check i18n-title title="Show confirmation dialogs" formControlName="bulkEditConfirmationDialogs"></pngx-input-check>
 | |
|                 <pngx-input-check i18n-title title="Apply on close" formControlName="bulkEditApplyOnClose"></pngx-input-check>
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|             <h5 class="mt-3" i18n>Notes</h5>
 | |
|             <div class="row mb-3">
 | |
|               <div class="col">
 | |
|                 <pngx-input-check i18n-title title="Enable notes" formControlName="notesEnabled"></pngx-input-check>
 | |
|               </div>
 | |
|             </div>
 | |
| 
 | |
|           </div>
 | |
|         </div>
 | |
| 
 | |
|       </ng-template>
 | |
|     </li>
 | |
| 
 | |
|     <li [ngbNavItem]="SettingsNavIDs.Permissions">
 | |
|       <a ngbNavLink i18n>Permissions</a>
 | |
|       <ng-template ngbNavContent>
 | |
| 
 | |
|         <h5 i18n>Default Permissions</h5>
 | |
| 
 | |
|         <div class="row mb-3">
 | |
|           <div class="col">
 | |
|             <p i18n>
 | |
|               Settings apply to this user account for objects (Tags, Mail Rules, etc. but not documents) created via the web UI.
 | |
|             </p>
 | |
|           </div>
 | |
|         </div>
 | |
|         <div class="row mb-3">
 | |
|           <div class="col-md-3 col-form-label pt-0">
 | |
|             <span i18n>Default Owner</span>
 | |
|           </div>
 | |
|           <div class="col-md-5">
 | |
|             <pngx-input-select [items]="users" bindLabel="username" formControlName="defaultPermsOwner" [allowNull]="true"></pngx-input-select>
 | |
|             <small class="form-text text-muted text-end d-block mt-n2" i18n>Objects without an owner can be viewed and edited by all users</small>
 | |
|           </div>
 | |
|         </div>
 | |
|         <div class="row mb-3">
 | |
|           <div class="col-md-3 col-form-label pt-0">
 | |
|             <span i18n>Default View Permissions</span>
 | |
|           </div>
 | |
|           <div class="col-md-5">
 | |
|             <div class="row">
 | |
|               <div class="col-3">
 | |
|                 <span class="d-block pt-1" i18n>Users:</span>
 | |
|               </div>
 | |
|               <div class="col">
 | |
|                 <ng-container *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.User }">
 | |
|                   <pngx-permissions-user type="view" formControlName="defaultPermsViewUsers"></pngx-permissions-user>
 | |
|                 </ng-container>
 | |
|               </div>
 | |
|             </div>
 | |
|             <div class="row">
 | |
|               <div class="col-3">
 | |
|                 <span class="d-block pt-1" i18n>Groups:</span>
 | |
|               </div>
 | |
|               <div class="col">
 | |
|                 <ng-container *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Group }">
 | |
|                   <pngx-permissions-group type="view" formControlName="defaultPermsViewGroups"></pngx-permissions-group>
 | |
|                 </ng-container>
 | |
|               </div>
 | |
|             </div>
 | |
|           </div>
 | |
|         </div>
 | |
|         <div class="row">
 | |
|           <div class="col-md-3 col-form-label pt-0">
 | |
|             <span i18n>Default Edit Permissions</span>
 | |
|           </div>
 | |
|           <div class="col-md-5">
 | |
|             <div class="row">
 | |
|               <div class="col-3">
 | |
|                 <span class="d-block pt-1" i18n>Users:</span>
 | |
|               </div>
 | |
|               <div class="col">
 | |
|                 <ng-container *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.User }">
 | |
|                   <pngx-permissions-user type="view" formControlName="defaultPermsEditUsers"></pngx-permissions-user>
 | |
|                 </ng-container>
 | |
|               </div>
 | |
|             </div>
 | |
|             <div class="row">
 | |
|               <div class="col-3">
 | |
|                 <span class="d-block pt-1" i18n>Groups:</span>
 | |
|               </div>
 | |
|               <div class="col">
 | |
|                 <ng-container *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Group }">
 | |
|                   <pngx-permissions-group type="view" formControlName="defaultPermsEditGroups"></pngx-permissions-group>
 | |
|                 </ng-container>
 | |
|               </div>
 | |
|             </div>
 | |
|             <div class="row">
 | |
|               <small class="form-text text-muted text-end d-block" i18n>Edit permissions also grant viewing permissions</small>
 | |
|             </div>
 | |
|           </div>
 | |
|         </div>
 | |
|       </ng-template>
 | |
|     </li>
 | |
| 
 | |
|     <li [ngbNavItem]="SettingsNavIDs.Notifications">
 | |
|       <a ngbNavLink i18n>Notifications</a>
 | |
|       <ng-template ngbNavContent>
 | |
| 
 | |
|         <h5 i18n>Document processing</h5>
 | |
| 
 | |
|         <div class="row">
 | |
|           <div class="col">
 | |
|             <pngx-input-check i18n-title title="Show notifications when new documents are detected" formControlName="notificationsConsumerNewDocument"></pngx-input-check>
 | |
|             <pngx-input-check i18n-title title="Show notifications when document processing completes successfully" formControlName="notificationsConsumerSuccess"></pngx-input-check>
 | |
|             <pngx-input-check i18n-title title="Show notifications when document processing fails" formControlName="notificationsConsumerFailed"></pngx-input-check>
 | |
|             <pngx-input-check i18n-title title="Suppress notifications on dashboard" formControlName="notificationsConsumerSuppressOnDashboard" i18n-hint hint="This will suppress all messages about document processing status on the dashboard."></pngx-input-check>
 | |
|           </div>
 | |
|         </div>
 | |
| 
 | |
|       </ng-template>
 | |
|     </li>
 | |
|   </ul>
 | |
| 
 | |
|   <div [ngbNavOutlet]="nav" class="border-start border-end border-bottom p-3 mb-3 shadow-sm"></div>
 | |
| 
 | |
|   <button type="submit" class="btn btn-primary mb-2" [disabled]="(isDirty$ | async) === false" i18n>Save</button>
 | |
|   <button type="button" (click)="reset()" class="btn btn-secondary ms-2 mb-2" [disabled]="(isDirty$ | async) === false" i18n>Cancel</button>
 | |
| </form>
 | 
