mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-23 09:08:26 +01:00
Merge pull request #2112 from vmware/master-ui-aot
Updates for AoT building.
This commit is contained in:
commit
6acf49581c
10
.gitignore
vendored
10
.gitignore
vendored
@ -29,6 +29,16 @@ src/ui_ng/typings/
|
|||||||
**/node_modules
|
**/node_modules
|
||||||
**/ssl/
|
**/ssl/
|
||||||
**/proxy.config.json
|
**/proxy.config.json
|
||||||
|
|
||||||
|
src/ui_ng/src/**/*.js
|
||||||
|
src/ui_ng/src/**/*.js.map
|
||||||
|
src/ui_ng/src/**/*.json
|
||||||
|
|
||||||
**/npm*.log
|
**/npm*.log
|
||||||
|
|
||||||
|
src/ui_ng/aot/**/*.js
|
||||||
|
src/ui_ng/aot/**/*.js.map
|
||||||
|
src/ui_ng/aot/**/*.json
|
||||||
|
|
||||||
**/*ngsummary.json
|
**/*ngsummary.json
|
||||||
**/*ngfactory.ts
|
**/*ngfactory.ts
|
||||||
|
@ -97,7 +97,7 @@ script:
|
|||||||
- docker-compose -f make/docker-compose.test.yml down
|
- docker-compose -f make/docker-compose.test.yml down
|
||||||
- sudo rm -rf /data/config/*
|
- sudo rm -rf /data/config/*
|
||||||
- ls /data/cert
|
- ls /data/cert
|
||||||
- sudo make install GOBUILDIMAGE=golang:1.7.3 COMPILETAG=compile_golangimage CLARITYIMAGE=vmware/harbor-clarity-ui-builder:0.8.4 NOTARYFLAG=true
|
- sudo make install GOBUILDIMAGE=golang:1.7.3 COMPILETAG=compile_golangimage CLARITYIMAGE=vmware/harbor-clarity-ui-builder:1.1.0 NOTARYFLAG=true
|
||||||
|
|
||||||
- docker ps
|
- docker ps
|
||||||
- ./tests/notarytest.sh
|
- ./tests/notarytest.sh
|
||||||
|
22
Makefile
22
Makefile
@ -86,6 +86,8 @@ NOTARYVERSION=server-0.5.0
|
|||||||
NOTARYSIGNERVERSION=signer-0.5.0
|
NOTARYSIGNERVERSION=signer-0.5.0
|
||||||
MARIADBVERSION=mariadb-10.1.10
|
MARIADBVERSION=mariadb-10.1.10
|
||||||
HTTPPROXY=
|
HTTPPROXY=
|
||||||
|
REBUILDCLARITYFLAG=false
|
||||||
|
NEWCLARITYVERSION=
|
||||||
|
|
||||||
#clarity parameters
|
#clarity parameters
|
||||||
CLARITYIMAGE=vmware/harbor-clarity-ui-builder[:tag]
|
CLARITYIMAGE=vmware/harbor-clarity-ui-builder[:tag]
|
||||||
@ -149,6 +151,7 @@ MAKEFILEPATH_PHOTON=$(MAKEPATH)/photon
|
|||||||
DOCKERFILEPATH_COMMON=$(MAKEPATH)/common
|
DOCKERFILEPATH_COMMON=$(MAKEPATH)/common
|
||||||
DOCKERFILEPATH_DB=$(DOCKERFILEPATH_COMMON)/db
|
DOCKERFILEPATH_DB=$(DOCKERFILEPATH_COMMON)/db
|
||||||
DOCKERFILENAME_DB=Dockerfile
|
DOCKERFILENAME_DB=Dockerfile
|
||||||
|
DOCKERFILE_CLARITY=$(MAKEPATH)/dev/nodeclarity/Dockerfile
|
||||||
|
|
||||||
# docker image name
|
# docker image name
|
||||||
DOCKERIMAGENAME_ADMINSERVER=vmware/harbor-adminserver
|
DOCKERIMAGENAME_ADMINSERVER=vmware/harbor-adminserver
|
||||||
@ -156,6 +159,7 @@ DOCKERIMAGENAME_UI=vmware/harbor-ui
|
|||||||
DOCKERIMAGENAME_JOBSERVICE=vmware/harbor-jobservice
|
DOCKERIMAGENAME_JOBSERVICE=vmware/harbor-jobservice
|
||||||
DOCKERIMAGENAME_LOG=vmware/harbor-log
|
DOCKERIMAGENAME_LOG=vmware/harbor-log
|
||||||
DOCKERIMAGENAME_DB=vmware/harbor-db
|
DOCKERIMAGENAME_DB=vmware/harbor-db
|
||||||
|
DOCKERIMAGENAME_CLATIRY=vmware/harbor-clarity-ui-builder
|
||||||
|
|
||||||
# docker-compose files
|
# docker-compose files
|
||||||
DOCKERCOMPOSEFILEPATH=$(MAKEPATH)
|
DOCKERCOMPOSEFILEPATH=$(MAKEPATH)
|
||||||
@ -354,6 +358,24 @@ package_offline: compile build modify_sourcefiles modify_composefile
|
|||||||
|
|
||||||
@rm -rf $(HARBORPKG)
|
@rm -rf $(HARBORPKG)
|
||||||
@echo "Done."
|
@echo "Done."
|
||||||
|
|
||||||
|
refresh_clarity_builder:
|
||||||
|
@if [ "$(REBUILDCLIATRYFLAG)" = "true" ] ; then \
|
||||||
|
echo "set http proxy.."; \
|
||||||
|
if [ "$(HTTPPROXY)" != "" ] ; then \
|
||||||
|
$(SEDCMD) -i 's/__proxy__/--proxy $(HTTPPROXY)/g' $(DOCKERFILE_CLARITY) ; \
|
||||||
|
else \
|
||||||
|
$(SEDCMD) -i 's/__proxy__/ /g' $(DOCKERFILE_CLARITY) ; \
|
||||||
|
fi ; \
|
||||||
|
echo "build new clarity image.."; \
|
||||||
|
$(DOCKERBUILD) -f $(DOCKERFILE_CLARITY) -t $(DOCKERIMAGENAME_CLATIRY):$(NEWCLARITYVERSION) . ; \
|
||||||
|
echo "push clarity image.."; \
|
||||||
|
$(DOCKERTAG) $(DOCKERIMAGENAME_CLATIRY):$(NEWCLARITYVERSION) $(DOCKERIMAGENAME_CLATIRY):$(NEWCLARITYVERSION); \
|
||||||
|
$(PUSHSCRIPTPATH)/$(PUSHSCRIPTNAME) $(REGISTRYSERVER)$(DOCKERIMAGENAME_CLATIRY):$(NEWCLARITYVERSION) \
|
||||||
|
$(REGISTRYUSER) $(REGISTRYPASSWORD) $(REGISTRYSERVER); \
|
||||||
|
echo "remove local clarity image.."; \
|
||||||
|
$(DOCKERRMIMAGE) $(REGISTRYSERVER)$(DOCKERIMAGENAME_ADMINSERVER):$(NEWCLARITYVERSION); \
|
||||||
|
fi
|
||||||
|
|
||||||
pushimage:
|
pushimage:
|
||||||
@echo "pushing harbor images ..."
|
@echo "pushing harbor images ..."
|
||||||
|
@ -9,10 +9,12 @@ COPY src/ui_ng/yarn.lock /clarity-seed
|
|||||||
COPY make/dev/nodeclarity/angular-cli.json /clarity-seed
|
COPY make/dev/nodeclarity/angular-cli.json /clarity-seed
|
||||||
COPY make/dev/nodeclarity/entrypoint.sh /
|
COPY make/dev/nodeclarity/entrypoint.sh /
|
||||||
|
|
||||||
|
COPY src/ui_ng/tsconfig-aot.json /clarity-seed
|
||||||
|
COPY src/ui_ng/rollup-config.js /clarity-seed
|
||||||
|
|
||||||
WORKDIR /clarity-seed
|
WORKDIR /clarity-seed
|
||||||
|
|
||||||
RUN npm install -g @angular/cli && \
|
RUN npm __proxy__ install -g @angular/cli && \
|
||||||
npm install && \
|
npm __proxy__ install && \
|
||||||
chmod u+x /entrypoint.sh
|
chmod u+x /entrypoint.sh
|
||||||
|
VOLUME ["/clarity-seed", "/clarity-seed/dist"]
|
||||||
VOLUME ["/clarity-seed", "/clarity-seed/dist"]
|
|
||||||
|
@ -19,7 +19,17 @@ if [ ! -z "$npm_proxy" -a "$npm_proxy" != " " ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
npm install
|
npm install
|
||||||
ng build
|
|
||||||
|
./node_modules/.bin/ngc -p tsconfig-aot.json
|
||||||
|
sed -i 's/* as//g' src/app/shared/gauge/gauge.component.js
|
||||||
|
./node_modules/.bin/rollup -c rollup-config.js
|
||||||
|
|
||||||
cp -r ./src/i18n/ dist/
|
cp -r ./src/i18n/ dist/
|
||||||
|
cp ./src/styles.css dist/
|
||||||
|
|
||||||
|
cp ./node_modules/clarity-icons/clarity-icons.min.css dist/
|
||||||
|
cp ./node_modules/mutationobserver-shim/dist/mutationobserver.min.js dist/
|
||||||
|
cp ./node_modules/@webcomponents/custom-elements/custom-elements.min.js dist/
|
||||||
|
cp ./node_modules/clarity-icons/clarity-icons.min.js dist/
|
||||||
|
cp ./node_modules/clarity-ui/clarity-ui.min.css dist/
|
||||||
|
cp -r ./node_modules/clarity-icons/shapes/ dist/
|
||||||
|
@ -15,13 +15,16 @@
|
|||||||
Loading...
|
Loading...
|
||||||
</div>
|
</div>
|
||||||
</harbor-app>
|
</harbor-app>
|
||||||
<script type="text/javascript" src="/static/inline.bundle.js"></script>
|
|
||||||
<script type="text/javascript" src="/static/scripts.bundle.js">
|
<link rel="stylesheet" href="/static/clarity-ui.min.css">
|
||||||
</script>
|
<link rel="stylesheet" href="/static/clarity-icons.min.css">
|
||||||
<script type="text/javascript" src="/static/styles.bundle.js">
|
<link rel="stylesheet" href="/static/styles.css">
|
||||||
</script>
|
|
||||||
<script type="text/javascript" src="/static/vendor.bundle.js"></script>
|
<script src="/static/mutationobserver.min.js"></script>
|
||||||
<script type="text/javascript" src="/static/main.bundle.js"></script>
|
<script src="/static/custom-elements.min.js"></script>
|
||||||
|
<script src="/static/clarity-icons.min.js"></script>
|
||||||
|
|
||||||
|
<script src="/static/build.min.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,63 +1,70 @@
|
|||||||
{
|
{
|
||||||
"name": "harbor",
|
"name": "harbor",
|
||||||
"version": "0.6.0",
|
"version": "1.1.0",
|
||||||
"description": "Harbor UI with Clarity",
|
"description": "Harbor UI with Clarity",
|
||||||
"angular-cli": {},
|
"angular-cli": {},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "ng serve --ssl 1 --ssl-key ssl/server.key --ssl-cert ssl/server.crt --host 0.0.0.0 --proxy-config proxy.config.json",
|
"start": "ng serve --ssl 1 --ssl-key ssl/server.key --ssl-cert ssl/server.crt --host 0.0.0.0 --proxy-config proxy.config.json",
|
||||||
"lint": "tslint \"src/**/*.ts\"",
|
"lint": "tslint \"src/**/*.ts\"",
|
||||||
"test": "ng test --single-run",
|
"test": "ng test --single-run",
|
||||||
"pree2e": "webdriver-manager update",
|
"pree2e": "webdriver-manager update",
|
||||||
"e2e": "protractor"
|
"e2e": "protractor"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/common": "^2.4.1",
|
"@angular/animations": "^4.0.1",
|
||||||
"@angular/compiler": "^2.4.1",
|
"@angular/common": "^4.0.1",
|
||||||
"@angular/core": "^2.4.1",
|
"@angular/compiler": "^4.0.1",
|
||||||
"@angular/forms": "^2.4.1",
|
"@angular/compiler-cli": "^4.0.2",
|
||||||
"@angular/http": "^2.4.1",
|
"@angular/core": "^4.0.1",
|
||||||
"@angular/platform-browser": "^2.4.1",
|
"@angular/forms": "^4.0.1",
|
||||||
"@angular/platform-browser-dynamic": "^2.4.1",
|
"@angular/http": "^4.0.1",
|
||||||
"@angular/router": "^3.4.1",
|
"@angular/platform-browser": "^4.0.1",
|
||||||
"@ngx-translate/core": "^6.0.0",
|
"@angular/platform-browser-dynamic": "^4.0.1",
|
||||||
"@ngx-translate/http-loader": "0.0.3",
|
"@angular/platform-server": "^4.0.2",
|
||||||
"@webcomponents/custom-elements": "1.0.0-alpha.3",
|
"@angular/router": "^4.0.1",
|
||||||
"angular2-cookie": "^1.2.6",
|
"@ngx-translate/core": "^6.0.0",
|
||||||
"clarity-angular": "0.8.7",
|
"@ngx-translate/http-loader": "0.0.3",
|
||||||
"clarity-icons": "0.8.7",
|
"@types/jquery": "^2.0.41",
|
||||||
"clarity-ui": "0.8.7",
|
"@webcomponents/custom-elements": "1.0.0-alpha.3",
|
||||||
"core-js": "^2.4.1",
|
"angular2-cookie": "^1.2.6",
|
||||||
"fs": "0.0.1-security",
|
"clarity-angular": "^0.9.0",
|
||||||
"jquery": "^2.2.4",
|
"clarity-icons": "^0.9.0",
|
||||||
"mutationobserver-shim": "^0.3.2",
|
"clarity-ui": "^0.9.0",
|
||||||
"rxjs": "^5.0.1",
|
"core-js": "^2.4.1",
|
||||||
"ts-helpers": "^1.1.1",
|
"mutationobserver-shim": "^0.3.2",
|
||||||
"web-animations-js": "^2.2.1",
|
"ngx-cookie": "^1.0.0",
|
||||||
"zone.js": "^0.7.2"
|
"rxjs": "^5.0.1",
|
||||||
},
|
"ts-helpers": "^1.1.1",
|
||||||
"devDependencies": {
|
"web-animations-js": "^2.2.1",
|
||||||
"@angular/compiler-cli": "^2.4.1",
|
"zone.js": "^0.8.4"
|
||||||
"@angular/cli": "^1.0.0",
|
},
|
||||||
"@types/core-js": "^0.9.34",
|
"devDependencies": {
|
||||||
"@types/jasmine": "^2.2.30",
|
"@angular/cli": "^1.0.0",
|
||||||
"@types/node": "^6.0.42",
|
"@angular/compiler-cli": "^4.0.1",
|
||||||
"bootstrap": "4.0.0-alpha.5",
|
"@types/core-js": "^0.9.34",
|
||||||
"codelyzer": "~1.0.0-beta.3",
|
"@types/jasmine": "~2.2.30",
|
||||||
"enhanced-resolve": "^3.0.0",
|
"@types/node": "^6.0.42",
|
||||||
"jasmine-core": "2.4.1",
|
"bootstrap": "4.0.0-alpha.5",
|
||||||
"jasmine-spec-reporter": "2.5.0",
|
"codelyzer": "~2.0.0-beta.4",
|
||||||
"karma": "1.2.0",
|
"enhanced-resolve": "^3.0.0",
|
||||||
"karma-cli": "^1.0.1",
|
"jasmine-core": "2.4.1",
|
||||||
"karma-jasmine": "^1.0.2",
|
"jasmine-spec-reporter": "2.5.0",
|
||||||
"karma-mocha-reporter": "^2.2.1",
|
"karma": "1.2.0",
|
||||||
"karma-phantomjs-launcher": "^1.0.0",
|
"karma-cli": "^1.0.1",
|
||||||
"karma-remap-istanbul": "^0.2.1",
|
"karma-jasmine": "^1.0.2",
|
||||||
"protractor": "4.0.9",
|
"karma-mocha-reporter": "^2.2.1",
|
||||||
"ts-node": "1.2.1",
|
"karma-phantomjs-launcher": "^1.0.0",
|
||||||
"tslint": "^4.1.1",
|
"karma-remap-istanbul": "^0.2.1",
|
||||||
"typescript": "~2.2.1",
|
"protractor": "4.0.9",
|
||||||
"typings": "^1.4.0",
|
"rollup": "^0.41.6",
|
||||||
"webdriver-manager": "10.2.5"
|
"rollup-plugin-commonjs": "^8.0.2",
|
||||||
}
|
"rollup-plugin-node-resolve": "^3.0.0",
|
||||||
}
|
"rollup-plugin-uglify": "^1.0.1",
|
||||||
|
"ts-node": "1.2.1",
|
||||||
|
"tslint": "^4.1.1",
|
||||||
|
"typescript": "~2.2.0",
|
||||||
|
"typings": "^1.4.0",
|
||||||
|
"webdriver-manager": "10.2.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
28
src/ui_ng/rollup-config.js
Normal file
28
src/ui_ng/rollup-config.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import nodeResolve from 'rollup-plugin-node-resolve';
|
||||||
|
import commonjs from 'rollup-plugin-commonjs';
|
||||||
|
import uglify from 'rollup-plugin-uglify';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
entry: 'src/main-aot.js',
|
||||||
|
dest: 'dist/build.min.js', // output a single application compressed file.
|
||||||
|
sourceMap: false,
|
||||||
|
format: 'iife',
|
||||||
|
onwarn: function(warning) {
|
||||||
|
// Skip certain warnings
|
||||||
|
|
||||||
|
// should intercept ... but doesn't in some rollup versions
|
||||||
|
if ( warning.code === 'THIS_IS_UNDEFINED' ) { return; }
|
||||||
|
// intercepts in some rollup versions
|
||||||
|
if ( typeof warning === 'string' && warning.indexOf("The 'this' keyword is equivalent to 'undefined'") > -1 ) { return; }
|
||||||
|
|
||||||
|
// console.warn everything else
|
||||||
|
console.warn( warning.message );
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
nodeResolve({jsnext: true, module: true, browser: true}),
|
||||||
|
commonjs({
|
||||||
|
include: ['node_modules/**']
|
||||||
|
}),
|
||||||
|
uglify()
|
||||||
|
]
|
||||||
|
}
|
@ -31,21 +31,21 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
|
|||||||
account: SessionUser;
|
account: SessionUser;
|
||||||
error: any = null;
|
error: any = null;
|
||||||
originalStaticData: SessionUser;
|
originalStaticData: SessionUser;
|
||||||
private emailTooltip: string = 'TOOLTIP.EMAIL';
|
emailTooltip: string = 'TOOLTIP.EMAIL';
|
||||||
private validationStateMap: any = {
|
private validationStateMap: any = {
|
||||||
"account_settings_email": true,
|
"account_settings_email": true,
|
||||||
"account_settings_full_name": true
|
"account_settings_full_name": true
|
||||||
};
|
};
|
||||||
private mailAlreadyChecked = {};
|
mailAlreadyChecked = {};
|
||||||
|
|
||||||
private isOnCalling: boolean = false;
|
isOnCalling: boolean = false;
|
||||||
private formValueChanged: boolean = false;
|
formValueChanged: boolean = false;
|
||||||
private checkOnGoing: boolean = false;
|
checkOnGoing: boolean = false;
|
||||||
|
|
||||||
accountFormRef: NgForm;
|
accountFormRef: NgForm;
|
||||||
@ViewChild("accountSettingsFrom") accountForm: NgForm;
|
@ViewChild("accountSettingsFrom") accountForm: NgForm;
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent)
|
||||||
private inlineAlert: InlineAlertComponent;
|
inlineAlert: InlineAlertComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private session: SessionService,
|
private session: SessionService,
|
||||||
@ -56,11 +56,11 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
|
|||||||
this.account = Object.assign({}, this.session.getCurrentUser());
|
this.account = Object.assign({}, this.session.getCurrentUser());
|
||||||
}
|
}
|
||||||
|
|
||||||
private getValidationState(key: string): boolean {
|
getValidationState(key: string): boolean {
|
||||||
return this.validationStateMap[key];
|
return this.validationStateMap[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleValidation(key: string, flag: boolean): void {
|
handleValidation(key: string, flag: boolean): void {
|
||||||
if (flag) {
|
if (flag) {
|
||||||
//Checking
|
//Checking
|
||||||
let cont = this.accountForm.controls[key];
|
let cont = this.accountForm.controls[key];
|
||||||
@ -104,7 +104,7 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private isUserDataChange(): boolean {
|
isUserDataChange(): boolean {
|
||||||
if (!this.originalStaticData || !this.account) {
|
if (!this.originalStaticData || !this.account) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -215,7 +215,7 @@ export class AccountSettingsModalComponent implements OnInit, AfterViewChecked {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmCancel(): void {
|
confirmCancel($event: any): void {
|
||||||
this.inlineAlert.close();
|
this.inlineAlert.close();
|
||||||
this.opened = false;
|
this.opened = false;
|
||||||
}
|
}
|
||||||
|
@ -25,14 +25,14 @@ import { InlineAlertComponent } from '../../shared/inline-alert/inline-alert.com
|
|||||||
})
|
})
|
||||||
export class ForgotPasswordComponent {
|
export class ForgotPasswordComponent {
|
||||||
opened: boolean = false;
|
opened: boolean = false;
|
||||||
private onGoing: boolean = false;
|
onGoing: boolean = false;
|
||||||
private email: string = "";
|
email: string = "";
|
||||||
private validationState: boolean = true;
|
validationState: boolean = true;
|
||||||
private isSuccess: boolean = false;
|
isSuccess: boolean = false;
|
||||||
|
|
||||||
@ViewChild("forgotPasswordFrom") forgotPwdForm: NgForm;
|
@ViewChild("forgotPasswordFrom") forgotPwdForm: NgForm;
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent)
|
||||||
private inlineAlert: InlineAlertComponent;
|
inlineAlert: InlineAlertComponent;
|
||||||
|
|
||||||
constructor(private pwdService: PasswordSettingService) { }
|
constructor(private pwdService: PasswordSettingService) { }
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ export class PasswordSettingComponent implements AfterViewChecked {
|
|||||||
reNewPwd: string = "";
|
reNewPwd: string = "";
|
||||||
error: any = null;
|
error: any = null;
|
||||||
|
|
||||||
private formValueChanged: boolean = false;
|
formValueChanged: boolean = false;
|
||||||
private onCalling: boolean = false;
|
onCalling: boolean = false;
|
||||||
private validationStateMap: any = {
|
private validationStateMap: any = {
|
||||||
"newPassword": true,
|
"newPassword": true,
|
||||||
"reNewPassword": true
|
"reNewPassword": true
|
||||||
@ -43,7 +43,7 @@ export class PasswordSettingComponent implements AfterViewChecked {
|
|||||||
pwdFormRef: NgForm;
|
pwdFormRef: NgForm;
|
||||||
@ViewChild("changepwdForm") pwdForm: NgForm;
|
@ViewChild("changepwdForm") pwdForm: NgForm;
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent)
|
||||||
private inlineAlert: InlineAlertComponent;
|
inlineAlert: InlineAlertComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private passwordService: PasswordSettingService,
|
private passwordService: PasswordSettingService,
|
||||||
@ -68,11 +68,11 @@ export class PasswordSettingComponent implements AfterViewChecked {
|
|||||||
return this.onCalling;
|
return this.onCalling;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getValidationState(key: string): boolean {
|
getValidationState(key: string): boolean {
|
||||||
return this.validationStateMap[key];
|
return this.validationStateMap[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleValidation(key: string, flag: boolean): void {
|
handleValidation(key: string, flag: boolean): void {
|
||||||
if (flag) {
|
if (flag) {
|
||||||
//Checking
|
//Checking
|
||||||
let cont = this.pwdForm.controls[key];
|
let cont = this.pwdForm.controls[key];
|
||||||
@ -139,7 +139,7 @@ export class PasswordSettingComponent implements AfterViewChecked {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmCancel(): void {
|
confirmCancel($event: any): void {
|
||||||
this.opened = false;
|
this.opened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,11 +23,11 @@ const resetPasswordEndpoint = "/reset";
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class PasswordSettingService {
|
export class PasswordSettingService {
|
||||||
private headers: Headers = new Headers({
|
headers: Headers = new Headers({
|
||||||
"Accept": 'application/json',
|
"Accept": 'application/json',
|
||||||
"Content-Type": 'application/json'
|
"Content-Type": 'application/json'
|
||||||
});
|
});
|
||||||
private options: RequestOptions = new RequestOptions({
|
options: RequestOptions = new RequestOptions({
|
||||||
'headers': this.headers
|
'headers': this.headers
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -27,19 +27,19 @@ import { CommonRoutes } from '../../shared/shared.const';
|
|||||||
})
|
})
|
||||||
export class ResetPasswordComponent implements OnInit {
|
export class ResetPasswordComponent implements OnInit {
|
||||||
opened: boolean = true;
|
opened: boolean = true;
|
||||||
private onGoing: boolean = false;
|
onGoing: boolean = false;
|
||||||
private password: string = "";
|
password: string = "";
|
||||||
private validationState: any = {
|
private validationState: any = {
|
||||||
"newPassword": true,
|
"newPassword": true,
|
||||||
"reNewPassword": true
|
"reNewPassword": true
|
||||||
};
|
};
|
||||||
private resetUuid: string = "";
|
resetUuid: string = "";
|
||||||
private resetOk: boolean = false;
|
resetOk: boolean = false;
|
||||||
confirmPwd: string = "";
|
confirmPwd: string = "";
|
||||||
|
|
||||||
@ViewChild("resetPwdForm") resetPwdForm: NgForm;
|
@ViewChild("resetPwdForm") resetPwdForm: NgForm;
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent)
|
||||||
private inlineAlert: InlineAlertComponent;
|
inlineAlert: InlineAlertComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private pwdService: PasswordSettingService,
|
private pwdService: PasswordSettingService,
|
||||||
@ -131,7 +131,7 @@ export class ResetPasswordComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getControlValidationState(key: string): boolean {
|
getControlValidationState(key: string): boolean {
|
||||||
if (this.resetPwdForm) {
|
if (this.resetPwdForm) {
|
||||||
let control = this.resetPwdForm.controls[key];
|
let control = this.resetPwdForm.controls[key];
|
||||||
if (control) {
|
if (control) {
|
||||||
@ -142,7 +142,7 @@ export class ResetPasswordComponent implements OnInit {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private samePassword(): boolean {
|
samePassword(): boolean {
|
||||||
if (this.resetPwdForm) {
|
if (this.resetPwdForm) {
|
||||||
let control1 = this.resetPwdForm.controls["newPassword"];
|
let control1 = this.resetPwdForm.controls["newPassword"];
|
||||||
let control2 = this.resetPwdForm.controls["reNewPassword"];
|
let control2 = this.resetPwdForm.controls["reNewPassword"];
|
||||||
|
@ -27,7 +27,7 @@ import { AppConfigService } from '../../app-config.service';
|
|||||||
import { AppConfig } from '../../app-config';
|
import { AppConfig } from '../../app-config';
|
||||||
import { User } from '../../user/user';
|
import { User } from '../../user/user';
|
||||||
|
|
||||||
import { CookieService, CookieOptions } from 'angular2-cookie/core';
|
import { CookieService, CookieOptions } from 'ngx-cookie';
|
||||||
|
|
||||||
//Define status flags for signing in states
|
//Define status flags for signing in states
|
||||||
export const signInStatusNormal = 0;
|
export const signInStatusNormal = 0;
|
||||||
@ -43,11 +43,11 @@ const expireDays = 10;
|
|||||||
})
|
})
|
||||||
|
|
||||||
export class SignInComponent implements AfterViewChecked, OnInit {
|
export class SignInComponent implements AfterViewChecked, OnInit {
|
||||||
private redirectUrl: string = "";
|
redirectUrl: string = "";
|
||||||
private appConfig: AppConfig = new AppConfig();
|
appConfig: AppConfig = new AppConfig();
|
||||||
//Remeber me indicator
|
//Remeber me indicator
|
||||||
private rememberMe: boolean = false;
|
rememberMe: boolean = false;
|
||||||
private rememberedName: string = "";
|
rememberedName: string = "";
|
||||||
//Form reference
|
//Form reference
|
||||||
signInForm: NgForm;
|
signInForm: NgForm;
|
||||||
@ViewChild('signInForm') currentForm: NgForm;
|
@ViewChild('signInForm') currentForm: NgForm;
|
||||||
@ -126,7 +126,7 @@ export class SignInComponent implements AfterViewChecked, OnInit {
|
|||||||
return this.appConfig.auth_mode != 'ldap_auth';
|
return this.appConfig.auth_mode != 'ldap_auth';
|
||||||
}
|
}
|
||||||
|
|
||||||
private clickRememberMe($event): void {
|
clickRememberMe($event: any): void {
|
||||||
if ($event && $event.target) {
|
if ($event && $event.target) {
|
||||||
this.rememberMe = $event.target.checked;
|
this.rememberMe = $event.target.checked;
|
||||||
if (!this.rememberMe) {
|
if (!this.rememberMe) {
|
||||||
@ -137,23 +137,23 @@ export class SignInComponent implements AfterViewChecked, OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private remeberMe(): void {
|
remeberMe(): void {
|
||||||
if (this.rememberMe) {
|
if (this.rememberMe) {
|
||||||
if (this.rememberedName != this.signInCredential.principal) {
|
if (this.rememberedName != this.signInCredential.principal) {
|
||||||
//Set expire time
|
//Set expire time
|
||||||
let expires: number = expireDays * 3600 * 24 * 1000;
|
let expires: number = expireDays * 3600 * 24 * 1000;
|
||||||
let date = new Date(Date.now() + expires);
|
let date = new Date(Date.now() + expires);
|
||||||
let cookieptions = new CookieOptions({
|
let cookieptions: CookieOptions = {
|
||||||
path: "/",
|
path: "/",
|
||||||
expires: date
|
expires: date
|
||||||
});
|
};
|
||||||
this.cookie.put(remCookieKey, this.signInCredential.principal, cookieptions);
|
this.cookie.put(remCookieKey, this.signInCredential.principal, cookieptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//General error handler
|
//General error handler
|
||||||
private handleError(error) {
|
handleError(error: any) {
|
||||||
//Set error status
|
//Set error status
|
||||||
this.signInStatus = signInStatusError;
|
this.signInStatus = signInStatusError;
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ export class SignInComponent implements AfterViewChecked, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Hande form values changes
|
//Hande form values changes
|
||||||
private formChanged() {
|
formChanged() {
|
||||||
if (this.currentForm === this.signInForm) {
|
if (this.currentForm === this.signInForm) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -177,7 +177,7 @@ export class SignInComponent implements AfterViewChecked, OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Fill the new user info into the sign in form
|
//Fill the new user info into the sign in form
|
||||||
private handleUserCreation(user: User): void {
|
handleUserCreation(user: User): void {
|
||||||
if (user) {
|
if (user) {
|
||||||
this.currentForm.setValue({
|
this.currentForm.setValue({
|
||||||
"login_username": user.username,
|
"login_username": user.username,
|
||||||
|
@ -27,14 +27,14 @@ const signInUrl = '/login';
|
|||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SignInService {
|
export class SignInService {
|
||||||
private headers = new Headers({
|
headers = new Headers({
|
||||||
"Content-Type": 'application/x-www-form-urlencoded'
|
"Content-Type": 'application/x-www-form-urlencoded'
|
||||||
});
|
});
|
||||||
|
|
||||||
constructor(private http: Http) {}
|
constructor(private http: Http) {}
|
||||||
|
|
||||||
//Handle the related exceptions
|
//Handle the related exceptions
|
||||||
private handleError(error: any): Promise<any>{
|
handleError(error: any): Promise<any>{
|
||||||
return Promise.reject(error.message || error);
|
return Promise.reject(error.message || error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,9 +29,9 @@ import { MessageService } from '../../global-message/message.service';
|
|||||||
templateUrl: "sign-up-page.component.html"
|
templateUrl: "sign-up-page.component.html"
|
||||||
})
|
})
|
||||||
export class SignUpPageComponent implements OnInit {
|
export class SignUpPageComponent implements OnInit {
|
||||||
private error: any;
|
error: any;
|
||||||
private onGoing: boolean = false;
|
onGoing: boolean = false;
|
||||||
private formValueChanged: boolean = false;
|
formValueChanged: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private userService: UserService,
|
private userService: UserService,
|
||||||
@ -39,9 +39,9 @@ export class SignUpPageComponent implements OnInit {
|
|||||||
private router: Router) { }
|
private router: Router) { }
|
||||||
|
|
||||||
@ViewChild(NewUserFormComponent)
|
@ViewChild(NewUserFormComponent)
|
||||||
private newUserForm: NewUserFormComponent;
|
newUserForm: NewUserFormComponent;
|
||||||
|
|
||||||
private getNewUser(): User {
|
getNewUser(): User {
|
||||||
return this.newUserForm.getData();
|
return this.newUserForm.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,9 +30,9 @@ import { Modal } from 'clarity-angular';
|
|||||||
export class SignUpComponent {
|
export class SignUpComponent {
|
||||||
opened: boolean = false;
|
opened: boolean = false;
|
||||||
staticBackdrop: boolean = true;
|
staticBackdrop: boolean = true;
|
||||||
private error: any;
|
error: any;
|
||||||
private onGoing: boolean = false;
|
onGoing: boolean = false;
|
||||||
private formValueChanged: boolean = false;
|
formValueChanged: boolean = false;
|
||||||
|
|
||||||
@Output() userCreation = new EventEmitter<User>();
|
@Output() userCreation = new EventEmitter<User>();
|
||||||
|
|
||||||
@ -41,15 +41,15 @@ export class SignUpComponent {
|
|||||||
private userService: UserService) { }
|
private userService: UserService) { }
|
||||||
|
|
||||||
@ViewChild(NewUserFormComponent)
|
@ViewChild(NewUserFormComponent)
|
||||||
private newUserForm: NewUserFormComponent;
|
newUserForm: NewUserFormComponent;
|
||||||
|
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent)
|
||||||
private inlienAlert: InlineAlertComponent;
|
inlienAlert: InlineAlertComponent;
|
||||||
|
|
||||||
@ViewChild(Modal)
|
@ViewChild(Modal)
|
||||||
private modal: Modal;
|
modal: Modal;
|
||||||
|
|
||||||
private getNewUser(): User {
|
getNewUser(): User {
|
||||||
return this.newUserForm.getData();
|
return this.newUserForm.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ export class SignUpComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmCancel(): void {
|
confirmCancel($event: any): void {
|
||||||
this.opened = false;
|
this.opened = false;
|
||||||
this.modal.close();
|
this.modal.close();
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ import { Headers, Http, RequestOptions } from '@angular/http';
|
|||||||
import 'rxjs/add/operator/toPromise';
|
import 'rxjs/add/operator/toPromise';
|
||||||
|
|
||||||
import { AppConfig } from './app-config';
|
import { AppConfig } from './app-config';
|
||||||
import { CookieService } from 'angular2-cookie/core';
|
import { CookieService } from 'ngx-cookie';
|
||||||
import { CookieKeyOfAdmiral, HarborQueryParamKey } from './shared/shared.const';
|
import { CookieKeyOfAdmiral, HarborQueryParamKey } from './shared/shared.const';
|
||||||
import { maintainUrlQueryParmas } from './shared/shared.utils';
|
import { maintainUrlQueryParmas } from './shared/shared.utils';
|
||||||
|
|
||||||
@ -30,15 +30,15 @@ export const systemInfoEndpoint = "/api/systeminfo";
|
|||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AppConfigService {
|
export class AppConfigService {
|
||||||
private headers = new Headers({
|
headers = new Headers({
|
||||||
"Content-Type": 'application/json'
|
"Content-Type": 'application/json'
|
||||||
});
|
});
|
||||||
private options = new RequestOptions({
|
options = new RequestOptions({
|
||||||
headers: this.headers
|
headers: this.headers
|
||||||
});
|
});
|
||||||
|
|
||||||
//Store the application configuration
|
//Store the application configuration
|
||||||
private configurations: AppConfig = new AppConfig();
|
configurations: AppConfig = new AppConfig();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private http: Http,
|
private http: Http,
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, ReflectiveInjector, LOCALE_ID } from '@angular/core';
|
import { Component, ReflectiveInjector, LOCALE_ID } from '@angular/core';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { CookieService } from 'angular2-cookie/core';
|
import { CookieService } from 'ngx-cookie';
|
||||||
|
|
||||||
import { supportedLangs, enLang } from './shared/shared.const';
|
import { supportedLangs, enLang } from './shared/shared.const';
|
||||||
import { SessionService } from './shared/session.service';
|
import { SessionService } from './shared/session.service';
|
||||||
@ -43,8 +43,7 @@ export class AppComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let selectedLang = this.isLangMatch(langSetting, supportedLangs) ? langSetting : enLang;
|
let selectedLang = this.isLangMatch(langSetting, supportedLangs) ? langSetting : enLang;
|
||||||
translate.use(selectedLang);
|
translate.use(selectedLang);
|
||||||
//this.session.switchLanguage(selectedLang).catch(error => console.error(error));
|
|
||||||
|
|
||||||
//Override page title
|
//Override page title
|
||||||
let key: string = "APP_TITLE.HARBOR";
|
let key: string = "APP_TITLE.HARBOR";
|
||||||
@ -57,7 +56,7 @@ export class AppComponent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private isLangMatch(browserLang: string, supportedLangs: string[]) {
|
isLangMatch(browserLang: string, supportedLangs: string[]) {
|
||||||
if (supportedLangs && supportedLangs.length > 0) {
|
if (supportedLangs && supportedLangs.length > 0) {
|
||||||
return supportedLangs.find(lang => lang === browserLang);
|
return supportedLangs.find(lang => lang === browserLang);
|
||||||
}
|
}
|
||||||
|
@ -32,15 +32,15 @@ const deBounceTime = 500; //ms
|
|||||||
})
|
})
|
||||||
export class GlobalSearchComponent implements OnInit, OnDestroy {
|
export class GlobalSearchComponent implements OnInit, OnDestroy {
|
||||||
//Keep search term as Subject
|
//Keep search term as Subject
|
||||||
private searchTerms = new Subject<string>();
|
searchTerms = new Subject<string>();
|
||||||
|
|
||||||
//Keep subscription for future use
|
//Keep subscription for future use
|
||||||
private searchSub: Subscription;
|
searchSub: Subscription;
|
||||||
private closeSub: Subscription;
|
closeSub: Subscription;
|
||||||
|
|
||||||
//To indicate if the result panel is opened
|
//To indicate if the result panel is opened
|
||||||
private isResPanelOpened: boolean = false;
|
isResPanelOpened: boolean = false;
|
||||||
private searchTerm: string = "";
|
searchTerm: string = "";
|
||||||
|
|
||||||
//Placeholder text
|
//Placeholder text
|
||||||
placeholderText: string = "GLOBAL_SEARCH.PLACEHOLDER";
|
placeholderText: string = "GLOBAL_SEARCH.PLACEHOLDER";
|
||||||
|
@ -27,10 +27,10 @@ const searchEndpoint = "/api/search";
|
|||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GlobalSearchService {
|
export class GlobalSearchService {
|
||||||
private headers = new Headers({
|
headers = new Headers({
|
||||||
"Content-Type": 'application/json'
|
"Content-Type": 'application/json'
|
||||||
});
|
});
|
||||||
private options = new RequestOptions({
|
options = new RequestOptions({
|
||||||
headers: this.headers
|
headers: this.headers
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -30,22 +30,22 @@ import { MessageHandlerService } from '../../shared/message-handler/message-hand
|
|||||||
})
|
})
|
||||||
|
|
||||||
export class SearchResultComponent implements OnInit, OnDestroy {
|
export class SearchResultComponent implements OnInit, OnDestroy {
|
||||||
private searchResults: SearchResults = new SearchResults();
|
searchResults: SearchResults = new SearchResults();
|
||||||
private originalCopy: SearchResults;
|
originalCopy: SearchResults;
|
||||||
|
|
||||||
private currentTerm: string = "";
|
currentTerm: string = "";
|
||||||
|
|
||||||
//Open or close
|
//Open or close
|
||||||
private stateIndicator: boolean = false;
|
stateIndicator: boolean = false;
|
||||||
//Search in progress
|
//Search in progress
|
||||||
private onGoing: boolean = false;
|
onGoing: boolean = false;
|
||||||
|
|
||||||
//Whether or not mouse point is onto the close indicator
|
//Whether or not mouse point is onto the close indicator
|
||||||
private mouseOn: boolean = false;
|
mouseOn: boolean = false;
|
||||||
|
|
||||||
//Watch message channel
|
//Watch message channel
|
||||||
private searchSub: Subscription;
|
searchSub: Subscription;
|
||||||
private closeSearchSub: Subscription;
|
closeSearchSub: Subscription;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private search: GlobalSearchService,
|
private search: GlobalSearchService,
|
||||||
@ -71,7 +71,7 @@ export class SearchResultComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private clone(src: SearchResults): SearchResults {
|
clone(src: SearchResults): SearchResults {
|
||||||
let res: SearchResults = new SearchResults();
|
let res: SearchResults = new SearchResults();
|
||||||
|
|
||||||
if (src) {
|
if (src) {
|
||||||
|
@ -18,9 +18,9 @@ import { AlertType } from '../../shared/shared.const';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class SearchTriggerService {
|
export class SearchTriggerService {
|
||||||
|
|
||||||
private searchTriggerSource = new Subject<string>();
|
searchTriggerSource = new Subject<string>();
|
||||||
private searchCloseSource = new Subject<boolean>();
|
searchCloseSource = new Subject<boolean>();
|
||||||
private searchClearSource = new Subject<boolean>();
|
searchClearSource = new Subject<boolean>();
|
||||||
|
|
||||||
searchTriggerChan$ = this.searchTriggerSource.asObservable();
|
searchTriggerChan$ = this.searchTriggerSource.asObservable();
|
||||||
searchCloseChan$ = this.searchCloseSource.asObservable();
|
searchCloseChan$ = this.searchCloseSource.asObservable();
|
||||||
@ -37,7 +37,7 @@ export class SearchTriggerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Clear search term
|
//Clear search term
|
||||||
clear(event): void {
|
clear(event: any): void {
|
||||||
this.searchClearSource.next(event);
|
this.searchClearSource.next(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,23 +39,23 @@ import { CommonRoutes } from '../../shared/shared.const';
|
|||||||
export class HarborShellComponent implements OnInit, OnDestroy {
|
export class HarborShellComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@ViewChild(AccountSettingsModalComponent)
|
@ViewChild(AccountSettingsModalComponent)
|
||||||
private accountSettingsModal: AccountSettingsModalComponent;
|
accountSettingsModal: AccountSettingsModalComponent;
|
||||||
|
|
||||||
@ViewChild(PasswordSettingComponent)
|
@ViewChild(PasswordSettingComponent)
|
||||||
private pwdSetting: PasswordSettingComponent;
|
pwdSetting: PasswordSettingComponent;
|
||||||
|
|
||||||
@ViewChild(NavigatorComponent)
|
@ViewChild(NavigatorComponent)
|
||||||
private navigator: NavigatorComponent;
|
navigator: NavigatorComponent;
|
||||||
|
|
||||||
@ViewChild(AboutDialogComponent)
|
@ViewChild(AboutDialogComponent)
|
||||||
private aboutDialog: AboutDialogComponent;
|
aboutDialog: AboutDialogComponent;
|
||||||
|
|
||||||
//To indicator whwther or not the search results page is displayed
|
//To indicator whwther or not the search results page is displayed
|
||||||
//We need to use this property to do some overriding work
|
//We need to use this property to do some overriding work
|
||||||
private isSearchResultsOpened: boolean = false;
|
isSearchResultsOpened: boolean = false;
|
||||||
|
|
||||||
private searchSub: Subscription;
|
searchSub: Subscription;
|
||||||
private searchCloseSub: Subscription;
|
searchCloseSub: Subscription;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
|
@ -20,7 +20,7 @@ import { modalEvents } from '../modal-events.const';
|
|||||||
|
|
||||||
import { SessionUser } from '../../shared/session-user';
|
import { SessionUser } from '../../shared/session-user';
|
||||||
import { SessionService } from '../../shared/session.service';
|
import { SessionService } from '../../shared/session.service';
|
||||||
import { CookieService, CookieOptions } from 'angular2-cookie/core';
|
import { CookieService, CookieOptions } from 'ngx-cookie';
|
||||||
|
|
||||||
import { supportedLangs, enLang, languageNames, CommonRoutes } from '../../shared/shared.const';
|
import { supportedLangs, enLang, languageNames, CommonRoutes } from '../../shared/shared.const';
|
||||||
import { AppConfigService } from '../../app-config.service';
|
import { AppConfigService } from '../../app-config.service';
|
||||||
@ -38,8 +38,8 @@ export class NavigatorComponent implements OnInit {
|
|||||||
@Output() showAccountSettingsModal = new EventEmitter<ModalEvent>();
|
@Output() showAccountSettingsModal = new EventEmitter<ModalEvent>();
|
||||||
@Output() showPwdChangeModal = new EventEmitter<ModalEvent>();
|
@Output() showPwdChangeModal = new EventEmitter<ModalEvent>();
|
||||||
|
|
||||||
private selectedLang: string = enLang;
|
selectedLang: string = enLang;
|
||||||
private appTitle: string = 'APP_TITLE.HARBOR';
|
appTitle: string = 'APP_TITLE.HARBOR';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private session: SessionService,
|
private session: SessionService,
|
||||||
@ -54,10 +54,10 @@ export class NavigatorComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.selectedLang = this.translate.currentLang;
|
this.selectedLang = this.translate.currentLang;
|
||||||
this.translate.onLangChange.subscribe(langChange => {
|
this.translate.onLangChange.subscribe((langChange: {lang: string}) => {
|
||||||
this.selectedLang = langChange.lang;
|
this.selectedLang = langChange.lang;
|
||||||
//Keep in cookie for next use
|
//Keep in cookie for next use
|
||||||
let opt = new CookieOptions({path: '/', expires: new Date(Date.now() + 3600*1000*24*31)});
|
let opt:CookieOptions = {path: '/', expires: new Date(Date.now() + 3600*1000*24*31)};
|
||||||
this.cookie.put("harbor-lang", langChange.lang, opt);
|
this.cookie.put("harbor-lang", langChange.lang, opt);
|
||||||
});
|
});
|
||||||
if (this.appConfigService.isIntegrationMode()) {
|
if (this.appConfigService.isIntegrationMode()) {
|
||||||
|
@ -22,7 +22,7 @@ import { SessionUser } from '../../shared/session-user';
|
|||||||
styleUrls: ['start.component.css']
|
styleUrls: ['start.component.css']
|
||||||
})
|
})
|
||||||
export class StartPageComponent implements OnInit{
|
export class StartPageComponent implements OnInit{
|
||||||
private isSessionValid: boolean = false;
|
isSessionValid: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private session: SessionService
|
private session: SessionService
|
||||||
|
@ -23,7 +23,7 @@ import { Configuration } from '../config';
|
|||||||
styleUrls: ['../config.component.css']
|
styleUrls: ['../config.component.css']
|
||||||
})
|
})
|
||||||
export class ConfigurationAuthComponent {
|
export class ConfigurationAuthComponent {
|
||||||
private changeSub: Subscription;
|
changeSub: Subscription;
|
||||||
@Input("ldapConfig") currentConfig: Configuration = new Configuration();
|
@Input("ldapConfig") currentConfig: Configuration = new Configuration();
|
||||||
|
|
||||||
@ViewChild("authConfigFrom") authForm: NgForm;
|
@ViewChild("authConfigFrom") authForm: NgForm;
|
||||||
@ -44,7 +44,7 @@ export class ConfigurationAuthComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private disabled(prop: any): boolean {
|
disabled(prop: any): boolean {
|
||||||
return !(prop && prop.editable);
|
return !(prop && prop.editable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ export class ConfigurationAuthComponent {
|
|||||||
return this.authForm && this.authForm.valid;
|
return this.authForm && this.authForm.valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleOnChange($event): void {
|
handleOnChange($event: any): void {
|
||||||
if ($event && $event.target && $event.target["value"]) {
|
if ($event && $event.target && $event.target["value"]) {
|
||||||
let authMode = $event.target["value"];
|
let authMode = $event.target["value"];
|
||||||
if (authMode === 'ldap_auth') {
|
if (authMode === 'ldap_auth') {
|
||||||
|
@ -44,13 +44,13 @@ const TabLinkContentMap = {
|
|||||||
styleUrls: ['config.component.css']
|
styleUrls: ['config.component.css']
|
||||||
})
|
})
|
||||||
export class ConfigurationComponent implements OnInit, OnDestroy {
|
export class ConfigurationComponent implements OnInit, OnDestroy {
|
||||||
private onGoing: boolean = false;
|
onGoing: boolean = false;
|
||||||
allConfig: Configuration = new Configuration();
|
allConfig: Configuration = new Configuration();
|
||||||
private currentTabId: string = "config-auth";//default tab
|
currentTabId: string = "config-auth";//default tab
|
||||||
private originalCopy: Configuration;
|
originalCopy: Configuration;
|
||||||
private confirmSub: Subscription;
|
confirmSub: Subscription;
|
||||||
private testingMailOnGoing: boolean = false;
|
testingMailOnGoing: boolean = false;
|
||||||
private testingLDAPOnGoing: boolean = false;
|
testingLDAPOnGoing: boolean = false;
|
||||||
|
|
||||||
@ViewChild("repoConfigFrom") repoConfigForm: NgForm;
|
@ViewChild("repoConfigFrom") repoConfigForm: NgForm;
|
||||||
@ViewChild("systemConfigFrom") systemConfigForm: NgForm;
|
@ViewChild("systemConfigFrom") systemConfigForm: NgForm;
|
||||||
@ -64,15 +64,15 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
|
|||||||
private appConfigService: AppConfigService,
|
private appConfigService: AppConfigService,
|
||||||
private session: SessionService) { }
|
private session: SessionService) { }
|
||||||
|
|
||||||
private isCurrentTabLink(tabId: string): boolean {
|
isCurrentTabLink(tabId: string): boolean {
|
||||||
return this.currentTabId === tabId;
|
return this.currentTabId === tabId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private isCurrentTabContent(contentId: string): boolean {
|
isCurrentTabContent(contentId: string): boolean {
|
||||||
return TabLinkContentMap[this.currentTabId] === contentId;
|
return TabLinkContentMap[this.currentTabId] === contentId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private hasUnsavedChangesOfCurrentTab(): any {
|
hasUnsavedChangesOfCurrentTab(): any {
|
||||||
let allChanges = this.getChanges();
|
let allChanges = this.getChanges();
|
||||||
if (this.isEmpty(allChanges)) {
|
if (this.isEmpty(allChanges)) {
|
||||||
return null;
|
return null;
|
||||||
@ -331,7 +331,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private confirmUnsavedChanges(changes: any) {
|
confirmUnsavedChanges(changes: any) {
|
||||||
let msg = new ConfirmationMessage(
|
let msg = new ConfirmationMessage(
|
||||||
"CONFIG.CONFIRM_TITLE",
|
"CONFIG.CONFIRM_TITLE",
|
||||||
"CONFIG.CONFIRM_SUMMARY",
|
"CONFIG.CONFIRM_SUMMARY",
|
||||||
@ -343,7 +343,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
|
|||||||
this.confirmService.openComfirmDialog(msg);
|
this.confirmService.openComfirmDialog(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private confirmUnsavedTabChanges(changes: any, tabId: string) {
|
confirmUnsavedTabChanges(changes: any, tabId: string) {
|
||||||
let msg = new ConfirmationMessage(
|
let msg = new ConfirmationMessage(
|
||||||
"CONFIG.CONFIRM_TITLE",
|
"CONFIG.CONFIRM_TITLE",
|
||||||
"CONFIG.CONFIRM_SUMMARY",
|
"CONFIG.CONFIRM_SUMMARY",
|
||||||
@ -358,7 +358,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
|
|||||||
this.confirmService.openComfirmDialog(msg);
|
this.confirmService.openComfirmDialog(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private retrieveConfig(): void {
|
retrieveConfig(): void {
|
||||||
this.onGoing = true;
|
this.onGoing = true;
|
||||||
this.configService.getConfiguration()
|
this.configService.getConfiguration()
|
||||||
.then(configurations => {
|
.then(configurations => {
|
||||||
@ -387,7 +387,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
|
|||||||
*
|
*
|
||||||
* @memberOf ConfigurationComponent
|
* @memberOf ConfigurationComponent
|
||||||
*/
|
*/
|
||||||
private getChanges(): any {
|
getChanges(): any {
|
||||||
let changes = {};
|
let changes = {};
|
||||||
if (!this.allConfig || !this.originalCopy) {
|
if (!this.allConfig || !this.originalCopy) {
|
||||||
return changes;
|
return changes;
|
||||||
@ -419,7 +419,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
|
|||||||
*
|
*
|
||||||
* @memberOf ConfigurationComponent
|
* @memberOf ConfigurationComponent
|
||||||
*/
|
*/
|
||||||
private clone(src: Configuration): Configuration {
|
clone(src: Configuration): Configuration {
|
||||||
let dest = new Configuration();
|
let dest = new Configuration();
|
||||||
if (!src) {
|
if (!src) {
|
||||||
return dest;//Empty
|
return dest;//Empty
|
||||||
@ -443,7 +443,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
|
|||||||
*
|
*
|
||||||
* @memberOf ConfigurationComponent
|
* @memberOf ConfigurationComponent
|
||||||
*/
|
*/
|
||||||
private reset(changes: any): void {
|
reset(changes: any): void {
|
||||||
if (!this.isEmpty(changes)) {
|
if (!this.isEmpty(changes)) {
|
||||||
for (let prop in changes) {
|
for (let prop in changes) {
|
||||||
if (this.originalCopy[prop]) {
|
if (this.originalCopy[prop]) {
|
||||||
@ -456,7 +456,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private isEmpty(obj) {
|
isEmpty(obj: any) {
|
||||||
for (let key in obj) {
|
for (let key in obj) {
|
||||||
if (obj.hasOwnProperty(key))
|
if (obj.hasOwnProperty(key))
|
||||||
return false;
|
return false;
|
||||||
@ -464,7 +464,7 @@ export class ConfigurationComponent implements OnInit, OnDestroy {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private disabled(prop: any): boolean {
|
disabled(prop: any): boolean {
|
||||||
return !(prop && prop.editable);
|
return !(prop && prop.editable);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,11 +23,11 @@ const ldapEndpoint = "/api/ldap/ping";
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ConfigurationService {
|
export class ConfigurationService {
|
||||||
private headers: Headers = new Headers({
|
headers: Headers = new Headers({
|
||||||
"Accept": 'application/json',
|
"Accept": 'application/json',
|
||||||
"Content-Type": 'application/json'
|
"Content-Type": 'application/json'
|
||||||
});
|
});
|
||||||
private options: RequestOptions = new RequestOptions({
|
options: RequestOptions = new RequestOptions({
|
||||||
'headers': this.headers
|
'headers': this.headers
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ export class ConfigurationEmailComponent {
|
|||||||
|
|
||||||
constructor() { }
|
constructor() { }
|
||||||
|
|
||||||
private disabled(prop: any): boolean {
|
disabled(prop: any): boolean {
|
||||||
return !(prop && prop.editable);
|
return !(prop && prop.editable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,20 +15,25 @@ import { BrowserModule } from '@angular/platform-browser';
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { HttpModule } from '@angular/http';
|
import { HttpModule } from '@angular/http';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
import { ClarityModule } from 'clarity-angular';
|
import { ClarityModule } from 'clarity-angular';
|
||||||
|
import { CookieModule } from 'ngx-cookie';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
HttpModule,
|
HttpModule,
|
||||||
ClarityModule.forRoot()
|
ClarityModule.forRoot(),
|
||||||
|
CookieModule.forRoot(),
|
||||||
|
BrowserAnimationsModule
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
HttpModule,
|
HttpModule,
|
||||||
ClarityModule
|
ClarityModule,
|
||||||
|
BrowserAnimationsModule
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class CoreModule {
|
export class CoreModule {
|
||||||
|
@ -31,11 +31,11 @@ export class MessageComponent implements OnInit, OnDestroy {
|
|||||||
globalMessage: Message = new Message();
|
globalMessage: Message = new Message();
|
||||||
globalMessageOpened: boolean;
|
globalMessageOpened: boolean;
|
||||||
messageText: string = "";
|
messageText: string = "";
|
||||||
private timer: any = null;
|
timer: any = null;
|
||||||
|
|
||||||
private appLevelMsgSub: Subscription;
|
appLevelMsgSub: Subscription;
|
||||||
private msgSub: Subscription;
|
msgSub: Subscription;
|
||||||
private clearSub: Subscription;
|
clearSub: Subscription;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private messageService: MessageService,
|
private messageService: MessageService,
|
||||||
|
@ -19,9 +19,9 @@ import { AlertType } from '../shared/shared.const';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class MessageService {
|
export class MessageService {
|
||||||
|
|
||||||
private messageAnnouncedSource = new Subject<Message>();
|
messageAnnouncedSource = new Subject<Message>();
|
||||||
private appLevelAnnouncedSource = new Subject<Message>();
|
appLevelAnnouncedSource = new Subject<Message>();
|
||||||
private clearSource = new Subject<boolean>();
|
clearSource = new Subject<boolean>();
|
||||||
|
|
||||||
messageAnnounced$ = this.messageAnnouncedSource.asObservable();
|
messageAnnounced$ = this.messageAnnouncedSource.asObservable();
|
||||||
appLevelAnnounced$ = this.appLevelAnnouncedSource.asObservable();
|
appLevelAnnounced$ = this.appLevelAnnouncedSource.asObservable();
|
||||||
|
@ -77,7 +77,6 @@ export class AuditLogComponent implements OnInit {
|
|||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.projectId = +this.route.snapshot.parent.params['id'];
|
this.projectId = +this.route.snapshot.parent.params['id'];
|
||||||
console.log('Get projectId from route params snapshot:' + this.projectId);
|
|
||||||
this.queryParam.project_id = this.projectId;
|
this.queryParam.project_id = this.projectId;
|
||||||
this.queryParam.page_size = this.pageSize;
|
this.queryParam.page_size = this.pageSize;
|
||||||
}
|
}
|
||||||
@ -92,7 +91,6 @@ export class AuditLogComponent implements OnInit {
|
|||||||
response=>{
|
response=>{
|
||||||
this.totalRecordCount = response.headers.get('x-total-count');
|
this.totalRecordCount = response.headers.get('x-total-count');
|
||||||
this.totalPage = Math.ceil(this.totalRecordCount / this.pageSize);
|
this.totalPage = Math.ceil(this.totalRecordCount / this.pageSize);
|
||||||
console.log('TotalRecordCount:' + this.totalRecordCount + ', totalPage:' + this.totalPage);
|
|
||||||
this.auditLogs = response.json();
|
this.auditLogs = response.json();
|
||||||
},
|
},
|
||||||
error=>{
|
error=>{
|
||||||
@ -117,7 +115,6 @@ export class AuditLogComponent implements OnInit {
|
|||||||
this.queryParam.end_timestamp = new Date(strDate).getTime() / 1000 + oneDayOffset;
|
this.queryParam.end_timestamp = new Date(strDate).getTime() / 1000 + oneDayOffset;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
console.log('Search audit log filtered by time range, begin: ' + this.queryParam.begin_timestamp + ', end:' + this.queryParam.end_timestamp);
|
|
||||||
this.retrieve();
|
this.retrieve();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,8 +133,7 @@ export class AuditLogComponent implements OnInit {
|
|||||||
operationFilter = [];
|
operationFilter = [];
|
||||||
}
|
}
|
||||||
this.queryParam.keywords = operationFilter.join('/');
|
this.queryParam.keywords = operationFilter.join('/');
|
||||||
this.retrieve();
|
this.retrieve();
|
||||||
console.log('Search option filter:' + operationFilter.join('/'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleOptionalName(option: number): void {
|
toggleOptionalName(option: number): void {
|
||||||
|
@ -25,7 +25,7 @@ export const logEndpoint = "/api/logs";
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuditLogService {
|
export class AuditLogService {
|
||||||
private httpOptions = new RequestOptions({
|
httpOptions = new RequestOptions({
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
"Content-Type": 'application/json',
|
"Content-Type": 'application/json',
|
||||||
"Accept": 'application/json'
|
"Accept": 'application/json'
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
<clr-dg-column>{{'AUDIT_LOG.TAGS' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'AUDIT_LOG.TAGS' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'AUDIT_LOG.OPERATION' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'AUDIT_LOG.OPERATION' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'AUDIT_LOG.TIMESTAMP' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'AUDIT_LOG.TIMESTAMP' | translate}}</clr-dg-column>
|
||||||
<clr-dg-row *ngFor="let l of recentLogs">
|
<clr-dg-row *clrDgItems="let l of recentLogs">
|
||||||
<clr-dg-cell>{{l.username}}</clr-dg-cell>
|
<clr-dg-cell>{{l.username}}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{l.repo_name}}</clr-dg-cell>
|
<clr-dg-cell>{{l.repo_name}}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{l.repo_tag}}</clr-dg-cell>
|
<clr-dg-cell>{{l.repo_tag}}</clr-dg-cell>
|
||||||
|
@ -30,11 +30,11 @@ import { errorHandler, accessErrorHandler } from '../shared/shared.utils';
|
|||||||
})
|
})
|
||||||
|
|
||||||
export class RecentLogComponent implements OnInit {
|
export class RecentLogComponent implements OnInit {
|
||||||
private sessionUser: SessionUser = null;
|
sessionUser: SessionUser = null;
|
||||||
private recentLogs: AuditLog[];
|
recentLogs: AuditLog[];
|
||||||
private logsCache: AuditLog[];
|
logsCache: AuditLog[];
|
||||||
private onGoing: boolean = false;
|
onGoing: boolean = false;
|
||||||
private lines: number = 10; //Support 10, 25 and 50
|
lines: number = 10; //Support 10, 25 and 50
|
||||||
currentTerm: string;
|
currentTerm: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -48,7 +48,7 @@ export class RecentLogComponent implements OnInit {
|
|||||||
this.retrieveLogs();
|
this.retrieveLogs();
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleOnchange($event: any) {
|
handleOnchange($event: any) {
|
||||||
this.currentTerm = '';
|
this.currentTerm = '';
|
||||||
if ($event && $event.target && $event.target["value"]) {
|
if ($event && $event.target && $event.target["value"]) {
|
||||||
this.lines = $event.target["value"];
|
this.lines = $event.target["value"];
|
||||||
@ -80,7 +80,7 @@ export class RecentLogComponent implements OnInit {
|
|||||||
this.retrieveLogs();
|
this.retrieveLogs();
|
||||||
}
|
}
|
||||||
|
|
||||||
private retrieveLogs(): void {
|
retrieveLogs(): void {
|
||||||
if (this.lines < 10) {
|
if (this.lines < 10) {
|
||||||
this.lines = 10;
|
this.lines = 10;
|
||||||
}
|
}
|
||||||
@ -102,7 +102,7 @@ export class RecentLogComponent implements OnInit {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private isMatched(terms: string, log: AuditLog): boolean {
|
isMatched(terms: string, log: AuditLog): boolean {
|
||||||
let reg = new RegExp('.*' + terms + '.*', 'i');
|
let reg = new RegExp('.*' + terms + '.*', 'i');
|
||||||
return reg.test(log.username) ||
|
return reg.test(log.username) ||
|
||||||
reg.test(log.repo_name) ||
|
reg.test(log.repo_name) ||
|
||||||
|
@ -47,7 +47,7 @@ export class CreateProjectComponent implements AfterViewChecked {
|
|||||||
|
|
||||||
@Output() create = new EventEmitter<boolean>();
|
@Output() create = new EventEmitter<boolean>();
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent)
|
||||||
private inlineAlert: InlineAlertComponent;
|
inlineAlert: InlineAlertComponent;
|
||||||
|
|
||||||
constructor(private projectService: ProjectService,
|
constructor(private projectService: ProjectService,
|
||||||
private translateService: TranslateService,
|
private translateService: TranslateService,
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
<clr-dg-column *ngIf="showRoleInfo">{{'PROJECT.ROLE' | translate}}</clr-dg-column>
|
<clr-dg-column *ngIf="showRoleInfo">{{'PROJECT.ROLE' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'PROJECT.REPO_COUNT'| translate}}</clr-dg-column>
|
<clr-dg-column>{{'PROJECT.REPO_COUNT'| translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'PROJECT.CREATION_TIME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'PROJECT.CREATION_TIME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-row *ngFor="let p of projects" [clrDgItem]="p">
|
<clr-dg-row *clrDgItems="let p of projects">
|
||||||
<clr-dg-action-overflow [hidden]="!(p.current_user_role_id === 1 || isSystemAdmin)">
|
<clr-dg-action-overflow [hidden]="!(p.current_user_role_id === 1 || isSystemAdmin)">
|
||||||
<button class="action-item" (click)="newReplicationRule(p)" [hidden]="!isSystemAdmin">{{'PROJECT.REPLICATION_RULE' | translate}}</button>
|
<button class="action-item" (click)="newReplicationRule(p)" [hidden]="!isSystemAdmin">{{'PROJECT.REPLICATION_RULE' | translate}}</button>
|
||||||
<button class="action-item" (click)="toggleProject(p)">{{'PROJECT.MAKE' | translate}} {{(p.public === 0 ? 'PROJECT.PUBLIC' : 'PROJECT.PRIVATE') | translate}} </button>
|
<button class="action-item" (click)="toggleProject(p)">{{'PROJECT.MAKE' | translate}} {{(p.public === 0 ? 'PROJECT.PUBLIC' : 'PROJECT.PRIVATE') | translate}} </button>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<clr-dg-cell>{{p.creation_time | date: 'short'}}</clr-dg-cell>
|
<clr-dg-cell>{{p.creation_time | date: 'short'}}</clr-dg-cell>
|
||||||
</clr-dg-row>
|
</clr-dg-row>
|
||||||
<clr-dg-footer>
|
<clr-dg-footer>
|
||||||
{{totalRecordCount || (projects ? projects.length : 0)}} {{'PROJECT.ITEMS' | translate}}
|
{{(projects ? projects.length : 0)}} {{'PROJECT.ITEMS' | translate}}
|
||||||
<clr-dg-pagination [clrDgPageSize]="pageOffset" [clrDgTotalItems]="totalPage"></clr-dg-pagination>
|
<clr-dg-pagination [clrDgPageSize]="15"></clr-dg-pagination>
|
||||||
</clr-dg-footer>
|
</clr-dg-footer>
|
||||||
</clr-datagrid>
|
</clr-datagrid>
|
@ -11,7 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, EventEmitter, Output, Input, OnInit } from '@angular/core';
|
import { Component, EventEmitter, Output, Input, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
import { Router, NavigationExtras } from '@angular/router';
|
import { Router, NavigationExtras } from '@angular/router';
|
||||||
import { Project } from '../project';
|
import { Project } from '../project';
|
||||||
import { ProjectService } from '../project.service';
|
import { ProjectService } from '../project.service';
|
||||||
@ -24,17 +24,12 @@ import { State } from 'clarity-angular';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'list-project',
|
selector: 'list-project',
|
||||||
templateUrl: 'list-project.component.html'
|
templateUrl: 'list-project.component.html',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class ListProjectComponent implements OnInit {
|
export class ListProjectComponent {
|
||||||
|
|
||||||
@Input() projects: Project[];
|
@Input() projects: Project[];
|
||||||
|
|
||||||
|
|
||||||
@Input() totalPage: number;
|
|
||||||
@Input() totalRecordCount: number;
|
|
||||||
pageOffset: number = 1;
|
|
||||||
|
|
||||||
@Input() filteredType: string;
|
@Input() filteredType: string;
|
||||||
|
|
||||||
@Output() paginate = new EventEmitter<State>();
|
@Output() paginate = new EventEmitter<State>();
|
||||||
@ -47,10 +42,11 @@ export class ListProjectComponent implements OnInit {
|
|||||||
constructor(
|
constructor(
|
||||||
private session: SessionService,
|
private session: SessionService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private searchTrigger: SearchTriggerService) { }
|
private searchTrigger: SearchTriggerService,
|
||||||
|
private ref: ChangeDetectorRef) {
|
||||||
ngOnInit(): void {
|
let hnd = setInterval(()=>ref.markForCheck(), 100);
|
||||||
}
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
get showRoleInfo(): boolean {
|
get showRoleInfo(): boolean {
|
||||||
return this.filteredType === ProjectTypes[0];
|
return this.filteredType === ProjectTypes[0];
|
||||||
|
@ -63,7 +63,6 @@ export class AddMemberComponent implements AfterViewChecked {
|
|||||||
.subscribe(
|
.subscribe(
|
||||||
response=>{
|
response=>{
|
||||||
this.messageHandlerService.showSuccess('MEMBER.ADDED_SUCCESS');
|
this.messageHandlerService.showSuccess('MEMBER.ADDED_SUCCESS');
|
||||||
console.log('Added member successfully.');
|
|
||||||
this.added.emit(true);
|
this.added.emit(true);
|
||||||
this.addMemberOpened = false;
|
this.addMemberOpened = false;
|
||||||
},
|
},
|
||||||
@ -89,7 +88,6 @@ export class AddMemberComponent implements AfterViewChecked {
|
|||||||
.subscribe(errorMessage=>this.inlineAlert.showInlineError(errorMessage));
|
.subscribe(errorMessage=>this.inlineAlert.showInlineError(errorMessage));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log('Failed to add member of project:' + this.projectId, ' with error:' + error);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<clr-datagrid>
|
<clr-datagrid>
|
||||||
<clr-dg-column>{{'MEMBER.NAME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'MEMBER.NAME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'MEMBER.ROLE' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'MEMBER.ROLE' | translate}}</clr-dg-column>
|
||||||
<clr-dg-row *ngFor="let m of members">
|
<clr-dg-row *clrDgItems="let m of members">
|
||||||
<clr-dg-action-overflow [hidden]="m.user_id === currentUser.user_id || !hasProjectAdminRole">
|
<clr-dg-action-overflow [hidden]="m.user_id === currentUser.user_id || !hasProjectAdminRole">
|
||||||
<button class="action-item" (click)="changeRole(m, 1)">{{'MEMBER.PROJECT_ADMIN' | translate}}</button>
|
<button class="action-item" (click)="changeRole(m, 1)">{{'MEMBER.PROJECT_ADMIN' | translate}}</button>
|
||||||
<button class="action-item" (click)="changeRole(m, 2)">{{'MEMBER.DEVELOPER' | translate}}</button>
|
<button class="action-item" (click)="changeRole(m, 2)">{{'MEMBER.DEVELOPER' | translate}}</button>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core';
|
import { Component, OnInit, ViewChild, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
import { ActivatedRoute, Params, Router } from '@angular/router';
|
||||||
import { Response } from '@angular/http';
|
import { Response } from '@angular/http';
|
||||||
|
|
||||||
@ -41,14 +41,15 @@ import { Project } from '../../project/project';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: 'member.component.html',
|
templateUrl: 'member.component.html',
|
||||||
styleUrls: ['./member.component.css']
|
styleUrls: ['./member.component.css'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class MemberComponent implements OnInit, OnDestroy {
|
export class MemberComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
members: Member[];
|
members: Member[];
|
||||||
projectId: number;
|
projectId: number;
|
||||||
roleInfo = RoleInfo;
|
roleInfo = RoleInfo;
|
||||||
private delSub: Subscription;
|
delSub: Subscription;
|
||||||
|
|
||||||
@ViewChild(AddMemberComponent)
|
@ViewChild(AddMemberComponent)
|
||||||
addMemberComponent: AddMemberComponent;
|
addMemberComponent: AddMemberComponent;
|
||||||
@ -64,7 +65,8 @@ export class MemberComponent implements OnInit, OnDestroy {
|
|||||||
private memberService: MemberService,
|
private memberService: MemberService,
|
||||||
private messageHandlerService: MessageHandlerService,
|
private messageHandlerService: MessageHandlerService,
|
||||||
private deletionDialogService: ConfirmationDialogService,
|
private deletionDialogService: ConfirmationDialogService,
|
||||||
private session: SessionService) {
|
private session: SessionService,
|
||||||
|
private ref: ChangeDetectorRef) {
|
||||||
|
|
||||||
this.delSub = deletionDialogService.confirmationConfirm$.subscribe(message => {
|
this.delSub = deletionDialogService.confirmationConfirm$.subscribe(message => {
|
||||||
if (message &&
|
if (message &&
|
||||||
@ -75,20 +77,25 @@ export class MemberComponent implements OnInit, OnDestroy {
|
|||||||
.subscribe(
|
.subscribe(
|
||||||
response => {
|
response => {
|
||||||
this.messageHandlerService.showSuccess('MEMBER.DELETED_SUCCESS');
|
this.messageHandlerService.showSuccess('MEMBER.DELETED_SUCCESS');
|
||||||
console.log('Successful delete member: ' + message.data);
|
|
||||||
this.retrieve(this.projectId, '');
|
this.retrieve(this.projectId, '');
|
||||||
},
|
},
|
||||||
error => this.messageHandlerService.handleError(error)
|
error => this.messageHandlerService.handleError(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
let hnd = setInterval(()=>ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
retrieve(projectId: number, username: string) {
|
retrieve(projectId: number, username: string) {
|
||||||
this.memberService
|
this.memberService
|
||||||
.listMembers(projectId, username)
|
.listMembers(projectId, username)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
response => this.members = response,
|
response => {
|
||||||
|
this.members = response;
|
||||||
|
let hnd = setInterval(()=>this.ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
|
},
|
||||||
error => {
|
error => {
|
||||||
this.router.navigate(['/harbor', 'projects']);
|
this.router.navigate(['/harbor', 'projects']);
|
||||||
this.messageHandlerService.handleError(error);
|
this.messageHandlerService.handleError(error);
|
||||||
@ -103,18 +110,13 @@ export class MemberComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
//Get projectId from route params snapshot.
|
//Get projectId from route params snapshot.
|
||||||
this.projectId = +this.route.snapshot.parent.params['id'];
|
this.projectId = +this.route.snapshot.parent.params['id'];
|
||||||
console.log('Get projectId from route params snapshot:' + this.projectId);
|
|
||||||
|
|
||||||
this.currentUser = this.session.getCurrentUser();
|
this.currentUser = this.session.getCurrentUser();
|
||||||
//Get current user from registered resolver.
|
//Get current user from registered resolver.
|
||||||
let resolverData = this.route.snapshot.parent.data;
|
let resolverData = this.route.snapshot.parent.data;
|
||||||
if(resolverData) {
|
if(resolverData) {
|
||||||
this.hasProjectAdminRole = (<Project>resolverData['projectResolver']).has_project_admin_role;
|
this.hasProjectAdminRole = (<Project>resolverData['projectResolver']).has_project_admin_role;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.retrieve(this.projectId, '');
|
this.retrieve(this.projectId, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +124,7 @@ export class MemberComponent implements OnInit, OnDestroy {
|
|||||||
this.addMemberComponent.openAddMemberModal();
|
this.addMemberComponent.openAddMemberModal();
|
||||||
}
|
}
|
||||||
|
|
||||||
addedMember() {
|
addedMember($event: any) {
|
||||||
this.searchMember = '';
|
this.searchMember = '';
|
||||||
this.retrieve(this.projectId, '');
|
this.retrieve(this.projectId, '');
|
||||||
}
|
}
|
||||||
@ -134,7 +136,6 @@ export class MemberComponent implements OnInit, OnDestroy {
|
|||||||
.subscribe(
|
.subscribe(
|
||||||
response => {
|
response => {
|
||||||
this.messageHandlerService.showSuccess('MEMBER.SWITCHED_SUCCESS');
|
this.messageHandlerService.showSuccess('MEMBER.SWITCHED_SUCCESS');
|
||||||
console.log('Successful change role with user ' + m.user_id + ' to roleId ' + roleId);
|
|
||||||
this.retrieve(this.projectId, '');
|
this.retrieve(this.projectId, '');
|
||||||
},
|
},
|
||||||
error => this.messageHandlerService.handleError(error)
|
error => this.messageHandlerService.handleError(error)
|
||||||
@ -153,7 +154,7 @@ export class MemberComponent implements OnInit, OnDestroy {
|
|||||||
this.deletionDialogService.openComfirmDialog(deletionMessage);
|
this.deletionDialogService.openComfirmDialog(deletionMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
doSearch(searchMember) {
|
doSearch(searchMember: string) {
|
||||||
this.searchMember = searchMember;
|
this.searchMember = searchMember;
|
||||||
this.retrieve(this.projectId, this.searchMember);
|
this.retrieve(this.projectId, this.searchMember);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ export class MemberService {
|
|||||||
constructor(private http: Http) {}
|
constructor(private http: Http) {}
|
||||||
|
|
||||||
listMembers(projectId: number, username: string): Observable<Member[]> {
|
listMembers(projectId: number, username: string): Observable<Member[]> {
|
||||||
console.log('Get member from project_id:' + projectId + ', username:' + username);
|
|
||||||
return this.http
|
return this.http
|
||||||
.get(`/api/projects/${projectId}/members?username=${username}`)
|
.get(`/api/projects/${projectId}/members?username=${username}`)
|
||||||
.map(response=>response.json() as Member[])
|
.map(response=>response.json() as Member[])
|
||||||
@ -35,7 +34,6 @@ export class MemberService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
addMember(projectId: number, username: string, roleId: number): Observable<any> {
|
addMember(projectId: number, username: string, roleId: number): Observable<any> {
|
||||||
console.log('Adding member with username:' + username + ', roleId:' + roleId + ' under projectId:' + projectId);
|
|
||||||
return this.http
|
return this.http
|
||||||
.post(`/api/projects/${projectId}/members`, { username: username, roles: [ roleId ] })
|
.post(`/api/projects/${projectId}/members`, { username: username, roles: [ roleId ] })
|
||||||
.map(response=>response.status)
|
.map(response=>response.status)
|
||||||
@ -43,7 +41,6 @@ export class MemberService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
changeMemberRole(projectId: number, userId: number, roleId: number): Observable<any> {
|
changeMemberRole(projectId: number, userId: number, roleId: number): Observable<any> {
|
||||||
console.log('Changing member role with userId:' + ' to roleId:' + roleId + ' under projectId:' + projectId);
|
|
||||||
return this.http
|
return this.http
|
||||||
.put(`/api/projects/${projectId}/members/${userId}`, { roles: [ roleId ]})
|
.put(`/api/projects/${projectId}/members/${userId}`, { roles: [ roleId ]})
|
||||||
.map(response=>response.status)
|
.map(response=>response.status)
|
||||||
@ -51,7 +48,6 @@ export class MemberService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteMember(projectId: number, userId: number): Observable<any> {
|
deleteMember(projectId: number, userId: number): Observable<any> {
|
||||||
console.log('Deleting member role with userId:' + userId + ' under projectId:' + projectId);
|
|
||||||
return this.http
|
return this.http
|
||||||
.delete(`/api/projects/${projectId}/members/${userId}`)
|
.delete(`/api/projects/${projectId}/members/${userId}`)
|
||||||
.map(response=>response.status)
|
.map(response=>response.status)
|
||||||
|
@ -29,7 +29,6 @@ export class ProjectRoutingResolver implements Resolve<Project>{
|
|||||||
|
|
||||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<Project> {
|
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<Project> {
|
||||||
let projectId = route.params['id'];
|
let projectId = route.params['id'];
|
||||||
console.log('Project resolver, projectID:' + projectId);
|
|
||||||
return this.projectService
|
return this.projectService
|
||||||
.getProject(projectId)
|
.getProject(projectId)
|
||||||
.toPromise()
|
.toPromise()
|
||||||
|
@ -24,6 +24,6 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<list-project [projects]="changedProjects" [filteredType]="projectTypes[currentFilteredType]" (toggle)="toggleProject($event)" (delete)="deleteProject($event)" (paginate)="retrieve($event)" [totalPage]="totalPage" [totalRecordCount]="totalRecordCount"></list-project>
|
<list-project [projects]="changedProjects" [filteredType]="projectTypes[currentFilteredType]" (toggle)="toggleProject($event)" (delete)="deleteProject($event)" (paginate)="retrieve($event)"></list-project>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -47,7 +47,6 @@ import { StatisticHandler } from '../shared/statictics/statistic-handler.service
|
|||||||
})
|
})
|
||||||
export class ProjectComponent implements OnInit, OnDestroy {
|
export class ProjectComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
selected = [];
|
|
||||||
changedProjects: Project[];
|
changedProjects: Project[];
|
||||||
projectTypes = ProjectTypes;
|
projectTypes = ProjectTypes;
|
||||||
|
|
||||||
@ -64,12 +63,6 @@ export class ProjectComponent implements OnInit, OnDestroy {
|
|||||||
projectName: string;
|
projectName: string;
|
||||||
isPublic: number;
|
isPublic: number;
|
||||||
|
|
||||||
page: number = 1;
|
|
||||||
pageSize: number = 15;
|
|
||||||
|
|
||||||
totalPage: number;
|
|
||||||
totalRecordCount: number;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private projectService: ProjectService,
|
private projectService: ProjectService,
|
||||||
private messageHandlerService: MessageHandlerService,
|
private messageHandlerService: MessageHandlerService,
|
||||||
@ -129,15 +122,10 @@ export class ProjectComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
retrieve(state?: State): void {
|
retrieve(state?: State): void {
|
||||||
if (state) {
|
|
||||||
this.page = state.page.to + 1;
|
|
||||||
}
|
|
||||||
this.projectService
|
this.projectService
|
||||||
.listProjects(this.projectName, this.isPublic, this.page, this.pageSize)
|
.listProjects(this.projectName, this.isPublic)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
response => {
|
response => {
|
||||||
this.totalRecordCount = response.headers.get('x-total-count');
|
|
||||||
this.totalPage = Math.ceil(this.totalRecordCount / this.pageSize);
|
|
||||||
this.changedProjects = response.json();
|
this.changedProjects = response.json();
|
||||||
},
|
},
|
||||||
error => this.messageHandlerService.handleError(error)
|
error => this.messageHandlerService.handleError(error)
|
||||||
|
@ -42,8 +42,10 @@ export class ProjectService {
|
|||||||
|
|
||||||
listProjects(name: string, isPublic: number, page?: number, pageSize?: number): Observable<any>{
|
listProjects(name: string, isPublic: number, page?: number, pageSize?: number): Observable<any>{
|
||||||
let params = new URLSearchParams();
|
let params = new URLSearchParams();
|
||||||
params.set('page', page + '');
|
if(page && pageSize) {
|
||||||
params.set('page_size', pageSize + '');
|
params.set('page', page + '');
|
||||||
|
params.set('page_size', pageSize + '');
|
||||||
|
}
|
||||||
return this.http
|
return this.http
|
||||||
.get(`/api/projects?project_name=${name}&is_public=${isPublic}`, {search: params})
|
.get(`/api/projects?project_name=${name}&is_public=${isPublic}`, {search: params})
|
||||||
.map(response=>response)
|
.map(response=>response)
|
||||||
|
@ -157,7 +157,6 @@ export class CreateEditDestinationComponent implements AfterViewChecked {
|
|||||||
.subscribe(
|
.subscribe(
|
||||||
response=>{
|
response=>{
|
||||||
this.messageHandlerService.showSuccess('DESTINATION.CREATED_SUCCESS');
|
this.messageHandlerService.showSuccess('DESTINATION.CREATED_SUCCESS');
|
||||||
console.log('Successful added target.');
|
|
||||||
this.createEditDestinationOpened = false;
|
this.createEditDestinationOpened = false;
|
||||||
this.reload.emit(true);
|
this.reload.emit(true);
|
||||||
},
|
},
|
||||||
@ -206,7 +205,6 @@ export class CreateEditDestinationComponent implements AfterViewChecked {
|
|||||||
.subscribe(
|
.subscribe(
|
||||||
response=>{
|
response=>{
|
||||||
this.messageHandlerService.showSuccess('DESTINATION.UPDATED_SUCCESS');
|
this.messageHandlerService.showSuccess('DESTINATION.UPDATED_SUCCESS');
|
||||||
console.log('Successful updated target.');
|
|
||||||
this.createEditDestinationOpened = false;
|
this.createEditDestinationOpened = false;
|
||||||
this.reload.emit(true);
|
this.reload.emit(true);
|
||||||
},
|
},
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
<clr-dg-column>{{'DESTINATION.NAME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'DESTINATION.NAME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'DESTINATION.URL' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'DESTINATION.URL' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'DESTINATION.CREATION_TIME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'DESTINATION.CREATION_TIME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-row *ngFor="let t of targets" [clrDgItem]='t'>
|
<clr-dg-row *clrDgItems="let t of targets" [clrDgItem]='t'>
|
||||||
<clr-dg-action-overflow>
|
<clr-dg-action-overflow>
|
||||||
<button class="action-item" (click)="editTarget(t)">{{'DESTINATION.TITLE_EDIT' | translate}}</button>
|
<button class="action-item" (click)="editTarget(t)">{{'DESTINATION.TITLE_EDIT' | translate}}</button>
|
||||||
<button class="action-item" (click)="deleteTarget(t)">{{'DESTINATION.DELETE' | translate}}</button>
|
<button class="action-item" (click)="deleteTarget(t)">{{'DESTINATION.DELETE' | translate}}</button>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core';
|
import { Component, OnInit, ViewChild, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
import { Target } from '../target';
|
import { Target } from '../target';
|
||||||
import { ReplicationService } from '../replication.service';
|
import { ReplicationService } from '../replication.service';
|
||||||
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
|
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
|
||||||
@ -28,7 +28,8 @@ import { CreateEditDestinationComponent } from '../create-edit-destination/creat
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'destination',
|
selector: 'destination',
|
||||||
templateUrl: 'destination.component.html',
|
templateUrl: 'destination.component.html',
|
||||||
styleUrls: ['./destination.component.css']
|
styleUrls: ['./destination.component.css'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class DestinationComponent implements OnInit {
|
export class DestinationComponent implements OnInit {
|
||||||
|
|
||||||
@ -44,7 +45,8 @@ export class DestinationComponent implements OnInit {
|
|||||||
constructor(
|
constructor(
|
||||||
private replicationService: ReplicationService,
|
private replicationService: ReplicationService,
|
||||||
private messageHandlerService: MessageHandlerService,
|
private messageHandlerService: MessageHandlerService,
|
||||||
private deletionDialogService: ConfirmationDialogService) {
|
private deletionDialogService: ConfirmationDialogService,
|
||||||
|
private ref: ChangeDetectorRef) {
|
||||||
this.subscription = this.deletionDialogService.confirmationConfirm$.subscribe(message => {
|
this.subscription = this.deletionDialogService.confirmationConfirm$.subscribe(message => {
|
||||||
if (message &&
|
if (message &&
|
||||||
message.source === ConfirmationTargets.TARGET &&
|
message.source === ConfirmationTargets.TARGET &&
|
||||||
@ -55,7 +57,7 @@ export class DestinationComponent implements OnInit {
|
|||||||
.subscribe(
|
.subscribe(
|
||||||
response => {
|
response => {
|
||||||
this.messageHandlerService.showSuccess('DESTINATION.DELETED_SUCCESS');
|
this.messageHandlerService.showSuccess('DESTINATION.DELETED_SUCCESS');
|
||||||
this.reload();
|
this.reload(true);
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
if(error && error.status === 412) {
|
if(error && error.status === 412) {
|
||||||
@ -66,6 +68,8 @@ export class DestinationComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
let hnd = setInterval(()=>ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@ -83,7 +87,11 @@ export class DestinationComponent implements OnInit {
|
|||||||
this.replicationService
|
this.replicationService
|
||||||
.listTargets(targetName)
|
.listTargets(targetName)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
targets => this.targets = targets,
|
targets => {
|
||||||
|
this.targets = targets || [];
|
||||||
|
let hnd = setInterval(()=>this.ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
|
},
|
||||||
error => this.messageHandlerService.handleError(error)
|
error => this.messageHandlerService.handleError(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -97,7 +105,7 @@ export class DestinationComponent implements OnInit {
|
|||||||
this.retrieve('');
|
this.retrieve('');
|
||||||
}
|
}
|
||||||
|
|
||||||
reload() {
|
reload($event: any) {
|
||||||
this.targetName = '';
|
this.targetName = '';
|
||||||
this.retrieve('');
|
this.retrieve('');
|
||||||
}
|
}
|
||||||
@ -124,6 +132,8 @@ export class DestinationComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.createEditDestinationComponent.openCreateEditTarget(editable, target.id);
|
this.createEditDestinationComponent.openCreateEditTarget(editable, target.id);
|
||||||
|
let hnd = setInterval(()=>this.ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
},
|
},
|
||||||
error=>this.messageHandlerService.handleError(error)
|
error=>this.messageHandlerService.handleError(error)
|
||||||
);
|
);
|
||||||
|
@ -11,14 +11,15 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
import { Job } from '../job';
|
import { Job } from '../job';
|
||||||
import { State } from 'clarity-angular';
|
import { State } from 'clarity-angular';
|
||||||
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
|
import { MessageHandlerService } from '../../shared/message-handler/message-handler.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'list-job',
|
selector: 'list-job',
|
||||||
templateUrl: 'list-job.component.html'
|
templateUrl: 'list-job.component.html',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class ListJobComponent {
|
export class ListJobComponent {
|
||||||
@Input() jobs: Job[];
|
@Input() jobs: Job[];
|
||||||
@ -26,7 +27,12 @@ export class ListJobComponent {
|
|||||||
@Input() totalPage: number;
|
@Input() totalPage: number;
|
||||||
@Output() paginate = new EventEmitter<State>();
|
@Output() paginate = new EventEmitter<State>();
|
||||||
|
|
||||||
constructor(private messageHandlerService: MessageHandlerService) {}
|
constructor(
|
||||||
|
private messageHandlerService: MessageHandlerService,
|
||||||
|
private ref: ChangeDetectorRef) {
|
||||||
|
let hnd = setInterval(()=>ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
pageOffset: number = 1;
|
pageOffset: number = 1;
|
||||||
|
|
||||||
|
@ -18,11 +18,8 @@ import { CreateEditPolicyComponent } from '../shared/create-edit-policy/create-e
|
|||||||
|
|
||||||
import { MessageHandlerService } from '../shared/message-handler/message-handler.service';
|
import { MessageHandlerService } from '../shared/message-handler/message-handler.service';
|
||||||
|
|
||||||
import { SessionService } from '../shared/session.service';
|
|
||||||
|
|
||||||
import { ReplicationService } from './replication.service';
|
import { ReplicationService } from './replication.service';
|
||||||
|
|
||||||
import { SessionUser } from '../shared/session-user';
|
|
||||||
import { Policy } from './policy';
|
import { Policy } from './policy';
|
||||||
import { Job } from './job';
|
import { Job } from './job';
|
||||||
import { Target } from './target';
|
import { Target } from './target';
|
||||||
@ -65,8 +62,7 @@ class SearchOption {
|
|||||||
styleUrls: ['./replication.component.css']
|
styleUrls: ['./replication.component.css']
|
||||||
})
|
})
|
||||||
export class ReplicationComponent implements OnInit {
|
export class ReplicationComponent implements OnInit {
|
||||||
|
|
||||||
currentUser: SessionUser;
|
|
||||||
projectId: number;
|
projectId: number;
|
||||||
|
|
||||||
search: SearchOption;
|
search: SearchOption;
|
||||||
@ -94,11 +90,9 @@ export class ReplicationComponent implements OnInit {
|
|||||||
createEditPolicyComponent: CreateEditPolicyComponent;
|
createEditPolicyComponent: CreateEditPolicyComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private sessionService: SessionService,
|
|
||||||
private messageHandlerService: MessageHandlerService,
|
private messageHandlerService: MessageHandlerService,
|
||||||
private replicationService: ReplicationService,
|
private replicationService: ReplicationService,
|
||||||
private route: ActivatedRoute) {
|
private route: ActivatedRoute) {
|
||||||
this.currentUser = this.sessionService.getCurrentUser();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@ -120,7 +114,7 @@ export class ReplicationComponent implements OnInit {
|
|||||||
.listPolicies(this.search.policyName, this.projectId)
|
.listPolicies(this.search.policyName, this.projectId)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
response=>{
|
response=>{
|
||||||
this.changedPolicies = response;
|
this.changedPolicies = response || [];
|
||||||
if(this.changedPolicies && this.changedPolicies.length > 0) {
|
if(this.changedPolicies && this.changedPolicies.length > 0) {
|
||||||
this.initSelectedId = this.changedPolicies[0].id;
|
this.initSelectedId = this.changedPolicies[0].id;
|
||||||
}
|
}
|
||||||
@ -128,8 +122,6 @@ export class ReplicationComponent implements OnInit {
|
|||||||
if(this.changedPolicies && this.changedPolicies.length > 0) {
|
if(this.changedPolicies && this.changedPolicies.length > 0) {
|
||||||
this.search.policyId = this.changedPolicies[0].id;
|
this.search.policyId = this.changedPolicies[0].id;
|
||||||
this.fetchPolicyJobs();
|
this.fetchPolicyJobs();
|
||||||
} else {
|
|
||||||
this.changedJobs = [];
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error=>this.messageHandlerService.handleError(error)
|
error=>this.messageHandlerService.handleError(error)
|
||||||
@ -169,7 +161,7 @@ export class ReplicationComponent implements OnInit {
|
|||||||
this.messageHandlerService.showError('REPLICATION.FOUND_ERROR_IN_JOBS', '');
|
this.messageHandlerService.showError('REPLICATION.FOUND_ERROR_IN_JOBS', '');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error=>this.messageHandlerService.handleError(error)
|
error=>this.messageHandlerService.handleError(error)
|
||||||
);
|
);
|
||||||
|
@ -100,7 +100,6 @@ export class ReplicationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enablePolicy(policyId: number, enabled: number): Observable<any> {
|
enablePolicy(policyId: number, enabled: number): Observable<any> {
|
||||||
console.log('Enable or disable policy ID:' + policyId + ' with activation status:' + enabled);
|
|
||||||
return this.http
|
return this.http
|
||||||
.put(`/api/policies/replication/${policyId}/enablement`, {enabled: enabled})
|
.put(`/api/policies/replication/${policyId}/enablement`, {enabled: enabled})
|
||||||
.map(response=>response.status)
|
.map(response=>response.status)
|
||||||
@ -108,7 +107,6 @@ export class ReplicationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deletePolicy(policyId: number): Observable<any> {
|
deletePolicy(policyId: number): Observable<any> {
|
||||||
console.log('Delete policy ID:' + policyId);
|
|
||||||
return this.http
|
return this.http
|
||||||
.delete(`/api/policies/replication/${policyId}`)
|
.delete(`/api/policies/replication/${policyId}`)
|
||||||
.map(response=>response.status)
|
.map(response=>response.status)
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
import { Component, OnInit, ViewChild, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
import { ReplicationService } from '../../replication/replication.service';
|
import { ReplicationService } from '../../replication/replication.service';
|
||||||
|
|
||||||
import { CreateEditPolicyComponent } from '../../shared/create-edit-policy/create-edit-policy.component';
|
import { CreateEditPolicyComponent } from '../../shared/create-edit-policy/create-edit-policy.component';
|
||||||
@ -24,7 +24,8 @@ import { Policy } from '../../replication/policy';
|
|||||||
selector: 'total-replication',
|
selector: 'total-replication',
|
||||||
templateUrl: 'total-replication.component.html',
|
templateUrl: 'total-replication.component.html',
|
||||||
providers: [ ReplicationService ],
|
providers: [ ReplicationService ],
|
||||||
styleUrls: ['./total-replication.component.css']
|
styleUrls: ['./total-replication.component.css'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class TotalReplicationComponent implements OnInit {
|
export class TotalReplicationComponent implements OnInit {
|
||||||
|
|
||||||
@ -38,7 +39,11 @@ export class TotalReplicationComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private replicationService: ReplicationService,
|
private replicationService: ReplicationService,
|
||||||
private messageHandlerService: MessageHandlerService) {}
|
private messageHandlerService: MessageHandlerService,
|
||||||
|
private ref: ChangeDetectorRef) {
|
||||||
|
let hnd = setInterval(()=>ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.retrievePolicies();
|
this.retrievePolicies();
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<clr-dg-column>{{'REPOSITORY.NAME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPOSITORY.NAME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'REPOSITORY.TAGS_COUNT' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPOSITORY.TAGS_COUNT' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'REPOSITORY.PULL_COUNT' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPOSITORY.PULL_COUNT' | translate}}</clr-dg-column>
|
||||||
<clr-dg-row *ngFor="let r of repositories" [clrDgItem]='r'>
|
<clr-dg-row *clrDgItems="let r of repositories" [clrDgItem]='r'>
|
||||||
<clr-dg-action-overflow [hidden]="!hasProjectAdminRole">
|
<clr-dg-action-overflow [hidden]="!hasProjectAdminRole">
|
||||||
<button class="action-item" (click)="deleteRepo(r.name)">{{'REPOSITORY.DELETE' | translate}}</button>
|
<button class="action-item" (click)="deleteRepo(r.name)">{{'REPOSITORY.DELETE' | translate}}</button>
|
||||||
</clr-dg-action-overflow>
|
</clr-dg-action-overflow>
|
||||||
@ -11,7 +11,7 @@
|
|||||||
<clr-dg-cell>{{r.pull_count}}</clr-dg-cell>
|
<clr-dg-cell>{{r.pull_count}}</clr-dg-cell>
|
||||||
</clr-dg-row>
|
</clr-dg-row>
|
||||||
<clr-dg-footer>
|
<clr-dg-footer>
|
||||||
{{totalRecordCount || (repositories ? repositories.length : 0)}} {{'REPOSITORY.ITEMS' | translate}}
|
{{(repositories ? repositories.length : 0)}} {{'REPOSITORY.ITEMS' | translate}}
|
||||||
<clr-dg-pagination [clrDgPageSize]="pageOffset" [clrDgTotalItems]="totalPage"></clr-dg-pagination>
|
<clr-dg-pagination [clrDgPageSize]="15"></clr-dg-pagination>
|
||||||
</clr-dg-footer>
|
</clr-dg-footer>
|
||||||
</clr-datagrid>
|
</clr-datagrid>
|
@ -11,7 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
|
import { Component, Input, Output, EventEmitter, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { Repository } from '../repository';
|
import { Repository } from '../repository';
|
||||||
import { State } from 'clarity-angular';
|
import { State } from 'clarity-angular';
|
||||||
@ -20,18 +20,15 @@ import { SearchTriggerService } from '../../base/global-search/search-trigger.se
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'list-repository',
|
selector: 'list-repository',
|
||||||
templateUrl: 'list-repository.component.html'
|
templateUrl: 'list-repository.component.html',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class ListRepositoryComponent implements OnInit {
|
export class ListRepositoryComponent implements OnInit {
|
||||||
|
|
||||||
@Input() projectId: number;
|
@Input() projectId: number;
|
||||||
@Input() repositories: Repository[];
|
@Input() repositories: Repository[];
|
||||||
|
|
||||||
|
|
||||||
@Output() delete = new EventEmitter<string>();
|
@Output() delete = new EventEmitter<string>();
|
||||||
|
|
||||||
@Input() totalPage: number;
|
|
||||||
@Input() totalRecordCount: number;
|
|
||||||
@Output() paginate = new EventEmitter<State>();
|
@Output() paginate = new EventEmitter<State>();
|
||||||
|
|
||||||
@Input() hasProjectAdminRole: boolean;
|
@Input() hasProjectAdminRole: boolean;
|
||||||
@ -40,7 +37,11 @@ export class ListRepositoryComponent implements OnInit {
|
|||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private searchTrigger: SearchTriggerService) { }
|
private searchTrigger: SearchTriggerService,
|
||||||
|
private ref: ChangeDetectorRef) {
|
||||||
|
let hnd = setInterval(()=>ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit() { }
|
ngOnInit() { }
|
||||||
|
|
||||||
|
@ -8,6 +8,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||||
<list-repository [projectId]="projectId" [repositories]="changedRepositories" (delete)="deleteRepo($event)" [totalPage]="totalPage" [totalRecordCount]="totalRecordCount" [hasProjectAdminRole]="hasProjectAdminRole" (paginate)="retrieve($event)"></list-repository>
|
<list-repository [projectId]="projectId" [repositories]="changedRepositories" (delete)="deleteRepo($event)" [hasProjectAdminRole]="hasProjectAdminRole" (paginate)="retrieve($event)"></list-repository>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -41,9 +41,6 @@ export class RepositoryComponent implements OnInit {
|
|||||||
|
|
||||||
lastFilteredRepoName: string;
|
lastFilteredRepoName: string;
|
||||||
|
|
||||||
page: number = 1;
|
|
||||||
pageSize: number = 15;
|
|
||||||
|
|
||||||
totalPage: number;
|
totalPage: number;
|
||||||
totalRecordCount: number;
|
totalRecordCount: number;
|
||||||
|
|
||||||
@ -71,7 +68,6 @@ export class RepositoryComponent implements OnInit {
|
|||||||
response => {
|
response => {
|
||||||
this.refresh();
|
this.refresh();
|
||||||
this.messageHandlerService.showSuccess('REPOSITORY.DELETED_REPO_SUCCESS');
|
this.messageHandlerService.showSuccess('REPOSITORY.DELETED_REPO_SUCCESS');
|
||||||
console.log('Successful deleted repo:' + repoName);
|
|
||||||
},
|
},
|
||||||
error => this.messageHandlerService.handleError(error)
|
error => this.messageHandlerService.handleError(error)
|
||||||
);
|
);
|
||||||
@ -97,16 +93,10 @@ export class RepositoryComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
retrieve(state?: State) {
|
retrieve(state?: State) {
|
||||||
if (state) {
|
|
||||||
this.page = state.page.to + 1;
|
|
||||||
}
|
|
||||||
this.repositoryService
|
this.repositoryService
|
||||||
.listRepositories(this.projectId, this.lastFilteredRepoName, this.page, this.pageSize)
|
.listRepositories(this.projectId, this.lastFilteredRepoName)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
response => {
|
response => {
|
||||||
this.totalRecordCount = response.headers.get('x-total-count');
|
|
||||||
this.totalPage = Math.ceil(this.totalRecordCount / this.pageSize);
|
|
||||||
console.log('TotalRecordCount:' + this.totalRecordCount + ', totalPage:' + this.totalPage);
|
|
||||||
this.changedRepositories = response.json();
|
this.changedRepositories = response.json();
|
||||||
},
|
},
|
||||||
error => this.messageHandlerService.handleError(error)
|
error => this.messageHandlerService.handleError(error)
|
||||||
|
@ -28,10 +28,11 @@ export class RepositoryService {
|
|||||||
constructor(private http: Http){}
|
constructor(private http: Http){}
|
||||||
|
|
||||||
listRepositories(projectId: number, repoName: string, page?: number, pageSize?: number): Observable<any> {
|
listRepositories(projectId: number, repoName: string, page?: number, pageSize?: number): Observable<any> {
|
||||||
console.log('List repositories with project ID:' + projectId);
|
|
||||||
let params = new URLSearchParams();
|
let params = new URLSearchParams();
|
||||||
params.set('page', page + '');
|
if(page && pageSize) {
|
||||||
params.set('page_size', pageSize + '');
|
params.set('page', page + '');
|
||||||
|
params.set('page_size', pageSize + '');
|
||||||
|
}
|
||||||
return this.http
|
return this.http
|
||||||
.get(`/api/repositories?project_id=${projectId}&q=${repoName}&detail=1`, {search: params})
|
.get(`/api/repositories?project_id=${projectId}&q=${repoName}&detail=1`, {search: params})
|
||||||
.map(response=>response)
|
.map(response=>response)
|
||||||
@ -75,7 +76,6 @@ export class RepositoryService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteRepository(repoName: string): Observable<any> {
|
deleteRepository(repoName: string): Observable<any> {
|
||||||
console.log('Delete repository with repo name:' + repoName);
|
|
||||||
return this.http
|
return this.http
|
||||||
.delete(`/api/repositories/${repoName}/tags`)
|
.delete(`/api/repositories/${repoName}/tags`)
|
||||||
.map(response=>response.status)
|
.map(response=>response.status)
|
||||||
@ -83,7 +83,6 @@ export class RepositoryService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteRepoByTag(repoName: string, tag: string): Observable<any> {
|
deleteRepoByTag(repoName: string, tag: string): Observable<any> {
|
||||||
console.log('Delete repository with repo name:' + repoName + ', tag:' + tag);
|
|
||||||
return this.http
|
return this.http
|
||||||
.delete(`/api/repositories/${repoName}/tags/${tag}`)
|
.delete(`/api/repositories/${repoName}/tags/${tag}`)
|
||||||
.map(response=>response.status)
|
.map(response=>response.status)
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
<clr-dg-column>{{'REPOSITORY.DOCKER_VERSION' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPOSITORY.DOCKER_VERSION' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'REPOSITORY.ARCHITECTURE' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPOSITORY.ARCHITECTURE' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'REPOSITORY.OS' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPOSITORY.OS' | translate}}</clr-dg-column>
|
||||||
<clr-dg-row *ngFor="let t of tags" [clrDgItem]='t'>
|
<clr-dg-row *clrDgItems="let t of tags" [clrDgItem]='t'>
|
||||||
<clr-dg-action-overflow>
|
<clr-dg-action-overflow>
|
||||||
<button class="action-item" (click)="showTagID('tag', t)">{{'REPOSITORY.COPY_ID' | translate}}</button>
|
<button class="action-item" (click)="showTagID('tag', t)">{{'REPOSITORY.COPY_ID' | translate}}</button>
|
||||||
<button class="action-item" (click)="showTagID('parent', t)">{{'REPOSITORY.COPY_PARENT_ID' | translate}}</button>
|
<button class="action-item" (click)="showTagID('parent', t)">{{'REPOSITORY.COPY_PARENT_ID' | translate}}</button>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
import { Component, OnInit, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
|
||||||
import { RepositoryService } from '../repository.service';
|
import { RepositoryService } from '../repository.service';
|
||||||
@ -35,7 +35,8 @@ import { Project } from '../../project/project';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'tag-repository',
|
selector: 'tag-repository',
|
||||||
templateUrl: 'tag-repository.component.html',
|
templateUrl: 'tag-repository.component.html',
|
||||||
styleUrls: ['./tag-repository.component.css']
|
styleUrls: ['./tag-repository.component.css'],
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class TagRepositoryComponent implements OnInit, OnDestroy {
|
export class TagRepositoryComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
@ -58,7 +59,7 @@ export class TagRepositoryComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
selectAll: boolean = false;
|
selectAll: boolean = false;
|
||||||
|
|
||||||
private subscription: Subscription;
|
subscription: Subscription;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
@ -66,8 +67,9 @@ export class TagRepositoryComponent implements OnInit, OnDestroy {
|
|||||||
private deletionDialogService: ConfirmationDialogService,
|
private deletionDialogService: ConfirmationDialogService,
|
||||||
private repositoryService: RepositoryService,
|
private repositoryService: RepositoryService,
|
||||||
private appConfigService: AppConfigService,
|
private appConfigService: AppConfigService,
|
||||||
private session: SessionService){
|
private session: SessionService,
|
||||||
|
private ref: ChangeDetectorRef){
|
||||||
|
|
||||||
this.subscription = this.deletionDialogService.confirmationConfirm$.subscribe(
|
this.subscription = this.deletionDialogService.confirmationConfirm$.subscribe(
|
||||||
message => {
|
message => {
|
||||||
if (message &&
|
if (message &&
|
||||||
@ -85,7 +87,6 @@ export class TagRepositoryComponent implements OnInit, OnDestroy {
|
|||||||
response => {
|
response => {
|
||||||
this.retrieve();
|
this.retrieve();
|
||||||
this.messageHandlerService.showSuccess('REPOSITORY.DELETED_TAG_SUCCESS');
|
this.messageHandlerService.showSuccess('REPOSITORY.DELETED_TAG_SUCCESS');
|
||||||
console.log('Deleted repo:' + this.repoName + ' with tag:' + tagName);
|
|
||||||
},
|
},
|
||||||
error => this.messageHandlerService.handleError(error)
|
error => this.messageHandlerService.handleError(error)
|
||||||
);
|
);
|
||||||
@ -132,7 +133,7 @@ export class TagRepositoryComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private listTags(tags: Tag[]): void {
|
listTags(tags: Tag[]): void {
|
||||||
tags.forEach(t => {
|
tags.forEach(t => {
|
||||||
let tag = new TagView();
|
let tag = new TagView();
|
||||||
tag.tag = t.tag;
|
tag.tag = t.tag;
|
||||||
@ -148,6 +149,8 @@ export class TagRepositoryComponent implements OnInit, OnDestroy {
|
|||||||
tag.parent = data['parent'];
|
tag.parent = data['parent'];
|
||||||
this.tags.push(tag);
|
this.tags.push(tag);
|
||||||
});
|
});
|
||||||
|
let hnd = setInterval(()=>this.ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteTag(tag: TagView) {
|
deleteTag(tag: TagView) {
|
||||||
@ -187,7 +190,7 @@ export class TagRepositoryComponent implements OnInit, OnDestroy {
|
|||||||
this.showTagManifestOpened = true;
|
this.showTagManifestOpened = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
selectAndCopy($event) {
|
selectAndCopy($event: any) {
|
||||||
$event.target.select();
|
$event.target.select();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -27,7 +27,7 @@ import { Repository } from '../repository';
|
|||||||
providers: [TopRepoService]
|
providers: [TopRepoService]
|
||||||
})
|
})
|
||||||
export class TopRepoComponent implements OnInit{
|
export class TopRepoComponent implements OnInit{
|
||||||
private topRepos: Repository[] = [];
|
topRepos: Repository[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private topRepoService: TopRepoService,
|
private topRepoService: TopRepoService,
|
||||||
|
@ -27,10 +27,10 @@ export const topRepoEndpoint = "/api/repositories/top?detail=1";
|
|||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class TopRepoService {
|
export class TopRepoService {
|
||||||
private headers = new Headers({
|
headers = new Headers({
|
||||||
"Content-Type": 'application/json'
|
"Content-Type": 'application/json'
|
||||||
});
|
});
|
||||||
private options = new RequestOptions({
|
options = new RequestOptions({
|
||||||
headers: this.headers
|
headers: this.headers
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@ import { AppConfigService } from '../../app-config.service';
|
|||||||
styleUrls: ["about-dialog.component.css"]
|
styleUrls: ["about-dialog.component.css"]
|
||||||
})
|
})
|
||||||
export class AboutDialogComponent {
|
export class AboutDialogComponent {
|
||||||
private opened: boolean = false;
|
opened: boolean = false;
|
||||||
private build: string = "4276418";
|
build: string = "4276418";
|
||||||
|
|
||||||
constructor(private appConfigService: AppConfigService) { }
|
constructor(private appConfigService: AppConfigService) { }
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ export class ConfirmationDialogComponent implements OnDestroy {
|
|||||||
buttonKey: string = 'BUTTON.OK';
|
buttonKey: string = 'BUTTON.OK';
|
||||||
confirmOnly: boolean = false;
|
confirmOnly: boolean = false;
|
||||||
message: ConfirmationMessage;
|
message: ConfirmationMessage;
|
||||||
private annouceSubscription: Subscription;
|
annouceSubscription: Subscription;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private confirmationService: ConfirmationDialogService,
|
private confirmationService: ConfirmationDialogService,
|
||||||
|
@ -20,8 +20,8 @@ import { ConfirmationAcknowledgement } from './confirmation-state-message';
|
|||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ConfirmationDialogService {
|
export class ConfirmationDialogService {
|
||||||
private confirmationAnnoucedSource = new Subject<ConfirmationMessage>();
|
confirmationAnnoucedSource = new Subject<ConfirmationMessage>();
|
||||||
private confirmationConfirmSource = new Subject<ConfirmationAcknowledgement>();
|
confirmationConfirmSource = new Subject<ConfirmationAcknowledgement>();
|
||||||
|
|
||||||
confirmationAnnouced$ = this.confirmationAnnoucedSource.asObservable();
|
confirmationAnnouced$ = this.confirmationAnnoucedSource.asObservable();
|
||||||
confirmationConfirm$ = this.confirmationConfirmSource.asObservable();
|
confirmationConfirm$ = this.confirmationConfirmSource.asObservable();
|
||||||
|
@ -157,7 +157,6 @@ export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
newDestination(checkedAddNew: boolean): void {
|
newDestination(checkedAddNew: boolean): void {
|
||||||
console.log('CheckedAddNew:' + checkedAddNew);
|
|
||||||
this.isCreateDestination = checkedAddNew;
|
this.isCreateDestination = checkedAddNew;
|
||||||
if(this.isCreateDestination) {
|
if(this.isCreateDestination) {
|
||||||
this.createEditPolicy.targetName = '';
|
this.createEditPolicy.targetName = '';
|
||||||
@ -201,13 +200,11 @@ export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createPolicy(): void {
|
createPolicy(): void {
|
||||||
console.log('Create policy with existing target in component.');
|
|
||||||
this.replicationService
|
this.replicationService
|
||||||
.createPolicy(this.getPolicyByForm())
|
.createPolicy(this.getPolicyByForm())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
response=>{
|
response=>{
|
||||||
this.messageHandlerService.showSuccess('REPLICATION.CREATED_SUCCESS');
|
this.messageHandlerService.showSuccess('REPLICATION.CREATED_SUCCESS');
|
||||||
console.log('Successful created policy: ' + response);
|
|
||||||
this.createEditPolicyOpened = false;
|
this.createEditPolicyOpened = false;
|
||||||
this.reload.emit(true);
|
this.reload.emit(true);
|
||||||
},
|
},
|
||||||
@ -220,18 +217,16 @@ export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
|||||||
} else {
|
} else {
|
||||||
this.inlineAlert.showInlineError(error);
|
this.inlineAlert.showInlineError(error);
|
||||||
}
|
}
|
||||||
console.log('Failed to create policy:' + error.status + ', error message:' + JSON.stringify(error['_body']));
|
console.error('Failed to create policy:' + error.status + ', error message:' + JSON.stringify(error['_body']));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
createOrUpdatePolicyAndCreateTarget(): void {
|
createOrUpdatePolicyAndCreateTarget(): void {
|
||||||
console.log('Creating policy with new created target.');
|
|
||||||
this.replicationService
|
this.replicationService
|
||||||
.createOrUpdatePolicyWithNewTarget(this.getPolicyByForm(), this.getTargetByForm())
|
.createOrUpdatePolicyWithNewTarget(this.getPolicyByForm(), this.getTargetByForm())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
response=>{
|
response=>{
|
||||||
this.messageHandlerService.showSuccess('REPLICATION.CREATED_SUCCESS');
|
this.messageHandlerService.showSuccess('REPLICATION.CREATED_SUCCESS');
|
||||||
console.log('Successful created policy and target:' + response);
|
|
||||||
this.createEditPolicyOpened = false;
|
this.createEditPolicyOpened = false;
|
||||||
this.reload.emit(true);
|
this.reload.emit(true);
|
||||||
},
|
},
|
||||||
@ -244,18 +239,16 @@ export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
|||||||
} else {
|
} else {
|
||||||
this.inlineAlert.showInlineError(error);
|
this.inlineAlert.showInlineError(error);
|
||||||
}
|
}
|
||||||
console.log('Failed to create policy and target:' + error.status + ', error message:' + JSON.stringify(error['_body']));
|
console.error('Failed to create policy and target:' + error.status + ', error message:' + JSON.stringify(error['_body']));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePolicy(): void {
|
updatePolicy(): void {
|
||||||
console.log('Creating policy with existing target.');
|
|
||||||
this.replicationService
|
this.replicationService
|
||||||
.updatePolicy(this.getPolicyByForm())
|
.updatePolicy(this.getPolicyByForm())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
response=>{
|
response=>{
|
||||||
console.log('Successful created policy and target:' + response);
|
|
||||||
this.messageHandlerService.showSuccess('REPLICATION.UPDATED_SUCCESS')
|
this.messageHandlerService.showSuccess('REPLICATION.UPDATED_SUCCESS')
|
||||||
this.createEditPolicyOpened = false;
|
this.createEditPolicyOpened = false;
|
||||||
this.reload.emit(true);
|
this.reload.emit(true);
|
||||||
@ -269,7 +262,7 @@ export class CreateEditPolicyComponent implements OnInit, AfterViewChecked {
|
|||||||
} else {
|
} else {
|
||||||
this.inlineAlert.showInlineError(error);
|
this.inlineAlert.showInlineError(error);
|
||||||
}
|
}
|
||||||
console.log('Failed to create policy and target:' + error.status + ', error message:' + JSON.stringify(error['_body']));
|
console.error('Failed to create policy and target:' + error.status + ', error message:' + JSON.stringify(error['_body']));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -27,12 +27,12 @@ import 'rxjs/add/operator/distinctUntilChanged';
|
|||||||
|
|
||||||
export class FilterComponent implements OnInit {
|
export class FilterComponent implements OnInit {
|
||||||
|
|
||||||
private placeHolder: string = "";
|
placeHolder: string = "";
|
||||||
private filterTerms = new Subject<string>();
|
filterTerms = new Subject<string>();
|
||||||
|
|
||||||
@Output("filter") private filterEvt = new EventEmitter<string>();
|
@Output("filter") private filterEvt = new EventEmitter<string>();
|
||||||
|
|
||||||
@Input() currentValue;
|
@Input() currentValue: string;
|
||||||
@Input("filterPlaceholder")
|
@Input("filterPlaceholder")
|
||||||
public set flPlaceholder(placeHolder: string) {
|
public set flPlaceholder(placeHolder: string) {
|
||||||
this.placeHolder = placeHolder;
|
this.placeHolder = placeHolder;
|
||||||
|
@ -37,13 +37,13 @@ const RESOURCE_COLOR_GREY600: string = '#C7D1D6';
|
|||||||
})
|
})
|
||||||
|
|
||||||
export class GaugeComponent implements AfterViewInit {
|
export class GaugeComponent implements AfterViewInit {
|
||||||
private _backgroundColor: string;
|
_backgroundColor: string;
|
||||||
private _colorOne: string;
|
_colorOne: string;
|
||||||
private _colorTwo: string;
|
_colorTwo: string;
|
||||||
private _size: string = "small"; //Support small, medium, large
|
_size: string = "small"; //Support small, medium, large
|
||||||
private _title: string = "UNKNOWN"; //Lang key
|
_title: string = "UNKNOWN"; //Lang key
|
||||||
private _free: number = 0;
|
_free: number = 0;
|
||||||
private _threasHold: number = 0;
|
_threasHold: number = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Background color of the component. Default is white.
|
* Background color of the component. Default is white.
|
||||||
@ -60,7 +60,7 @@ export class GaugeComponent implements AfterViewInit {
|
|||||||
this._backgroundColor = value;
|
this._backgroundColor = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _positionOne: number;
|
_positionOne: number;
|
||||||
/**
|
/**
|
||||||
* Keep these two properties
|
* Keep these two properties
|
||||||
* Percentage of the total width for the first portion of the bar.
|
* Percentage of the total width for the first portion of the bar.
|
||||||
@ -77,7 +77,7 @@ export class GaugeComponent implements AfterViewInit {
|
|||||||
this.setBars();
|
this.setBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _positionTwo: number;
|
_positionTwo: number;
|
||||||
/**
|
/**
|
||||||
* Percentage of the total width for the second portion of the bar
|
* Percentage of the total width for the second portion of the bar
|
||||||
*/
|
*/
|
||||||
@ -91,7 +91,7 @@ export class GaugeComponent implements AfterViewInit {
|
|||||||
this.setBars();
|
this.setBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _animate: boolean;
|
_animate: boolean;
|
||||||
/**
|
/**
|
||||||
* Whether to animate transitions in the bars
|
* Whether to animate transitions in the bars
|
||||||
*/
|
*/
|
||||||
@ -170,7 +170,7 @@ export class GaugeComponent implements AfterViewInit {
|
|||||||
@ViewChild('barOne') private barOne: ElementRef;
|
@ViewChild('barOne') private barOne: ElementRef;
|
||||||
@ViewChild('barTwo') private barTwo: ElementRef;
|
@ViewChild('barTwo') private barTwo: ElementRef;
|
||||||
|
|
||||||
private determineColors() {
|
determineColors() {
|
||||||
let percent: number = 0;
|
let percent: number = 0;
|
||||||
if (this._threasHold !== 0) {
|
if (this._threasHold !== 0) {
|
||||||
let used: number = this._threasHold - this._free;
|
let used: number = this._threasHold - this._free;
|
||||||
@ -200,7 +200,7 @@ export class GaugeComponent implements AfterViewInit {
|
|||||||
this.setAnimate();
|
this.setAnimate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private setBars() {
|
setBars() {
|
||||||
if (!this.barOne || !this.barTwo) {
|
if (!this.barOne || !this.barTwo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ export class GaugeComponent implements AfterViewInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private setColors() {
|
setColors() {
|
||||||
if (!this.barOne || !this.barTwo) {
|
if (!this.barOne || !this.barTwo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -259,7 +259,7 @@ export class GaugeComponent implements AfterViewInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private setAnimate() {
|
setAnimate() {
|
||||||
if (!this.barOne || !this.barTwo) {
|
if (!this.barOne || !this.barTwo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -24,15 +24,15 @@ import { Subscription } from "rxjs";
|
|||||||
styleUrls: ['inline-alert.component.css']
|
styleUrls: ['inline-alert.component.css']
|
||||||
})
|
})
|
||||||
export class InlineAlertComponent {
|
export class InlineAlertComponent {
|
||||||
private inlineAlertType: string = 'alert-danger';
|
inlineAlertType: string = 'alert-danger';
|
||||||
private inlineAlertClosable: boolean = false;
|
inlineAlertClosable: boolean = false;
|
||||||
private alertClose: boolean = true;
|
alertClose: boolean = true;
|
||||||
private displayedText: string = "";
|
displayedText: string = "";
|
||||||
private showCancelAction: boolean = false;
|
showCancelAction: boolean = false;
|
||||||
private useAppLevelStyle: boolean = false;
|
useAppLevelStyle: boolean = false;
|
||||||
private timer: Subscription = null;
|
timer: Subscription = null;
|
||||||
private count: number = 0;
|
count: number = 0;
|
||||||
private blinking: boolean = false;
|
blinking: boolean = false;
|
||||||
|
|
||||||
@Output() confirmEvt = new EventEmitter<boolean>();
|
@Output() confirmEvt = new EventEmitter<boolean>();
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ export class InlineAlertComponent {
|
|||||||
public blink() {
|
public blink() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private confirmCancel(): void {
|
confirmCancel(): void {
|
||||||
this.confirmEvt.emit(true);
|
this.confirmEvt.emit(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,26 +5,26 @@
|
|||||||
<clr-dg-column>{{'REPLICATION.DESTINATION_NAME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPLICATION.DESTINATION_NAME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'REPLICATION.LAST_START_TIME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPLICATION.LAST_START_TIME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'REPLICATION.ACTIVATION' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPLICATION.ACTIVATION' | translate}}</clr-dg-column>
|
||||||
<clr-dg-row *ngFor="let p of policies;let i = index;" [clrDgItem]="p" (click)="selectPolicy(p)" [style.backgroundColor]="(!projectless && selectedId === p.id) ? '#eee' : ''">
|
<clr-dg-row *clrDgItems="let p of policies" [clrDgItem]="p" (click)="selectPolicy(p)" [style.backgroundColor]="(!projectless && selectedId === p.id) ? '#eee' : ''">
|
||||||
<clr-dg-action-overflow>
|
<clr-dg-action-overflow>
|
||||||
<button class="action-item" (click)="editPolicy(p)">{{'REPLICATION.EDIT_POLICY' | translate}}</button>
|
<button class="action-item" (click)="editPolicy(p)">{{'REPLICATION.EDIT_POLICY' | translate}}</button>
|
||||||
<button class="action-item" (click)="togglePolicy(p)">{{ (p.enabled === 0 ? 'REPLICATION.ENABLE' : 'REPLICATION.DISABLE') | translate}}</button>
|
<button class="action-item" (click)="togglePolicy(p)">{{ (p.enabled === 0 ? 'REPLICATION.ENABLE' : 'REPLICATION.DISABLE') | translate}}</button>
|
||||||
<button class="action-item" (click)="deletePolicy(p)">{{'REPLICATION.DELETE_POLICY' | translate}}</button>
|
<button class="action-item" (click)="deletePolicy(p)">{{'REPLICATION.DELETE_POLICY' | translate}}</button>
|
||||||
</clr-dg-action-overflow>
|
</clr-dg-action-overflow>
|
||||||
<clr-dg-cell>
|
<clr-dg-cell>
|
||||||
<template [ngIf]="projectless">
|
<ng-template [ngIf]="projectless">
|
||||||
<a href="javascript:void(0)" [routerLink]="['/harbor', 'projects', p.project_id, 'replication']">{{p.name}}</a>
|
<a href="javascript:void(0)" [routerLink]="['/harbor', 'projects', p.project_id, 'replication']">{{p.name}}</a>
|
||||||
</template>
|
</ng-template>
|
||||||
<template [ngIf]="!projectless">
|
<ng-template [ngIf]="!projectless">
|
||||||
{{p.name}}
|
{{p.name}}
|
||||||
</template>
|
</ng-template>
|
||||||
</clr-dg-cell>
|
</clr-dg-cell>
|
||||||
<clr-dg-cell *ngIf="projectless">{{p.project_name}}</clr-dg-cell>
|
<clr-dg-cell *ngIf="projectless">{{p.project_name}}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{p.description ? p.description : '-'}}</clr-dg-cell>
|
<clr-dg-cell>{{p.description ? p.description : '-'}}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{p.target_name}}</clr-dg-cell>
|
<clr-dg-cell>{{p.target_name}}</clr-dg-cell>
|
||||||
<clr-dg-cell>
|
<clr-dg-cell>
|
||||||
<template [ngIf]="p.start_time === nullTime">-</template>
|
<ng-template [ngIf]="p.start_time === nullTime">-</ng-template>
|
||||||
<template [ngIf]="p.start_time !== nullTime">{{p.start_time | date: 'short'}}</template>
|
<ng-template [ngIf]="p.start_time !== nullTime">{{p.start_time | date: 'short'}}</ng-template>
|
||||||
</clr-dg-cell>
|
</clr-dg-cell>
|
||||||
<clr-dg-cell>
|
<clr-dg-cell>
|
||||||
{{ (p.enabled === 1 ? 'REPLICATION.ENABLED' : 'REPLICATION.DISABLED') | translate}}
|
{{ (p.enabled === 1 ? 'REPLICATION.ENABLED' : 'REPLICATION.DISABLED') | translate}}
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, Input, Output, EventEmitter, ViewChild, OnDestroy } from '@angular/core';
|
import { Component, Input, Output, EventEmitter, ViewChild, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
|
|
||||||
import { ReplicationService } from '../../replication/replication.service';
|
import { ReplicationService } from '../../replication/replication.service';
|
||||||
import { Policy } from '../../replication/policy';
|
import { Policy } from '../../replication/policy';
|
||||||
@ -28,6 +28,7 @@ import { Subscription } from 'rxjs/Subscription';
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'list-policy',
|
selector: 'list-policy',
|
||||||
templateUrl: 'list-policy.component.html',
|
templateUrl: 'list-policy.component.html',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class ListPolicyComponent implements OnDestroy {
|
export class ListPolicyComponent implements OnDestroy {
|
||||||
|
|
||||||
@ -49,8 +50,9 @@ export class ListPolicyComponent implements OnDestroy {
|
|||||||
private replicationService: ReplicationService,
|
private replicationService: ReplicationService,
|
||||||
private toggleConfirmDialogService: ConfirmationDialogService,
|
private toggleConfirmDialogService: ConfirmationDialogService,
|
||||||
private deletionDialogService: ConfirmationDialogService,
|
private deletionDialogService: ConfirmationDialogService,
|
||||||
private messageHandlerService: MessageHandlerService) {
|
private messageHandlerService: MessageHandlerService,
|
||||||
|
private ref: ChangeDetectorRef) {
|
||||||
|
setInterval(()=>ref.markForCheck(), 500);
|
||||||
this.toggleSubscription = this.toggleConfirmDialogService
|
this.toggleSubscription = this.toggleConfirmDialogService
|
||||||
.confirmationConfirm$
|
.confirmationConfirm$
|
||||||
.subscribe(
|
.subscribe(
|
||||||
@ -60,13 +62,11 @@ export class ListPolicyComponent implements OnDestroy {
|
|||||||
message.state === ConfirmationState.CONFIRMED) {
|
message.state === ConfirmationState.CONFIRMED) {
|
||||||
let policy: Policy = message.data;
|
let policy: Policy = message.data;
|
||||||
policy.enabled = policy.enabled === 0 ? 1 : 0;
|
policy.enabled = policy.enabled === 0 ? 1 : 0;
|
||||||
console.log('Enable policy ID:' + policy.id + ' with activation status ' + policy.enabled);
|
|
||||||
this.replicationService
|
this.replicationService
|
||||||
.enablePolicy(policy.id, policy.enabled)
|
.enablePolicy(policy.id, policy.enabled)
|
||||||
.subscribe(
|
.subscribe(
|
||||||
response => {
|
response => {
|
||||||
this.messageHandlerService.showSuccess('REPLICATION.TOGGLED_SUCCESS');
|
this.messageHandlerService.showSuccess('REPLICATION.TOGGLED_SUCCESS');
|
||||||
console.log('Successful toggled policy status')
|
|
||||||
},
|
},
|
||||||
error => this.messageHandlerService.handleError(error)
|
error => this.messageHandlerService.handleError(error)
|
||||||
);
|
);
|
||||||
@ -85,7 +85,6 @@ export class ListPolicyComponent implements OnDestroy {
|
|||||||
.subscribe(
|
.subscribe(
|
||||||
response => {
|
response => {
|
||||||
this.messageHandlerService.showSuccess('REPLICATION.DELETED_SUCCESS');
|
this.messageHandlerService.showSuccess('REPLICATION.DELETED_SUCCESS');
|
||||||
console.log('Successful delete policy with ID:' + message.data);
|
|
||||||
this.reload.emit(true);
|
this.reload.emit(true);
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
@ -98,8 +97,7 @@ export class ListPolicyComponent implements OnDestroy {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
@ -113,12 +111,10 @@ export class ListPolicyComponent implements OnDestroy {
|
|||||||
|
|
||||||
selectPolicy(policy: Policy): void {
|
selectPolicy(policy: Policy): void {
|
||||||
this.selectedId = policy.id;
|
this.selectedId = policy.id;
|
||||||
console.log('Select policy ID:' + policy.id);
|
|
||||||
this.selectOne.emit(policy);
|
this.selectOne.emit(policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
editPolicy(policy: Policy) {
|
editPolicy(policy: Policy) {
|
||||||
console.log('Open modal to edit policy.');
|
|
||||||
this.editOne.emit(policy);
|
this.editOne.emit(policy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
<clr-dg-column>{{'PROJECT.PUBLIC_OR_PRIVATE' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'PROJECT.PUBLIC_OR_PRIVATE' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'PROJECT.REPO_COUNT'| translate}}</clr-dg-column>
|
<clr-dg-column>{{'PROJECT.REPO_COUNT'| translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'PROJECT.CREATION_TIME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'PROJECT.CREATION_TIME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-row *ngFor="let p of projects" [clrDgItem]="p">
|
<clr-dg-row *clrDgItems="let p of projects" [clrDgItem]="p">
|
||||||
<clr-dg-cell><a href="javascript:void(0)" (click)="goToLink(p.project_id)">{{p.name}}</a></clr-dg-cell>
|
<clr-dg-cell><a href="javascript:void(0)" (click)="goToLink(p.project_id)">{{p.name}}</a></clr-dg-cell>
|
||||||
<clr-dg-cell>{{ (p.public === 1 ? 'PROJECT.PUBLIC' : 'PROJECT.PRIVATE') | translate}}</clr-dg-cell>
|
<clr-dg-cell>{{ (p.public === 1 ? 'PROJECT.PUBLIC' : 'PROJECT.PRIVATE') | translate}}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{p.repo_count}}</clr-dg-cell>
|
<clr-dg-cell>{{p.repo_count}}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{p.creation_time | date: 'short'}}</clr-dg-cell>
|
<clr-dg-cell>{{p.creation_time | date: 'short'}}</clr-dg-cell>
|
||||||
</clr-dg-row>
|
</clr-dg-row>
|
||||||
<clr-dg-footer>
|
<clr-dg-footer>
|
||||||
{{totalRecordCount || (projects ? projects.length : 0)}} {{'PROJECT.ITEMS' | translate}}
|
{{(projects ? projects.length : 0)}} {{'PROJECT.ITEMS' | translate}}
|
||||||
<clr-dg-pagination [clrDgPageSize]="pageOffset" [clrDgTotalItems]="totalPage"></clr-dg-pagination>
|
<clr-dg-pagination [clrDgPageSize]="5"></clr-dg-pagination>
|
||||||
</clr-dg-footer>
|
</clr-dg-footer>
|
||||||
</clr-datagrid>
|
</clr-datagrid>
|
@ -11,7 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, EventEmitter, Output, Input } from '@angular/core';
|
import { Component, EventEmitter, Output, Input, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
import { SearchTriggerService } from '../../base/global-search/search-trigger.service';
|
import { SearchTriggerService } from '../../base/global-search/search-trigger.service';
|
||||||
@ -21,20 +21,21 @@ import { State } from 'clarity-angular';
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'list-project-ro',
|
selector: 'list-project-ro',
|
||||||
templateUrl: 'list-project-ro.component.html'
|
templateUrl: 'list-project-ro.component.html',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class ListProjectROComponent {
|
export class ListProjectROComponent {
|
||||||
@Input() projects: Project[];
|
@Input() projects: Project[];
|
||||||
|
|
||||||
@Input() totalPage: number;
|
|
||||||
@Input() totalRecordCount: number;
|
|
||||||
pageOffset: number = 1;
|
|
||||||
|
|
||||||
@Output() paginate = new EventEmitter<State>();
|
@Output() paginate = new EventEmitter<State>();
|
||||||
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private searchTrigger: SearchTriggerService,
|
private searchTrigger: SearchTriggerService,
|
||||||
private router: Router) { }
|
private router: Router,
|
||||||
|
private ref: ChangeDetectorRef) {
|
||||||
|
let hnd = setInterval(()=>ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
goToLink(proId: number): void {
|
goToLink(proId: number): void {
|
||||||
this.searchTrigger.closeSearch(true);
|
this.searchTrigger.closeSearch(true);
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
<clr-dg-column>{{'REPOSITORY.NAME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPOSITORY.NAME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'REPOSITORY.TAGS_COUNT' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPOSITORY.TAGS_COUNT' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'REPOSITORY.PULL_COUNT' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'REPOSITORY.PULL_COUNT' | translate}}</clr-dg-column>
|
||||||
<clr-dg-row *ngFor="let r of repositories" [clrDgItem]='r'>
|
<clr-dg-row *clrDgItems="let r of repositories" [clrDgItem]='r'>
|
||||||
<clr-dg-cell><a href="javascript:void(0)" (click)="gotoLink(projectId || r.project_id, r.name || r.repository_name)">{{r.name || r.repository_name}}</a></clr-dg-cell>
|
<clr-dg-cell><a href="javascript:void(0)" (click)="gotoLink(projectId || r.project_id, r.name || r.repository_name)">{{r.name || r.repository_name}}</a></clr-dg-cell>
|
||||||
<clr-dg-cell>{{r.tags_count}}</clr-dg-cell>
|
<clr-dg-cell>{{r.tags_count}}</clr-dg-cell>
|
||||||
<clr-dg-cell>{{r.pull_count}}</clr-dg-cell>
|
<clr-dg-cell>{{r.pull_count}}</clr-dg-cell>
|
||||||
</clr-dg-row>
|
</clr-dg-row>
|
||||||
<clr-dg-footer>
|
<clr-dg-footer>
|
||||||
{{totalRecordCount || (repositories ? repositories.length : 0)}} {{'REPOSITORY.ITEMS' | translate}}
|
{{(repositories ? repositories.length : 0)}} {{'REPOSITORY.ITEMS' | translate}}
|
||||||
<clr-dg-pagination [clrDgPageSize]="pageOffset" [clrDgTotalItems]="totalPage"></clr-dg-pagination>
|
<clr-dg-pagination [clrDgPageSize]="3"></clr-dg-pagination>
|
||||||
</clr-dg-footer>
|
</clr-dg-footer>
|
||||||
</clr-datagrid>
|
</clr-datagrid>
|
@ -11,7 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, Input, Output, EventEmitter } from '@angular/core';
|
import { Component, Input, Output, EventEmitter, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
import { Router, NavigationExtras } from '@angular/router';
|
import { Router, NavigationExtras } from '@angular/router';
|
||||||
import { Repository } from '../../repository/repository';
|
import { Repository } from '../../repository/repository';
|
||||||
import { State } from 'clarity-angular';
|
import { State } from 'clarity-angular';
|
||||||
@ -20,22 +20,23 @@ import { SearchTriggerService } from '../../base/global-search/search-trigger.se
|
|||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'list-repository-ro',
|
selector: 'list-repository-ro',
|
||||||
templateUrl: 'list-repository-ro.component.html'
|
templateUrl: 'list-repository-ro.component.html',
|
||||||
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class ListRepositoryROComponent {
|
export class ListRepositoryROComponent {
|
||||||
|
|
||||||
@Input() projectId: number;
|
@Input() projectId: number;
|
||||||
@Input() repositories: Repository[];
|
@Input() repositories: Repository[];
|
||||||
|
|
||||||
@Input() totalPage: number;
|
|
||||||
@Input() totalRecordCount: number;
|
|
||||||
@Output() paginate = new EventEmitter<State>();
|
@Output() paginate = new EventEmitter<State>();
|
||||||
pageOffset: number = 1;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private searchTrigger: SearchTriggerService
|
private searchTrigger: SearchTriggerService,
|
||||||
) { }
|
private ref: ChangeDetectorRef) {
|
||||||
|
let hnd = setInterval(()=>ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
|
}
|
||||||
|
|
||||||
refresh(state: State) {
|
refresh(state: State) {
|
||||||
if (this.repositories) {
|
if (this.repositories) {
|
||||||
|
@ -45,7 +45,7 @@ export function maxLengthExtValidator(length: number): ValidatorFn {
|
|||||||
|
|
||||||
export class MaxLengthExtValidatorDirective implements Validator, OnChanges {
|
export class MaxLengthExtValidatorDirective implements Validator, OnChanges {
|
||||||
@Input() maxLengthExt: number;
|
@Input() maxLengthExt: number;
|
||||||
private valFn = Validators.nullValidator;
|
valFn = Validators.nullValidator;
|
||||||
|
|
||||||
ngOnChanges(changes: SimpleChanges): void {
|
ngOnChanges(changes: SimpleChanges): void {
|
||||||
const change = changes['maxLengthExt'];
|
const change = changes['maxLengthExt'];
|
||||||
|
@ -82,7 +82,7 @@ export class MessageHandlerService {
|
|||||||
this.msgService.clear();
|
this.msgService.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public isAppLevel(error): boolean {
|
public isAppLevel(error: any): boolean {
|
||||||
return error && error.statusCode === httpStatusCode.Unauthorized;
|
return error && error.statusCode === httpStatusCode.Unauthorized;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -42,23 +42,25 @@ export class NewUserFormComponent implements AfterViewChecked, OnInit {
|
|||||||
//Notify the form value changes
|
//Notify the form value changes
|
||||||
@Output() valueChange = new EventEmitter<boolean>();
|
@Output() valueChange = new EventEmitter<boolean>();
|
||||||
|
|
||||||
|
confirmedPwd: string;
|
||||||
|
|
||||||
constructor(private session: SessionService) { }
|
constructor(private session: SessionService) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.resetState();
|
this.resetState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private validationStateMap: any = {};
|
validationStateMap: any = {};
|
||||||
|
|
||||||
private mailAlreadyChecked: any = {};
|
mailAlreadyChecked: any = {};
|
||||||
private userNameAlreadyChecked: any = {};
|
userNameAlreadyChecked: any = {};
|
||||||
private emailTooltip: string = 'TOOLTIP.EMAIL';
|
emailTooltip: string = 'TOOLTIP.EMAIL';
|
||||||
private usernameTooltip: string = 'TOOLTIP.USER_NAME';
|
usernameTooltip: string = 'TOOLTIP.USER_NAME';
|
||||||
private formValueChanged: boolean = false;
|
formValueChanged: boolean = false;
|
||||||
|
|
||||||
private checkOnGoing: any = {};
|
checkOnGoing: any = {};
|
||||||
|
|
||||||
private resetState(): void {
|
resetState(): void {
|
||||||
this.mailAlreadyChecked = {};
|
this.mailAlreadyChecked = {};
|
||||||
this.userNameAlreadyChecked = {};
|
this.userNameAlreadyChecked = {};
|
||||||
this.emailTooltip = 'TOOLTIP.EMAIL';
|
this.emailTooltip = 'TOOLTIP.EMAIL';
|
||||||
@ -82,11 +84,11 @@ export class NewUserFormComponent implements AfterViewChecked, OnInit {
|
|||||||
return !this.checkOnGoing[key];
|
return !this.checkOnGoing[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
private getValidationState(key: string): boolean {
|
getValidationState(key: string): boolean {
|
||||||
return !this.validationStateMap[key];
|
return !this.validationStateMap[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleValidation(key: string, flag: boolean): void {
|
handleValidation(key: string, flag: boolean): void {
|
||||||
if (flag) {
|
if (flag) {
|
||||||
//Checking
|
//Checking
|
||||||
let cont = this.newUserForm.controls[key];
|
let cont = this.newUserForm.controls[key];
|
||||||
|
@ -23,8 +23,8 @@ const defaultLeftTime = 5;
|
|||||||
styleUrls: ['not-found.component.css']
|
styleUrls: ['not-found.component.css']
|
||||||
})
|
})
|
||||||
export class PageNotFoundComponent implements OnInit, OnDestroy{
|
export class PageNotFoundComponent implements OnInit, OnDestroy{
|
||||||
private leftSeconds: number = defaultLeftTime;
|
leftSeconds: number = defaultLeftTime;
|
||||||
private timeInterval: any = null;
|
timeInterval: any = null;
|
||||||
|
|
||||||
constructor(private router: Router){}
|
constructor(private router: Router){}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ export function portValidator(): ValidatorFn {
|
|||||||
})
|
})
|
||||||
|
|
||||||
export class PortValidatorDirective implements Validator {
|
export class PortValidatorDirective implements Validator {
|
||||||
private valFn = portValidator();
|
valFn = portValidator();
|
||||||
|
|
||||||
validate(control: AbstractControl): { [key: string]: any } {
|
validate(control: AbstractControl): { [key: string]: any } {
|
||||||
return this.valFn(control);
|
return this.valFn(control);
|
||||||
|
@ -35,7 +35,7 @@ export class AuthCheckGuard implements CanActivate, CanActivateChild {
|
|||||||
private msgHandler: MessageHandlerService,
|
private msgHandler: MessageHandlerService,
|
||||||
private searchTrigger: SearchTriggerService) { }
|
private searchTrigger: SearchTriggerService) { }
|
||||||
|
|
||||||
private isGuest(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
|
isGuest(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
|
||||||
const proRegExp = /\/harbor\/projects\/[\d]+\/.+/i;
|
const proRegExp = /\/harbor\/projects\/[\d]+\/.+/i;
|
||||||
const libRegExp = /\/harbor\/tags\/[\d]+\/.+/i;
|
const libRegExp = /\/harbor\/tags\/[\d]+\/.+/i;
|
||||||
if (proRegExp.test(state.url) || libRegExp.test(state.url)) {
|
if (proRegExp.test(state.url) || libRegExp.test(state.url)) {
|
||||||
|
@ -44,18 +44,18 @@ export class SessionService {
|
|||||||
|
|
||||||
projectMembers: Member[];
|
projectMembers: Member[];
|
||||||
|
|
||||||
private headers = new Headers({
|
headers = new Headers({
|
||||||
"Content-Type": 'application/json'
|
"Content-Type": 'application/json'
|
||||||
});
|
});
|
||||||
|
|
||||||
private formHeaders = new Headers({
|
formHeaders = new Headers({
|
||||||
"Content-Type": 'application/x-www-form-urlencoded'
|
"Content-Type": 'application/x-www-form-urlencoded'
|
||||||
});
|
});
|
||||||
|
|
||||||
constructor(private http: Http) { }
|
constructor(private http: Http) { }
|
||||||
|
|
||||||
//Handle the related exceptions
|
//Handle the related exceptions
|
||||||
private handleError(error: any): Promise<any> {
|
handleError(error: any): Promise<any> {
|
||||||
return Promise.reject(error.message || error);
|
return Promise.reject(error.message || error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { CoreModule } from '../core/core.module';
|
import { CoreModule } from '../core/core.module';
|
||||||
import { CookieService } from 'angular2-cookie/core';
|
import { CookieService } from 'ngx-cookie';
|
||||||
|
|
||||||
import { SessionService } from '../shared/session.service';
|
import { SessionService } from '../shared/session.service';
|
||||||
import { MessageComponent } from '../global-message/message.component';
|
import { MessageComponent } from '../global-message/message.component';
|
||||||
|
@ -24,7 +24,6 @@ export const errorHandler = function (error: any): string {
|
|||||||
if (!error) {
|
if (!error) {
|
||||||
return "UNKNOWN_ERROR";
|
return "UNKNOWN_ERROR";
|
||||||
}
|
}
|
||||||
console.log(error);
|
|
||||||
if (!(error.statusCode || error.status)) {
|
if (!(error.statusCode || error.status)) {
|
||||||
//treat as string message
|
//treat as string message
|
||||||
return '' + error;
|
return '' + error;
|
||||||
|
@ -17,7 +17,7 @@ import { Subject } from 'rxjs/Subject';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class StatisticHandler {
|
export class StatisticHandler {
|
||||||
|
|
||||||
private refreshSource = new Subject<boolean>();
|
refreshSource = new Subject<boolean>();
|
||||||
|
|
||||||
refreshChan$ = this.refreshSource.asObservable();
|
refreshChan$ = this.refreshSource.asObservable();
|
||||||
|
|
||||||
|
@ -32,10 +32,11 @@ import { StatisticHandler } from './statistic-handler.service';
|
|||||||
|
|
||||||
export class StatisticsPanelComponent implements OnInit, OnDestroy {
|
export class StatisticsPanelComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
private originalCopy: Statistics = new Statistics();
|
originalCopy: Statistics = new Statistics();
|
||||||
private volumesInfo: Volumes = new Volumes();
|
volumesInfo: Volumes = new Volumes();
|
||||||
refreshSub: Subscription;
|
refreshSub: Subscription;
|
||||||
|
small: number;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private statistics: StatisticsService,
|
private statistics: StatisticsService,
|
||||||
private msgHandler: MessageHandlerService,
|
private msgHandler: MessageHandlerService,
|
||||||
@ -97,7 +98,7 @@ export class StatisticsPanelComponent implements OnInit, OnDestroy {
|
|||||||
return this.volumesInfo.storage.total != 0;
|
return this.volumesInfo.storage.total != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private getGBFromBytes(bytes: number): number {
|
getGBFromBytes(bytes: number): number {
|
||||||
return Math.round((bytes / (1024 * 1024 * 1024)));
|
return Math.round((bytes / (1024 * 1024 * 1024)));
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -29,10 +29,10 @@ const volumesEndpoint = "/api/systeminfo/volumes";
|
|||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class StatisticsService {
|
export class StatisticsService {
|
||||||
private headers = new Headers({
|
headers = new Headers({
|
||||||
"Content-Type": 'application/json'
|
"Content-Type": 'application/json'
|
||||||
});
|
});
|
||||||
private options = new RequestOptions({
|
options = new RequestOptions({
|
||||||
headers: this.headers
|
headers: this.headers
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ export class TargetExistsValidatorDirective implements Validator, OnChanges {
|
|||||||
@Input() targetExists: string;
|
@Input() targetExists: string;
|
||||||
@Input() projectId: number;
|
@Input() projectId: number;
|
||||||
|
|
||||||
private valFn = Validators.nullValidator;
|
valFn = Validators.nullValidator;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private projectService: ProjectService,
|
private projectService: ProjectService,
|
||||||
@ -51,7 +51,6 @@ export class TargetExistsValidatorDirective implements Validator, OnChanges {
|
|||||||
|
|
||||||
targetExistsValidator(target: string): ValidatorFn {
|
targetExistsValidator(target: string): ValidatorFn {
|
||||||
return (control: AbstractControl): {[key: string]: any} => {
|
return (control: AbstractControl): {[key: string]: any} => {
|
||||||
console.log('Target:' + target + ', validate value:' + control.value);
|
|
||||||
switch(target) {
|
switch(target) {
|
||||||
case 'PROJECT_NAME':
|
case 'PROJECT_NAME':
|
||||||
return new Promise(resolve=>{
|
return new Promise(resolve=>{
|
||||||
|
@ -29,9 +29,9 @@ import { MessageHandlerService } from '../shared/message-handler/message-handler
|
|||||||
|
|
||||||
export class NewUserModalComponent {
|
export class NewUserModalComponent {
|
||||||
opened: boolean = false;
|
opened: boolean = false;
|
||||||
private error: any;
|
error: any;
|
||||||
private onGoing: boolean = false;
|
onGoing: boolean = false;
|
||||||
private formValueChanged: boolean = false;
|
formValueChanged: boolean = false;
|
||||||
|
|
||||||
@Output() addNew = new EventEmitter<User>();
|
@Output() addNew = new EventEmitter<User>();
|
||||||
|
|
||||||
@ -40,11 +40,11 @@ export class NewUserModalComponent {
|
|||||||
private msgHandler: MessageHandlerService) { }
|
private msgHandler: MessageHandlerService) { }
|
||||||
|
|
||||||
@ViewChild(NewUserFormComponent)
|
@ViewChild(NewUserFormComponent)
|
||||||
private newUserForm: NewUserFormComponent;
|
newUserForm: NewUserFormComponent;
|
||||||
@ViewChild(InlineAlertComponent)
|
@ViewChild(InlineAlertComponent)
|
||||||
private inlineAlert: InlineAlertComponent;
|
inlineAlert: InlineAlertComponent;
|
||||||
|
|
||||||
private getNewUser(): User {
|
getNewUser(): User {
|
||||||
return this.newUserForm.getData();
|
return this.newUserForm.getData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
<clr-dg-column>{{'USER.COLUMN_ADMIN' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'USER.COLUMN_ADMIN' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'USER.COLUMN_EMAIL' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'USER.COLUMN_EMAIL' | translate}}</clr-dg-column>
|
||||||
<clr-dg-column>{{'USER.COLUMN_REG_NAME' | translate}}</clr-dg-column>
|
<clr-dg-column>{{'USER.COLUMN_REG_NAME' | translate}}</clr-dg-column>
|
||||||
<clr-dg-row *ngFor="let user of users" [clrDgItem]="user">
|
<clr-dg-row *clrDgItems="let user of users" [clrDgItem]="user">
|
||||||
<clr-dg-action-overflow [hidden]="isMySelf(user.user_id)">
|
<clr-dg-action-overflow [hidden]="isMySelf(user.user_id)">
|
||||||
<button class="action-item" (click)="changeAdminRole(user)">{{adminActions(user)}}</button>
|
<button class="action-item" (click)="changeAdminRole(user)">{{adminActions(user)}}</button>
|
||||||
<button class="action-item" (click)="deleteUser(user)">{{'USER.DEL_ACTION' | translate}}</button>
|
<button class="action-item" (click)="deleteUser(user)">{{'USER.DEL_ACTION' | translate}}</button>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
import { Component, OnInit, ViewChild, OnDestroy } from '@angular/core';
|
import { Component, OnInit, ViewChild, OnDestroy, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
import 'rxjs/add/operator/toPromise';
|
import 'rxjs/add/operator/toPromise';
|
||||||
import { Subscription } from 'rxjs/Subscription';
|
import { Subscription } from 'rxjs/Subscription';
|
||||||
|
|
||||||
@ -31,22 +31,22 @@ import { AppConfigService } from '../app-config.service';
|
|||||||
selector: 'harbor-user',
|
selector: 'harbor-user',
|
||||||
templateUrl: 'user.component.html',
|
templateUrl: 'user.component.html',
|
||||||
styleUrls: ['user.component.css'],
|
styleUrls: ['user.component.css'],
|
||||||
|
providers: [UserService],
|
||||||
providers: [UserService]
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
|
|
||||||
export class UserComponent implements OnInit, OnDestroy {
|
export class UserComponent implements OnInit, OnDestroy {
|
||||||
users: User[] = [];
|
users: User[] = [];
|
||||||
originalUsers: Promise<User[]>;
|
originalUsers: Promise<User[]>;
|
||||||
private onGoing: boolean = false;
|
onGoing: boolean = false;
|
||||||
private adminMenuText: string = "";
|
adminMenuText: string = "";
|
||||||
private adminColumn: string = "";
|
adminColumn: string = "";
|
||||||
private deletionSubscription: Subscription;
|
deletionSubscription: Subscription;
|
||||||
|
|
||||||
currentTerm: string;
|
currentTerm: string;
|
||||||
|
|
||||||
@ViewChild(NewUserModalComponent)
|
@ViewChild(NewUserModalComponent)
|
||||||
private newUserDialog: NewUserModalComponent;
|
newUserDialog: NewUserModalComponent;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private userService: UserService,
|
private userService: UserService,
|
||||||
@ -54,7 +54,8 @@ export class UserComponent implements OnInit, OnDestroy {
|
|||||||
private deletionDialogService: ConfirmationDialogService,
|
private deletionDialogService: ConfirmationDialogService,
|
||||||
private msgHandler: MessageHandlerService,
|
private msgHandler: MessageHandlerService,
|
||||||
private session: SessionService,
|
private session: SessionService,
|
||||||
private appConfigService: AppConfigService) {
|
private appConfigService: AppConfigService,
|
||||||
|
private ref: ChangeDetectorRef) {
|
||||||
this.deletionSubscription = deletionDialogService.confirmationConfirm$.subscribe(confirmed => {
|
this.deletionSubscription = deletionDialogService.confirmationConfirm$.subscribe(confirmed => {
|
||||||
if (confirmed &&
|
if (confirmed &&
|
||||||
confirmed.source === ConfirmationTargets.USER &&
|
confirmed.source === ConfirmationTargets.USER &&
|
||||||
@ -62,9 +63,11 @@ export class UserComponent implements OnInit, OnDestroy {
|
|||||||
this.delUser(confirmed.data);
|
this.delUser(confirmed.data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
let hnd = setInterval(()=>ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private isMySelf(uid: number): boolean {
|
isMySelf(uid: number): boolean {
|
||||||
let currentUser = this.session.getCurrentUser();
|
let currentUser = this.session.getCurrentUser();
|
||||||
if (currentUser) {
|
if (currentUser) {
|
||||||
if (currentUser.user_id === uid) {
|
if (currentUser.user_id === uid) {
|
||||||
@ -75,7 +78,7 @@ export class UserComponent implements OnInit, OnDestroy {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private isMatchFilterTerm(terms: string, testedItem: string): boolean {
|
isMatchFilterTerm(terms: string, testedItem: string): boolean {
|
||||||
return testedItem.indexOf(terms) != -1;
|
return testedItem.indexOf(terms) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,6 +135,8 @@ export class UserComponent implements OnInit, OnDestroy {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
let hnd = setInterval(()=>this.ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Disable the admin role for the specified user
|
//Disable the admin role for the specified user
|
||||||
@ -159,6 +164,8 @@ export class UserComponent implements OnInit, OnDestroy {
|
|||||||
.then(() => {
|
.then(() => {
|
||||||
//Change view now
|
//Change view now
|
||||||
user.has_admin_role = updatedUser.has_admin_role;
|
user.has_admin_role = updatedUser.has_admin_role;
|
||||||
|
let hnd = setInterval(()=>this.ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
this.msgHandler.handleError(error);
|
this.msgHandler.handleError(error);
|
||||||
@ -186,7 +193,7 @@ export class UserComponent implements OnInit, OnDestroy {
|
|||||||
this.deletionDialogService.openComfirmDialog(msg);
|
this.deletionDialogService.openComfirmDialog(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private delUser(user: User): void {
|
delUser(user: User): void {
|
||||||
this.userService.deleteUser(user.user_id)
|
this.userService.deleteUser(user.user_id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
//Remove it from current user list
|
//Remove it from current user list
|
||||||
@ -195,6 +202,8 @@ export class UserComponent implements OnInit, OnDestroy {
|
|||||||
this.originalUsers.then(users => {
|
this.originalUsers.then(users => {
|
||||||
this.users = users.filter(u => u.user_id != user.user_id);
|
this.users = users.filter(u => u.user_id != user.user_id);
|
||||||
this.msgHandler.showSuccess("USER.DELETE_SUCCESS");
|
this.msgHandler.showSuccess("USER.DELETE_SUCCESS");
|
||||||
|
let hnd = setInterval(()=>this.ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
@ -211,7 +220,6 @@ export class UserComponent implements OnInit, OnDestroy {
|
|||||||
this.originalUsers = this.userService.getUsers()
|
this.originalUsers = this.userService.getUsers()
|
||||||
.then(users => {
|
.then(users => {
|
||||||
this.onGoing = false;
|
this.onGoing = false;
|
||||||
|
|
||||||
this.users = users;
|
this.users = users;
|
||||||
return users;
|
return users;
|
||||||
})
|
})
|
||||||
@ -219,6 +227,8 @@ export class UserComponent implements OnInit, OnDestroy {
|
|||||||
this.onGoing = false;
|
this.onGoing = false;
|
||||||
this.msgHandler.handleError(error);
|
this.msgHandler.handleError(error);
|
||||||
});
|
});
|
||||||
|
let hnd = setInterval(()=>this.ref.markForCheck(), 100);
|
||||||
|
setTimeout(()=>clearInterval(hnd), 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add new user
|
//Add new user
|
||||||
|
@ -27,7 +27,7 @@ const userMgmtEndpoint = '/api/users';
|
|||||||
*/
|
*/
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserService {
|
export class UserService {
|
||||||
private httpOptions = new RequestOptions({
|
httpOptions = new RequestOptions({
|
||||||
headers: new Headers({
|
headers: new Headers({
|
||||||
"Content-Type": 'application/json'
|
"Content-Type": 'application/json'
|
||||||
})
|
})
|
||||||
@ -36,7 +36,7 @@ export class UserService {
|
|||||||
constructor(private http: Http) { }
|
constructor(private http: Http) { }
|
||||||
|
|
||||||
//Handle the related exceptions
|
//Handle the related exceptions
|
||||||
private handleError(error: any): Promise<any> {
|
handleError(error: any): Promise<any> {
|
||||||
return Promise.reject(error.message || error);
|
return Promise.reject(error.message || error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
src/ui_ng/src/main-aot.ts
Normal file
11
src/ui_ng/src/main-aot.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import './polyfills.ts';
|
||||||
|
|
||||||
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
import { enableProdMode } from '@angular/core';
|
||||||
|
import { environment } from './environments/environment';
|
||||||
|
import { AppModuleNgFactory } from '../aot/src/app/app.module.ngfactory';
|
||||||
|
|
||||||
|
|
||||||
|
enableProdMode();
|
||||||
|
|
||||||
|
platformBrowserDynamic().bootstrapModuleFactory(AppModuleNgFactory);
|
25
src/ui_ng/tsconfig-aot.json
Normal file
25
src/ui_ng/tsconfig-aot.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"module": "es2015",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"sourceMap": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"lib": ["es2015", "dom"],
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"suppressImplicitAnyIndexErrors": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"typeRoots": [
|
||||||
|
"./node_modules/@types/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/app/app.module.ts",
|
||||||
|
"src/main-aot.ts"
|
||||||
|
],
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"genDir": "aot",
|
||||||
|
"skipMetadataEmit" : true
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user