From bda89943a89b1be89c0c98d86ba29ad5defb430f Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Thu, 17 May 2018 10:38:13 +0100 Subject: [PATCH] [desktop] settings dialog (#360) * settings route * settings component * translate strings * use 'www' output folder for electron builds --- .gitignore | 1 + package.json | 2 +- src/app/app.module.ts | 8 +- src/app/app.routes.ts | 8 ++ .../services/hybrid-app-config.service.ts | 37 ++++++++ .../settings/settings.component.html | 43 +++++++++ .../settings/settings.component.scss | 69 +++++++++++++++ .../components/settings/settings.component.ts | 88 +++++++++++++++++++ src/assets/i18n/en.json | 7 ++ 9 files changed, 260 insertions(+), 3 deletions(-) create mode 100644 src/app/common/services/hybrid-app-config.service.ts create mode 100644 src/app/components/settings/settings.component.html create mode 100644 src/app/components/settings/settings.component.scss create mode 100644 src/app/components/settings/settings.component.ts diff --git a/.gitignore b/.gitignore index c5d885dad..e2df279f2 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ npm-debug.log testem.log /typings +/www # e2e /e2e/*.js diff --git a/package.json b/package.json index be7e9ff6e..ef8c23ba5 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "build:prod": "npm run server-versions && ng build --prod", "build:dev": "npm run server-versions && ng build", "build:tomcat": "npm run server-versions && ng build --base-href ./", - "build:electron": "npm run server-versions && ng build --base-href ./", + "build:electron": "npm run server-versions && ng build --output-path www --base-href ./", "test": "ng test --code-coverage", "test:ci": "ng test --code-coverage --single-run --no-progress && cat ./coverage/lcov.info | ./node_modules/.bin/codacy-coverage && rm -rf ./coverage", "lint": "ng lint", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 519b51d76..f12f94d52 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -28,7 +28,7 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { TRANSLATION_PROVIDER, CoreModule } from '@alfresco/adf-core'; +import { TRANSLATION_PROVIDER, CoreModule, AppConfigService } from '@alfresco/adf-core'; import { ContentModule } from '@alfresco/adf-content-services'; import { ElectronModule } from '@ngstack/electron'; @@ -66,6 +66,8 @@ import { NodeActionsService } from './common/services/node-actions.service'; import { NodePermissionService } from './common/services/node-permission.service'; import { MatMenuModule, MatIconModule, MatButtonModule, MatDialogModule, MatInputModule } from '@angular/material'; import { SearchComponent } from './components/search/search.component'; +import { SettingsComponent } from './components/settings/settings.component'; +import { HybridAppConfigService } from './common/services/hybrid-app-config.service'; @NgModule({ imports: [ @@ -113,9 +115,11 @@ import { SearchComponent } from './components/search/search.component'; NodeInfoDirective, NodeVersionsDirective, VersionManagerDialogAdapterComponent, - SearchComponent + SearchComponent, + SettingsComponent ], providers: [ + { provide: AppConfigService, useClass: HybridAppConfigService }, { provide: TRANSLATION_PROVIDER, multi: true, diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index 3a098acb5..eb6089c30 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -40,6 +40,7 @@ import { LoginComponent } from './components/login/login.component'; import { PreviewComponent } from './components/preview/preview.component'; import { GenericErrorComponent } from './components/generic-error/generic-error.component'; import { SearchComponent } from './components/search/search.component'; +import { SettingsComponent } from './components/settings/settings.component'; export const APP_ROUTES: Routes = [ { @@ -49,6 +50,13 @@ export const APP_ROUTES: Routes = [ i18nTitle: 'APP.SIGN_IN' } }, + { + path: 'settings', + component: SettingsComponent, + data: { + i18nTitle: 'Settings' + } + }, { path: '', component: LayoutComponent, diff --git a/src/app/common/services/hybrid-app-config.service.ts b/src/app/common/services/hybrid-app-config.service.ts new file mode 100644 index 000000000..9aa53e017 --- /dev/null +++ b/src/app/common/services/hybrid-app-config.service.ts @@ -0,0 +1,37 @@ +/*! + * @license + * Copyright 2016 Alfresco Software, Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { AppConfigService, StorageService } from '@alfresco/adf-core'; + +@Injectable() +export class HybridAppConfigService extends AppConfigService { + + constructor(private storage: StorageService, http: HttpClient) { + super(http); + } + + /** @override */ + get(key: string, defaultValue?: T): T { + if (key === 'ecmHost' || key === 'bpmHost') { + return ( this.storage.getItem(key) || super.get(key)); + } + return super.get(key, defaultValue); + } + +} diff --git a/src/app/components/settings/settings.component.html b/src/app/components/settings/settings.component.html new file mode 100644 index 000000000..89c2e8cb7 --- /dev/null +++ b/src/app/components/settings/settings.component.html @@ -0,0 +1,43 @@ + + + + {{ appName }} + + + + +
+ + + + {{ 'APP.SETTINGS.REPOSITORY-SETTINGS' | translate }} + + +
+ + + + {{ 'APP.SETTINGS.INVALID-VALUE-FORMAT' | translate }} + + + {{ 'APP.SETTINGS.REQUIRED-FIELD' | translate }} + + +
+ +
+ + +
+ +
+
+
diff --git a/src/app/components/settings/settings.component.scss b/src/app/components/settings/settings.component.scss new file mode 100644 index 000000000..ad87b6492 --- /dev/null +++ b/src/app/components/settings/settings.component.scss @@ -0,0 +1,69 @@ +@import 'variables'; + +.app-settings { + .settings-input { + width: 50%; + } + + .settings-buttons { + text-align: right; + + .mat-button { + text-transform: uppercase; + } + } + + $app-menu-height: 64px; + + .app-menu { + height: $app-menu-height; + + &.adf-toolbar { + .mat-toolbar { + background-color: inherit; + font-family: inherit; + min-height: $app-menu-height; + height: $app-menu-height; + + .mat-toolbar-layout { + height: $app-menu-height; + + .mat-toolbar-row { + height: $app-menu-height; + } + } + } + + .adf-toolbar-divider { + margin-left: 5px; + margin-right: 5px; + + & > div { + background-color: $alfresco-white !important; + } + } + + .adf-toolbar-title { + color: $alfresco-white; + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + } + } + + .app-menu__title { + width: 100px; + height: 50px; + margin-left: 40px; + display: flex; + justify-content: center; + align-items: stretch; + + &> img { + width: 100%; + object-fit: contain; + } + } + } +} diff --git a/src/app/components/settings/settings.component.ts b/src/app/components/settings/settings.component.ts new file mode 100644 index 000000000..f0087bb06 --- /dev/null +++ b/src/app/components/settings/settings.component.ts @@ -0,0 +1,88 @@ +/*! + * @license + * Alfresco Example Content Application + * + * Copyright (C) 2005 - 2018 Alfresco Software Limited + * + * This file is part of the Alfresco Example Content Application. + * If the software was purchased under a paid Alfresco license, the terms of + * the paid license agreement will prevail. Otherwise, the software is + * provided under the following open source license terms: + * + * The Alfresco Example Content Application is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The Alfresco Example Content Application is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Alfresco. If not, see . + */ + +import { Component, ViewEncapsulation, SecurityContext, OnInit } from '@angular/core'; +import { AppConfigService, StorageService, SettingsService } from '@alfresco/adf-core'; +import { DomSanitizer } from '@angular/platform-browser'; +import { Validators, FormGroup, FormBuilder } from '@angular/forms'; + +@Component({ + selector: 'app-settings', + templateUrl: './settings.component.html', + styleUrls: ['./settings.component.scss'], + encapsulation: ViewEncapsulation.None, + // tslint:disable-next-line:use-host-property-decorator + host: { class: 'app-settings' } +}) +export class SettingsComponent implements OnInit { + + private defaultPath = '/assets/images/alfresco-logo-white.svg'; + private defaultBackgroundColor = '#2196F3'; + + form: FormGroup; + + constructor( + private appConfig: AppConfigService, + private sanitizer: DomSanitizer, + private settingsService: SettingsService, + private storage: StorageService, + private fb: FormBuilder) { + + } + + get appName(): string { + return this.appConfig.get('application.name'); + } + + get logo() { + return this.appConfig.get('application.logo', this.defaultPath); + } + + get backgroundColor() { + const color = this.appConfig.get('headerColor', this.defaultBackgroundColor); + return this.sanitizer.sanitize(SecurityContext.STYLE, color); + } + + ngOnInit() { + this.form = this.fb.group({ + ecmHost: ['', [Validators.required, Validators.pattern('^(http|https):\/\/.*[^/]$')]] + }); + + this.reset(); + } + + apply(model: any, isValid: boolean) { + if (isValid) { + this.storage.setItem('ecmHost', model.ecmHost); + // window.location.reload(true); + } + } + + reset() { + this.form.reset({ + ecmHost: this.storage.getItem('ecmHost') || this.settingsService.ecmHost + }); + } +} diff --git a/src/assets/i18n/en.json b/src/assets/i18n/en.json index 8d0e088ed..0316a4f36 100644 --- a/src/assets/i18n/en.json +++ b/src/assets/i18n/en.json @@ -3,6 +3,13 @@ "LANGUAGE": "Language", "SIGN_IN": "Sign in", "SIGN_OUT": "Sign out", + "SETTINGS": { + "REPOSITORY-SETTINGS": "Repository Settings", + "INVALID-VALUE-FORMAT": "Invalid value format", + "REQUIRED-FIELD": "This field is required", + "RESET": "Reset", + "APPLY": "Apply" + }, "PREVIEW": { "TITLE": "Preview" },