mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2025-08-14 00:26:21 +00:00
@@ -1,8 +1,15 @@
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { Inject, Injectable, LOCALE_ID, Renderer2, RendererFactory2, RendererStyleFlags2 } from '@angular/core';
|
||||
import { Meta } from '@angular/platform-browser';
|
||||
import { CookieService } from 'ngx-cookie-service';
|
||||
import { hexToHsl } from 'src/app/utils/color';
|
||||
import { DOCUMENT } from '@angular/common'
|
||||
import {
|
||||
Inject,
|
||||
Injectable,
|
||||
LOCALE_ID,
|
||||
Renderer2,
|
||||
RendererFactory2,
|
||||
RendererStyleFlags2,
|
||||
} from '@angular/core'
|
||||
import { Meta } from '@angular/platform-browser'
|
||||
import { CookieService } from 'ngx-cookie-service'
|
||||
import { hexToHsl } from 'src/app/utils/color'
|
||||
|
||||
export interface PaperlessSettings {
|
||||
key: string
|
||||
@@ -22,7 +29,8 @@ export interface LanguageOption {
|
||||
}
|
||||
|
||||
export const SETTINGS_KEYS = {
|
||||
BULK_EDIT_CONFIRMATION_DIALOGS: 'general-settings:bulk-edit:confirmation-dialogs',
|
||||
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',
|
||||
@@ -32,35 +40,66 @@ export const SETTINGS_KEYS = {
|
||||
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',
|
||||
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},
|
||||
{
|
||||
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'
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class SettingsService {
|
||||
|
||||
private renderer: Renderer2;
|
||||
private renderer: Renderer2
|
||||
|
||||
constructor(
|
||||
private rendererFactory: RendererFactory2,
|
||||
@@ -69,67 +108,177 @@ export class SettingsService {
|
||||
private meta: Meta,
|
||||
@Inject(LOCALE_ID) private localeId: string
|
||||
) {
|
||||
this.renderer = rendererFactory.createRenderer(null, null);
|
||||
this.renderer = rendererFactory.createRenderer(null, null)
|
||||
|
||||
this.updateAppearanceSettings()
|
||||
}
|
||||
|
||||
public updateAppearanceSettings(darkModeUseSystem = null, darkModeEnabled = null, themeColor = null): void {
|
||||
public updateAppearanceSettings(
|
||||
darkModeUseSystem = null,
|
||||
darkModeEnabled = null,
|
||||
themeColor = null
|
||||
): void {
|
||||
darkModeUseSystem ??= this.get(SETTINGS_KEYS.DARK_MODE_USE_SYSTEM)
|
||||
darkModeEnabled ??= this.get(SETTINGS_KEYS.DARK_MODE_ENABLED)
|
||||
themeColor ??= this.get(SETTINGS_KEYS.THEME_COLOR);
|
||||
themeColor ??= this.get(SETTINGS_KEYS.THEME_COLOR)
|
||||
|
||||
if (darkModeUseSystem) {
|
||||
this.renderer.addClass(this.document.body, 'color-scheme-system')
|
||||
this.renderer.removeClass(this.document.body, 'color-scheme-dark')
|
||||
} else {
|
||||
this.renderer.removeClass(this.document.body, 'color-scheme-system')
|
||||
darkModeEnabled ? this.renderer.addClass(this.document.body, 'color-scheme-dark') : this.renderer.removeClass(this.document.body, 'color-scheme-dark')
|
||||
darkModeEnabled
|
||||
? this.renderer.addClass(this.document.body, 'color-scheme-dark')
|
||||
: this.renderer.removeClass(this.document.body, 'color-scheme-dark')
|
||||
}
|
||||
|
||||
if (themeColor) {
|
||||
const hsl = hexToHsl(themeColor)
|
||||
this.renderer.setStyle(document.documentElement, '--pngx-primary',`${+hsl.h * 360},${hsl.s * 100}%`, RendererStyleFlags2.DashCase)
|
||||
this.renderer.setStyle(document.documentElement, '--pngx-primary-lightness',`${hsl.l * 100}%`, RendererStyleFlags2.DashCase)
|
||||
this.renderer.setStyle(
|
||||
document.documentElement,
|
||||
'--pngx-primary',
|
||||
`${+hsl.h * 360},${hsl.s * 100}%`,
|
||||
RendererStyleFlags2.DashCase
|
||||
)
|
||||
this.renderer.setStyle(
|
||||
document.documentElement,
|
||||
'--pngx-primary-lightness',
|
||||
`${hsl.l * 100}%`,
|
||||
RendererStyleFlags2.DashCase
|
||||
)
|
||||
} else {
|
||||
this.renderer.removeStyle(document.documentElement, '--pngx-primary', RendererStyleFlags2.DashCase)
|
||||
this.renderer.removeStyle(document.documentElement, '--pngx-primary-lightness', RendererStyleFlags2.DashCase)
|
||||
this.renderer.removeStyle(
|
||||
document.documentElement,
|
||||
'--pngx-primary',
|
||||
RendererStyleFlags2.DashCase
|
||||
)
|
||||
this.renderer.removeStyle(
|
||||
document.documentElement,
|
||||
'--pngx-primary-lightness',
|
||||
RendererStyleFlags2.DashCase
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
getLanguageOptions(): LanguageOption[] {
|
||||
const languages = [
|
||||
{code: "en-us", name: $localize`English (US)`, englishName: "English (US)", dateInputFormat: "mm/dd/yyyy"},
|
||||
{code: "cs-cz", name: $localize`Czech`, englishName: "Czech", dateInputFormat: "dd.mm.yyyy"},
|
||||
{code: "da-dk", name: $localize`Danish`, englishName: "Danish", dateInputFormat: "dd.mm.yyyy"},
|
||||
{code: "de-de", name: $localize`German`, englishName: "German", dateInputFormat: "dd.mm.yyyy"},
|
||||
{code: "en-gb", name: $localize`English (GB)`, englishName: "English (GB)", dateInputFormat: "dd/mm/yyyy"},
|
||||
{code: "es-es", name: $localize`Spanish`, englishName: "Spanish", dateInputFormat: "dd/mm/yyyy"},
|
||||
{code: "fr-fr", name: $localize`French`, englishName: "French", dateInputFormat: "dd/mm/yyyy"},
|
||||
{code: "it-it", name: $localize`Italian`, englishName: "Italian", dateInputFormat: "dd/mm/yyyy"},
|
||||
{code: "lb-lu", name: $localize`Luxembourgish`, englishName: "Luxembourgish", dateInputFormat: "dd.mm.yyyy"},
|
||||
{code: "nl-nl", name: $localize`Dutch`, englishName: "Dutch", dateInputFormat: "dd-mm-yyyy"},
|
||||
{code: "pl-pl", name: $localize`Polish`, englishName: "Polish", dateInputFormat: "dd.mm.yyyy"},
|
||||
{code: "pt-br", name: $localize`Portuguese (Brazil)`, englishName: "Portuguese (Brazil)", dateInputFormat: "dd/mm/yyyy"},
|
||||
{code: "pt-pt", name: $localize`Portuguese`, englishName: "Portuguese", dateInputFormat: "dd/mm/yyyy"},
|
||||
{code: "ro-ro", name: $localize`Romanian`, englishName: "Romanian", dateInputFormat: "dd.mm.yyyy"},
|
||||
{code: "ru-ru", name: $localize`Russian`, englishName: "Russian", dateInputFormat: "dd.mm.yyyy"},
|
||||
{code: "sv-se", name: $localize`Swedish`, englishName: "Swedish", dateInputFormat: "yyyy-mm-dd"}
|
||||
{
|
||||
code: 'en-us',
|
||||
name: $localize`English (US)`,
|
||||
englishName: 'English (US)',
|
||||
dateInputFormat: 'mm/dd/yyyy',
|
||||
},
|
||||
{
|
||||
code: 'cs-cz',
|
||||
name: $localize`Czech`,
|
||||
englishName: 'Czech',
|
||||
dateInputFormat: 'dd.mm.yyyy',
|
||||
},
|
||||
{
|
||||
code: 'da-dk',
|
||||
name: $localize`Danish`,
|
||||
englishName: 'Danish',
|
||||
dateInputFormat: 'dd.mm.yyyy',
|
||||
},
|
||||
{
|
||||
code: 'de-de',
|
||||
name: $localize`German`,
|
||||
englishName: 'German',
|
||||
dateInputFormat: 'dd.mm.yyyy',
|
||||
},
|
||||
{
|
||||
code: 'en-gb',
|
||||
name: $localize`English (GB)`,
|
||||
englishName: 'English (GB)',
|
||||
dateInputFormat: 'dd/mm/yyyy',
|
||||
},
|
||||
{
|
||||
code: 'es-es',
|
||||
name: $localize`Spanish`,
|
||||
englishName: 'Spanish',
|
||||
dateInputFormat: 'dd/mm/yyyy',
|
||||
},
|
||||
{
|
||||
code: 'fr-fr',
|
||||
name: $localize`French`,
|
||||
englishName: 'French',
|
||||
dateInputFormat: 'dd/mm/yyyy',
|
||||
},
|
||||
{
|
||||
code: 'it-it',
|
||||
name: $localize`Italian`,
|
||||
englishName: 'Italian',
|
||||
dateInputFormat: 'dd/mm/yyyy',
|
||||
},
|
||||
{
|
||||
code: 'lb-lu',
|
||||
name: $localize`Luxembourgish`,
|
||||
englishName: 'Luxembourgish',
|
||||
dateInputFormat: 'dd.mm.yyyy',
|
||||
},
|
||||
{
|
||||
code: 'nl-nl',
|
||||
name: $localize`Dutch`,
|
||||
englishName: 'Dutch',
|
||||
dateInputFormat: 'dd-mm-yyyy',
|
||||
},
|
||||
{
|
||||
code: 'pl-pl',
|
||||
name: $localize`Polish`,
|
||||
englishName: 'Polish',
|
||||
dateInputFormat: 'dd.mm.yyyy',
|
||||
},
|
||||
{
|
||||
code: 'pt-br',
|
||||
name: $localize`Portuguese (Brazil)`,
|
||||
englishName: 'Portuguese (Brazil)',
|
||||
dateInputFormat: 'dd/mm/yyyy',
|
||||
},
|
||||
{
|
||||
code: 'pt-pt',
|
||||
name: $localize`Portuguese`,
|
||||
englishName: 'Portuguese',
|
||||
dateInputFormat: 'dd/mm/yyyy',
|
||||
},
|
||||
{
|
||||
code: 'ro-ro',
|
||||
name: $localize`Romanian`,
|
||||
englishName: 'Romanian',
|
||||
dateInputFormat: 'dd.mm.yyyy',
|
||||
},
|
||||
{
|
||||
code: 'ru-ru',
|
||||
name: $localize`Russian`,
|
||||
englishName: 'Russian',
|
||||
dateInputFormat: 'dd.mm.yyyy',
|
||||
},
|
||||
{
|
||||
code: 'sv-se',
|
||||
name: $localize`Swedish`,
|
||||
englishName: 'Swedish',
|
||||
dateInputFormat: 'yyyy-mm-dd',
|
||||
},
|
||||
]
|
||||
|
||||
// Sort languages by localized name at runtime
|
||||
languages.sort((a, b) => { return a.name < b.name ? -1 : 1 })
|
||||
languages.sort((a, b) => {
|
||||
return a.name < b.name ? -1 : 1
|
||||
})
|
||||
|
||||
return languages
|
||||
}
|
||||
|
||||
getDateLocaleOptions(): LanguageOption[] {
|
||||
let isoOption: LanguageOption = {code: "iso-8601", name: $localize`ISO 8601`, dateInputFormat: "yyyy-mm-dd"}
|
||||
let isoOption: LanguageOption = {
|
||||
code: 'iso-8601',
|
||||
name: $localize`ISO 8601`,
|
||||
dateInputFormat: 'yyyy-mm-dd',
|
||||
}
|
||||
return [isoOption].concat(this.getLanguageOptions())
|
||||
}
|
||||
|
||||
private getLanguageCookieName() {
|
||||
let prefix = ""
|
||||
let prefix = ''
|
||||
if (this.meta.getTag('name=cookie_prefix')) {
|
||||
prefix = this.meta.getTag('name=cookie_prefix').content
|
||||
}
|
||||
@@ -149,12 +298,18 @@ export class SettingsService {
|
||||
}
|
||||
|
||||
getLocalizedDateInputFormat(): string {
|
||||
let dateLocale = this.get(SETTINGS_KEYS.DATE_LOCALE) || this.getLanguage() || this.localeId.toLowerCase()
|
||||
return this.getDateLocaleOptions().find(o => o.code == dateLocale)?.dateInputFormat || "yyyy-mm-dd"
|
||||
let dateLocale =
|
||||
this.get(SETTINGS_KEYS.DATE_LOCALE) ||
|
||||
this.getLanguage() ||
|
||||
this.localeId.toLowerCase()
|
||||
return (
|
||||
this.getDateLocaleOptions().find((o) => o.code == dateLocale)
|
||||
?.dateInputFormat || 'yyyy-mm-dd'
|
||||
)
|
||||
}
|
||||
|
||||
get(key: string): any {
|
||||
let setting = SETTINGS.find(s => s.key == key)
|
||||
let setting = SETTINGS.find((s) => s.key == key)
|
||||
|
||||
if (!setting) {
|
||||
return null
|
||||
@@ -164,11 +319,11 @@ export class SettingsService {
|
||||
|
||||
if (value != null) {
|
||||
switch (setting.type) {
|
||||
case "boolean":
|
||||
case 'boolean':
|
||||
return JSON.parse(value)
|
||||
case "number":
|
||||
case 'number':
|
||||
return +value
|
||||
case "string":
|
||||
case 'string':
|
||||
return value
|
||||
default:
|
||||
return value
|
||||
|
Reference in New Issue
Block a user