mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-07-28 18:24:38 -05:00
Merge pull request #919 from paperless-ngx/feature-settings-saved-to-db
Feature: frontend settings saved to database
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { SettingsService, SETTINGS_KEYS } from './services/settings.service'
|
||||
import { SettingsService } from './services/settings.service'
|
||||
import { SETTINGS_KEYS } from './data/paperless-uisettings'
|
||||
import { Component, OnDestroy, OnInit } from '@angular/core'
|
||||
import { Router } from '@angular/router'
|
||||
import { Subscription } from 'rxjs'
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { BrowserModule } from '@angular/platform-browser'
|
||||
import { NgModule } from '@angular/core'
|
||||
import { APP_INITIALIZER, NgModule } from '@angular/core'
|
||||
import { AppRoutingModule } from './app-routing.module'
|
||||
import { AppComponent } from './app.component'
|
||||
import {
|
||||
@@ -87,6 +87,7 @@ import localeSr from '@angular/common/locales/sr'
|
||||
import localeSv from '@angular/common/locales/sv'
|
||||
import localeTr from '@angular/common/locales/tr'
|
||||
import localeZh from '@angular/common/locales/zh'
|
||||
import { SettingsService } from './services/settings.service'
|
||||
|
||||
registerLocaleData(localeBe)
|
||||
registerLocaleData(localeCs)
|
||||
@@ -109,6 +110,12 @@ registerLocaleData(localeSv)
|
||||
registerLocaleData(localeTr)
|
||||
registerLocaleData(localeZh)
|
||||
|
||||
function initializeApp(settings: SettingsService) {
|
||||
return () => {
|
||||
return settings.initializeSettings()
|
||||
}
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
@@ -174,6 +181,12 @@ registerLocaleData(localeZh)
|
||||
ColorSliderModule,
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: initializeApp,
|
||||
deps: [SettingsService],
|
||||
multi: true,
|
||||
},
|
||||
DatePipe,
|
||||
CookieService,
|
||||
{
|
||||
|
@@ -21,17 +21,17 @@
|
||||
</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 me-2 text-light d-none d-sm-inline">
|
||||
{{displayName}}
|
||||
<button class="btn" id="userDropdown" ngbDropdownToggle>
|
||||
<span class="small me-2 d-none d-sm-inline">
|
||||
{{this.settingsService.displayName}}
|
||||
</span>
|
||||
<svg width="1.3em" height="1.3em" fill="currentColor">
|
||||
<use xlink:href="assets/bootstrap-icons.svg#person-circle"/>
|
||||
</svg>
|
||||
</button>
|
||||
<div ngbDropdownMenu class="dropdown-menu-end shadow me-2" aria-labelledby="userDropdown">
|
||||
<div *ngIf="displayName" class="d-sm-none">
|
||||
<p class="small mb-0 px-3 text-muted" i18n>Logged in as {{displayName}}</p>
|
||||
<div class="d-sm-none">
|
||||
<p class="small mb-0 px-3 text-muted" i18n>Logged in as {{this.settingsService.displayName}}</p>
|
||||
<div class="dropdown-divider"></div>
|
||||
</div>
|
||||
<a ngbDropdownItem class="nav-link" routerLink="settings" (click)="closeMenu()">
|
||||
|
@@ -23,6 +23,7 @@ import {
|
||||
AppRemoteVersion,
|
||||
} from 'src/app/services/rest/remote-version.service'
|
||||
import { QueryParamsService } from 'src/app/services/query-params.service'
|
||||
import { SettingsService } from 'src/app/services/settings.service'
|
||||
|
||||
@Component({
|
||||
selector: 'app-app-frame',
|
||||
@@ -36,10 +37,9 @@ export class AppFrameComponent {
|
||||
private openDocumentsService: OpenDocumentsService,
|
||||
private searchService: SearchService,
|
||||
public savedViewService: SavedViewService,
|
||||
private list: DocumentListViewService,
|
||||
private meta: Meta,
|
||||
private remoteVersionService: RemoteVersionService,
|
||||
private queryParamsService: QueryParamsService
|
||||
private queryParamsService: QueryParamsService,
|
||||
public settingsService: SettingsService
|
||||
) {
|
||||
this.remoteVersionService
|
||||
.checkForUpdates()
|
||||
@@ -143,17 +143,4 @@ export class AppFrameComponent {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core'
|
||||
import { Meta } from '@angular/platform-browser'
|
||||
import { SavedViewService } from 'src/app/services/rest/saved-view.service'
|
||||
import { SettingsService } from 'src/app/services/settings.service'
|
||||
|
||||
@Component({
|
||||
selector: 'app-dashboard',
|
||||
@@ -8,23 +9,14 @@ import { SavedViewService } from 'src/app/services/rest/saved-view.service'
|
||||
styleUrls: ['./dashboard.component.scss'],
|
||||
})
|
||||
export class DashboardComponent {
|
||||
constructor(public savedViewService: SavedViewService, private meta: Meta) {}
|
||||
|
||||
get displayName() {
|
||||
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
|
||||
}
|
||||
}
|
||||
constructor(
|
||||
public savedViewService: SavedViewService,
|
||||
public settingsService: SettingsService
|
||||
) {}
|
||||
|
||||
get subtitle() {
|
||||
if (this.displayName) {
|
||||
return $localize`Hello ${this.displayName}, welcome to Paperless-ngx!`
|
||||
if (this.settingsService.displayName) {
|
||||
return $localize`Hello ${this.settingsService.displayName}, welcome to Paperless-ngx!`
|
||||
} else {
|
||||
return $localize`Welcome to Paperless-ngx!`
|
||||
}
|
||||
|
@@ -18,10 +18,7 @@ import { DocumentTypeEditDialogComponent } from '../common/edit-dialog/document-
|
||||
import { PDFDocumentProxy } from 'ng2-pdf-viewer'
|
||||
import { ToastService } from 'src/app/services/toast.service'
|
||||
import { TextComponent } from '../common/input/text/text.component'
|
||||
import {
|
||||
SettingsService,
|
||||
SETTINGS_KEYS,
|
||||
} from 'src/app/services/settings.service'
|
||||
import { SettingsService } from 'src/app/services/settings.service'
|
||||
import { dirtyCheck, DirtyComponent } from '@ngneat/dirty-check-forms'
|
||||
import { Observable, Subject, BehaviorSubject } from 'rxjs'
|
||||
import {
|
||||
@@ -36,6 +33,7 @@ import { PaperlessDocumentSuggestions } from 'src/app/data/paperless-document-su
|
||||
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type'
|
||||
import { normalizeDateStr } from 'src/app/utils/date'
|
||||
import { QueryParamsService } from 'src/app/services/query-params.service'
|
||||
import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings'
|
||||
|
||||
@Component({
|
||||
selector: 'app-document-detail',
|
||||
|
@@ -19,12 +19,10 @@ import {
|
||||
} from '../../common/filterable-dropdown/filterable-dropdown.component'
|
||||
import { ToggleableItemState } from '../../common/filterable-dropdown/toggleable-dropdown-button/toggleable-dropdown-button.component'
|
||||
import { MatchingModel } from 'src/app/data/matching-model'
|
||||
import {
|
||||
SettingsService,
|
||||
SETTINGS_KEYS,
|
||||
} from 'src/app/services/settings.service'
|
||||
import { SettingsService } from 'src/app/services/settings.service'
|
||||
import { ToastService } from 'src/app/services/toast.service'
|
||||
import { saveAs } from 'file-saver'
|
||||
import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings'
|
||||
|
||||
@Component({
|
||||
selector: 'app-bulk-editor',
|
||||
|
@@ -8,12 +8,12 @@ import {
|
||||
} from '@angular/core'
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document'
|
||||
import { DocumentService } from 'src/app/services/rest/document.service'
|
||||
import {
|
||||
SettingsService,
|
||||
SETTINGS_KEYS,
|
||||
} from 'src/app/services/settings.service'
|
||||
import { SettingsService } from 'src/app/services/settings.service'
|
||||
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { OpenDocumentsService } from 'src/app/services/open-documents.service'
|
||||
import { DocumentListViewService } from 'src/app/services/document-list-view.service'
|
||||
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type'
|
||||
import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings'
|
||||
|
||||
@Component({
|
||||
selector: 'app-document-card-large',
|
||||
|
@@ -9,12 +9,10 @@ import {
|
||||
import { map } from 'rxjs/operators'
|
||||
import { PaperlessDocument } from 'src/app/data/paperless-document'
|
||||
import { DocumentService } from 'src/app/services/rest/document.service'
|
||||
import {
|
||||
SettingsService,
|
||||
SETTINGS_KEYS,
|
||||
} from 'src/app/services/settings.service'
|
||||
import { SettingsService } from 'src/app/services/settings.service'
|
||||
import { NgbPopover } from '@ng-bootstrap/ng-bootstrap'
|
||||
import { OpenDocumentsService } from 'src/app/services/open-documents.service'
|
||||
import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings'
|
||||
|
||||
@Component({
|
||||
selector: 'app-document-card-small',
|
||||
|
@@ -13,11 +13,11 @@ import { SavedViewService } from 'src/app/services/rest/saved-view.service'
|
||||
import {
|
||||
LanguageOption,
|
||||
SettingsService,
|
||||
SETTINGS_KEYS,
|
||||
} from 'src/app/services/settings.service'
|
||||
import { ToastService } from 'src/app/services/toast.service'
|
||||
import { dirtyCheck, DirtyComponent } from '@ngneat/dirty-check-forms'
|
||||
import { Observable, Subscription, BehaviorSubject } from 'rxjs'
|
||||
import { Observable, Subscription, BehaviorSubject, first } from 'rxjs'
|
||||
import { SETTINGS_KEYS } from 'src/app/data/paperless-uisettings'
|
||||
|
||||
@Component({
|
||||
selector: 'app-settings',
|
||||
@@ -227,10 +227,23 @@ export class SettingsComponent implements OnInit, OnDestroy, DirtyComponent {
|
||||
this.settingsForm.value.notificationsConsumerSuppressOnDashboard
|
||||
)
|
||||
this.settings.setLanguage(this.settingsForm.value.displayLanguage)
|
||||
this.store.next(this.settingsForm.value)
|
||||
this.documentListViewService.updatePageSize()
|
||||
this.settings.updateAppearanceSettings()
|
||||
this.toastService.showInfo($localize`Settings saved successfully.`)
|
||||
this.settings
|
||||
.storeSettings()
|
||||
.pipe(first())
|
||||
.subscribe({
|
||||
next: () => {
|
||||
this.store.next(this.settingsForm.value)
|
||||
this.documentListViewService.updatePageSize()
|
||||
this.settings.updateAppearanceSettings()
|
||||
this.toastService.showInfo($localize`Settings saved successfully.`)
|
||||
},
|
||||
error: (error) => {
|
||||
this.toastService.showError(
|
||||
$localize`An error occurred while saving settings.`
|
||||
)
|
||||
console.log(error)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
get displayLanguageOptions(): LanguageOption[] {
|
||||
|
117
src-ui/src/app/data/paperless-uisettings.ts
Normal file
117
src-ui/src/app/data/paperless-uisettings.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
export interface PaperlessUiSettings {
|
||||
user_id: number
|
||||
|
||||
username: string
|
||||
|
||||
display_name: string
|
||||
|
||||
settings: Object
|
||||
}
|
||||
|
||||
export interface PaperlessUiSetting {
|
||||
key: string
|
||||
type: string
|
||||
default: any
|
||||
}
|
||||
|
||||
export const SETTINGS_KEYS = {
|
||||
LANGUAGE: 'language',
|
||||
// maintain old general-settings: for backwards compatibility
|
||||
BULK_EDIT_CONFIRMATION_DIALOGS:
|
||||
'general-settings:bulk-edit:confirmation-dialogs',
|
||||
BULK_EDIT_APPLY_ON_CLOSE: 'general-settings:bulk-edit:apply-on-close',
|
||||
DOCUMENT_LIST_SIZE: 'general-settings:documentListSize',
|
||||
DARK_MODE_USE_SYSTEM: 'general-settings:dark-mode:use-system',
|
||||
DARK_MODE_ENABLED: 'general-settings:dark-mode:enabled',
|
||||
DARK_MODE_THUMB_INVERTED: 'general-settings:dark-mode:thumb-inverted',
|
||||
THEME_COLOR: 'general-settings:theme:color',
|
||||
USE_NATIVE_PDF_VIEWER: 'general-settings:document-details:native-pdf-viewer',
|
||||
DATE_LOCALE: 'general-settings:date-display:date-locale',
|
||||
DATE_FORMAT: 'general-settings:date-display:date-format',
|
||||
NOTIFICATIONS_CONSUMER_NEW_DOCUMENT:
|
||||
'general-settings:notifications:consumer-new-documents',
|
||||
NOTIFICATIONS_CONSUMER_SUCCESS:
|
||||
'general-settings:notifications:consumer-success',
|
||||
NOTIFICATIONS_CONSUMER_FAILED:
|
||||
'general-settings:notifications:consumer-failed',
|
||||
NOTIFICATIONS_CONSUMER_SUPPRESS_ON_DASHBOARD:
|
||||
'general-settings:notifications:consumer-suppress-on-dashboard',
|
||||
}
|
||||
|
||||
export const SETTINGS: PaperlessUiSetting[] = [
|
||||
{
|
||||
key: SETTINGS_KEYS.LANGUAGE,
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.BULK_EDIT_CONFIRMATION_DIALOGS,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE,
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.DOCUMENT_LIST_SIZE,
|
||||
type: 'number',
|
||||
default: 50,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.DARK_MODE_USE_SYSTEM,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.DARK_MODE_ENABLED,
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.THEME_COLOR,
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER,
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.DATE_LOCALE,
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.DATE_FORMAT,
|
||||
type: 'string',
|
||||
default: 'mediumDate',
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_NEW_DOCUMENT,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUCCESS,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_FAILED,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUPPRESS_ON_DASHBOARD,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
]
|
@@ -1,6 +1,7 @@
|
||||
import { DatePipe } from '@angular/common'
|
||||
import { Inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core'
|
||||
import { SettingsService, SETTINGS_KEYS } from '../services/settings.service'
|
||||
import { SETTINGS_KEYS } from '../data/paperless-uisettings'
|
||||
import { SettingsService } from '../services/settings.service'
|
||||
import { normalizeDateStr } from '../utils/date'
|
||||
|
||||
const FORMAT_TO_ISO_FORMAT = {
|
||||
|
@@ -8,9 +8,10 @@ import {
|
||||
} from '../data/filter-rule'
|
||||
import { PaperlessDocument } from '../data/paperless-document'
|
||||
import { PaperlessSavedView } from '../data/paperless-saved-view'
|
||||
import { SETTINGS_KEYS } from '../data/paperless-uisettings'
|
||||
import { DOCUMENT_LIST_SERVICE } from '../data/storage-keys'
|
||||
import { DocumentService, DOCUMENT_SORT_FIELDS } from './rest/document.service'
|
||||
import { SettingsService, SETTINGS_KEYS } from './settings.service'
|
||||
import { SettingsService } from './settings.service'
|
||||
|
||||
/**
|
||||
* Captures the current state of the list view.
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { DOCUMENT } from '@angular/common'
|
||||
import { HttpClient } from '@angular/common/http'
|
||||
import {
|
||||
Inject,
|
||||
Injectable,
|
||||
@@ -9,17 +10,19 @@ import {
|
||||
} from '@angular/core'
|
||||
import { Meta } from '@angular/platform-browser'
|
||||
import { CookieService } from 'ngx-cookie-service'
|
||||
import { first, Observable, tap } from 'rxjs'
|
||||
import {
|
||||
BRIGHTNESS,
|
||||
estimateBrightnessForColor,
|
||||
hexToHsl,
|
||||
} from 'src/app/utils/color'
|
||||
|
||||
export interface PaperlessSettings {
|
||||
key: string
|
||||
type: string
|
||||
default: any
|
||||
}
|
||||
import { environment } from 'src/environments/environment'
|
||||
import {
|
||||
PaperlessUiSettings,
|
||||
SETTINGS,
|
||||
SETTINGS_KEYS,
|
||||
} from '../data/paperless-uisettings'
|
||||
import { ToastService } from './toast.service'
|
||||
|
||||
export interface LanguageOption {
|
||||
code: string
|
||||
@@ -32,89 +35,42 @@ export interface LanguageOption {
|
||||
dateInputFormat?: string
|
||||
}
|
||||
|
||||
export const SETTINGS_KEYS = {
|
||||
BULK_EDIT_CONFIRMATION_DIALOGS:
|
||||
'general-settings:bulk-edit:confirmation-dialogs',
|
||||
BULK_EDIT_APPLY_ON_CLOSE: 'general-settings:bulk-edit:apply-on-close',
|
||||
DOCUMENT_LIST_SIZE: 'general-settings:documentListSize',
|
||||
DARK_MODE_USE_SYSTEM: 'general-settings:dark-mode:use-system',
|
||||
DARK_MODE_ENABLED: 'general-settings:dark-mode:enabled',
|
||||
DARK_MODE_THUMB_INVERTED: 'general-settings:dark-mode:thumb-inverted',
|
||||
THEME_COLOR: 'general-settings:theme:color',
|
||||
USE_NATIVE_PDF_VIEWER: 'general-settings:document-details:native-pdf-viewer',
|
||||
DATE_LOCALE: 'general-settings:date-display:date-locale',
|
||||
DATE_FORMAT: 'general-settings:date-display:date-format',
|
||||
NOTIFICATIONS_CONSUMER_NEW_DOCUMENT:
|
||||
'general-settings:notifications:consumer-new-documents',
|
||||
NOTIFICATIONS_CONSUMER_SUCCESS:
|
||||
'general-settings:notifications:consumer-success',
|
||||
NOTIFICATIONS_CONSUMER_FAILED:
|
||||
'general-settings:notifications:consumer-failed',
|
||||
NOTIFICATIONS_CONSUMER_SUPPRESS_ON_DASHBOARD:
|
||||
'general-settings:notifications:consumer-suppress-on-dashboard',
|
||||
}
|
||||
|
||||
const SETTINGS: PaperlessSettings[] = [
|
||||
{
|
||||
key: SETTINGS_KEYS.BULK_EDIT_CONFIRMATION_DIALOGS,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.BULK_EDIT_APPLY_ON_CLOSE,
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
},
|
||||
{ key: SETTINGS_KEYS.DOCUMENT_LIST_SIZE, type: 'number', default: 50 },
|
||||
{ key: SETTINGS_KEYS.DARK_MODE_USE_SYSTEM, type: 'boolean', default: true },
|
||||
{ key: SETTINGS_KEYS.DARK_MODE_ENABLED, type: 'boolean', default: false },
|
||||
{
|
||||
key: SETTINGS_KEYS.DARK_MODE_THUMB_INVERTED,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{ key: SETTINGS_KEYS.THEME_COLOR, type: 'string', default: '' },
|
||||
{ key: SETTINGS_KEYS.USE_NATIVE_PDF_VIEWER, type: 'boolean', default: false },
|
||||
{ key: SETTINGS_KEYS.DATE_LOCALE, type: 'string', default: '' },
|
||||
{ key: SETTINGS_KEYS.DATE_FORMAT, type: 'string', default: 'mediumDate' },
|
||||
{
|
||||
key: SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_NEW_DOCUMENT,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUCCESS,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_FAILED,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
key: SETTINGS_KEYS.NOTIFICATIONS_CONSUMER_SUPPRESS_ON_DASHBOARD,
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
},
|
||||
]
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class SettingsService {
|
||||
private renderer: Renderer2
|
||||
protected baseUrl: string = environment.apiBaseUrl + 'ui_settings/'
|
||||
|
||||
private settings: Object = {}
|
||||
|
||||
public displayName: string
|
||||
|
||||
constructor(
|
||||
private rendererFactory: RendererFactory2,
|
||||
rendererFactory: RendererFactory2,
|
||||
@Inject(DOCUMENT) private document,
|
||||
private cookieService: CookieService,
|
||||
private meta: Meta,
|
||||
@Inject(LOCALE_ID) private localeId: string
|
||||
@Inject(LOCALE_ID) private localeId: string,
|
||||
protected http: HttpClient,
|
||||
private toastService: ToastService
|
||||
) {
|
||||
this.renderer = rendererFactory.createRenderer(null, null)
|
||||
}
|
||||
|
||||
this.updateAppearanceSettings()
|
||||
// this is called by the app initializer in app.module
|
||||
public initializeSettings(): Observable<PaperlessUiSettings> {
|
||||
return this.http.get<PaperlessUiSettings>(this.baseUrl).pipe(
|
||||
first(),
|
||||
tap((uisettings) => {
|
||||
Object.assign(this.settings, uisettings.settings)
|
||||
this.maybeMigrateSettings()
|
||||
// to update lang cookie
|
||||
if (this.settings['language']?.length)
|
||||
this.setLanguage(this.settings['language'])
|
||||
this.displayName = uisettings.display_name.trim()
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
public updateAppearanceSettings(
|
||||
@@ -333,11 +289,13 @@ export class SettingsService {
|
||||
}
|
||||
|
||||
getLanguage(): string {
|
||||
return this.cookieService.get(this.getLanguageCookieName())
|
||||
return this.get(SETTINGS_KEYS.LANGUAGE)
|
||||
}
|
||||
|
||||
setLanguage(language: string) {
|
||||
if (language) {
|
||||
this.set(SETTINGS_KEYS.LANGUAGE, language)
|
||||
if (language?.length) {
|
||||
// for Django
|
||||
this.cookieService.set(this.getLanguageCookieName(), language)
|
||||
} else {
|
||||
this.cookieService.delete(this.getLanguageCookieName())
|
||||
@@ -362,7 +320,16 @@ export class SettingsService {
|
||||
return null
|
||||
}
|
||||
|
||||
let value = localStorage.getItem(key)
|
||||
let value = null
|
||||
// parse key:key:key into nested object
|
||||
const keys = key.replace('general-settings:', '').split(':')
|
||||
let settingObj = this.settings
|
||||
keys.forEach((keyPart, index) => {
|
||||
keyPart = keyPart.replace(/-/g, '_')
|
||||
if (!settingObj.hasOwnProperty(keyPart)) return
|
||||
if (index == keys.length - 1) value = settingObj[keyPart]
|
||||
else settingObj = settingObj[keyPart]
|
||||
})
|
||||
|
||||
if (value != null) {
|
||||
switch (setting.type) {
|
||||
@@ -381,10 +348,57 @@ export class SettingsService {
|
||||
}
|
||||
|
||||
set(key: string, value: any) {
|
||||
localStorage.setItem(key, value.toString())
|
||||
// parse key:key:key into nested object
|
||||
let settingObj = this.settings
|
||||
const keys = key.replace('general-settings:', '').split(':')
|
||||
keys.forEach((keyPart, index) => {
|
||||
keyPart = keyPart.replace(/-/g, '_')
|
||||
if (!settingObj.hasOwnProperty(keyPart)) settingObj[keyPart] = {}
|
||||
if (index == keys.length - 1) settingObj[keyPart] = value
|
||||
else settingObj = settingObj[keyPart]
|
||||
})
|
||||
}
|
||||
|
||||
unset(key: string) {
|
||||
localStorage.removeItem(key)
|
||||
storeSettings(): Observable<any> {
|
||||
return this.http.post(this.baseUrl, { settings: this.settings })
|
||||
}
|
||||
|
||||
maybeMigrateSettings() {
|
||||
if (
|
||||
!this.settings.hasOwnProperty('documentListSize') &&
|
||||
localStorage.getItem(SETTINGS_KEYS.DOCUMENT_LIST_SIZE)
|
||||
) {
|
||||
// lets migrate
|
||||
const successMessage = $localize`Successfully completed one-time migratration of settings to the database!`
|
||||
const errorMessage = $localize`Unable to migrate settings to the database, please try saving manually.`
|
||||
|
||||
try {
|
||||
for (const setting in SETTINGS_KEYS) {
|
||||
const key = SETTINGS_KEYS[setting]
|
||||
const value = localStorage.getItem(key)
|
||||
this.set(key, value)
|
||||
}
|
||||
this.set(
|
||||
SETTINGS_KEYS.LANGUAGE,
|
||||
this.cookieService.get(this.getLanguageCookieName())
|
||||
)
|
||||
} catch (error) {
|
||||
this.toastService.showError(errorMessage)
|
||||
console.log(error)
|
||||
}
|
||||
|
||||
this.storeSettings()
|
||||
.pipe(first())
|
||||
.subscribe({
|
||||
next: () => {
|
||||
this.updateAppearanceSettings()
|
||||
this.toastService.showInfo(successMessage)
|
||||
},
|
||||
error: (e) => {
|
||||
this.toastService.showError(errorMessage)
|
||||
console.log(e)
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user