Revision 60218
Added by Argiro Kokogiannaki over 3 years ago
modules/uoa-admin-portal/branches/new-UI/angular.json | ||
---|---|---|
1 |
{ |
|
2 |
"$schema": "./node_modules/@angular-devkit/core/src/workspace/workspace-schema.json", |
|
3 |
"version": 1, |
|
4 |
"newProjectRoot": "projects", |
|
5 |
"projects": { |
|
6 |
"admin-portal": { |
|
7 |
"root": "", |
|
8 |
"sourceRoot": "src", |
|
9 |
"projectType": "application", |
|
10 |
"architect": { |
|
11 |
"build": { |
|
12 |
"builder": "@angular-devkit/build-angular:browser", |
|
13 |
"options": { |
|
14 |
"outputPath": "dist", |
|
15 |
"index": "src/index.html", |
|
16 |
"main": "src/main.ts", |
|
17 |
"tsConfig": "src/tsconfig.app.json", |
|
18 |
"polyfills": "src/polyfills.ts", |
|
19 |
"assets": [ |
|
20 |
"src/assets", |
|
21 |
"src/robots.txt" |
|
22 |
], |
|
23 |
"styles": [ |
|
24 |
"src/styles.css", |
|
25 |
"src/material.scss", |
|
26 |
"node_modules/datatables.net-dt/css/jquery.dataTables.css", |
|
27 |
"node_modules/interactiveminingv3/assets/css/interactive-mining.css", |
|
28 |
"node_modules/interactiveminingv3/assets/css/animations.css" |
|
29 |
], |
|
30 |
"scripts": [ |
|
31 |
"node_modules/jquery/dist/jquery.js", |
|
32 |
"node_modules/datatables.net/js/jquery.dataTables.js", |
|
33 |
"node_modules/interactiveminingv3/assets/js/ResizeSensor.js", |
|
34 |
"node_modules/interactiveminingv3/assets/js/jquery.sticky-sidebar.js" |
|
35 |
] |
|
36 |
}, |
|
37 |
"configurations": { |
|
38 |
"production": { |
|
39 |
"optimization": true, |
|
40 |
"outputHashing": "all", |
|
41 |
"sourceMap": false, |
|
42 |
"extractCss": true, |
|
43 |
"namedChunks": false, |
|
44 |
"aot": true, |
|
45 |
"extractLicenses": true, |
|
46 |
"vendorChunk": false, |
|
47 |
"buildOptimizer": true, |
|
48 |
"fileReplacements": [ |
|
49 |
{ |
|
50 |
"replace": "src/environments/environment.ts", |
|
51 |
"with": "src/environments/environment.prod.ts" |
|
52 |
} |
|
53 |
] |
|
54 |
}, |
|
55 |
"beta": { |
|
56 |
"optimization": true, |
|
57 |
"outputHashing": "all", |
|
58 |
"sourceMap": false, |
|
59 |
"extractCss": true, |
|
60 |
"namedChunks": false, |
|
61 |
"aot": true, |
|
62 |
"extractLicenses": true, |
|
63 |
"vendorChunk": false, |
|
64 |
"buildOptimizer": true, |
|
65 |
"fileReplacements": [ |
|
66 |
{ |
|
67 |
"replace": "src/environments/environment.ts", |
|
68 |
"with": "src/environments/environment.beta.ts" |
|
69 |
} |
|
70 |
] |
|
71 |
} |
|
72 |
} |
|
73 |
}, |
|
74 |
"serve": { |
|
75 |
"builder": "@angular-devkit/build-angular:dev-server", |
|
76 |
"options": { |
|
77 |
"browserTarget": "admin-portal:build" |
|
78 |
}, |
|
79 |
"configurations": { |
|
80 |
"production": { |
|
81 |
"browserTarget": "admin-portal:build:production" |
|
82 |
}, |
|
83 |
"beta": { |
|
84 |
"browserTarget": "admin-portal:build:beta" |
|
85 |
} |
|
86 |
} |
|
87 |
}, |
|
88 |
"extract-i18n": { |
|
89 |
"builder": "@angular-devkit/build-angular:extract-i18n", |
|
90 |
"options": { |
|
91 |
"browserTarget": "admin-portal:build" |
|
92 |
} |
|
93 |
}, |
|
94 |
"test": { |
|
95 |
"builder": "@angular-devkit/build-angular:karma", |
|
96 |
"options": { |
|
97 |
"main": "src/test.ts", |
|
98 |
"karmaConfig": "./karma.conf.js", |
|
99 |
"polyfills": "src/polyfills.ts", |
|
100 |
"tsConfig": "src/tsconfig.spec.json", |
|
101 |
"scripts": [ |
|
102 |
"node_modules/jquery/dist/jquery.js", |
|
103 |
"node_modules/datatables.net/js/jquery.dataTables.js", |
|
104 |
"node_modules/interactiveminingv3/assets/js/ResizeSensor.js", |
|
105 |
"node_modules/interactiveminingv3/assets/js/jquery.sticky-sidebar.js" |
|
106 |
], |
|
107 |
"styles": [ |
|
108 |
"src/styles.css", |
|
109 |
"node_modules/datatables.net-dt/css/jquery.dataTables.css", |
|
110 |
"node_modules/interactiveminingv3/assets/css/interactive-mining.css", |
|
111 |
"node_modules/interactiveminingv3/assets/css/animations.css" |
|
112 |
], |
|
113 |
"assets": [ |
|
114 |
"src/assets", |
|
115 |
"src/robots.txt" |
|
116 |
] |
|
117 |
} |
|
118 |
}, |
|
119 |
"lint": { |
|
120 |
"builder": "@angular-devkit/build-angular:tslint", |
|
121 |
"options": { |
|
122 |
"tsConfig": [ |
|
123 |
"src/tsconfig.app.json", |
|
124 |
"src/tsconfig.spec.json" |
|
125 |
], |
|
126 |
"exclude": [ |
|
127 |
"**/node_modules/**" |
|
128 |
] |
|
129 |
} |
|
130 |
} |
|
131 |
} |
|
132 |
}, |
|
133 |
"admin-portal-e2e": { |
|
134 |
"root": "e2e", |
|
135 |
"sourceRoot": "e2e", |
|
136 |
"projectType": "application", |
|
137 |
"architect": { |
|
138 |
"e2e": { |
|
139 |
"builder": "@angular-devkit/build-angular:protractor", |
|
140 |
"options": { |
|
141 |
"protractorConfig": "./protractor.conf.js", |
|
142 |
"devServerTarget": "admin-portal:serve" |
|
143 |
} |
|
144 |
}, |
|
145 |
"lint": { |
|
146 |
"builder": "@angular-devkit/build-angular:tslint", |
|
147 |
"options": { |
|
148 |
"tsConfig": [ |
|
149 |
"e2e/tsconfig.e2e.json" |
|
150 |
], |
|
151 |
"exclude": [ |
|
152 |
"**/node_modules/**" |
|
153 |
] |
|
154 |
} |
|
155 |
} |
|
156 |
} |
|
157 |
} |
|
158 |
}, |
|
159 |
"defaultProject": "admin-portal", |
|
160 |
"schematics": { |
|
161 |
"@schematics/angular:component": { |
|
162 |
"prefix": "app", |
|
163 |
"styleext": "css" |
|
164 |
}, |
|
165 |
"@schematics/angular:directive": { |
|
166 |
"prefix": "app" |
|
167 |
} |
|
168 |
} |
|
169 |
} |
modules/uoa-admin-portal/branches/new-UI/LICENSE | ||
---|---|---|
1 |
MIT License |
|
2 |
|
|
3 |
Copyright (c) 2017 Stefanos Gatsios |
|
4 |
|
|
5 |
Permission is hereby granted, free of charge, to any person obtaining a copy |
|
6 |
of this software and associated documentation files (the "Software"), to deal |
|
7 |
in the Software without restriction, including without limitation the rights |
|
8 |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
|
9 |
copies of the Software, and to permit persons to whom the Software is |
|
10 |
furnished to do so, subject to the following conditions: |
|
11 |
|
|
12 |
The above copyright notice and this permission notice shall be included in all |
|
13 |
copies or substantial portions of the Software. |
|
14 |
|
|
15 |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|
16 |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|
17 |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
|
18 |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|
19 |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
|
20 |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
21 |
SOFTWARE. |
modules/uoa-admin-portal/branches/new-UI/package.json | ||
---|---|---|
1 |
{ |
|
2 |
"name": "admin-portal", |
|
3 |
"version": "0.0.0", |
|
4 |
"license": "MIT", |
|
5 |
"scripts": { |
|
6 |
"ng": "ng", |
|
7 |
"start": "ng serve --host 0.0.0.0 --disable-host-check --port=5000", |
|
8 |
"build": "ng build --prod; npm run after-build-clean", |
|
9 |
"build-beta": "ng build --configuration=beta; npm run after-build-clean", |
|
10 |
"test": "ng test", |
|
11 |
"lint": "ng lint", |
|
12 |
"e2e": "ng e2e", |
|
13 |
"after-build-clean": "rm -rf dist/assets/common-assets/.svn/ dist/assets/connect-assets/.svn/" |
|
14 |
}, |
|
15 |
"private": true, |
|
16 |
"dependencies": { |
|
17 |
"@angular/animations": "7.2.14", |
|
18 |
"@angular/cdk": "^7.3.7", |
|
19 |
"@angular/common": "7.2.14", |
|
20 |
"@angular/compiler": "7.2.14", |
|
21 |
"@angular/core": "7.2.14", |
|
22 |
"@angular/forms": "7.2.14", |
|
23 |
"@angular/http": "7.2.14", |
|
24 |
"@angular/material": "^7.3.7", |
|
25 |
"@angular/platform-browser": "7.2.14", |
|
26 |
"@angular/platform-browser-dynamic": "7.2.14", |
|
27 |
"@angular/router": "7.2.14", |
|
28 |
"@nguniversal/express-engine": "^6.0.0", |
|
29 |
"@types/express": "^4.16.1", |
|
30 |
"angular-datatables": "^4.4.1", |
|
31 |
"citation-js": "^0.3.4", |
|
32 |
"ng2-ckeditor": "1.1.9", |
|
33 |
"clipboard": "^1.5.16", |
|
34 |
"core-js": "2.6.8", |
|
35 |
"datatables.net": "^1.10.19", |
|
36 |
"datatables.net-dt": "^1.10.19", |
|
37 |
"interactiveminingv3": "file:interactiveminingv3.tgz", |
|
38 |
"jquery": "^3.4.1", |
|
39 |
"ng-recaptcha": "^3.0.5", |
|
40 |
"ngx-bootstrap": "^1.6.6", |
|
41 |
"ngx-color-picker": "^8.1.0", |
|
42 |
"ngx-json-ld": "0.1.6", |
|
43 |
"ts-md5": "^1.2.0", |
|
44 |
"tslib": "^1.9.0", |
|
45 |
"zone.js": "0.8.29" |
|
46 |
}, |
|
47 |
"devDependencies": { |
|
48 |
"@angular-devkit/build-angular": "~0.13.0", |
|
49 |
"@angular/cli": "7.3.9", |
|
50 |
"@angular/compiler-cli": "7.2.14", |
|
51 |
"@angular/language-service": "7.2.14", |
|
52 |
"@types/datatables.net": "^1.10.17", |
|
53 |
"@types/jasmine": "~2.8.8", |
|
54 |
"@types/jasminewd2": "~2.0.3", |
|
55 |
"@types/jquery": "^3.3.29", |
|
56 |
"@types/node": "^8.0.30", |
|
57 |
"codelyzer": "~4.5.0", |
|
58 |
"jasmine-core": "~2.99.1", |
|
59 |
"jasmine-spec-reporter": "~4.2.1", |
|
60 |
"karma": "~3.0.0", |
|
61 |
"karma-chrome-launcher": "~2.1.1", |
|
62 |
"karma-cli": "~1.0.1", |
|
63 |
"karma-coverage-istanbul-reporter": "~2.0.1", |
|
64 |
"karma-jasmine": "~1.1.2", |
|
65 |
"karma-jasmine-html-reporter": "^0.2.2", |
|
66 |
"protractor": "~5.4.0", |
|
67 |
"ts-node": "~7.0.0", |
|
68 |
"tslint": "^5.7.0", |
|
69 |
"typescript": "3.2.4", |
|
70 |
"rxjs": "6.5.1", |
|
71 |
"rxjs-compat": "^6.5.1", |
|
72 |
"rxjs-tslint": "^0.1.7" |
|
73 |
} |
|
74 |
} |
modules/uoa-admin-portal/branches/new-UI/tsconfig.json | ||
---|---|---|
1 |
{ |
|
2 |
"compileOnSave": false, |
|
3 |
"compilerOptions": { |
|
4 |
"importHelpers": true, |
|
5 |
"outDir": "./dist/out-tsc", |
|
6 |
"sourceMap": true, |
|
7 |
"declaration": false, |
|
8 |
"moduleResolution": "node", |
|
9 |
"emitDecoratorMetadata": true, |
|
10 |
"experimentalDecorators": true, |
|
11 |
"target": "es5", |
|
12 |
"typeRoots": [ |
|
13 |
"node_modules/@types" |
|
14 |
], |
|
15 |
"lib": [ |
|
16 |
"es2017", |
|
17 |
"dom" |
|
18 |
], |
|
19 |
"module": "es2015", |
|
20 |
"baseUrl": "./" |
|
21 |
} |
|
22 |
} |
modules/uoa-admin-portal/branches/new-UI/tslint.json | ||
---|---|---|
1 |
{ |
|
2 |
"rulesDirectory": [ |
|
3 |
"node_modules/codelyzer" |
|
4 |
], |
|
5 |
"rules": { |
|
6 |
"arrow-return-shorthand": true, |
|
7 |
"callable-types": true, |
|
8 |
"class-name": true, |
|
9 |
"comment-format": [ |
|
10 |
true, |
|
11 |
"check-space" |
|
12 |
], |
|
13 |
"curly": true, |
|
14 |
"eofline": true, |
|
15 |
"forin": true, |
|
16 |
"import-blacklist": [ |
|
17 |
true |
|
18 |
], |
|
19 |
"import-spacing": true, |
|
20 |
"indent": [ |
|
21 |
true, |
|
22 |
"spaces" |
|
23 |
], |
|
24 |
"interface-over-type-literal": true, |
|
25 |
"label-position": true, |
|
26 |
"max-line-length": [ |
|
27 |
true, |
|
28 |
140 |
|
29 |
], |
|
30 |
"member-access": false, |
|
31 |
"member-ordering": [ |
|
32 |
true, |
|
33 |
{ |
|
34 |
"order": [ |
|
35 |
"static-field", |
|
36 |
"instance-field", |
|
37 |
"static-method", |
|
38 |
"instance-method" |
|
39 |
] |
|
40 |
} |
|
41 |
], |
|
42 |
"no-arg": true, |
|
43 |
"no-bitwise": true, |
|
44 |
"no-console": [ |
|
45 |
true, |
|
46 |
"debug", |
|
47 |
"info", |
|
48 |
"time", |
|
49 |
"timeEnd", |
|
50 |
"trace" |
|
51 |
], |
|
52 |
"no-construct": true, |
|
53 |
"no-debugger": true, |
|
54 |
"no-duplicate-super": true, |
|
55 |
"no-empty": false, |
|
56 |
"no-empty-interface": true, |
|
57 |
"no-eval": true, |
|
58 |
"no-inferrable-types": [ |
|
59 |
true, |
|
60 |
"ignore-params" |
|
61 |
], |
|
62 |
"no-misused-new": true, |
|
63 |
"no-non-null-assertion": true, |
|
64 |
"no-shadowed-variable": true, |
|
65 |
"no-string-literal": false, |
|
66 |
"no-string-throw": true, |
|
67 |
"no-switch-case-fall-through": true, |
|
68 |
"no-trailing-whitespace": true, |
|
69 |
"no-unnecessary-initializer": true, |
|
70 |
"no-unused-expression": true, |
|
71 |
"no-use-before-declare": true, |
|
72 |
"no-var-keyword": true, |
|
73 |
"object-literal-sort-keys": false, |
|
74 |
"one-line": [ |
|
75 |
true, |
|
76 |
"check-open-brace", |
|
77 |
"check-catch", |
|
78 |
"check-else", |
|
79 |
"check-whitespace" |
|
80 |
], |
|
81 |
"prefer-const": true, |
|
82 |
"quotemark": [ |
|
83 |
true, |
|
84 |
"single" |
|
85 |
], |
|
86 |
"radix": true, |
|
87 |
"semicolon": [ |
|
88 |
true, |
|
89 |
"always" |
|
90 |
], |
|
91 |
"triple-equals": [ |
|
92 |
true, |
|
93 |
"allow-null-check" |
|
94 |
], |
|
95 |
"typedef-whitespace": [ |
|
96 |
true, |
|
97 |
{ |
|
98 |
"call-signature": "nospace", |
|
99 |
"index-signature": "nospace", |
|
100 |
"parameter": "nospace", |
|
101 |
"property-declaration": "nospace", |
|
102 |
"variable-declaration": "nospace" |
|
103 |
} |
|
104 |
], |
|
105 |
"typeof-compare": true, |
|
106 |
"unified-signatures": true, |
|
107 |
"variable-name": false, |
|
108 |
"whitespace": [ |
|
109 |
true, |
|
110 |
"check-branch", |
|
111 |
"check-decl", |
|
112 |
"check-operator", |
|
113 |
"check-separator", |
|
114 |
"check-type" |
|
115 |
], |
|
116 |
"directive-selector": [ |
|
117 |
true, |
|
118 |
"attribute", |
|
119 |
"app", |
|
120 |
"camelCase" |
|
121 |
], |
|
122 |
"component-selector": [ |
|
123 |
true, |
|
124 |
"element", |
|
125 |
"app", |
|
126 |
"kebab-case" |
|
127 |
], |
|
128 |
"use-input-property-decorator": true, |
|
129 |
"use-output-property-decorator": true, |
|
130 |
"use-host-property-decorator": true, |
|
131 |
"no-input-rename": true, |
|
132 |
"no-output-rename": true, |
|
133 |
"use-life-cycle-interface": true, |
|
134 |
"use-pipe-transform-interface": true, |
|
135 |
"component-class-suffix": true, |
|
136 |
"directive-class-suffix": true, |
|
137 |
"no-access-missing-member": true, |
|
138 |
"templates-use-public": true, |
|
139 |
"invoke-injectable": true |
|
140 |
} |
|
141 |
} |
modules/uoa-admin-portal/branches/new-UI/src/app/app.component.spec.ts | ||
---|---|---|
1 |
import { TestBed, async } from '@angular/core/testing'; |
|
2 |
|
|
3 |
import { AppComponent } from './app.component'; |
|
4 |
|
|
5 |
describe('AppComponent', () => { |
|
6 |
beforeEach(async(() => { |
|
7 |
TestBed.configureTestingModule({ |
|
8 |
declarations: [ |
|
9 |
AppComponent |
|
10 |
], |
|
11 |
}).compileComponents(); |
|
12 |
})); |
|
13 |
|
|
14 |
it('should create the app', async(() => { |
|
15 |
const fixture = TestBed.createComponent(AppComponent); |
|
16 |
const app = fixture.debugElement.componentInstance; |
|
17 |
expect(app).toBeTruthy(); |
|
18 |
})); |
|
19 |
|
|
20 |
it(`should have as title 'app'`, async(() => { |
|
21 |
const fixture = TestBed.createComponent(AppComponent); |
|
22 |
const app = fixture.debugElement.componentInstance; |
|
23 |
expect(app.title).toEqual('app'); |
|
24 |
})); |
|
25 |
|
|
26 |
it('should render title in a h1 tag', async(() => { |
|
27 |
const fixture = TestBed.createComponent(AppComponent); |
|
28 |
fixture.detectChanges(); |
|
29 |
const compiled = fixture.debugElement.nativeElement; |
|
30 |
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!'); |
|
31 |
})); |
|
32 |
}); |
modules/uoa-admin-portal/branches/new-UI/src/app/pages/curator/curator.component.html | ||
---|---|---|
1 |
<ng-template #buttons> |
|
2 |
<!--<a class="portal-link uk-margin-small-right" (click)="privacy()">Privacy policy statement</a>--> |
|
3 |
<button class="uk-button uk-margin-small-right" (click)="resetMessages(); resetForm()">Cancel</button> |
|
4 |
<button *ngIf="enabled && (hasChanged || affiliationsChanged)" class="uk-button uk-button-primary" (click)="resetMessages(); updateCurator()">Save</button> |
|
5 |
<button *ngIf="!enabled || (!hasChanged && !affiliationsChanged)" class="uk-button uk-button-default" disabled>Save</button> |
|
6 |
</ng-template> |
|
7 |
<div class="uk-padding uk-padding-remove-top uk-text-large uk-text-center uk-width">Manage Personal Info</div> |
|
8 |
<div class="uk-margin-large-bottom uk-flex uk-grid-divider" uk-grid> |
|
9 |
<div *ngIf="showLoading" class="uk-animation-fade uk-width-1-1" role="alert"> |
|
10 |
<span class="loading-gif uk-align-center"></span> |
|
11 |
</div> |
|
12 |
<div *ngIf="curatorId != null && curator != null && !showLoading" class="uk-width-1-1 uk-margin-left"> |
|
13 |
<div class="uk-alert uk-alert-primary uk-flex uk-flex-middle"> |
|
14 |
<span class="uk-icon uk-margin-small-right" uk-icon="info"></span> |
|
15 |
<div> |
|
16 |
Your personal info will be visible in the Curators' page of your Community Gateway. |
|
17 |
Read <a (click)="privacy()">privacy policy statement</a>.<br> |
|
18 |
<span *ngIf="!newCurator && !curatorsEnabled"> |
|
19 |
Curators' page is disabled. Please enable it <a routerLink="/pages" routerLinkActive="router-link-active" [queryParams]="{communityId: communityId, type: 'other'}">here</a>. |
|
20 |
</span> |
|
21 |
</div> |
|
22 |
</div> |
|
23 |
</div> |
|
24 |
<table *ngIf="curatorId != null && curator != null && !showLoading" class="uk-width-1-2@m uk-width-1-1@s uk-align-center"> |
|
25 |
<tbody class="uk-table uk-align-center"> |
|
26 |
<tr *ngIf="curator.name != null"> |
|
27 |
<td for="name" class="uk-text-bold uk-text-right"> |
|
28 |
Name |
|
29 |
<span class="uk-text-danger uk-text-bold"> |
|
30 |
* |
|
31 |
</span> |
|
32 |
: |
|
33 |
</td> |
|
34 |
<td class="uk-text-left uk-width-1-1"> |
|
35 |
<div *ngIf="!curator.name || curator.name === ''" class=" uk-text-danger uk-text-small style=display:none"> Please add name. </div> |
|
36 |
<input type="text" |
|
37 |
class="form-control uk-input" id="name" |
|
38 |
[(ngModel)]="curator.name" (input)="resetMessages(); onNameChange()" #name="ngModel" required> |
|
39 |
</td> |
|
40 |
</tr> |
|
41 |
<tr *ngIf="photo != null"> |
|
42 |
<td for="photo" class="uk-text-bold uk-align-right">Photo:</td> |
|
43 |
<td class="uk-text-left"> |
|
44 |
<div class="uk-flex uk-flex-middle" uk-grid> |
|
45 |
<div class="uk-width-auto@l"> |
|
46 |
<img class="uk-border-circle curator-photo" src="{{photo}}" alt="Curator Photo"> |
|
47 |
</div> |
|
48 |
<div class="uk-width-expand@l uk-grid-margin-small" uk-grid> |
|
49 |
<div uk-form-custom class="uk-width-auto"> |
|
50 |
<input id="photo" type="file" (change)="fileChangeEvent($event)" (input)="resetMessages(); change()"/> |
|
51 |
<button class="uk-button portal-button" type="button" tabindex="-1"> |
|
52 |
Upload a photo |
|
53 |
</button> |
|
54 |
</div> |
|
55 |
<div *ngIf="photo !== 'assets/common-assets/curator-default.png'" class="uk-width-auto"> |
|
56 |
<button class="uk-button uk-button-danger" type="button" (click)="resetMessages(); removePhotoModal.open()"> |
|
57 |
Remove |
|
58 |
</button> |
|
59 |
</div> |
|
60 |
</div> |
|
61 |
</div> |
|
62 |
<div class="uk-margin-small-top uk-text-warning"> |
|
63 |
Maximum photo resolution is 256x256 pixels. |
|
64 |
</div> |
|
65 |
</td> |
|
66 |
</tr> |
|
67 |
<tr *ngIf="curator.bio != null"> |
|
68 |
<td for="bio" class="uk-text-bold uk-text-right">Biography:</td> |
|
69 |
<td class="uk-text-left"> |
|
70 |
<textarea placeholder={{curator.bio}} type="text" |
|
71 |
class="form-control uk-textarea" rows="6" |
|
72 |
id="bio" |
|
73 |
[(ngModel)]="curator.bio" |
|
74 |
(input)="resetMessages(); change()"> |
|
75 |
</textarea> |
|
76 |
</td> |
|
77 |
</tr> |
|
78 |
<tr *ngIf="curator.bio != null"> |
|
79 |
<td class="uk-text-right"></td> |
|
80 |
<td class="uk-text-left"> |
|
81 |
<div class="uk-text-danger uk-text-bold"> |
|
82 |
* Required fields |
|
83 |
</div> |
|
84 |
</td> |
|
85 |
</tr> |
|
86 |
<tr> |
|
87 |
<td class="uk-text-right"></td> |
|
88 |
<td> |
|
89 |
<div *ngIf="updateErrorMessage" class="uk-alert uk-alert-danger" role="alert">{{updateErrorMessage}}</div> |
|
90 |
<div *ngIf="successfulSaveMessage" class="uk-alert uk-alert-success" role="alert">{{successfulSaveMessage}}</div> |
|
91 |
</tr> |
|
92 |
</tbody> |
|
93 |
</table> |
|
94 |
<div *ngIf="curatorId != null && curator != null && !showLoading" class="uk-width-1-2@m uk-width-1-1@s"> |
|
95 |
<affiliations [curatorAffiliations]="true" [affiliations]="curator.affiliations" |
|
96 |
(affiliationsChange)="affiliationsChanged = $event" |
|
97 |
(resetCuratorMessages)="resetMessages();"> |
|
98 |
</affiliations> |
|
99 |
</div> |
|
100 |
</div> |
|
101 |
<div class="uk-float-right uk-flex uk-flex-middle uk-visible@m" style="z-index: 100; bottom: 45px; position: fixed; right: 45px;"> |
|
102 |
<ng-container *ngTemplateOutlet="buttons"></ng-container> |
|
103 |
</div> |
|
104 |
<div class="uk-float-right uk-margin-bottom uk-hidden@m"> |
|
105 |
<ng-container *ngTemplateOutlet="buttons"></ng-container> |
|
106 |
</div> |
|
107 |
<modal-alert #removePhotoModal (alertOutput)="removePhoto()"> |
|
108 |
Your photo will be removed after you save your data. Are you sure you want to proceed? |
|
109 |
</modal-alert> |
|
110 |
<modal-alert #privacyStatement (alertOutput)="privacyStatement.cancel()"> |
|
111 |
<div class=""> |
|
112 |
Your personal data and photo are processed by OpenAIRE in conformity with personal data protection legal framework. |
|
113 |
They will be stored safely in our system for as long as OpenAIRE exists. Since you press the "save" button, |
|
114 |
you give us the consent to make them public in your Community Gateway to let users know who is |
|
115 |
configuring the platform. You always have the right to exercise your rights and ask for access, |
|
116 |
rectification, erasure and restriction of your data. Please contact <a href="mailto:rcd-helpdesk@openaire.eu">rcd-helpdesk@openaire.eu</a> if |
|
117 |
you have any inquiries. |
|
118 |
</div> |
|
119 |
</modal-alert> |
modules/uoa-admin-portal/branches/new-UI/src/app/pages/curator/curator.component.ts | ||
---|---|---|
1 |
import {Component, ElementRef, OnInit, ViewChild} from '@angular/core'; |
|
2 |
import {ActivatedRoute, Router} from '@angular/router'; |
|
3 |
|
|
4 |
import {EnvProperties} from '../../openaireLibrary/utils/properties/env-properties'; |
|
5 |
|
|
6 |
import {Session, User} from '../../openaireLibrary/login/utils/helper.class'; |
|
7 |
import {LoginErrorCodes} from '../../openaireLibrary/login/utils/guardHelper.class'; |
|
8 |
import {CuratorService} from '../../openaireLibrary/connect/curators/curator.service'; |
|
9 |
import {Curator} from '../../openaireLibrary/utils/entities/CuratorInfo'; |
|
10 |
import {HelperFunctions} from '../../openaireLibrary/utils/HelperFunctions.class'; |
|
11 |
import {UtilitiesService} from '../../openaireLibrary/services/utilities.service'; |
|
12 |
import {HelpContentService} from '../../services/help-content.service'; |
|
13 |
import {AlertModal} from '../../openaireLibrary/utils/modal/alert'; |
|
14 |
import {UserManagementService} from '../../openaireLibrary/services/user-management.service'; |
|
15 |
import {Title} from '@angular/platform-browser'; |
|
16 |
|
|
17 |
@Component({ |
|
18 |
selector: 'curator', |
|
19 |
templateUrl: './curator.component.html', |
|
20 |
}) |
|
21 |
|
|
22 |
export class CuratorComponent implements OnInit { |
|
23 |
|
|
24 |
public showLoading = true; |
|
25 |
public updateErrorMessage = ''; |
|
26 |
public successfulSaveMessage = ''; |
|
27 |
|
|
28 |
public curatorsEnabled = false; |
|
29 |
public newCurator = false; |
|
30 |
|
|
31 |
public communityId = null; |
|
32 |
|
|
33 |
public affiliationsChanged = false; |
|
34 |
public hasChanged = false; |
|
35 |
public curatorId = null; |
|
36 |
public curator: Curator = null; |
|
37 |
public photo: any = null; |
|
38 |
public properties: EnvProperties = null; |
|
39 |
public user: User; |
|
40 |
|
|
41 |
private file: File = null; |
|
42 |
private maxsize: number = 200 * 1024; |
|
43 |
public enabled = true; |
|
44 |
private deletePhoto = false; |
|
45 |
|
|
46 |
@ViewChild('privacyStatement') privacyStatement: AlertModal; |
|
47 |
|
|
48 |
constructor(private element: ElementRef, |
|
49 |
private route: ActivatedRoute, |
|
50 |
private _router: Router, |
|
51 |
private title: Title, |
|
52 |
private curatorService: CuratorService, |
|
53 |
private utilitiesService: UtilitiesService, |
|
54 |
private helpContentService: HelpContentService, |
|
55 |
private userManagementService: UserManagementService) { |
|
56 |
} |
|
57 |
|
|
58 |
|
|
59 |
ngOnInit() { |
|
60 |
this.route.data.subscribe((data: { envSpecific: EnvProperties }) => { |
|
61 |
this.properties = data.envSpecific; |
|
62 |
if (!Session.isLoggedIn()) { |
|
63 |
this._router.navigate(['/user-info'], { |
|
64 |
queryParams: {'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url} |
|
65 |
}); |
|
66 |
} else { |
|
67 |
this.route.queryParams.subscribe((params) => { |
|
68 |
this.communityId = params['communityId']; |
|
69 |
this.title.setTitle('Administration Dashboard | Personal Info'); |
|
70 |
this.showLoading = true; |
|
71 |
this.updateErrorMessage = ''; |
|
72 |
this.userManagementService.getUserInfo().subscribe(user => { |
|
73 |
this.user = user; |
|
74 |
if(this.user) { |
|
75 |
this.curatorId = this.user.id; |
|
76 |
this.getCurator(); |
|
77 |
} |
|
78 |
}); |
|
79 |
}); |
|
80 |
} |
|
81 |
}); |
|
82 |
|
|
83 |
} |
|
84 |
|
|
85 |
public getCurator() { |
|
86 |
this.curatorService.getCurator(this.properties, this.curatorId).subscribe( |
|
87 |
curator => { |
|
88 |
if (curator && Object.keys(curator).length > 0) { |
|
89 |
this.curator = curator; |
|
90 |
this.curator.email = this.user.email; |
|
91 |
if (this.curator.photo && this.curator.photo !== '') { |
|
92 |
this.photo = this.properties.utilsService + '/download/' + this.curator.photo; |
|
93 |
} else { |
|
94 |
this.photo = 'assets/common-assets/curator-default.png'; |
|
95 |
} |
|
96 |
this.curatorsPageStatus(); |
|
97 |
this.showLoading = false; |
|
98 |
HelperFunctions.scroll(); |
|
99 |
} else { |
|
100 |
this.newCurator = true; |
|
101 |
this.curator = new Curator(); |
|
102 |
this.curator._id = this.curatorId; |
|
103 |
this.curator.email = this.user.email; |
|
104 |
this.curator.name = this.user.fullname; |
|
105 |
this.curator.affiliations = []; |
|
106 |
this.curator.bio = ''; |
|
107 |
this.curator.photo = null; |
|
108 |
this.photo = 'assets/common-assets/curator-default.png'; |
|
109 |
this.showLoading = false; |
|
110 |
HelperFunctions.scroll(); |
|
111 |
} |
|
112 |
}, |
|
113 |
error => { |
|
114 |
} |
|
115 |
); |
|
116 |
} |
|
117 |
|
|
118 |
|
|
119 |
public resetForm() { |
|
120 |
if (!Session.isLoggedIn()) { |
|
121 |
this._router.navigate(['/user-info'], { |
|
122 |
queryParams: |
|
123 |
{'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url} |
|
124 |
}); |
|
125 |
} else { |
|
126 |
if (this.curatorId != null && this.curatorId !== '') { |
|
127 |
this.showLoading = true; |
|
128 |
this.updateErrorMessage = ''; |
|
129 |
this.getCurator(); |
|
130 |
} |
|
131 |
this.resetChange(); |
|
132 |
} |
|
133 |
} |
|
134 |
|
|
135 |
private curatorsPageStatus() { |
|
136 |
this.curatorsEnabled = false; |
|
137 |
this.helpContentService.getCommunityFull(this.communityId, this.properties.adminToolsAPIURL).subscribe((community) => { |
|
138 |
for (let page of community.pages) { |
|
139 |
if (page['route'] === '/curators') { |
|
140 |
this.curatorsEnabled = page['isEnabled']; |
|
141 |
return; |
|
142 |
} |
|
143 |
} |
|
144 |
}); |
|
145 |
} |
|
146 |
|
|
147 |
private change() { |
|
148 |
this.hasChanged = true; |
|
149 |
this.affiliationsChanged = true; |
|
150 |
} |
|
151 |
|
|
152 |
private resetChange() { |
|
153 |
this.hasChanged = false; |
|
154 |
this.affiliationsChanged = false; |
|
155 |
} |
|
156 |
|
|
157 |
public resetMessages() { |
|
158 |
this.successfulSaveMessage = ''; |
|
159 |
this.updateErrorMessage = ''; |
|
160 |
} |
|
161 |
|
|
162 |
handleUpdateError(message: string, error) { |
|
163 |
this.resetMessages(); |
|
164 |
this.updateErrorMessage = message; |
|
165 |
console.log('Server responded: ' + error); |
|
166 |
|
|
167 |
this.showLoading = false; |
|
168 |
} |
|
169 |
|
|
170 |
handleSuccessfulSave(message) { |
|
171 |
this.resetMessages(); |
|
172 |
this.showLoading = false; |
|
173 |
HelperFunctions.scroll(); |
|
174 |
this.successfulSaveMessage = message; |
|
175 |
} |
|
176 |
|
|
177 |
fileChangeEvent(event) { |
|
178 |
this.showLoading = true; |
|
179 |
if (event.target.files && event.target.files[0]) { |
|
180 |
this.file = event.target.files[0]; |
|
181 |
if (this.file.type !== 'image/png' && this.file.type !== 'image/jpeg') { |
|
182 |
this.handleUpdateError('You must choose a file with type: image/png or image/jpeg!', null); |
|
183 |
this.file = null; |
|
184 |
} else if (this.file.size > this.maxsize) { |
|
185 |
this.handleUpdateError('File exceeds size\'s limit! Maximum resolution is 256x256 pixels.', null); |
|
186 |
this.file = null; |
|
187 |
} else { |
|
188 |
this.updateErrorMessage = ''; |
|
189 |
const reader = new FileReader(); |
|
190 |
reader.readAsDataURL(this.file); |
|
191 |
reader.onload = () => { |
|
192 |
this.photo = reader.result; |
|
193 |
this.showLoading = false; |
|
194 |
HelperFunctions.scroll(); |
|
195 |
}; |
|
196 |
} |
|
197 |
} |
|
198 |
} |
|
199 |
|
|
200 |
saveCurator() { |
|
201 |
this.curatorService.updateCurator(this.properties, this.curator).subscribe((curator) => { |
|
202 |
if (curator) { |
|
203 |
this.handleSuccessfulSave('Your data has been saved successfully!'); |
|
204 |
this.newCurator = false; |
|
205 |
this.file = null; |
|
206 |
this.deletePhoto = false; |
|
207 |
this.resetChange(); |
|
208 |
} |
|
209 |
}, |
|
210 |
error => { |
|
211 |
this.handleUpdateError('An error has occurred. Try again later!', error); |
|
212 |
this.resetChange(); |
|
213 |
}); |
|
214 |
} |
|
215 |
|
|
216 |
|
|
217 |
updateCurator() { |
|
218 |
if (!Session.isLoggedIn()) { |
|
219 |
this._router.navigate(['/user-info'], { |
|
220 |
queryParams: |
|
221 |
{'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url} |
|
222 |
}); |
|
223 |
} else { |
|
224 |
if ((this.hasChanged || this.affiliationsChanged) && this.curator && this.curator.name && this.curator.name !== '') { |
|
225 |
this.showLoading = true; |
|
226 |
if (this.file) { |
|
227 |
this.utilitiesService.uploadPhoto(this.properties.utilsService + '/upload/' + this.curator._id, this.file).subscribe((res) => { |
|
228 |
if (this.curator.photo && this.curator.photo !== '') { |
|
229 |
this.utilitiesService.deletePhoto(this.properties.utilsService + '/delete/' + this.curator.photo).subscribe(); |
|
230 |
} |
|
231 |
this.curator.photo = res.filename; |
|
232 |
this.saveCurator(); |
|
233 |
}, error => { |
|
234 |
this.handleUpdateError('An error has occurred during photo uploading.', error); |
|
235 |
} |
|
236 |
); |
|
237 |
} else { |
|
238 |
if (this.deletePhoto) { |
|
239 |
if(this.curator.photo && this.curator.photo != '') { |
|
240 |
this.utilitiesService.deletePhoto(this.properties.utilsService + '/delete/' + this.curator.photo).subscribe(); |
|
241 |
this.curator.photo = ''; |
|
242 |
} |
|
243 |
} |
|
244 |
this.saveCurator(); |
|
245 |
} |
|
246 |
} |
|
247 |
} |
|
248 |
} |
|
249 |
|
|
250 |
onNameChange() { |
|
251 |
this.hasChanged = true; |
|
252 |
this.enabled = !(!this.curator.name || this.curator.name === ''); |
|
253 |
} |
|
254 |
|
|
255 |
removePhoto() { |
|
256 |
this.deletePhoto = true; |
|
257 |
this.hasChanged = true; |
|
258 |
this.file = null; |
|
259 |
this.photo = 'assets/common-assets/curator-default.png'; |
|
260 |
} |
|
261 |
|
|
262 |
privacy() { |
|
263 |
this.privacyStatement.cancelButton = false; |
|
264 |
this.privacyStatement.okButtonText = 'Close'; |
|
265 |
this.privacyStatement.alertTitle = 'Privacy policy statement'; |
|
266 |
this.privacyStatement.open(); |
|
267 |
} |
|
268 |
} |
modules/uoa-admin-portal/branches/new-UI/src/app/pages/curator/curator.module.ts | ||
---|---|---|
1 |
import {NgModule} from '@angular/core'; |
|
2 |
import {CommonModule} from '@angular/common'; |
|
3 |
import {FormsModule} from '@angular/forms'; |
|
4 |
import {RouterModule} from '@angular/router'; |
|
5 |
|
|
6 |
import {CuratorComponent} from './curator.component'; |
|
7 |
|
|
8 |
import {CuratorRoutingModule} from './curator-routing.module'; |
|
9 |
import {IsCommunity} from '../../openaireLibrary/connect/communityGuard/isCommunity.guard'; |
|
10 |
import {ConnectAdminLoginGuard} from '../../openaireLibrary/connect/communityGuard/connectAdminLoginGuard.guard'; |
|
11 |
import {CuratorService} from '../../openaireLibrary/connect/curators/curator.service'; |
|
12 |
import {AlertModalModule} from '../../openaireLibrary/utils/modal/alertModal.module'; |
|
13 |
import {UtilitiesService} from '../../openaireLibrary/services/utilities.service'; |
|
14 |
import {AffiliationsModule} from "../affiliations/affiliations.module"; |
|
15 |
|
|
16 |
@NgModule({ |
|
17 |
imports: [ |
|
18 |
CuratorRoutingModule, CommonModule, FormsModule, RouterModule, |
|
19 |
AlertModalModule, AffiliationsModule |
|
20 |
], |
|
21 |
declarations: [ |
|
22 |
CuratorComponent |
|
23 |
], |
|
24 |
providers: [ |
|
25 |
CuratorService, UtilitiesService, IsCommunity, ConnectAdminLoginGuard |
|
26 |
], |
|
27 |
exports: [ |
|
28 |
CuratorComponent |
|
29 |
] |
|
30 |
}) |
|
31 |
|
|
32 |
export class CuratorModule { } |
modules/uoa-admin-portal/branches/new-UI/src/app/pages/curator/curator-routing.module.ts | ||
---|---|---|
1 |
import { NgModule } from '@angular/core'; |
|
2 |
import {RouterModule} from '@angular/router'; |
|
3 |
import {CuratorComponent} from './curator.component'; |
|
4 |
import {IsCommunity} from '../../openaireLibrary/connect/communityGuard/isCommunity.guard'; |
|
5 |
import {ConnectAdminLoginGuard} from '../../openaireLibrary/connect/communityGuard/connectAdminLoginGuard.guard'; |
|
6 |
|
|
7 |
@NgModule({ |
|
8 |
imports: [ |
|
9 |
RouterModule.forChild([ |
|
10 |
{ path: '', canActivate: [IsCommunity, ConnectAdminLoginGuard], component: CuratorComponent} |
|
11 |
]) |
|
12 |
] |
|
13 |
}) |
|
14 |
export class CuratorRoutingModule { } |
modules/uoa-admin-portal/branches/new-UI/src/app/pages/mining/mining.module.ts | ||
---|---|---|
1 |
import { NgModule } from '@angular/core'; |
|
2 |
import { InteractiveMiningModule, InteractiveMiningRoutingModule} from 'interactiveminingv3'; |
|
3 |
@NgModule({ |
|
4 |
imports: [ |
|
5 |
InteractiveMiningModule, |
|
6 |
InteractiveMiningRoutingModule |
|
7 |
] |
|
8 |
}) |
|
9 |
export class MiningModule { } |
modules/uoa-admin-portal/branches/new-UI/src/app/pages/subjects/subjects-edit-form/subjects-edit-form.module.ts | ||
---|---|---|
1 |
import {NgModule} from '@angular/core'; |
|
2 |
import {CommonModule} from '@angular/common'; |
|
3 |
import {FormsModule} from '@angular/forms'; |
|
4 |
import {RouterModule} from '@angular/router'; |
|
5 |
|
|
6 |
import {SubjectsEditFormComponent} from './subjects-edit-form.component'; |
|
7 |
|
|
8 |
import {SubjectsService} from '../subjects.service'; |
|
9 |
import {SubjectsEditFormRoutingModule} from './subjects-edit-form-routing.module'; |
|
10 |
import {IsCommunity} from '../../../openaireLibrary/connect/communityGuard/isCommunity.guard'; |
|
11 |
import {ConnectAdminLoginGuard} from '../../../openaireLibrary/connect/communityGuard/connectAdminLoginGuard.guard'; |
|
12 |
import {ConnectCommunityGuard} from '../../../openaireLibrary/connect/communityGuard/connectCommunityGuard.guard'; |
|
13 |
|
|
14 |
@NgModule({ |
|
15 |
imports: [ |
|
16 |
SubjectsEditFormRoutingModule, CommonModule, FormsModule, RouterModule, |
|
17 |
], |
|
18 |
declarations: [ |
|
19 |
SubjectsEditFormComponent |
|
20 |
], |
|
21 |
providers: [ |
|
22 |
SubjectsService, IsCommunity, ConnectAdminLoginGuard, ConnectCommunityGuard |
|
23 |
], |
|
24 |
exports: [ |
|
25 |
SubjectsEditFormComponent |
|
26 |
] |
|
27 |
}) |
|
28 |
export class SubjectsEditFormModule { } |
modules/uoa-admin-portal/branches/new-UI/src/app/pages/subjects/subjects-edit-form/subjects-edit-form-routing.module.ts | ||
---|---|---|
1 |
import { NgModule } from '@angular/core'; |
|
2 |
import {RouterModule} from '@angular/router'; |
|
3 |
import {SubjectsEditFormComponent} from './subjects-edit-form.component'; |
|
4 |
import {IsCommunity} from '../../../openaireLibrary/connect/communityGuard/isCommunity.guard'; |
|
5 |
import {ConnectAdminLoginGuard} from '../../../openaireLibrary/connect/communityGuard/connectAdminLoginGuard.guard'; |
|
6 |
import {ConnectCommunityGuard} from '../../../openaireLibrary/connect/communityGuard/connectCommunityGuard.guard'; |
|
7 |
|
|
8 |
@NgModule({ |
|
9 |
imports: [ |
|
10 |
RouterModule.forChild([ |
|
11 |
{ path: '', canActivate: [IsCommunity, ConnectAdminLoginGuard, ConnectCommunityGuard], component: SubjectsEditFormComponent} |
|
12 |
]) |
|
13 |
] |
|
14 |
}) |
|
15 |
export class SubjectsEditFormRoutingModule { } |
modules/uoa-admin-portal/branches/new-UI/src/app/pages/subjects/subjects-edit-form/subjects-edit-form.component.html | ||
---|---|---|
1 |
<div id="subjects-edit-form " class=" uk-card uk-card-default uk-padding"> |
|
2 |
<div class="uk-text-large uk-text-center uk-width-5-6@l uk-width ">Manage subjects</div> |
|
3 |
<div class="uk-alert uk-alert-primary uk-margin-top-large"> |
|
4 |
<div> |
|
5 |
<span class="uk-margin-small-right uk-icon" uk-icon="warning"></span> |
|
6 |
All the research results associated to the subjects specified here will be automatically linked to the community dashboard. |
|
7 |
</div> |
|
8 |
<div class="uk-text-small"> </div> |
|
9 |
|
|
10 |
</div> |
|
11 |
|
|
12 |
|
|
13 |
<div class="uk-margin-top uk-container-small uk-align-center"> |
|
14 |
|
|
15 |
<div *ngIf="updateErrorMessage" class="uk-alert uk-alert-danger" role="alert">{{updateErrorMessage}}</div> |
|
16 |
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger" role="alert">{{errorMessage}}</div> |
|
17 |
<div *ngIf="successfulSaveMessage" class="uk-alert uk-alert-success" role="alert">{{successfulSaveMessage}}</div> |
|
18 |
<div *ngIf="successfulResetMessage" class="uk-alert uk-alert-warning" role="alert">{{successfulResetMessage}}</div> |
|
19 |
<div *ngIf="showLoading" class="uk-animation-fade uk-width-1-1" role="alert"><img class="uk-align-center loading-gif"></div> |
|
20 |
<div *ngIf="communityId != null && community != null && !showLoading && !errorMessage" > |
|
21 |
<div *ngIf="originalSubjects.length ==0"class="uk-alert uk-alert-info" role="alert">No subjects available</div> |
|
22 |
<div *ngIf="community.subjects != null"> |
|
23 |
<div *ngFor='let subject of community.subjects; let i = index; trackBy:trackByFn'> |
|
24 |
<input placeholder="Type subjects" type="text" class="form-control uk-input uk-width-large@l uk-width-medium@s" |
|
25 |
id="{{'subject'+i}}" name="{{'subject'+i}}" [(ngModel)] = "community.subjects[i]" (input)="change()"> |
|
26 |
<!-- red_background_color red_color--> |
|
27 |
<a class="uk-icon-button remove uk-button-danger" uk-icon="close" title="Remove" (click)="removeSubject(i); change();"></a> |
|
28 |
<!-- green_background_color green_color--> |
|
29 |
<a *ngIf="i == community.subjects.length - 1" class="uk-icon-button add uk-button-primary" uk-icon="plus" title="Add" (click)="addSubject()"></a> |
|
30 |
</div> |
|
31 |
<!-- green_background_color green_color--> |
|
32 |
<a *ngIf="community.subjects.length == 0" class="uk-icon-button add uk-button-primary" uk-icon="plus" title="Add" (click)="addSubject()"></a> |
|
33 |
|
|
34 |
</div> |
|
35 |
|
|
36 |
<div class="uk-grid-margin uk-first-column uk-align-center uk-text-left uk-padding uk-padding-remove-top uk-padding-remove-bottom"> |
|
37 |
<button *ngIf="hasChanged" class="uk-button uk-button-primary" (click)="updateSubjects()">Save</button> |
|
38 |
<button *ngIf="!hasChanged" class="uk-button uk-button-default" disabled>Save</button> |
|
39 |
<button class="uk-button" (click)="resetForm(communityId)">Reset</button> |
|
40 |
</div> |
|
41 |
</div> |
|
42 |
</div> |
|
43 |
</div> |
modules/uoa-admin-portal/branches/new-UI/src/app/pages/subjects/subjects-edit-form/subjects-edit-form.component.ts | ||
---|---|---|
1 |
import {Component, OnInit, Input, ElementRef} from '@angular/core'; |
|
2 |
import {FormGroup, FormBuilder, Validators} from '@angular/forms'; |
|
3 |
import {ActivatedRoute, Router} from '@angular/router'; |
|
4 |
import {HelpContentService} from '../../../services/help-content.service'; |
|
5 |
import {CommunityService} from '../../../openaireLibrary/connect/community/community.service'; |
|
6 |
import {SubjectsService} from '../subjects.service'; |
|
7 |
import {EnvProperties} from '../../../openaireLibrary/utils/properties/env-properties'; |
|
8 |
import {Session} from '../../../openaireLibrary/login/utils/helper.class'; |
|
9 |
import {LoginErrorCodes} from '../../../openaireLibrary/login/utils/guardHelper.class'; |
|
10 |
|
|
11 |
import { concat } from 'rxjs/observable/concat'; |
|
12 |
import {HelperFunctions} from "../../../openaireLibrary/utils/HelperFunctions.class"; |
|
13 |
import {Title} from '@angular/platform-browser'; |
|
14 |
@Component({ |
|
15 |
selector: 'subjects-edit-form', |
|
16 |
templateUrl: './subjects-edit-form.component.html', |
|
17 |
}) |
|
18 |
|
|
19 |
export class SubjectsEditFormComponent implements OnInit { |
|
20 |
|
|
21 |
@Input('group') |
|
22 |
myForm: FormGroup; |
|
23 |
|
|
24 |
public showLoading = true; |
|
25 |
public errorMessage = ''; |
|
26 |
public updateErrorMessage = ''; |
|
27 |
|
|
28 |
public successfulSaveMessage = ''; |
|
29 |
public successfulResetMessage = ''; |
|
30 |
|
|
31 |
public hasChanged = false; |
|
32 |
|
|
33 |
public res = []; |
|
34 |
|
|
35 |
params: any; |
|
36 |
|
|
37 |
public communityId = null; |
|
38 |
public community = null; |
|
39 |
public properties: EnvProperties = null; |
|
40 |
public newsubject = ''; |
|
41 |
public edit = null; |
|
42 |
public editSubjectOriginalValue = null; |
|
43 |
public originalSubjects = []; |
|
44 |
|
|
45 |
constructor (private element: ElementRef, |
|
46 |
private route: ActivatedRoute, |
|
47 |
private _router: Router, |
|
48 |
public _fb: FormBuilder, |
|
49 |
private title: Title, |
|
50 |
private _helpContentService: HelpContentService, |
|
51 |
private _communityService: CommunityService, |
|
52 |
private _subjectsService: SubjectsService) { } |
|
53 |
|
|
54 |
|
|
55 |
ngOnInit() { |
|
56 |
this.route.data.subscribe((data: { envSpecific: EnvProperties }) => { |
|
57 |
this.properties = data.envSpecific; |
|
58 |
this.route.queryParams.subscribe( |
|
59 |
communityId => { |
|
60 |
HelperFunctions.scroll(); |
|
61 |
this.title.setTitle('Administration Dashboard | Subjects'); |
|
62 |
this.communityId = communityId['communityId']; |
|
63 |
|
|
64 |
if (!Session.isLoggedIn()) { |
|
65 |
this._router.navigate(['/user-info'], { |
|
66 |
queryParams: { 'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url} }); |
|
67 |
} else { |
|
68 |
if (this.communityId != null && this.communityId !== '') { |
|
69 |
this.showLoading = true; |
|
70 |
this.updateErrorMessage = ''; |
|
71 |
this.errorMessage = ''; |
|
72 |
|
|
73 |
this._communityService.getCommunity(this.properties, |
|
74 |
this.properties.communityAPI + this.communityId).subscribe ( |
|
75 |
community => { |
|
76 |
this.community = community; |
|
77 |
this.params = {community: encodeURIComponent( |
|
78 |
'"' + community.queryId + '"')}; |
|
79 |
this.originalSubjects = []; |
|
80 |
for (let i = 0; i < this.community.subjects.length; i++) { |
|
81 |
this.originalSubjects.push(this.community.subjects[i]); |
|
82 |
} |
|
83 |
if (this.community.subjects.length === 0) { |
|
84 |
this.community.subjects.push(''); |
|
85 |
} |
|
86 |
this.showLoading = false; |
|
87 |
}, |
|
88 |
error => this.handleError('System error retrieving community profile', error) |
|
89 |
); |
|
90 |
} |
|
91 |
} |
|
92 |
}); |
|
93 |
}); |
|
94 |
} |
|
95 |
|
|
96 |
|
|
97 |
|
|
98 |
public addSubject() { |
|
99 |
if (!Session.isLoggedIn()) { |
|
100 |
this._router.navigate( |
|
101 |
['/user-info'], { |
|
102 |
queryParams: { 'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url} }); |
|
103 |
} else { |
|
104 |
this.community.subjects.push(''); |
|
105 |
} |
|
106 |
} |
|
107 |
|
|
108 |
public removeSubject(i: any) { |
|
109 |
if (!Session.isLoggedIn()) { |
|
110 |
this._router.navigate(['/user-info'], { |
|
111 |
queryParams: { 'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url} }); |
|
112 |
} else { |
|
113 |
this.community.subjects.splice(i, 1); |
|
114 |
} |
|
115 |
} |
|
116 |
|
|
117 |
public resetForm(communityId: string) { |
|
118 |
if (!Session.isLoggedIn()) { |
|
119 |
this._router.navigate(['/user-info'], |
|
120 |
{ queryParams: { 'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url} }); |
|
121 |
} else { |
|
122 |
if (communityId != null && communityId !== '') { |
|
123 |
this.showLoading = true; |
|
124 |
this.updateErrorMessage = ''; |
|
125 |
this.errorMessage = ''; |
|
126 |
|
|
127 |
this._communityService.getCommunity(this.properties, |
|
128 |
this.properties.communityAPI + communityId).subscribe ( |
|
129 |
community => { |
|
130 |
this.community = community; |
|
131 |
this.params = {community: encodeURIComponent('"' + community.queryId + '"')}; |
|
132 |
this.showLoading = false; |
|
133 |
this.handleSuccessfulReset('Form reset!'); |
|
134 |
}, |
|
135 |
error => this.handleError('System error retrieving community profile', error) |
|
136 |
); |
|
137 |
} |
|
138 |
this.resetChange(); |
|
139 |
} |
|
140 |
} |
|
141 |
|
|
142 |
public getSubjectsExistOnlyInFirst(firstArray: string[], secondArray: string[]): string[] { |
|
143 |
|
|
144 |
const difference = []; |
|
145 |
for (let i = 0; i < firstArray.length; i++) { |
|
146 |
if (secondArray.indexOf(firstArray[i]) === -1) { |
|
147 |
difference.push(firstArray[i]); |
|
148 |
} |
|
149 |
|
|
150 |
} |
|
151 |
return difference; |
|
152 |
|
|
153 |
} |
|
154 |
|
|
155 |
public updateSubjects() { |
|
156 |
if (!Session.isLoggedIn()) { |
|
157 |
this._router.navigate(['/user-info'], |
|
158 |
{ queryParams: { 'errorCode': LoginErrorCodes.NOT_VALID, 'redirectUrl': this._router.url} }); |
|
159 |
} else { |
|
160 |
if (this.communityId != null && this.communityId !== '') { |
|
161 |
this.showLoading = true; |
|
162 |
const subjectsToDeleteAr = this.getSubjectsExistOnlyInFirst(this.originalSubjects, this.community.subjects); |
|
163 |
const subjectsToAddAr = this.getSubjectsExistOnlyInFirst(this.community.subjects, this.originalSubjects); |
|
164 |
const subjectsToDelete = this.parseUpdatedSubjects(subjectsToDeleteAr); |
|
165 |
const subjectsToAdd = this.parseUpdatedSubjects(subjectsToAddAr); |
|
166 |
if (subjectsToAddAr.length > 0 && subjectsToDeleteAr.length > 0) { |
|
167 |
const obs = concat(this._subjectsService.addSubjects( |
|
168 |
this.properties.communityAPI + this.communityId + '/subjects', subjectsToAdd), |
|
169 |
this._subjectsService.removeSubjects( |
|
170 |
this.properties.communityAPI + this.communityId + '/subjects', subjectsToDelete)); |
|
171 |
obs.subscribe(res => { |
|
172 |
if (res['method'] === 'delete') { |
|
173 |
this.afterUpdateActions(res); |
|
174 |
} |
|
175 |
}, |
|
176 |
error => this.handleUpdateError('System error updating subjects', error) |
|
177 |
); |
|
178 |
} else if (subjectsToAddAr.length > 0) { |
|
179 |
this._subjectsService.addSubjects( |
|
180 |
this.properties.communityAPI + this.communityId + '/subjects', subjectsToAdd). |
|
181 |
subscribe(res => { |
|
182 |
this.afterUpdateActions(res); |
|
183 |
}, |
|
184 |
error => this.handleUpdateError('System error updating subjects', error) |
|
185 |
); |
|
186 |
} else if (subjectsToDeleteAr.length > 0) { |
|
187 |
this._subjectsService.removeSubjects( |
|
188 |
this.properties.communityAPI + this.communityId + '/subjects', subjectsToDelete). |
|
189 |
subscribe(res => { |
|
190 |
this.afterUpdateActions(res); |
|
191 |
}, |
|
192 |
error => this.handleUpdateError('System error updating subjects', error) |
|
193 |
); |
|
194 |
} |
|
195 |
// this._router.navigate(['/manage-subjects'], {queryParams: { "communityId": this.communityId}}); |
|
196 |
} |
|
197 |
this.resetChange(); |
|
198 |
} |
|
199 |
} |
|
200 |
|
|
201 |
afterUpdateActions(res) { |
|
202 |
this.community.subjects = res['subjects']; |
|
203 |
this.originalSubjects = []; |
|
204 |
for (let i = 0; i < this.community.subjects.length; i++) { |
|
205 |
this.originalSubjects.push(this.community.subjects[i]); |
|
206 |
} |
|
207 |
if (this.community.subjects.length === 0) { |
|
208 |
this.community.subjects.push(''); |
|
209 |
} |
|
210 |
this.handleSuccessfulSave('Subjects updated!'); |
|
211 |
this.showLoading = false; |
|
212 |
} |
|
213 |
|
|
214 |
private parseUpdatedSubjects(subjects): {} { |
|
215 |
const parsedSubjects = this.getNonEmptyItems(subjects); |
|
216 |
return parsedSubjects; |
|
217 |
} |
|
218 |
|
|
219 |
|
|
220 |
|
|
221 |
private getNonEmptyItems(data: string[]): string[] { |
|
222 |
const length = data.length; |
|
223 |
const arrayNonEmpty = new Array<string>(); |
|
224 |
let j = 0; |
|
225 |
for (let i = 0; i < length; i++) { |
|
226 |
if (this.isEmpty(data[i])) { |
|
227 |
} else if (this.isNonEmpty(data[i])) { |
|
228 |
arrayNonEmpty[j] = data[i]; |
|
229 |
j++; |
|
230 |
} |
|
231 |
} |
|
232 |
return arrayNonEmpty; |
|
233 |
} |
|
234 |
|
|
235 |
private hasFilled(data: any): boolean { |
|
236 |
if (this.isNonEmpty(data) && !this.isEmpty(data)) { |
|
237 |
return true; |
|
238 |
} |
|
239 |
return false; |
|
240 |
} |
|
241 |
|
|
242 |
private isEmpty(data: string): boolean { |
|
243 |
if (data !== undefined && !data.replace(/\s/g, '').length) { |
|
244 |
return true; |
|
245 |
} else { |
|
246 |
return false; |
|
247 |
} |
|
248 |
} |
|
249 |
|
|
250 |
private isNonEmpty(data: string): boolean { |
|
251 |
if (data !== undefined && data != null) { |
|
252 |
return true; |
|
253 |
} else { |
|
254 |
return false; |
|
255 |
} |
|
256 |
} |
|
257 |
|
|
258 |
private hasValidEmail(data: any): boolean { |
|
259 |
const length = data['managers'].length; |
|
260 |
|
|
261 |
for (let i = 0; i < length; i++) { |
|
262 |
if (!this.emailValidator(data['managers'][i])) { |
|
263 |
// TODO remove console message after final testing |
|
264 |
// console.log("INVALID EMAIL"); |
|
265 |
return false; |
|
266 |
} |
|
267 |
} |
|
268 |
// TODO remove console message after final testing |
|
269 |
// console.log("ALL EMAILS ARE VALID"); |
|
270 |
return true; |
|
271 |
} |
|
272 |
|
|
273 |
private emailValidator(email: any): boolean { |
|
274 |
if (email.match('^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$')) { |
|
275 |
return true; |
|
276 |
} else { |
|
277 |
return false; |
|
278 |
} |
|
279 |
} |
|
280 |
|
|
281 |
private change() { |
|
282 |
this.hasChanged = true; |
|
283 |
this.successfulSaveMessage = ''; |
|
284 |
this.successfulResetMessage = ''; |
|
285 |
} |
|
286 |
|
|
287 |
private resetChange() { |
|
288 |
this.hasChanged = false; |
|
289 |
} |
|
290 |
|
|
291 |
public get form() { |
|
292 |
return this._fb.group({ |
|
293 |
_id : '', |
|
294 |
name : ['', Validators.required] |
|
295 |
}); |
|
296 |
} |
|
297 |
|
|
298 |
public reset() { |
|
299 |
this.myForm.patchValue({ |
|
300 |
name : '', |
|
301 |
_id : '' |
|
302 |
}); |
|
303 |
} |
|
304 |
|
|
305 |
handleUpdateError(message: string, error) { |
|
306 |
this.updateErrorMessage = message; |
|
307 |
console.log('Server responded: ' + error); |
|
308 |
this.showLoading = false; |
|
309 |
} |
|
310 |
|
|
311 |
handleError(message: string, error) { |
|
312 |
this.errorMessage = message; |
|
313 |
console.log('Server responded: ' + error); |
|
314 |
|
|
315 |
this.showLoading = false; |
|
316 |
} |
|
317 |
|
|
318 |
handleSuccessfulSave(message) { |
|
319 |
this.showLoading = false; |
|
320 |
this.successfulSaveMessage = message; |
|
321 |
} |
|
322 |
|
|
323 |
handleSuccessfulReset(message) { |
|
324 |
this.showLoading = false; |
|
325 |
this.successfulResetMessage = message; |
|
326 |
} |
|
327 |
|
|
328 |
trackByFn(index: any, item: any) { |
|
329 |
return index; |
|
330 |
} |
|
331 |
} |
modules/uoa-admin-portal/branches/new-UI/src/app/pages/subjects/subjects.service.ts | ||
---|---|---|
1 |
import { Injectable } from '@angular/core'; |
|
2 |
import {HttpClient, HttpHeaders} from "@angular/common/http"; |
|
3 |
import {map} from "rxjs/operators"; |
|
4 |
|
|
5 |
@Injectable() |
|
6 |
export class SubjectsService { |
|
7 |
|
|
8 |
constructor(private http: HttpClient) { |
|
9 |
|
|
10 |
} |
|
11 |
|
|
12 |
addSubjects(url: string, subjects: any) { |
|
13 |
let headers = new HttpHeaders({'Content-Type': 'application/json'}); |
|
14 |
|
|
15 |
const body = JSON.stringify(subjects); |
|
16 |
|
|
17 |
return this.http.post(url, body, {headers: headers}) |
|
18 |
// .do(request => console.log("Insert Response:"+request.status)) |
|
19 |
//.map(res => res.json()) |
|
20 |
.pipe(map(res => { |
|
21 |
res['method'] = 'post'; |
|
22 |
return res; |
|
23 |
})); |
|
24 |
} |
|
25 |
|
|
26 |
removeSubjects(url: string, subjects: any) { |
|
27 |
//const headers = new Headers({'Content-Type': 'application/json'}); |
|
28 |
let headers = new HttpHeaders({'Content-Type': 'application/json'}); |
|
29 |
|
|
30 |
const body = JSON.stringify(subjects); |
|
31 |
//const options = new RequestOptions({headers: headers, body: body}); |
|
32 |
|
|
33 |
//return this.http.delete(url, options) |
|
34 |
return this.http.request('delete', url, { body: body, headers: headers}) |
|
35 |
// .do(request => console.log("Delete Response:"+request.status)) |
|
36 |
//.map(res => res.json()) |
|
37 |
.pipe(map(res => { |
|
38 |
res['method'] = 'delete'; |
|
39 |
return res; |
|
40 |
})); |
|
41 |
} |
|
42 |
} |
modules/uoa-admin-portal/branches/new-UI/src/app/pages/helpcontent/new-page-help-content-routing.module.ts | ||
---|---|---|
1 |
import { NgModule } from '@angular/core'; |
|
2 |
import {RouterModule} from '@angular/router'; |
|
3 |
import {IsCommunity} from '../../openaireLibrary/connect/communityGuard/isCommunity.guard'; |
|
4 |
import {ConnectAdminLoginGuard} from '../../openaireLibrary/connect/communityGuard/connectAdminLoginGuard.guard'; |
|
5 |
import {NewPageHelpContentComponent} from './new-page-help-content.component'; |
|
6 |
|
|
7 |
@NgModule({ |
|
8 |
imports: [ |
|
9 |
RouterModule.forChild([ |
|
10 |
{ path: '', canActivate: [IsCommunity, ConnectAdminLoginGuard], component: NewPageHelpContentComponent} |
|
11 |
]) |
|
12 |
] |
|
13 |
}) |
|
14 |
export class NewPageHelpContentRoutingModule { } |
modules/uoa-admin-portal/branches/new-UI/src/app/pages/helpcontent/page-help-content-form.component.html | ||
---|---|---|
1 |
<div *ngIf="updateErrorMessage" class="uk-alert uk-alert-danger" role="alert">{{updateErrorMessage}}</div> |
|
2 |
<div *ngIf="errorMessage" class="uk-alert uk-alert-danger" role="alert">{{errorMessage}}</div> |
|
3 |
<div [style.display]="showLoading ? 'inline' : 'none'" class="uk-animation-fade uk-width-1-1" role="alert"><img class="uk-align-center loading-gif"></div> |
|
4 |
<div class="uk-alert uk-alert-primary uk-margin-top-large"> |
|
5 |
<span class="uk-margin-small-right uk-icon" uk-icon="info"></span> |
|
6 |
Create or edit help text |
|
7 |
<div class="uk-text-small"> |
|
8 |
Select the page to be displayed, select position of the page |
|
9 |
</div> |
|
10 |
|
|
11 |
</div> |
|
12 |
<form *ngIf="!errorMessage && !showLoading" [formGroup]="myForm"> |
|
13 |
<div *ngIf="!pageId" class="form-group" [ngClass]="{'has-error':!myForm.controls.page.valid && myForm.controls.page.dirty}"> |
|
14 |
<label for="pageTag">Select Page</label> |
|
15 |
<select formControlName="page" id="pageTag" class="form-control"> |
|
16 |
<option *ngFor="let page of availablePages" [value]="page._id">{{page.name}}</option> |
|
17 |
</select> |
|
18 |
</div> |
|
19 |
<div *ngIf="myForm.controls.page.value" class="form-group" [ngClass]="{'has-error':!myForm.controls.placement.valid && myForm.controls.placement.dirty}"> |
|
20 |
<label for="placementTag">Select Placement</label> |
|
21 |
<select formControlName="placement" id="placementTag" class="form-control"> |
|
22 |
<option *ngIf="placements.top" [value]="'top'">Top</option> |
|
23 |
<option *ngIf="placements.left" [value]="'left'">Left</option> |
|
24 |
<option *ngIf="placements.right" [value]="'right'">Right</option> |
|
25 |
<option *ngIf="placements.bottom" [value]="'bottom'">Bottom</option> |
|
26 |
</select> |
|
27 |
</div> |
|
28 |
<div class="form-group" [ngClass]="{'has-error':!myForm.controls.content.valid && myForm.controls.content.dirty}"> |
|
29 |
<label>Content</label> |
|
30 |
<div> |
|
31 |
<!-- [config]="{allowedContent: 'p(*); h; div; span'}"--> |
|
32 |
<!-- [config]="{allowedContent: true,extraAllowedContent : '*(*)'}" --> |
|
33 |
<!-- [config]="{allowedContent: true, disallowedContent:'script; *[on*]'}" --> |
|
34 |
<!-- [config]="{ allowedContent: '{ |
|
35 |
elements: dtd, |
|
36 |
attributes: true, |
Also available in: Unified diff
Creating a branch for the new IU uoa-admin-portal