diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 7057e34..24a2458 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -3,6 +3,7 @@ import {Routes, RouterModule} from '@angular/router'
import {CatalogComponent} from './pages/catalog/catalog.component'
import {AdministrationComponent} from './pages/administration/administration.component'
import {MiscComponent} from './pages/others/misc.component'
+import {CreConfigEditor} from './modules/configuration/config'
const routes: Routes = [{
@@ -38,6 +39,10 @@ const routes: Routes = [{
}, {
path: 'group',
loadChildren: () => import('./modules/groups/group.module').then(m => m.GroupModule)
+ }, {
+ path: 'config',
+ loadChildren: () => import('./modules/configuration/config.module').then(m => m.ConfigModule),
+ component: CreConfigEditor
}, {
path: '',
pathMatch: 'full',
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index df904ac..7f5758f 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -4,6 +4,9 @@ import {AppState} from './modules/shared/app-state'
import {SubscribingComponent} from './modules/shared/components/subscribing.component'
import {ActivatedRoute, Router} from '@angular/router'
import {ErrorService} from './modules/shared/service/error.service'
+import {ConfigService} from './modules/shared/service/config.service'
+import {Config} from './modules/shared/model/config.model'
+import {environment} from '../environments/environment'
@Component({
selector: 'cre-root',
@@ -13,9 +16,11 @@ import {ErrorService} from './modules/shared/service/error.service'
export class AppComponent extends SubscribingComponent {
isOnline: boolean
isServerOnline = true
+ favIcon: HTMLLinkElement = document.querySelector('#favicon')
constructor(
@Inject(PLATFORM_ID) private platformId: object,
+ private configService: ConfigService,
private appState: AppState,
errorService: ErrorService,
router: Router,
@@ -32,6 +37,8 @@ export class AppComponent extends SubscribingComponent {
this.appState.serverOnline$,
online => this.isServerOnline = online
)
+
+ this.favIcon.href = environment.apiUrl + "/file?path=images%2Ficon"
}
reload() {
diff --git a/src/app/modules/colors/components/step-list/step-list.component.html b/src/app/modules/colors/components/step-list/step-list.component.html
index efb9c0c..c53850d 100644
--- a/src/app/modules/colors/components/step-list/step-list.component.html
+++ b/src/app/modules/colors/components/step-list/step-list.component.html
@@ -9,7 +9,7 @@
-
Aucun groupe n'est sélectionné
- Il n'y a aucune étape définie pour ce groupe
+ Aucun groupe n'est sélectionné
+ Il n'y a aucune étape définie pour ce groupe
diff --git a/src/app/modules/colors/components/step-table/step-table.component.html b/src/app/modules/colors/components/step-table/step-table.component.html
index 115f924..800b6a4 100644
--- a/src/app/modules/colors/components/step-table/step-table.component.html
+++ b/src/app/modules/colors/components/step-table/step-table.component.html
@@ -12,7 +12,7 @@
- Aucun groupe n'est sélectionné
+ Aucun groupe n'est sélectionné
this.recipes = recipes
+ this.configService.get(Config.EMERGENCY_MODE),
+ config => {
+ if (config.content === "false") {
+ this.subscribe(
+ this.recipeService.allSortedByCompany,
+ recipes => this.recipes = recipes
+ )
+ } else {
+ this.urlUtils.navigateTo("/admin/config")
+ }
+ }
)
}
diff --git a/src/app/modules/configuration/bool-config.html b/src/app/modules/configuration/bool-config.html
new file mode 100644
index 0000000..53c694c
--- /dev/null
+++ b/src/app/modules/configuration/bool-config.html
@@ -0,0 +1,4 @@
+
+
+ Dernière mise à jour: {{lastUpdated}}
+
diff --git a/src/app/modules/configuration/config-actions.html b/src/app/modules/configuration/config-actions.html
new file mode 100644
index 0000000..d152dd7
--- /dev/null
+++ b/src/app/modules/configuration/config-actions.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/src/app/modules/configuration/config-section.html b/src/app/modules/configuration/config-section.html
new file mode 100644
index 0000000..08c2b94
--- /dev/null
+++ b/src/app/modules/configuration/config-section.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/app/modules/configuration/config.html b/src/app/modules/configuration/config.html
new file mode 100644
index 0000000..12f2ef0
--- /dev/null
+++ b/src/app/modules/configuration/config.html
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/src/app/modules/configuration/config.module.ts b/src/app/modules/configuration/config.module.ts
new file mode 100644
index 0000000..05dee32
--- /dev/null
+++ b/src/app/modules/configuration/config.module.ts
@@ -0,0 +1,35 @@
+import {NgModule} from '@angular/core'
+import {
+ CreConfig,
+ CreConfigLabel,
+ CreConfigEditor,
+ CreConfigSection,
+ CreImageConfig,
+ CreConfigList,
+ CreConfigActions,
+ CreConfigTooltip
+} from './config'
+import {SharedModule} from '../shared/shared.module'
+import {CreInputsModule} from '../shared/components/inputs/inputs.module'
+import {CreActionBarModule} from '../shared/components/action-bar/action-bar.module'
+import {CreButtonsModule} from '../shared/components/buttons/buttons.module'
+
+@NgModule({
+ declarations: [
+ CreConfigLabel,
+ CreConfigTooltip,
+ CreConfigEditor,
+ CreConfig,
+ CreImageConfig,
+ CreConfigSection,
+ CreConfigList,
+ CreConfigActions
+ ],
+ imports: [
+ SharedModule,
+ CreInputsModule,
+ CreActionBarModule,
+ CreButtonsModule
+ ]
+})
+export class ConfigModule { }
diff --git a/src/app/modules/configuration/config.sass b/src/app/modules/configuration/config.sass
new file mode 100644
index 0000000..6812169
--- /dev/null
+++ b/src/app/modules/configuration/config.sass
@@ -0,0 +1,52 @@
+mat-hint
+ font-size: .8em
+
+cre-config
+ display: block
+
+ cre-input.has-hint
+ margin-bottom: 1em
+
+ mat-hint
+ font-size: 1em
+
+cre-image-config
+ display: block
+ border: 1px solid rgba(0, 0, 0, 0.42)
+ border-radius: 4px
+ padding: 8px
+ position: relative
+ margin-bottom: 1.34375em
+ transition: border-color 300ms
+
+ &:hover
+ border: 2px solid black
+ padding: 7px
+
+ .cre-image-config-label
+ top: -10px
+ left: 3px
+
+ .cre-image-config-label
+ position: absolute
+ top: -9px
+ left: 4px
+ margin-bottom: 0
+ background-color: white
+ padding: 0 5px
+ color: rgba(0, 0, 0, 0.52)
+ font-size: .8em
+
+ .image-wrapper
+ width: 200px
+ text-align: right
+
+ hr
+ margin: 0 0 .5em
+ background-color: rgba(0, 0, 0, 0.42)
+
+ img
+ border: 2px solid black
+
+ mat-hint
+ margin-top: .2em
diff --git a/src/app/modules/configuration/config.ts b/src/app/modules/configuration/config.ts
new file mode 100644
index 0000000..5332d13
--- /dev/null
+++ b/src/app/modules/configuration/config.ts
@@ -0,0 +1,228 @@
+import {
+ AfterViewInit,
+ Component,
+ ContentChild,
+ Directive,
+ ElementRef,
+ EventEmitter,
+ Input,
+ Output,
+ ViewChild,
+ ViewEncapsulation
+} from '@angular/core'
+import {ConfigService} from '../shared/service/config.service'
+import {Config} from '../shared/model/config.model'
+import {ErrorHandlingComponent, SubscribingComponent} from '../shared/components/subscribing.component'
+import {ErrorService} from '../shared/service/error.service'
+import {ActivatedRoute, Router} from '@angular/router'
+import {formatDateTime, readFile} from '../shared/utils/utils'
+import {FormControl, Validators} from '@angular/forms'
+import {ConfirmBoxComponent} from '../shared/components/confirm-box/confirm-box.component'
+
+@Directive({
+ selector: 'cre-config-label'
+})
+export class CreConfigLabel implements AfterViewInit {
+ content: string
+
+ constructor(
+ private element: ElementRef
+ ) {
+ }
+
+ ngAfterViewInit(): void {
+ this.content = this.element.nativeElement.innerHTML
+ }
+}
+
+@Directive({
+ selector: 'cre-config-tooltip'
+})
+export class CreConfigTooltip implements AfterViewInit {
+ content: string
+
+ constructor(
+ private element: ElementRef
+ ) {
+ }
+
+ ngAfterViewInit(): void {
+ this.content = this.element.nativeElement.innerHTML
+ }
+}
+
+@Directive({
+ selector: 'cre-config-list'
+})
+export class CreConfigList {
+}
+
+@Component({
+ selector: 'cre-config-actions',
+ templateUrl: 'config-actions.html'
+})
+export class CreConfigActions {
+}
+
+@Component({
+ selector: 'cre-config-section',
+ templateUrl: 'config-section.html'
+})
+export class CreConfigSection {
+ @ContentChild(CreConfigActions) actions: CreConfigActions
+
+ get hasActions(): boolean {
+ return this.actions !== undefined
+ }
+}
+
+@Component({
+ selector: 'cre-config',
+ templateUrl: 'config.html',
+ styleUrls: ['config.sass']
+})
+export class CreConfig extends SubscribingComponent {
+ @Input() config: { key: string, control: FormControl }
+
+ @ContentChild(CreConfigLabel, {static: true}) label: CreConfigLabel
+ @ContentChild(CreConfigTooltip, {static: true}) tooltip: CreConfigTooltip
+
+ configuration: Config | null
+
+ constructor(
+ private configService: ConfigService,
+ errorService: ErrorService,
+ activatedRoute: ActivatedRoute,
+ router: Router
+ ) {
+ super(errorService, activatedRoute, router)
+ }
+
+ ngOnInit() {
+ super.ngOnInit()
+
+ this.subscribe(
+ this.configService.get(this.config.key),
+ config => this.setConfig(config)
+ )
+ }
+
+ setConfig(config: Config) {
+ this.configuration = config
+ this.config.control.setValue(config.content)
+ if (!config.editable) {
+ this.config.control.disable()
+ }
+ }
+
+ get lastUpdated(): string {
+ return formatDateTime(this.configuration.lastUpdated)
+ }
+}
+
+@Component({
+ selector: 'cre-image-config',
+ templateUrl: 'image-config.html',
+ styleUrls: ['config.sass'],
+ encapsulation: ViewEncapsulation.None
+})
+export class CreImageConfig extends CreConfig {
+ @Input() previewWidth: string | null
+
+ @Output() invalidFormat = new EventEmitter()
+
+ updatedImage: any | null
+
+ constructor(
+ configService: ConfigService,
+ errorService: ErrorService,
+ activatedRoute: ActivatedRoute,
+ router: Router
+ ) {
+ super(configService, errorService, activatedRoute, router)
+ }
+
+ updateImage(file: File): any {
+ readFile(file, (content) => this.updatedImage = content)
+ }
+}
+
+@Component({
+ selector: 'cre-bool-config',
+ templateUrl: 'bool-config.html'
+})
+export class CreBoolConfig extends CreConfig {
+ setConfig(config: Config) {
+ super.setConfig(config);
+ this.config.control.setValue(config.content === "true")
+ }
+}
+
+@Component({
+ selector: 'cre-config-editor',
+ templateUrl: 'editor.html'
+})
+export class CreConfigEditor extends ErrorHandlingComponent {
+ @ViewChild('restartingConfirmBox', {static: true}) restartConfirmBox: ConfirmBoxComponent
+
+ keys = {
+ INSTANCE_NAME: Config.INSTANCE_NAME,
+ INSTANCE_LOGO_PATH: Config.INSTANCE_LOGO_PATH,
+ INSTANCE_ICON_PATH: Config.INSTANCE_ICON_PATH,
+ INSTANCE_URL: Config.INSTANCE_URL,
+ DATABASE_URL: Config.DATABASE_URL,
+ DATABASE_USER: Config.DATABASE_USER,
+ DATABASE_PASSWORD: Config.DATABASE_PASSWORD,
+ DATABASE_VERSION: Config.DATABASE_VERSION,
+ TOUCH_UP_KIT_CACHE_PDF: Config.TOUCH_UP_KIT_CACHE_PDF,
+ APP_VERSION: Config.APP_VERSION,
+ JAVA_VERSION: Config.JAVA_VERSION,
+ OPERATING_SYSTEM: Config.OPERATING_SYSTEM
+ }
+ controls = new Map()
+ emergencyMode: string | null
+
+ constructor(
+ private configService: ConfigService,
+ errorService: ErrorService,
+ activatedRoute: ActivatedRoute,
+ router: Router
+ ) {
+ super(errorService, activatedRoute, router)
+
+ for (let key in this.keys) {
+ this.controls[this.keys[key]] = new FormControl(null, Validators.required)
+ }
+ }
+
+ ngOnInit() {
+ this.subscribe(
+ this.configService.get(Config.EMERGENCY_MODE),
+ config => {
+ this.emergencyMode = config.content
+ }
+ )
+ }
+
+ getConfig(key: string) {
+ return {key, control: this.controls[key]}
+ }
+
+ save() {
+ this.subscribe(
+ this.configService.set(this.controls),
+ () => this.reload()
+ )
+ }
+
+ restart() {
+ this.subscribe(
+ this.configService.restart(),
+ () => this.restartConfirmBox.show()
+ )
+ }
+
+ reload() {
+ window.location.reload()
+ }
+}
diff --git a/src/app/modules/configuration/editor.html b/src/app/modules/configuration/editor.html
new file mode 100644
index 0000000..0deb9df
--- /dev/null
+++ b/src/app/modules/configuration/editor.html
@@ -0,0 +1,105 @@
+
+
+ Retour
+
+
+ Enregistrer
+
+
+
+
+
+ Apparence
+
+
+
+
+
+
+
+
+
+ Logo
+
+ Affiché dans la bannière de l'application web. Il peut être nécessaire de forcer le
+ rafraîchissement du cache du navigateur pour que ce changement prenne effet (généralement avec les touches
+ 'Ctrl+F5').
+
+
+
+
+ Icône
+
+ Affiché dans l'onglet de la page dans le navigateur. Il peut être nécessaire de forcer le
+ rafraîchissement du cache du navigateur pour que ce changement prenne effet (généralement avec les touches
+ 'Ctrl+F5').
+
+
+
+
+
+
+ Kits de retouche
+
+
+ Activer le cache des PDFs générés
+
+ Cette option permet de stocker les PDFs générés sur le disque, ce qui permet d'accélérer
+ l'accès aux PDFs si la lecture des fichiers cachés sur le disque est plus rapide que la génération d'un
+ nouveau PDF.
+
+
+
+
+
+
+ Système
+
+
+ URL de l'instance
+
+ Utilisé pour générer l'URL de certaines ressources, comme les images et les fiches signalitiques.
+
+
+
+
+ URL de la base de données
+
+
+
+ Utilisateur de la base de données
+
+
+
+ Mot de passe de la base de données
+
+
+
+ Version de la base de données
+
+
+
+ Version de Color Recipes Explorer
+
+
+
+ Version de Java
+
+
+
+ Système d'exploitation
+
+
+
+ Redémarrer le serveur
+
+
+
+
+
+
+
diff --git a/src/app/modules/configuration/image-config.html b/src/app/modules/configuration/image-config.html
new file mode 100644
index 0000000..6056487
--- /dev/null
+++ b/src/app/modules/configuration/image-config.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
Dernière mise à jour: {{lastUpdated}}
+
+
diff --git a/src/app/modules/shared/components/header/header.component.html b/src/app/modules/shared/components/header/header.component.html
index 7a2bb30..a5382f8 100644
--- a/src/app/modules/shared/components/header/header.component.html
+++ b/src/app/modules/shared/components/header/header.component.html
@@ -19,7 +19,8 @@
+ title="Color Recipes Explorer"
+ height="70px"/>
diff --git a/src/app/modules/shared/components/header/header.component.ts b/src/app/modules/shared/components/header/header.component.ts
index 470a396..882d013 100644
--- a/src/app/modules/shared/components/header/header.component.ts
+++ b/src/app/modules/shared/components/header/header.component.ts
@@ -5,6 +5,8 @@ import {Permission} from '../../model/user'
import {AccountService} from '../../../accounts/services/account.service'
import {SubscribingComponent} from '../subscribing.component'
import {ErrorService} from '../../service/error.service'
+import {ConfigService} from '../../service/config.service'
+import {environment} from '../../../../../environments/environment'
@Component({
selector: 'cre-header',
@@ -22,6 +24,7 @@ export class HeaderComponent extends SubscribingComponent {
constructor(
private accountService: AccountService,
+ private configService: ConfigService,
private appState: AppState,
errorService: ErrorService,
router: Router,
@@ -62,6 +65,10 @@ export class HeaderComponent extends SubscribingComponent {
super.ngOnDestroy()
}
+ get logoUrl(): string {
+ return environment.apiUrl + "/file?path=images%2Flogo"
+ }
+
set activeLink(link: string) {
this._activeLink = link
this.router.navigate([link])
diff --git a/src/app/modules/shared/components/inputs/checkbox.html b/src/app/modules/shared/components/inputs/checkbox.html
new file mode 100644
index 0000000..dbadabf
--- /dev/null
+++ b/src/app/modules/shared/components/inputs/checkbox.html
@@ -0,0 +1,3 @@
+
+ {{label}}
+
diff --git a/src/app/modules/shared/components/inputs/file-input.html b/src/app/modules/shared/components/inputs/file-input.html
new file mode 100644
index 0000000..5bf6c13
--- /dev/null
+++ b/src/app/modules/shared/components/inputs/file-input.html
@@ -0,0 +1,10 @@
+
+
Choisir un fichier
+
+
+
{{selectedFileName}}
+
Aucun fichier sélectionné
+
+
+
+
diff --git a/src/app/modules/shared/components/inputs/input.html b/src/app/modules/shared/components/inputs/input.html
index d7ef1cd..d123b75 100644
--- a/src/app/modules/shared/components/inputs/input.html
+++ b/src/app/modules/shared/components/inputs/input.html
@@ -9,6 +9,7 @@
[(ngModel)]="value"
[required]="required"
[autocomplete]="autocomplete ? 'on' : 'off'"
+ [disabled]="disabled"
(change)="valueChange.emit(value)"/>
-
+
+
+ {{hint}}
Ce champ est requis
()
@@ -174,6 +180,50 @@ export class CreChipComboBoxComponent extends CreChipInputComponent implements O
}
}
+@Component({
+ selector: 'cre-checkbox-input',
+ templateUrl: 'checkbox.html'
+})
+export class CreCheckboxInputComponent {
+ @Input() label: string
+ @Input() control: FormControl
+}
+
+@Component({
+ selector: 'cre-file-input',
+ templateUrl: 'file-input.html'
+})
+export class CreFileInputComponent implements OnInit {
+ @Input() label: string
+ @Input() icon: string
+ @Input() accept = ''
+ @Input() control: FormControl | null
+
+ @Output() selection = new EventEmitter()
+ @Output() invalidFormat = new EventEmitter()
+
+ private acceptedMediaTypes: string[]
+
+ ngOnInit(): void {
+ this.acceptedMediaTypes = this.accept.split(',')
+ }
+
+ selectedFile: File | null
+ selectedFileName: string
+
+ onFileSelected(event: any) {
+ this.selectedFile = event.target.files[0]
+ if (this.acceptedMediaTypes.indexOf(this.selectedFile.type) >= 0) {
+ this.selectedFileName = this.selectedFile.name
+ this.control?.setValue(this.selectedFile)
+ this.control?.markAsDirty()
+ this.selection.emit(this.selectedFile)
+ } else {
+ this.invalidFormat.emit()
+ }
+ }
+}
+
export class ComboBoxEntry {
constructor(
public key: any,
diff --git a/src/app/modules/shared/model/config.model.ts b/src/app/modules/shared/model/config.model.ts
new file mode 100644
index 0000000..2d96d4d
--- /dev/null
+++ b/src/app/modules/shared/model/config.model.ts
@@ -0,0 +1,24 @@
+export class Config {
+ static readonly INSTANCE_NAME = 'instance.name'
+ static readonly INSTANCE_LOGO_PATH = 'instance.logo.path'
+ static readonly INSTANCE_ICON_PATH = 'instance.icon.path'
+ static readonly INSTANCE_URL = 'instance.url'
+ static readonly DATABASE_URL = 'database.url'
+ static readonly DATABASE_USER = 'database.user'
+ static readonly DATABASE_PASSWORD = 'database.password'
+ static readonly DATABASE_VERSION = 'database.version.supported'
+ static readonly TOUCH_UP_KIT_CACHE_PDF = 'touchupkit.pdf.cache'
+ static readonly EMERGENCY_MODE = 'env.emergency'
+ static readonly APP_VERSION = 'env.version'
+ static readonly JAVA_VERSION = 'env.java.version'
+ static readonly OPERATING_SYSTEM = 'env.os'
+
+ constructor(
+ public key: string,
+ public content: string,
+ public lastUpdated: string,
+ public requireRestart: boolean,
+ public editable: boolean
+ ) {
+ }
+}
diff --git a/src/app/modules/shared/service/config.service.ts b/src/app/modules/shared/service/config.service.ts
new file mode 100644
index 0000000..880b697
--- /dev/null
+++ b/src/app/modules/shared/service/config.service.ts
@@ -0,0 +1,61 @@
+import {Injectable} from '@angular/core'
+import {Config} from '../model/config.model'
+import {Observable} from 'rxjs'
+import {ApiService} from './api.service'
+import {FormControl} from '@angular/forms'
+
+const imageConfigsKeys = [
+ Config.INSTANCE_LOGO_PATH,
+ Config.INSTANCE_ICON_PATH
+]
+
+@Injectable({
+ providedIn: 'root'
+})
+export class ConfigService {
+ constructor(
+ private api: ApiService
+ ) {
+ }
+
+ get(key: string): Observable {
+ return this.api.get(`/config/${key}`)
+ }
+
+ set(configs: Map): Observable {
+ const body = []
+ for (let key in configs) {
+ const control = configs[key]
+ if (control.dirty && key.indexOf('path') < 0) {
+ body.push({key, content: control.value})
+ }
+ }
+
+ const subscriptions = []
+ imageConfigsKeys.forEach(key => {
+ if (configs[key].dirty) {
+ subscriptions.push(this.setImage(key, configs[key].value))
+ }
+ })
+
+ while (subscriptions.length > 0) {
+ const subscription = subscriptions.pop().subscribe({
+ next: () => subscription.unsubscribe()
+ })
+ }
+
+ return this.api.put('/config', body)
+ }
+
+ setImage(key: string, image: File): Observable {
+ const body = new FormData()
+ body.append('key', key)
+ body.append('image', image)
+
+ return this.api.put('/config/image', body)
+ }
+
+ restart(): Observable {
+ return this.api.post('/config/restart')
+ }
+}
diff --git a/src/app/modules/shared/utils/utils.ts b/src/app/modules/shared/utils/utils.ts
index e9eaab1..4ff71e9 100644
--- a/src/app/modules/shared/utils/utils.ts
+++ b/src/app/modules/shared/utils/utils.ts
@@ -1,5 +1,5 @@
/** Returns [value] if it is not null or [or]. */
-import {DateTimeFormatter, LocalDate} from 'js-joda'
+import {DateTimeFormatter, LocalDate, LocalDateTime} from 'js-joda'
import {TouchUpKit} from '../model/touch-up-kit.model'
import {environment} from '../../../../environments/environment'
@@ -32,13 +32,27 @@ export function openRawUrl(url: string) {
const dateFormatter = DateTimeFormatter
.ofPattern('dd-MM-yyyy')
+const dateTimeFormatter = DateTimeFormatter
+ .ofPattern('dd-MM-yyyy HH:mm:ss')
export function formatDate(date: string): string {
return LocalDate.parse(date).format(dateFormatter)
}
+export function formatDateTime(dateTime: string): string {
+ return LocalDateTime.parse(dateTime).format(dateTimeFormatter)
+}
+
export function reduceDashes(arr: string[]): string {
return arr.reduce((acc, cur) => {
return `${acc} - ${cur}`
})
}
+
+export function readFile(file: File, consumer: (any) => void) {
+ const reader = new FileReader()
+ reader.onload = (e: any) => {
+ consumer(e.target.result)
+ }
+ reader.readAsDataURL(file)
+}
diff --git a/src/app/pages/administration/administration.component.ts b/src/app/pages/administration/administration.component.ts
index 3406db0..c67a13e 100644
--- a/src/app/pages/administration/administration.component.ts
+++ b/src/app/pages/administration/administration.component.ts
@@ -12,5 +12,6 @@ export class AdministrationComponent extends SubMenuComponent {
links: NavLink[] = [
{route: '/admin/user', title: 'Utilisateurs', permission: Permission.VIEW_USERS},
{route: '/admin/group', title: 'Groupes', permission: Permission.VIEW_USERS},
+ {route: '/admin/config', title: 'Configuration', permission: Permission.ADMIN}
]
}
diff --git a/src/assets/favicon.png b/src/assets/favicon.png
index 22ef30a..1e877b7 100644
Binary files a/src/assets/favicon.png and b/src/assets/favicon.png differ
diff --git a/src/index.html b/src/index.html
index 852a73c..52117bc 100644
--- a/src/index.html
+++ b/src/index.html
@@ -5,7 +5,7 @@
Color Recipes Explorer
-
+
diff --git a/src/styles.sass b/src/styles.sass
index 5570317..218755c 100644
--- a/src/styles.sass
+++ b/src/styles.sass
@@ -170,7 +170,7 @@ div.empty
.alert p
margin-bottom: 0
-.empty-text
+.light-text
color: rgba(0, 0, 0, 0.54)
.dark-background