Merge pull request #1825 from steven-zou/dev

Fixed issue #1694, #1761, #1707
This commit is contained in:
Steven Zou 2017-03-28 15:00:07 +08:00 committed by GitHub
commit f62b890f0d
14 changed files with 156 additions and 144 deletions

View File

@ -3,10 +3,8 @@ import { NgForm } from '@angular/forms';
import { SessionUser } from '../../shared/session-user';
import { SessionService } from '../../shared/session.service';
import { MessageService } from '../../global-message/message.service';
import { AlertType, httpStatusCode } from '../../shared/shared.const';
import { errorHandler, accessErrorHandler } from '../../shared/shared.utils';
import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component';
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
@Component({
selector: "account-settings-modal",
@ -38,7 +36,7 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
constructor(
private session: SessionService,
private msgService: MessageService) { }
private msgHandler: MessageHandlerService) { }
ngOnInit(): void {
//Value copy
@ -112,10 +110,10 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
}
public get isValid(): boolean {
return this.accountForm &&
this.accountForm.valid &&
this.error === null &&
this.validationStateMap["account_settings_email"]; //backend check is valid as well
return this.accountForm &&
this.accountForm.valid &&
this.error === null &&
this.validationStateMap["account_settings_email"]; //backend check is valid as well
}
public get showProgress(): boolean {
@ -182,14 +180,15 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
.then(() => {
this.isOnCalling = false;
this.opened = false;
this.msgService.announceMessage(200, "PROFILE.SAVE_SUCCESS", AlertType.SUCCESS);
this.msgHandler.showSuccess("PROFILE.SAVE_SUCCESS");
})
.catch(error => {
this.isOnCalling = false;
this.error = error;
if (accessErrorHandler(error, this.msgService)) {
if (this.msgHandler.isAppLevel(error)) {
this.opened = false;
} else {
this.msgHandler.handleError(error);
}else{
this.inlineAlert.showInlineError(error);
}
});

View File

@ -4,10 +4,9 @@ import { NgForm } from '@angular/forms';
import { PasswordSettingService } from './password-setting.service';
import { SessionService } from '../../shared/session.service';
import { AlertType, httpStatusCode } from '../../shared/shared.const';
import { MessageService } from '../../global-message/message.service';
import { errorHandler, isEmptyForm, accessErrorHandler } from '../../shared/shared.utils';
import { isEmptyForm } from '../../shared/shared.utils';
import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component';
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
@Component({
selector: 'password-setting',
@ -36,7 +35,7 @@ export class PasswordSettingComponent implements AfterViewChecked {
constructor(
private passwordService: PasswordSettingService,
private session: SessionService,
private msgService: MessageService) { }
private msgHandler: MessageHandlerService) { }
//If form is valid
public get isValid(): boolean {
@ -66,10 +65,10 @@ export class PasswordSettingComponent implements AfterViewChecked {
let cont = this.pwdForm.controls[key];
if (cont) {
this.validationStateMap[key] = cont.valid;
if(key === "reNewPassword" && cont.valid){
if (key === "reNewPassword" && cont.valid) {
let compareCont = this.pwdForm.controls["newPassword"];
if(compareCont){
this.validationStateMap[key]= cont.value === compareCont.value;
if (compareCont) {
this.validationStateMap[key] = cont.value === compareCont.value;
}
}
}
@ -145,16 +144,23 @@ export class PasswordSettingComponent implements AfterViewChecked {
})
.then(() => {
this.onCalling = false;
this.opened = false;
this.msgService.announceMessage(200, "CHANGE_PWD.SAVE_SUCCESS", AlertType.SUCCESS);
this.opened = false
this.msgHandler.showSuccess("CHANGE_PWD.SAVE_SUCCESS");
})
.catch(error => {
this.onCalling = false;
this.error = error;
if(accessErrorHandler(error, this.msgService)){
if (this.msgHandler.isAppLevel(error)) {
this.opened = false;
}else{
this.inlineAlert.showInlineError(error);
this.msgHandler.handleError(error);
} else {
//Special case for 400
let msg = '' + error._body;
if (msg && msg.includes('old_password_is_not_correct')) {
this.inlineAlert.showInlineError("INCONRRECT_OLD_PWD");
} else {
this.inlineAlert.showInlineError(error);
}
}
});
}

View File

@ -4,16 +4,14 @@ import { NgForm } from '@angular/forms';
import { PasswordSettingService } from './password-setting.service';
import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component';
import { errorHandler, accessErrorHandler } from '../../shared/shared.utils';
import { AlertType } from '../../shared/shared.const';
import { MessageService } from '../../global-message/message.service';
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
@Component({
selector: 'reset-password',
templateUrl: "reset-password.component.html",
styleUrls: ['password.component.css', '../../common.css']
})
export class ResetPasswordComponent implements OnInit{
export class ResetPasswordComponent implements OnInit {
opened: boolean = true;
private onGoing: boolean = false;
private password: string = "";
@ -28,7 +26,7 @@ export class ResetPasswordComponent implements OnInit{
constructor(
private pwdService: PasswordSettingService,
private route: ActivatedRoute,
private msgService: MessageService,
private msgHandler: MessageHandlerService,
private router: Router) { }
ngOnInit(): void {
@ -44,9 +42,9 @@ export class ResetPasswordComponent implements OnInit{
}
public getValidationState(key: string): boolean {
return this.validationState &&
this.validationState[key] &&
key === 'reNewPassword'?this.samePassword():true;
return this.validationState &&
this.validationState[key] &&
key === 'reNewPassword' ? this.samePassword() : true;
}
public open(): void {
@ -61,7 +59,7 @@ export class ResetPasswordComponent implements OnInit{
public send(): void {
//If already reset password ok, navigator to sign-in
if(this.resetOk){
if (this.resetOk) {
this.router.navigate(['sign-in']);
return;
}
@ -77,24 +75,24 @@ export class ResetPasswordComponent implements OnInit{
this.onGoing = true;
this.pwdService.resetPassword(this.resetUuid, this.password)
.then(() => {
this.onGoing = false;
this.resetOk = true;
this.inlineAlert.showInlineSuccess({message:'RESET_PWD.RESET_OK'});
})
.catch(error => {
this.onGoing = false;
if(accessErrorHandler(error, this.msgService)){
this.close();
}else{
this.inlineAlert.showInlineError(errorHandler(error));
}
});
.then(() => {
this.onGoing = false;
this.resetOk = true;
this.inlineAlert.showInlineSuccess({ message: 'RESET_PWD.RESET_OK' });
})
.catch(error => {
this.onGoing = false;
if (this.msgHandler.isAppLevel(error)) {
this.close();
} else {
this.inlineAlert.showInlineError(error);
}
});
}
public handleValidation(key: string, flag: boolean): void {
if (flag) {
if(!this.validationState[key]){
if (!this.validationState[key]) {
this.validationState[key] = true;
}
} else {

View File

@ -6,7 +6,6 @@ import { User } from '../../user/user';
import { SessionService } from '../../shared/session.service';
import { UserService } from '../../user/user.service';
import { errorHandler } from '../../shared/shared.utils';
import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.component';
import { Modal } from 'clarity-angular';

View File

@ -2,14 +2,12 @@ import { Component, Output, EventEmitter, OnInit, OnDestroy } from '@angular/cor
import { GlobalSearchService } from './global-search.service';
import { SearchResults } from './search-results';
import { errorHandler, accessErrorHandler } from '../../shared/shared.utils';
import { AlertType, ListMode } from '../../shared/shared.const';
import { MessageService } from '../../global-message/message.service';
import { SearchTriggerService } from './search-trigger.service';
import { Subscription } from 'rxjs/Subscription';
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
@Component({
selector: "search-result",
templateUrl: "search-result.component.html",
@ -38,7 +36,7 @@ export class SearchResultComponent implements OnInit, OnDestroy {
constructor(
private search: GlobalSearchService,
private msgService: MessageService,
private msgHandler: MessageHandlerService,
private searchTrigger: SearchTriggerService) { }
ngOnInit() {
@ -73,10 +71,6 @@ export class SearchResultComponent implements OnInit, OnDestroy {
return res//Empty object
}
public get listMode(): string {
return ListMode.READONLY;
}
public get state(): boolean {
return this.stateIndicator;
}
@ -134,9 +128,7 @@ export class SearchResultComponent implements OnInit, OnDestroy {
})
.catch(error => {
this.onGoing = false;
if (!accessErrorHandler(error, this.msgService)) {
this.msgService.announceMessage(error.status, errorHandler(error), AlertType.DANGER);
}
this.msgHandler.handleError(error);
});
}
}

View File

@ -9,11 +9,10 @@ import { SessionUser } from '../../shared/session-user';
import { SessionService } from '../../shared/session.service';
import { CookieService } from 'angular2-cookie/core';
import { supportedLangs, enLang, languageNames, CommonRoutes, AlertType } from '../../shared/shared.const';
import { errorHandler } from '../../shared/shared.utils';
import { supportedLangs, enLang, languageNames, CommonRoutes } from '../../shared/shared.const';
import { AppConfigService } from '../../app-config.service';
import { SearchTriggerService } from '../global-search/search-trigger.service';
import { MessageService } from '../../global-message/message.service';
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
@Component({
selector: 'navigator',
@ -35,7 +34,7 @@ export class NavigatorComponent implements OnInit {
private translate: TranslateService,
private cookie: CookieService,
private appConfigService: AppConfigService,
private msgService: MessageService,
private msgHandler: MessageHandlerService,
private searchTrigger: SearchTriggerService) { }
ngOnInit(): void {
@ -71,10 +70,10 @@ export class NavigatorComponent implements OnInit {
}
public get canDownloadCert(): boolean {
return this.session.getCurrentUser() &&
this.session.getCurrentUser().has_admin_role>0 &&
this.appConfigService.getConfig() &&
this.appConfigService.getConfig().has_ca_root;
return this.session.getCurrentUser() &&
this.session.getCurrentUser().has_admin_role > 0 &&
this.appConfigService.getConfig() &&
this.appConfigService.getConfig().has_ca_root;
}
matchLang(lang: string): boolean {
@ -113,7 +112,7 @@ export class NavigatorComponent implements OnInit {
this.router.navigate([CommonRoutes.EMBEDDED_SIGN_IN]);
})
.catch(error => {
this.msgService.announceMessage(error.status | 500, errorHandler(error), AlertType.WARNING);
this.msgHandler.handleError(error);
});
//Confirm search result panel is close
this.searchTrigger.closeSearch(true);

View File

@ -4,9 +4,7 @@ import { NgForm } from '@angular/forms';
import { ConfigurationService } from './config.service';
import { Configuration } from './config';
import { MessageService } from '../global-message/message.service';
import { AlertType, ConfirmationTargets, ConfirmationState } from '../shared/shared.const';
import { errorHandler, accessErrorHandler } from '../shared/shared.utils';
import { ConfirmationTargets, ConfirmationState } from '../shared/shared.const';;
import { StringValueItem } from './config';
import { ConfirmationDialogService } from '../shared/confirmation-dialog/confirmation-dialog.service';
import { Subscription } from 'rxjs/Subscription';
@ -17,6 +15,7 @@ import { ConfigurationEmailComponent } from './email/config-email.component';
import { AppConfigService } from '../app-config.service';
import { SessionService } from '../shared/session.service';
import { MessageHandlerService } from '../shared/message-handler/message-handler.service';
const fakePass = "fakepassword";
const TabLinkContentMap = {
@ -45,7 +44,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
@ViewChild(ConfigurationAuthComponent) authConfig: ConfigurationAuthComponent;
constructor(
private msgService: MessageService,
private msgHandler: MessageHandlerService,
private configService: ConfigurationService,
private confirmService: ConfirmationDialogService,
private appConfigService: AppConfigService,
@ -204,13 +203,11 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
//Reload bootstrap option
this.appConfigService.load().catch(error => console.error("Failed to reload bootstrap option with error: ", error));
this.msgService.announceMessage(response.status, "CONFIG.SAVE_SUCCESS", AlertType.SUCCESS);
this.msgHandler.showSuccess("CONFIG.SAVE_SUCCESS");
})
.catch(error => {
this.onGoing = false;
if (!accessErrorHandler(error, this.msgService)) {
this.msgService.announceMessage(error.status, errorHandler(error), AlertType.DANGER);
}
this.msgHandler.handleError(error);
});
} else {
//Inprop situation, should not come here
@ -262,11 +259,15 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
this.configService.testMailServer(mailSettings)
.then(response => {
this.testingOnGoing = false;
this.msgService.announceMessage(200, "CONFIG.TEST_MAIL_SUCCESS", AlertType.SUCCESS);
this.msgHandler.showSuccess("CONFIG.TEST_MAIL_SUCCESS");
})
.catch(error => {
this.testingOnGoing = false;
this.msgService.announceMessage(error.status, errorHandler(error), AlertType.WARNING);
let err = error._body;
if(!err){
err = "UNKNOWN";
}
this.msgHandler.showError("CONFIG.TEST_MAIL_FAILED", {'param': err});
});
}
@ -279,7 +280,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
}
let allChanges = this.getChanges();
for(let prop in allChanges){
for (let prop in allChanges) {
if (prop.startsWith("ldap_")) {
ldapSettings[prop] = allChanges[prop];
}
@ -291,11 +292,15 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
this.configService.testLDAPServer(ldapSettings)
.then(respone => {
this.testingOnGoing = false;
this.msgService.announceMessage(200, "CONFIG.TEST_LDAP_SUCCESS", AlertType.SUCCESS);
this.msgHandler.showSuccess("CONFIG.TEST_LDAP_SUCCESS");
})
.catch(error => {
this.testingOnGoing = false;
this.msgService.announceMessage(error.status, errorHandler(error), AlertType.WARNING);
let err = error._body;
if(!err){
err = "UNKNOWN";
}
this.msgHandler.showError("CONFIG.TEST_LDAP_FAILED", err);
});
}
@ -342,9 +347,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
})
.catch(error => {
this.onGoing = false;
if (!accessErrorHandler(error, this.msgService)) {
this.msgService.announceMessage(error.status, errorHandler(error), AlertType.DANGER);
}
this.msgHandler.handleError(error);
});
}

View File

@ -17,7 +17,7 @@ export class InlineAlertComponent {
@Output() confirmEvt = new EventEmitter<boolean>();
constructor(private translate: TranslateService){}
constructor(private translate: TranslateService) { }
public get errorMessage(): string {
return this.displayedText;
@ -26,6 +26,9 @@ export class InlineAlertComponent {
//Show error message inline
public showInlineError(error: any): void {
this.displayedText = errorHandler(error);
if (this.displayedText) {
this.translate.get(this.displayedText).subscribe((res: string) => this.displayedText = res);
}
this.inlineAlertType = 'alert-danger';
this.showCancelAction = false;
@ -37,7 +40,7 @@ export class InlineAlertComponent {
//Show confirmation info with action button
public showInlineConfirmation(warning: any): void {
this.displayedText = "";
if(warning && warning.message){
if (warning && warning.message) {
this.translate.get(warning.message).subscribe((res: string) => this.displayedText = res);
}
this.inlineAlertType = 'alert-warning';
@ -50,7 +53,7 @@ export class InlineAlertComponent {
//Show inline sccess info
public showInlineSuccess(info: any): void {
this.displayedText = "";
if(info && info.message){
if (info && info.message) {
this.translate.get(info.message).subscribe((res: string) => this.displayedText = res);
}
this.inlineAlertType = 'alert-success';

View File

@ -3,11 +3,17 @@ import { Subject } from 'rxjs/Subject';
import { MessageService } from '../../global-message/message.service';
import { AlertType, httpStatusCode } from '../../shared/shared.const';
import { errorHandler } from '../../shared/shared.utils';
import { TranslateService } from '@ngx-translate/core';
import { SessionService } from '../../shared/session.service';
@Injectable()
export class MessageHandlerService {
constructor(private msgService: MessageService) { }
constructor(
private msgService: MessageService,
private translate: TranslateService,
private session: SessionService) { }
//Handle the error and map it to the suitable message
//base on the status code of error.
@ -16,42 +22,31 @@ export class MessageHandlerService {
if (!error) {
return;
}
console.log(JSON.stringify(error));
let msg = errorHandler(error);
if (!(error.statusCode || error.status)) {
//treat as string message
let msg = '' + error;
this.msgService.announceMessage(500, msg, AlertType.DANGER);
} else {
let msg = 'UNKNOWN_ERROR';
switch (error.statusCode || error.status) {
case 400:
msg = "BAD_REQUEST_ERROR";
break;
case 401:
msg = "UNAUTHORIZED_ERROR";
this.msgService.announceAppLevelMessage(error.statusCode, msg, AlertType.DANGER);
return;
case 403:
msg = "FORBIDDEN_ERROR";
break;
case 404:
msg = "NOT_FOUND_ERROR";
break;
case 412:
case 409:
msg = "CONFLICT_ERROR";
break;
case 500:
msg = "SERVER_ERROR";
break;
default:
break;
let code = error.statusCode | error.status;
if (code === httpStatusCode.Unauthorized) {
this.msgService.announceAppLevelMessage(code, msg, AlertType.DANGER);
//Session is invalida now, clare session cache
this.session.clear();
} else {
this.msgService.announceMessage(code, msg, AlertType.DANGER);
}
this.msgService.announceMessage(error.statusCode, msg, AlertType.DANGER);
}
}
public showError(message: string, params: any): void {
if (!params) {
params = {};
}
this.translate.get(message, params).subscribe((res: string) => {
this.msgService.announceMessage(500, res, AlertType.DANGER);
});
}
public showSuccess(message: string): void {
if (message && message.trim() != "") {
this.msgService.announceMessage(200, message, AlertType.SUCCESS);

View File

@ -46,6 +46,12 @@ export class SessionService {
return Promise.reject(error.message || error);
}
//Clear session
clear(): void {
this.currentUser = null;
this.projectMembers = [];
}
//Submit signin form to backend (NOT restful service)
signIn(signInCredential: SignInCredential): Promise<any> {
//Build the form package

View File

@ -8,19 +8,33 @@ import { MessageService } from '../global-message/message.service';
* @returns {string}
*/
export const errorHandler = function (error: any): string {
if (error) {
if (error.message) {
return error.message;
} else if (error._body) {
return error._body;
} else if (error.statusText) {
return error.statusText;
} else {
return error;
if (!error) {
return "UNKNOWN_ERROR";
}
console.log(JSON.stringify(error));
if (!(error.statusCode || error.status)) {
//treat as string message
return '' + error;
} else {
switch (error.statusCode || error.status) {
case 400:
return "BAD_REQUEST_ERROR";
case 401:
return "UNAUTHORIZED_ERROR";
case 403:
return "FORBIDDEN_ERROR";
case 404:
return "NOT_FOUND_ERROR";
case 412:
case 409:
return "CONFLICT_ERROR";
case 500:
return "SERVER_ERROR";
default:
return "UNKNOWN_ERROR";
}
}
return "UNKNOWN_ERROR";
}
/**
@ -52,9 +66,6 @@ export const accessErrorHandler = function (error: any, msgService: MessageServi
if (error.status === httpStatusCode.Unauthorized) {
msgService.announceAppLevelMessage(error.status, "UNAUTHORIZED_ERROR", AlertType.DANGER);
return true;
} else if (error.status === httpStatusCode.Forbidden) {
msgService.announceAppLevelMessage(error.status, "FORBIDDEN_ERROR", AlertType.DANGER);
return true;
}
}

View File

@ -1,16 +1,13 @@
import { Component, Input, OnInit } from '@angular/core';
import { StatisticsService } from './statistics.service';
import { errorHandler, accessErrorHandler } from '../../shared/shared.utils';
import { AlertType } from '../../shared/shared.const';
import { MessageService } from '../../global-message/message.service';
import { Statistics } from './statistics';
import { SessionService } from '../session.service';
import { Volumes } from './volumes';
import { MessageHandlerService } from '../message-handler/message-handler.service';
@Component({
selector: 'statistics-panel',
templateUrl: "statistics-panel.component.html",
@ -25,7 +22,7 @@ export class StatisticsPanelComponent implements OnInit {
constructor(
private statistics: StatisticsService,
private msgService: MessageService,
private msgHandler: MessageHandlerService,
private session: SessionService) { }
ngOnInit(): void {
@ -47,9 +44,7 @@ export class StatisticsPanelComponent implements OnInit {
this.statistics.getStatistics()
.then(statistics => this.originalCopy = statistics)
.catch(error => {
if (!accessErrorHandler(error, this.msgService)) {
this.msgService.announceMessage(error.status, errorHandler(error), AlertType.WARNING);
}
this.msgHandler.handleError(error);
});
}
@ -57,9 +52,7 @@ export class StatisticsPanelComponent implements OnInit {
this.statistics.getVolumes()
.then(volumes => this.volumesInfo = volumes)
.catch(error => {
if (!accessErrorHandler(error, this.msgService)) {
this.msgService.announceMessage(error.status, errorHandler(error), AlertType.WARNING);
}
this.msgHandler.handleError(error);
});
}

View File

@ -379,6 +379,8 @@
},
"TEST_MAIL_SUCCESS": "Connection to mail server is verified",
"TEST_LDAP_SUCCESS": "Connection to LDAP server is verified",
"TEST_MAIL_FAILED": "Failed to verify mail server with error: {{param}}",
"TEST_LDAP_FAILED": "Failed to verify LDAP server with error: {{param}}",
"LEAVING_CONFIRMATION_TITLE": "Confirm to leave",
"LEAVING_CONFIRMATION_SUMMARY": "Changes have not been saved yet, do you really want to leave currnet page?"
},
@ -419,5 +421,7 @@
"BAD_REQUEST_ERROR": "We are unable to perform your action because of a bad request",
"NOT_FOUND_ERROR": "Your request can not be completed because the object does not exist",
"CONFLICT_ERROR": "We are unable to perform your action because your submission has conflicts",
"SERVER_ERROR": "We are unable to perform your action because internal server errors have occurred"
"SERVER_ERROR": "We are unable to perform your action because internal server errors have occurred",
"INCONRRECT_OLD_PWD": "The old password is incorrect",
"UNKNOWN": "n/a"
}

View File

@ -379,6 +379,8 @@
},
"TEST_MAIL_SUCCESS": "邮件服务器的连通正常",
"TEST_LDAP_SUCCESS": "LDAP服务器的连通正常",
"TEST_MAIL_FAILED": "验证邮件服务器失败,错误: {{param}}",
"TEST_LDAP_FAILED": "验证LDAP服务器失败错误: {{param}}",
"LEAVING_CONFIRMATION_TITLE": "确定离开?",
"LEAVING_CONFIRMATION_SUMMARY": "存在未保存的配置更改, 确认离开当前配置页?"
},
@ -419,5 +421,7 @@
"BAD_REQUEST_ERROR": "错误请求导致无法完成操作",
"NOT_FOUND_ERROR": "对象不存在故无法完成你的请求",
"CONFLICT_ERROR": "你的提交包含冲突故操作无法完成",
"SERVER_ERROR": "服务器出现内部错误,请求无法完成"
"SERVER_ERROR": "服务器出现内部错误,请求无法完成",
"INCONRRECT_OLD_PWD": "旧密码不正确",
"UNKNOWN": "n/a"
}