[DEV] first application
This commit is contained in:
parent
bdc2e7d176
commit
4c226971f5
14
front/e2e/app.e2e-spec.ts
Normal file
14
front/e2e/app.e2e-spec.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { AppPage } from './app.po';
|
||||||
|
|
||||||
|
describe('karideo App', () => {
|
||||||
|
let page: AppPage;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
page = new AppPage();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display welcome message', () => {
|
||||||
|
page.navigateTo();
|
||||||
|
expect(page.getParagraphText()).toEqual('Welcome to app!');
|
||||||
|
});
|
||||||
|
});
|
11
front/e2e/app.po.ts
Normal file
11
front/e2e/app.po.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { browser, by, element } from 'protractor';
|
||||||
|
|
||||||
|
export class AppPage {
|
||||||
|
navigateTo() {
|
||||||
|
return browser.get('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
getParagraphText() {
|
||||||
|
return element(by.css('app-root h1')).getText();
|
||||||
|
}
|
||||||
|
}
|
14
front/e2e/tsconfig.e2e.json
Normal file
14
front/e2e/tsconfig.e2e.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "../out-tsc/e2e",
|
||||||
|
"baseUrl": "./",
|
||||||
|
"module": "commonjs",
|
||||||
|
"target": "es5",
|
||||||
|
"types": [
|
||||||
|
"jasmine",
|
||||||
|
"jasminewd2",
|
||||||
|
"node"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
33
front/karma.conf.js
Normal file
33
front/karma.conf.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Karma configuration file, see link for more information
|
||||||
|
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||||
|
|
||||||
|
module.exports = function (config) {
|
||||||
|
config.set({
|
||||||
|
basePath: '',
|
||||||
|
frameworks: ['jasmine', '@angular/cli'],
|
||||||
|
plugins: [
|
||||||
|
require('karma-jasmine'),
|
||||||
|
require('karma-chrome-launcher'),
|
||||||
|
require('karma-jasmine-html-reporter'),
|
||||||
|
require('karma-coverage-istanbul-reporter'),
|
||||||
|
require('@angular/cli/plugins/karma')
|
||||||
|
],
|
||||||
|
client:{
|
||||||
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||||
|
},
|
||||||
|
coverageIstanbulReporter: {
|
||||||
|
reports: [ 'html', 'lcovonly' ],
|
||||||
|
fixWebpackSourcePaths: true
|
||||||
|
},
|
||||||
|
angularCli: {
|
||||||
|
environment: 'dev'
|
||||||
|
},
|
||||||
|
reporters: ['progress', 'kjhtml'],
|
||||||
|
port: 9876,
|
||||||
|
colors: true,
|
||||||
|
logLevel: config.LOG_INFO,
|
||||||
|
autoWatch: true,
|
||||||
|
browsers: ['Chrome'],
|
||||||
|
singleRun: false
|
||||||
|
});
|
||||||
|
};
|
13309
front/package-lock.json
generated
Normal file
13309
front/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
48
front/package.json
Normal file
48
front/package.json
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"name": "karideo",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"ng": "ng",
|
||||||
|
"start": "ng serve",
|
||||||
|
"build": "ng build --prod",
|
||||||
|
"test": "ng test",
|
||||||
|
"lint": "ng lint",
|
||||||
|
"e2e": "ng e2e"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@angular/animations": "^5.2.0",
|
||||||
|
"@angular/common": "^5.2.0",
|
||||||
|
"@angular/compiler": "^5.2.0",
|
||||||
|
"@angular/core": "^5.2.0",
|
||||||
|
"@angular/forms": "^5.2.0",
|
||||||
|
"@angular/http": "^5.2.0",
|
||||||
|
"@angular/platform-browser": "^5.2.0",
|
||||||
|
"@angular/platform-browser-dynamic": "^5.2.0",
|
||||||
|
"@angular/router": "^5.2.0",
|
||||||
|
"core-js": "^2.4.1",
|
||||||
|
"rxjs": "^5.5.6",
|
||||||
|
"zone.js": "^0.8.19"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@angular/cli": "~1.7.3",
|
||||||
|
"@angular/compiler-cli": "^5.2.0",
|
||||||
|
"@angular/language-service": "^5.2.0",
|
||||||
|
"@types/jasmine": "~2.8.3",
|
||||||
|
"@types/jasminewd2": "~2.0.2",
|
||||||
|
"@types/node": "~6.0.60",
|
||||||
|
"codelyzer": "^4.0.1",
|
||||||
|
"jasmine-core": "~2.8.0",
|
||||||
|
"jasmine-spec-reporter": "~4.2.1",
|
||||||
|
"karma": "~2.0.0",
|
||||||
|
"karma-chrome-launcher": "~2.2.0",
|
||||||
|
"karma-coverage-istanbul-reporter": "^1.2.1",
|
||||||
|
"karma-jasmine": "~1.1.0",
|
||||||
|
"karma-jasmine-html-reporter": "^0.2.2",
|
||||||
|
"protractor": "~5.1.2",
|
||||||
|
"ts-node": "~4.1.0",
|
||||||
|
"tslint": "~5.9.1",
|
||||||
|
"typescript": "~2.5.3"
|
||||||
|
}
|
||||||
|
}
|
28
front/protractor.conf.js
Normal file
28
front/protractor.conf.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Protractor configuration file, see link for more information
|
||||||
|
// https://github.com/angular/protractor/blob/master/lib/config.ts
|
||||||
|
|
||||||
|
const { SpecReporter } = require('jasmine-spec-reporter');
|
||||||
|
|
||||||
|
exports.config = {
|
||||||
|
allScriptsTimeout: 11000,
|
||||||
|
specs: [
|
||||||
|
'./e2e/**/*.e2e-spec.ts'
|
||||||
|
],
|
||||||
|
capabilities: {
|
||||||
|
'browserName': 'chrome'
|
||||||
|
},
|
||||||
|
directConnect: true,
|
||||||
|
baseUrl: 'http://localhost:4200/',
|
||||||
|
framework: 'jasmine',
|
||||||
|
jasmineNodeOpts: {
|
||||||
|
showColors: true,
|
||||||
|
defaultTimeoutInterval: 30000,
|
||||||
|
print: function() {}
|
||||||
|
},
|
||||||
|
onPrepare() {
|
||||||
|
require('ts-node').register({
|
||||||
|
project: 'e2e/tsconfig.e2e.json'
|
||||||
|
});
|
||||||
|
jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
|
||||||
|
}
|
||||||
|
};
|
22
front/readme.md
Normal file
22
front/readme.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
|
||||||
|
|
||||||
|
Start the application:
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
upgrade package
|
||||||
|
```
|
||||||
|
npm audit fix
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
start the application:
|
||||||
|
```
|
||||||
|
npx ng serve
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
16
front/src/app/_animations/fade-in.animation.ts
Normal file
16
front/src/app/_animations/fade-in.animation.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { trigger, state, animate, transition, style } from '@angular/animations';
|
||||||
|
|
||||||
|
export const fadeInAnimation =
|
||||||
|
trigger('fadeInAnimation', [
|
||||||
|
// route 'enter' transition
|
||||||
|
transition(':enter', [
|
||||||
|
|
||||||
|
// styles at start of transition
|
||||||
|
style({ opacity: 0 }),
|
||||||
|
|
||||||
|
// animation and styles at end of transition
|
||||||
|
animate('.5s', style({ opacity: 1 }))
|
||||||
|
]),
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
2
front/src/app/_animations/index.ts
Normal file
2
front/src/app/_animations/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './fade-in.animation';
|
||||||
|
export * from './slide-in-out.animation';
|
51
front/src/app/_animations/slide-in-out.animation.ts
Normal file
51
front/src/app/_animations/slide-in-out.animation.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { trigger, state, animate, transition, style } from '@angular/animations';
|
||||||
|
|
||||||
|
export const slideInOutAnimation =
|
||||||
|
trigger('slideInOutAnimation', [
|
||||||
|
|
||||||
|
// end state styles for route container (host)
|
||||||
|
state('*', style({
|
||||||
|
// the view covers the whole screen with a semi tranparent background
|
||||||
|
position: 'fixed',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.8)'
|
||||||
|
})),
|
||||||
|
|
||||||
|
// route 'enter' transition
|
||||||
|
transition(':enter', [
|
||||||
|
|
||||||
|
// styles at start of transition
|
||||||
|
style({
|
||||||
|
// start with the content positioned off the right of the screen,
|
||||||
|
// -400% is required instead of -100% because the negative position adds to the width of the element
|
||||||
|
right: '-400%',
|
||||||
|
|
||||||
|
// start with background opacity set to 0 (invisible)
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0)'
|
||||||
|
}),
|
||||||
|
|
||||||
|
// animation and styles at end of transition
|
||||||
|
animate('.5s ease-in-out', style({
|
||||||
|
// transition the right position to 0 which slides the content into view
|
||||||
|
right: 0,
|
||||||
|
|
||||||
|
// transition the background opacity to 0.8 to fade it in
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.8)'
|
||||||
|
}))
|
||||||
|
]),
|
||||||
|
|
||||||
|
// route 'leave' transition
|
||||||
|
transition(':leave', [
|
||||||
|
// animation and styles at end of transition
|
||||||
|
animate('.5s ease-in-out', style({
|
||||||
|
// transition the right position to -400% which slides the content out of view
|
||||||
|
right: '-400%',
|
||||||
|
|
||||||
|
// transition the background opacity to 0 to fade it out
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0)'
|
||||||
|
}))
|
||||||
|
])
|
||||||
|
]);
|
42
front/src/app/app-routing.module.ts
Normal file
42
front/src/app/app-routing.module.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
import { ModuleWithProviders } from '@angular/core';
|
||||||
|
|
||||||
|
import { HomeComponent } from './home/home.component';
|
||||||
|
import { TypeDetailComponent } from './type-detail/type-detail.component';
|
||||||
|
import { LoginComponent } from './login/login.component';
|
||||||
|
import { SignUpComponent } from './sign-up/sign-up.component';
|
||||||
|
import { SettingsComponent } from './settings/settings.component';
|
||||||
|
//import { HelpComponent } from './help/help.component';
|
||||||
|
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{ path: '', redirectTo: '/home', pathMatch: 'full'},
|
||||||
|
{ path: 'home', component: HomeComponent },
|
||||||
|
{ path: 'type/:id', component: TypeDetailComponent },
|
||||||
|
{ path: 'login', component: LoginComponent },
|
||||||
|
{ path: 'signup', component: SignUpComponent },
|
||||||
|
{ path: 'settings', component: SettingsComponent },
|
||||||
|
/*{ path: 'help', component: HelpComponent }*/
|
||||||
|
];
|
||||||
|
/*
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forRoot(routes)
|
||||||
|
],
|
||||||
|
exports: [
|
||||||
|
RouterModule
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
export class AppRoutingModule {}
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const routing: ModuleWithProviders = RouterModule.forRoot(routes);
|
||||||
|
|
10
front/src/app/app.component.html
Normal file
10
front/src/app/app.component.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
<!-- exercice section -->
|
||||||
|
<app-top-menu></app-top-menu>
|
||||||
|
<!--
|
||||||
|
<div class="main-content" ng-include="currentDisplay" ng-if="currentDisplay != ''"></div>
|
||||||
|
<div class="main-modal" ng-include="currentModal" ng-if="currentModal != ''" ></div> <!-- (click)="onOutModal()" -->
|
||||||
|
-->
|
||||||
|
<div class="main-content">
|
||||||
|
<router-outlet></router-outlet>
|
||||||
|
</div>
|
42
front/src/app/app.component.less
Normal file
42
front/src/app/app.component.less
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#create-exercice-button {
|
||||||
|
position: fixed;
|
||||||
|
display: block;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin-right: 40px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
z-index: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
#save-exercice-button {
|
||||||
|
position: fixed;
|
||||||
|
display: block;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin-right: 110px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
z-index: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: ~"calc(100% - 56px)";
|
||||||
|
top: 56px;
|
||||||
|
left: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: block;
|
||||||
|
position: fixed;
|
||||||
|
//background-color:#FF0;
|
||||||
|
.main-reduce {
|
||||||
|
width: 80%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0px 10% 0px 10%;
|
||||||
|
display: block;
|
||||||
|
overflow-y:scroll;
|
||||||
|
}
|
||||||
|
}
|
27
front/src/app/app.component.spec.ts
Normal file
27
front/src/app/app.component.spec.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { TestBed, async } from '@angular/core/testing';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
describe('AppComponent', () => {
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent
|
||||||
|
],
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
it('should create the app', async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.debugElement.componentInstance;
|
||||||
|
expect(app).toBeTruthy();
|
||||||
|
}));
|
||||||
|
it(`should have as title 'app'`, async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
const app = fixture.debugElement.componentInstance;
|
||||||
|
expect(app.title).toEqual('app');
|
||||||
|
}));
|
||||||
|
it('should render title in a h1 tag', async(() => {
|
||||||
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
|
fixture.detectChanges();
|
||||||
|
const compiled = fixture.debugElement.nativeElement;
|
||||||
|
expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
|
||||||
|
}));
|
||||||
|
});
|
54
front/src/app/app.component.ts
Normal file
54
front/src/app/app.component.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, OnInit} from '@angular/core';
|
||||||
|
import { UserService } from './user.service';
|
||||||
|
import { SessionService } from './session.service';
|
||||||
|
import { CookiesService } from './cookies.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: [
|
||||||
|
'./app.component.less',
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class AppComponent implements OnInit {
|
||||||
|
title = 'Karideo';
|
||||||
|
constructor(private cookiesService: CookiesService,
|
||||||
|
private userService: UserService,
|
||||||
|
private sessionService: SessionService) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
let login = this.cookiesService.get("yota-login");
|
||||||
|
let password = this.cookiesService.get("yota-password");
|
||||||
|
if ( login != ""
|
||||||
|
&& password != ""
|
||||||
|
&& password.length > 40) {
|
||||||
|
console.log("Get previous connection ... " + login + ":xxxxxx");
|
||||||
|
let self = this;
|
||||||
|
this.userService.loginSha(login, password)
|
||||||
|
.then(function(response) {
|
||||||
|
console.log("auto log ==> OK");
|
||||||
|
self.sessionService.create(response['sessionId'],
|
||||||
|
response['login'],
|
||||||
|
response['email'],
|
||||||
|
response['role'],
|
||||||
|
response['avatar']);
|
||||||
|
//self.router.navigate(['home']);
|
||||||
|
}).catch(function(response) {
|
||||||
|
console.log("auto log ==> Error");
|
||||||
|
self.cookiesService.remove("yota-login");
|
||||||
|
self.cookiesService.remove("yota-password");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
81
front/src/app/app.module.ts
Normal file
81
front/src/app/app.module.ts
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { RouterModule } from '@angular/router';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
|
||||||
|
import { routing } from './app-routing.module';
|
||||||
|
|
||||||
|
|
||||||
|
import { CardListComponent } from './card-list/card-list.component';
|
||||||
|
import { AuthService } from './auth.service';
|
||||||
|
import { TopMenuComponent } from './top-menu/top-menu.component';
|
||||||
|
import { ElementGroupComponent } from './element-group/element-group.component';
|
||||||
|
import { ElementSaisonComponent } from './element-saison/element-saison.component';
|
||||||
|
import { ElementVideoComponent } from './element-video/element-video.component';
|
||||||
|
import { LoginComponent } from './login/login.component';
|
||||||
|
import { SignUpComponent } from './sign-up/sign-up.component';
|
||||||
|
import { ValidateEmailComponent } from './validate-email/validate-email.component';
|
||||||
|
import { HomeComponent } from './home/home.component';
|
||||||
|
import { TypeDetailComponent } from './type-detail/type-detail.component';
|
||||||
|
import { SettingsComponent } from './settings/settings.component';
|
||||||
|
import { ErrorViewerComponent } from './error-viewer/error-viewer.component';
|
||||||
|
import { ErrorComponent } from './error/error.component';
|
||||||
|
import { CookiesService } from './cookies.service';
|
||||||
|
import { HttpWrapperService } from './http-wrapper.service';
|
||||||
|
import { UserService } from './user.service';
|
||||||
|
import { GroupService } from './group.service';
|
||||||
|
import { TypeService } from './type.service';
|
||||||
|
import { SaisonService } from './saison.service';
|
||||||
|
import { VideoService } from './video.service';
|
||||||
|
import { SessionService } from './session.service';
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent,
|
||||||
|
TopMenuComponent,
|
||||||
|
ElementGroupComponent,
|
||||||
|
ElementSaisonComponent,
|
||||||
|
ElementVideoComponent,
|
||||||
|
LoginComponent,
|
||||||
|
SignUpComponent,
|
||||||
|
ValidateEmailComponent,
|
||||||
|
HomeComponent,
|
||||||
|
TypeDetailComponent,
|
||||||
|
SettingsComponent,
|
||||||
|
ErrorViewerComponent,
|
||||||
|
ErrorComponent
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
RouterModule,
|
||||||
|
routing,
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
HttpClientModule
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
HttpWrapperService,
|
||||||
|
AuthService,
|
||||||
|
SessionService,
|
||||||
|
CookiesService,
|
||||||
|
UserService,
|
||||||
|
TypeService,
|
||||||
|
GroupService,
|
||||||
|
SaisonService,
|
||||||
|
VideoService
|
||||||
|
],
|
||||||
|
bootstrap: [
|
||||||
|
AppComponent
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class AppModule { }
|
15
front/src/app/auth.service.spec.ts
Normal file
15
front/src/app/auth.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { AuthService } from './auth.service';
|
||||||
|
|
||||||
|
describe('AuthService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [AuthService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([AuthService], (service: AuthService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
15
front/src/app/auth.service.ts
Normal file
15
front/src/app/auth.service.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AuthService {
|
||||||
|
constructor() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
3
front/src/app/card-list/card-list.component.html
Normal file
3
front/src/app/card-list/card-list.component.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<p>
|
||||||
|
card-list works!
|
||||||
|
</p>
|
21
front/src/app/card-list/card-list.component.less
Normal file
21
front/src/app/card-list/card-list.component.less
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
.main-content {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: ~"calc(100% - 56px)";
|
||||||
|
top: 56px;
|
||||||
|
left: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: block;
|
||||||
|
position: fixed;
|
||||||
|
background-color:#FF0;
|
||||||
|
.main-reduce {
|
||||||
|
width: 80%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0px 10% 0px 10%;
|
||||||
|
display: block;
|
||||||
|
overflow-y:scroll;
|
||||||
|
}
|
||||||
|
}
|
25
front/src/app/card-list/card-list.component.spec.ts
Normal file
25
front/src/app/card-list/card-list.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CardListComponent } from './card-list.component';
|
||||||
|
|
||||||
|
describe('CardListComponent', () => {
|
||||||
|
let component: CardListComponent;
|
||||||
|
let fixture: ComponentFixture<CardListComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ CardListComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CardListComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
15
front/src/app/card-list/card-list.component.ts
Normal file
15
front/src/app/card-list/card-list.component.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-card-list',
|
||||||
|
templateUrl: './card-list.component.html',
|
||||||
|
styleUrls: ['./card-list.component.less']
|
||||||
|
})
|
||||||
|
export class CardListComponent implements OnInit {
|
||||||
|
//@Input() cards: Array<any>;
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
front/src/app/cookies.service.spec.ts
Normal file
15
front/src/app/cookies.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { CookiesService } from './cookies.service';
|
||||||
|
|
||||||
|
describe('CookiesService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [CookiesService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([CookiesService], (service: CookiesService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
46
front/src/app/cookies.service.ts
Normal file
46
front/src/app/cookies.service.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CookiesService {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
set(cname, cvalue, exdays) {
|
||||||
|
if (this.get(cname) != "") {
|
||||||
|
// reset previous cookies...
|
||||||
|
document.cookie = cname + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/";
|
||||||
|
}
|
||||||
|
let d = new Date();
|
||||||
|
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
|
||||||
|
let expires = "expires="+d.toUTCString();
|
||||||
|
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(cname) {
|
||||||
|
this.set(cname, "", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
get(cname) {
|
||||||
|
let name = cname + "=";
|
||||||
|
let ca = document.cookie.split(';');
|
||||||
|
for(let i = 0; i < ca.length; i++) {
|
||||||
|
let c = ca[i];
|
||||||
|
while (c.charAt(0) == ' ') {
|
||||||
|
c = c.substring(1);
|
||||||
|
}
|
||||||
|
if (c.indexOf(name) == 0) {
|
||||||
|
return c.substring(name.length, c.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
3
front/src/app/element-group/element-group.component.html
Normal file
3
front/src/app/element-group/element-group.component.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<div>
|
||||||
|
{{name}}
|
||||||
|
</div>
|
25
front/src/app/element-group/element-group.component.spec.ts
Normal file
25
front/src/app/element-group/element-group.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ElementGroupComponent } from './top-menu.component';
|
||||||
|
|
||||||
|
describe('ElementGroupComponent', () => {
|
||||||
|
let component: ElementGroupComponent;
|
||||||
|
let fixture: ComponentFixture<ElementGroupComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ElementGroupComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ElementGroupComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
46
front/src/app/element-group/element-group.component.ts
Normal file
46
front/src/app/element-group/element-group.component.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
import { Injectable, Component, OnInit, Input } from '@angular/core';
|
||||||
|
|
||||||
|
//import { AppRoutingModule } from "../app-routing.module";
|
||||||
|
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
import { ActivatedRoute, Params } from '@angular/router';
|
||||||
|
import { GroupService } from '../group.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-element-group',
|
||||||
|
templateUrl: './element-group.component.html',
|
||||||
|
styleUrls: ['./element-group.component.less']
|
||||||
|
})
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ElementGroupComponent implements OnInit {
|
||||||
|
// input parameters
|
||||||
|
@Input() id_group:number = -1;
|
||||||
|
@Input() id_type:number = -1;
|
||||||
|
|
||||||
|
error:string = ""
|
||||||
|
name:string = "plouf"
|
||||||
|
|
||||||
|
constructor(private router: Router,
|
||||||
|
private groupService: GroupService) {
|
||||||
|
|
||||||
|
}
|
||||||
|
ngOnInit() {
|
||||||
|
this.name = "ll " + this.id_type + "+" + this.id_group
|
||||||
|
let self = this;
|
||||||
|
console.log("get parameter id: " + this.id_type);
|
||||||
|
this.groupService.get(this.id_group)
|
||||||
|
.then(function(response) {
|
||||||
|
self.error = "";
|
||||||
|
self.name = response.name
|
||||||
|
}).catch(function(response) {
|
||||||
|
self.error = "Can not get the data";
|
||||||
|
self.name = ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
<div>
|
||||||
|
Saison {{numberSaison}}
|
||||||
|
</div>
|
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ElementSaisonComponent } from './top-menu.component';
|
||||||
|
|
||||||
|
describe('ElementSaisonComponent', () => {
|
||||||
|
let component: ElementSaisonComponent;
|
||||||
|
let fixture: ComponentFixture<ElementSaisonComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ElementSaisonComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ElementSaisonComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
43
front/src/app/element-saison/element-saison.component.ts
Normal file
43
front/src/app/element-saison/element-saison.component.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
import { Injectable, Component, OnInit, Input } from '@angular/core';
|
||||||
|
|
||||||
|
//import { AppRoutingModule } from "../app-routing.module";
|
||||||
|
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
import { ActivatedRoute, Params } from '@angular/router';
|
||||||
|
import { SaisonService } from '../saison.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-element-saison',
|
||||||
|
templateUrl: './element-saison.component.html',
|
||||||
|
styleUrls: ['./element-saison.component.less']
|
||||||
|
})
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ElementSaisonComponent implements OnInit {
|
||||||
|
// input parameters
|
||||||
|
@Input() id_saison:number = -1;
|
||||||
|
|
||||||
|
error:string = ""
|
||||||
|
numberSaison:number = -1
|
||||||
|
constructor(private router: Router,
|
||||||
|
private saisonService: SaisonService) {
|
||||||
|
|
||||||
|
}
|
||||||
|
ngOnInit() {
|
||||||
|
let self = this;
|
||||||
|
console.log("get saison properties id: " + this.id_saison);
|
||||||
|
this.saisonService.get(this.id_saison)
|
||||||
|
.then(function(response) {
|
||||||
|
self.error = "";
|
||||||
|
self.numberSaison = response.number
|
||||||
|
}).catch(function(response) {
|
||||||
|
self.error = "Can not get the data";
|
||||||
|
self.numberSaison = -1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
4
front/src/app/element-type/element-type.component.html
Normal file
4
front/src/app/element-type/element-type.component.html
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<div>
|
||||||
|
{{name}}<br/>
|
||||||
|
{{description}}
|
||||||
|
</div>
|
2
front/src/app/element-type/element-type.component.less
Normal file
2
front/src/app/element-type/element-type.component.less
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
|
25
front/src/app/element-type/element-type.component.spec.ts
Normal file
25
front/src/app/element-type/element-type.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ElementTypeComponent } from './top-menu.component';
|
||||||
|
|
||||||
|
describe('ElementTypeComponent', () => {
|
||||||
|
let component: ElementTypeComponent;
|
||||||
|
let fixture: ComponentFixture<ElementTypeComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ElementTypeComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ElementTypeComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
47
front/src/app/element-type/element-type.component.ts
Normal file
47
front/src/app/element-type/element-type.component.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
import { Injectable, Component, OnInit, Input } from '@angular/core';
|
||||||
|
|
||||||
|
//import { AppRoutingModule } from "../app-routing.module";
|
||||||
|
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
import { ActivatedRoute, Params } from '@angular/router';
|
||||||
|
import { TypeService } from '../type.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-element-type',
|
||||||
|
templateUrl: './element-type.component.html',
|
||||||
|
styleUrls: ['./element-type.component.less']
|
||||||
|
})
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ElementTypeComponent implements OnInit {
|
||||||
|
// input parameters
|
||||||
|
@Input() id_type:number = -1;
|
||||||
|
|
||||||
|
error:string = ""
|
||||||
|
name:string = ""
|
||||||
|
description:string = ""
|
||||||
|
constructor(private router: Router,
|
||||||
|
private typeService: TypeService) {
|
||||||
|
|
||||||
|
}
|
||||||
|
ngOnInit() {
|
||||||
|
this.name = "ll " + this.id_type
|
||||||
|
let self = this;
|
||||||
|
console.log("get parameter id: " + this.id_type);
|
||||||
|
this.typeService.get(this.id_type)
|
||||||
|
.then(function(response) {
|
||||||
|
self.error = "";
|
||||||
|
self.name = response.name
|
||||||
|
self.description = response.description
|
||||||
|
}).catch(function(response) {
|
||||||
|
self.error = "Can not get the data";
|
||||||
|
self.name = ""
|
||||||
|
self.description = ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
3
front/src/app/element-video/element-video.component.html
Normal file
3
front/src/app/element-video/element-video.component.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<div>
|
||||||
|
{{name}}
|
||||||
|
</div>
|
3
front/src/app/element-video/element-video.component.less
Normal file
3
front/src/app/element-video/element-video.component.less
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
25
front/src/app/element-video/element-video.component.spec.ts
Normal file
25
front/src/app/element-video/element-video.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ElementVideoComponent } from './top-menu.component';
|
||||||
|
|
||||||
|
describe('ElementVideoComponent', () => {
|
||||||
|
let component: ElementVideoComponent;
|
||||||
|
let fixture: ComponentFixture<ElementVideoComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ElementVideoComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ElementVideoComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
67
front/src/app/element-video/element-video.component.ts
Normal file
67
front/src/app/element-video/element-video.component.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
import { Injectable, Component, OnInit, Input } from '@angular/core';
|
||||||
|
|
||||||
|
//import { AppRoutingModule } from "../app-routing.module";
|
||||||
|
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
import { ActivatedRoute, Params } from '@angular/router';
|
||||||
|
import { VideoService } from '../video.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-element-video',
|
||||||
|
templateUrl: './element-video.component.html',
|
||||||
|
styleUrls: ['./element-video.component.less']
|
||||||
|
})
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ElementVideoComponent implements OnInit {
|
||||||
|
// input parameters
|
||||||
|
@Input() id_video:number = -1;
|
||||||
|
|
||||||
|
error:string = ""
|
||||||
|
|
||||||
|
name:string = ""
|
||||||
|
description:string = ""
|
||||||
|
episode:number = undefined
|
||||||
|
group_id:number = undefined
|
||||||
|
saison_id:number = undefined
|
||||||
|
sha512:string = ""
|
||||||
|
time:number = undefined
|
||||||
|
type_id:number = undefined
|
||||||
|
generated_name:string = ""
|
||||||
|
constructor(private router: Router,
|
||||||
|
private videoService: VideoService) {
|
||||||
|
|
||||||
|
}
|
||||||
|
ngOnInit() {
|
||||||
|
this.name = "ll " + this.id_video
|
||||||
|
let self = this;
|
||||||
|
console.log("get parameter id: " + this.id_video);
|
||||||
|
this.videoService.get(this.id_video)
|
||||||
|
.then(function(response) {
|
||||||
|
self.error = "";
|
||||||
|
self.name = response.name
|
||||||
|
self.description = response.description
|
||||||
|
self.episode = response.episode
|
||||||
|
self.group_id = response.group_id
|
||||||
|
self.saison_id = response.saison_id
|
||||||
|
self.sha512 = response.sha512
|
||||||
|
self.time = response.time
|
||||||
|
self.generated_name = response.generated_name
|
||||||
|
}).catch(function(response) {
|
||||||
|
self.error = "Can not get the data";
|
||||||
|
self.name = ""
|
||||||
|
self.description = ""
|
||||||
|
self.episode = undefined
|
||||||
|
self.group_id = undefined
|
||||||
|
self.saison_id = undefined
|
||||||
|
self.sha512 = ""
|
||||||
|
self.time = undefined
|
||||||
|
self.generated_name = ""
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
3
front/src/app/error-viewer/error-viewer.component.html
Normal file
3
front/src/app/error-viewer/error-viewer.component.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<p>
|
||||||
|
error-viewer works!
|
||||||
|
</p>
|
25
front/src/app/error-viewer/error-viewer.component.spec.ts
Normal file
25
front/src/app/error-viewer/error-viewer.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ErrorViewerComponent } from './error-viewer.component';
|
||||||
|
|
||||||
|
describe('ErrorViewerComponent', () => {
|
||||||
|
let component: ErrorViewerComponent;
|
||||||
|
let fixture: ComponentFixture<ErrorViewerComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ErrorViewerComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ErrorViewerComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
21
front/src/app/error-viewer/error-viewer.component.ts
Normal file
21
front/src/app/error-viewer/error-viewer.component.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-error-viewer',
|
||||||
|
templateUrl: './error-viewer.component.html',
|
||||||
|
styleUrls: ['./error-viewer.component.less']
|
||||||
|
})
|
||||||
|
export class ErrorViewerComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
3
front/src/app/error/error.component.html
Normal file
3
front/src/app/error/error.component.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<p>
|
||||||
|
error works!
|
||||||
|
</p>
|
0
front/src/app/error/error.component.less
Normal file
0
front/src/app/error/error.component.less
Normal file
25
front/src/app/error/error.component.spec.ts
Normal file
25
front/src/app/error/error.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ErrorComponent } from './error.component';
|
||||||
|
|
||||||
|
describe('ErrorComponent', () => {
|
||||||
|
let component: ErrorComponent;
|
||||||
|
let fixture: ComponentFixture<ErrorComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ErrorComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ErrorComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
21
front/src/app/error/error.component.ts
Normal file
21
front/src/app/error/error.component.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-error',
|
||||||
|
templateUrl: './error.component.html',
|
||||||
|
styleUrls: ['./error.component.less']
|
||||||
|
})
|
||||||
|
export class ErrorComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
front/src/app/group.service.spec.ts
Normal file
15
front/src/app/group.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { GroupService } from './group.service';
|
||||||
|
|
||||||
|
describe('GroupService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [GroupService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([GroupService], (service: GroupService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
39
front/src/app/group.service.ts
Normal file
39
front/src/app/group.service.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpWrapperService } from 'app/http-wrapper.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class GroupService {
|
||||||
|
// 0: Not hide password; 1 hide password;
|
||||||
|
private identificationVersion: number = 1;
|
||||||
|
|
||||||
|
constructor(private http: HttpWrapperService) {
|
||||||
|
console.log("Start GroupService");
|
||||||
|
}
|
||||||
|
|
||||||
|
get(_id:number):any {
|
||||||
|
console.log("Get All data from types");
|
||||||
|
const httpOption = { 'Content-Type': 'application/json' };
|
||||||
|
let url = "group/" + _id;
|
||||||
|
console.log("call GET " + url);
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.http.get(url, httpOption, {})
|
||||||
|
.then(function(response: any) {
|
||||||
|
if (response.status == 200) {
|
||||||
|
resolve(response.data);
|
||||||
|
console.log("get data from type : " + response.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reject("An error occured");
|
||||||
|
}, function(response: any) {
|
||||||
|
if (typeof response.data === 'undefined') {
|
||||||
|
reject("return ERROR undefined");
|
||||||
|
} else {
|
||||||
|
reject("return ERROR " + JSON.stringify(response.data, null, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
3
front/src/app/help/help.component.html
Normal file
3
front/src/app/help/help.component.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<p>
|
||||||
|
help works!
|
||||||
|
</p>
|
0
front/src/app/help/help.component.less
Normal file
0
front/src/app/help/help.component.less
Normal file
25
front/src/app/help/help.component.spec.ts
Normal file
25
front/src/app/help/help.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HelpComponent } from './help.component';
|
||||||
|
|
||||||
|
describe('HelpComponent', () => {
|
||||||
|
let component: HelpComponent;
|
||||||
|
let fixture: ComponentFixture<HelpComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ HelpComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(HelpComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
15
front/src/app/help/help.component.ts
Normal file
15
front/src/app/help/help.component.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-help',
|
||||||
|
templateUrl: './help.component.html',
|
||||||
|
styleUrls: ['./help.component.less']
|
||||||
|
})
|
||||||
|
export class HelpComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
front/src/app/home/home.component.html
Normal file
11
front/src/app/home/home.component.html
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<div class="main-reduce">
|
||||||
|
<div class="fill-all">
|
||||||
|
<div *ngFor="let data of data_list">
|
||||||
|
<div class="item" (click)="onSelectType(data.id)">
|
||||||
|
<!--<img src="../../assets/images/type/{{data.id}}.svg" width="45px"/><br/>-->
|
||||||
|
{{data.name}}
|
||||||
|
<!--{{data.description}}-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
55
front/src/app/home/home.component.less
Normal file
55
front/src/app/home/home.component.less
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
.fill-all{
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
border:0;
|
||||||
|
background-color:#0F0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
font-size: 20px;
|
||||||
|
height: 21%;
|
||||||
|
width: 23%;
|
||||||
|
margin: 1%;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
//box-shadow: 0 1px 1.5px 0 rgba(0,0,0,.12),0 1px 1px 0 rgba(0,0,0,.24);
|
||||||
|
box-shadow: 0px 2px 4px 0 rgba(0, 0, 0, 0.6);
|
||||||
|
line-height: normal;
|
||||||
|
border: none;
|
||||||
|
font-family: "Roboto","Helvetica","Arial",sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0;
|
||||||
|
will-change: box-shadow;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
transition-duration: 0.4s;
|
||||||
|
float:left;
|
||||||
|
display:block;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #F00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-icons {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-icons {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: ~"translate(-12px,-12px)";
|
||||||
|
line-height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
}
|
||||||
|
}
|
25
front/src/app/home/home.component.spec.ts
Normal file
25
front/src/app/home/home.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HomeComponent } from './home.component';
|
||||||
|
|
||||||
|
describe('HomeComponent', () => {
|
||||||
|
let component: HomeComponent;
|
||||||
|
let fixture: ComponentFixture<HomeComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ HomeComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(HomeComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
46
front/src/app/home/home.component.ts
Normal file
46
front/src/app/home/home.component.ts
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
import { fadeInAnimation } from '../_animations/index';
|
||||||
|
|
||||||
|
import { TypeService } from '../type.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-home',
|
||||||
|
templateUrl: './home.component.html',
|
||||||
|
styleUrls: ['./home.component.less'],
|
||||||
|
animations: [fadeInAnimation],
|
||||||
|
host: { '[@fadeInAnimation]': '' }
|
||||||
|
})
|
||||||
|
export class HomeComponent implements OnInit {
|
||||||
|
data_list = [{name:"lkjlkjlkj"}, {name:"lkjlkj222lkj"}, {name:"lkjlk333jlkj"}];
|
||||||
|
error = "";
|
||||||
|
constructor(private router: Router,
|
||||||
|
private locate: Location,
|
||||||
|
private typeService: TypeService) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
let self = this
|
||||||
|
this.typeService.getData()
|
||||||
|
.then(function(response) {
|
||||||
|
self.error = "";
|
||||||
|
self.data_list = response
|
||||||
|
}).catch(function(response) {
|
||||||
|
self.error = "Wrong e-mail/login or password";
|
||||||
|
self.data_list = []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onSelectType(_idSelected: number):void {
|
||||||
|
//this.router.navigate(['type/', { id: _idSelected} ]);
|
||||||
|
this.router.navigate(['type/' + _idSelected ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
front/src/app/http-wrapper.service.spec.ts
Normal file
15
front/src/app/http-wrapper.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { HttpWrapperService } from './http-wrapper.service';
|
||||||
|
|
||||||
|
describe('HttpWrapperService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [HttpWrapperService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([HttpWrapperService], (service: HttpWrapperService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
85
front/src/app/http-wrapper.service.ts
Normal file
85
front/src/app/http-wrapper.service.ts
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||||
|
import { catchError, map, tap } from 'rxjs/operators';
|
||||||
|
|
||||||
|
import { createRESTCall } from 'environments/environment';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class HttpWrapperService {
|
||||||
|
private displayReturn:boolean = true;
|
||||||
|
constructor(private http: HttpClient) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
get(_uriRest:string, _headerOption:any, _params:any) {
|
||||||
|
let connectionAdresse = createRESTCall(_uriRest, {});
|
||||||
|
let config = {
|
||||||
|
params: _params,
|
||||||
|
headers: new HttpHeaders(_headerOption)
|
||||||
|
};
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (this.displayReturn == true) {
|
||||||
|
console.log("call GET " + connectionAdresse + " params=" + JSON.stringify(_params, null, 2));
|
||||||
|
}
|
||||||
|
let request = this.http.get<any>(connectionAdresse, config);
|
||||||
|
let self = this;
|
||||||
|
request.subscribe((res: any) => {
|
||||||
|
if (self.displayReturn == true) {
|
||||||
|
console.log("!! data " + JSON.stringify(res, null, 2));
|
||||||
|
}
|
||||||
|
if (res) {
|
||||||
|
if (res.httpCode) {
|
||||||
|
resolve({status:res.httpCode, data:res});
|
||||||
|
} else {
|
||||||
|
resolve({status:200, data:res});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resolve({status:200, data:""});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
if (self.displayReturn == true) {
|
||||||
|
console.log("an error occured status: " + error.status);
|
||||||
|
console.log("answer: " + JSON.stringify(error, null, 2));
|
||||||
|
}
|
||||||
|
reject({status:error.status, data:error.error});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
post(_uriRest:string, _headerOption:any, _data:any) {
|
||||||
|
let connectionAdresse = createRESTCall(_uriRest, {});
|
||||||
|
const httpOption = {
|
||||||
|
headers: new HttpHeaders(_headerOption)
|
||||||
|
};
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (this.displayReturn == true) {
|
||||||
|
console.log("call POST " + connectionAdresse + " data=" + JSON.stringify(_data, null, 2));
|
||||||
|
}
|
||||||
|
let request = this.http.post<any>(connectionAdresse, _data, httpOption);
|
||||||
|
let self = this;
|
||||||
|
request.subscribe((res: any) => {
|
||||||
|
if (self.displayReturn == true) {
|
||||||
|
console.log("!! data " + JSON.stringify(res, null, 2));
|
||||||
|
}
|
||||||
|
if (res) {
|
||||||
|
if (res.httpCode) {
|
||||||
|
resolve({status:res.httpCode, data:res});
|
||||||
|
} else {
|
||||||
|
resolve({status:200, data:res});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resolve({status:200, data:""});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
if (self.displayReturn == true) {
|
||||||
|
console.log("an error occured status: " + error.status);
|
||||||
|
console.log("answer: " + JSON.stringify(error, null, 2));
|
||||||
|
}
|
||||||
|
reject({status:error.status, data:error.error});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
41
front/src/app/login/login.component.html
Normal file
41
front/src/app/login/login.component.html
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<div class="full">
|
||||||
|
<div class="color-background-vignette container-global">
|
||||||
|
<div class="imgContainer">
|
||||||
|
<img src="assets/images/avatar_generic.svg" alt="Avatar" class="avatar"/>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<label for="login_field"><b>{{loginType}}</b></label>
|
||||||
|
<input id="username"
|
||||||
|
name="username"
|
||||||
|
type="text"
|
||||||
|
required=""
|
||||||
|
placeholder="Enter Username/e-mail"
|
||||||
|
[value]="login"
|
||||||
|
(input)="checkLogin($event.target.value)"
|
||||||
|
/>
|
||||||
|
<div class="error color-shadow-black" *ngIf="loginHelp">{{loginHelp}}</div>
|
||||||
|
<label for="password"><b>Password</b></label> <a class="forgot" href="#">Forgot password?</a>
|
||||||
|
<input type="password"
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
placeholder="Enter Password"
|
||||||
|
required=""
|
||||||
|
[value]="password"
|
||||||
|
(input)="checkPassword($event.target.value)"
|
||||||
|
/>
|
||||||
|
<div class="error color-shadow-black" *ngIf="passHelp">{{passHelp}}</div>
|
||||||
|
<label class="container-checkbox">
|
||||||
|
Remember me
|
||||||
|
<input type="checkbox" ng-model="rememberMe"/>
|
||||||
|
<span class="checkmark"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<button class="button cancel color-button-cancel color-shadow-black" (click)="onCancel()">Cancel</button>
|
||||||
|
<button class="button login color-button-validate color-shadow-black" id="login-button" [disabled]="loginButtonDisabled" (click)="onLogin()" type="submit">Login</button>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
{{error}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
104
front/src/app/login/login.component.less
Normal file
104
front/src/app/login/login.component.less
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
|
||||||
|
.full{
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
right:0;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
border:0;
|
||||||
|
float:right;
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text], input[type=password] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 20px;
|
||||||
|
margin: 8px 0;
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.login {
|
||||||
|
margin: 2% 2%;
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel {
|
||||||
|
margin: 2% 2%;
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.imgContainer {
|
||||||
|
text-align: center;
|
||||||
|
margin: 15px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
img.avatar {
|
||||||
|
width: 150px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-global {
|
||||||
|
padding: 16px 32px 16px 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 16px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.psw {
|
||||||
|
float: right;
|
||||||
|
padding-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forgot {
|
||||||
|
color: #00B;
|
||||||
|
font-size: 14px;
|
||||||
|
float: right;
|
||||||
|
buttum: 0;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
.error {
|
||||||
|
background-color: #f44336;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 10;
|
||||||
|
display: block;
|
||||||
|
max-width: 450px;
|
||||||
|
padding: 5px 8px;
|
||||||
|
margin: 2px 0 0;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
&:after, &:before {
|
||||||
|
bottom: 100%;
|
||||||
|
left: 25px;
|
||||||
|
border: solid transparent;
|
||||||
|
content: " ";
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
border-bottom-color: #f44336;
|
||||||
|
border-width: 10px;
|
||||||
|
margin-left: -10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.container-global {
|
||||||
|
position:relative;
|
||||||
|
max-width:400px;
|
||||||
|
padding: 16px 32px 16px 32px;
|
||||||
|
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: ~"translate(-50%, -50%)";
|
||||||
|
box-shadow: 0px 8px 20px 0 rgba(0, 0, 0, 0.9);
|
||||||
|
}
|
25
front/src/app/login/login.component.spec.ts
Normal file
25
front/src/app/login/login.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { LoginComponent } from './login.component';
|
||||||
|
|
||||||
|
describe('LoginComponent', () => {
|
||||||
|
let component: LoginComponent;
|
||||||
|
let fixture: ComponentFixture<LoginComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ LoginComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(LoginComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
167
front/src/app/login/login.component.ts
Normal file
167
front/src/app/login/login.component.ts
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
import { fadeInAnimation } from '../_animations/index';
|
||||||
|
import { slideInOutAnimation } from '../_animations/index';
|
||||||
|
import { UserService } from '../user.service';
|
||||||
|
import { SessionService } from '../session.service';
|
||||||
|
import { CookiesService } from '../cookies.service';
|
||||||
|
|
||||||
|
|
||||||
|
export let checkLoginValidity = function(_value:string):boolean {
|
||||||
|
let regexCheck = new RegExp("^[a-zA-Z0-9_\.-]+$");
|
||||||
|
if (regexCheck.test(_value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
export let checkEmailValidity = function(_value:string):boolean {
|
||||||
|
let regexCheck = new RegExp("^[a-zA-Z0-9_\.@-]+@[a-zA-Z0-9_\.-]+\\.[a-zA-Z]+$");
|
||||||
|
if (regexCheck.test(_value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
export let checkPasswordValidity = function(_value:string):boolean {
|
||||||
|
let regexCheck = new RegExp("^[a-zA-Z0-9_\.@ %:;,=}{\?\!\*\+\(\)\[\]\|&#%~°/\\\<\>-]+$");
|
||||||
|
if (regexCheck.test(_value)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
declare function SHA512(param1: any): any;
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-login',
|
||||||
|
templateUrl: './login.component.html',
|
||||||
|
styleUrls: ['./login.component.less'],
|
||||||
|
animations: [fadeInAnimation],
|
||||||
|
host: { '[@fadeInAnimation]': '' }
|
||||||
|
})
|
||||||
|
export class LoginComponent implements OnInit {
|
||||||
|
public loginOK:boolean = false;
|
||||||
|
public loginHelp:string = "";
|
||||||
|
public login:string = "";
|
||||||
|
public passOK:boolean = false;
|
||||||
|
public passHelp:string = "";
|
||||||
|
public password:string = "";
|
||||||
|
public loginButtonDisabled:boolean = true;
|
||||||
|
public error:string = "";
|
||||||
|
public loginType:string = "Username/E-mail";
|
||||||
|
|
||||||
|
public rememberMe:boolean = true;
|
||||||
|
|
||||||
|
constructor(private router: Router,
|
||||||
|
private locate: Location,
|
||||||
|
private cookiesService: CookiesService,
|
||||||
|
private userService: UserService,
|
||||||
|
private sessionService: SessionService) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
// TODO : If already loaded ==> jusp in the home page ...
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
updateButtonVisibility():void {
|
||||||
|
if ( this.loginOK == true
|
||||||
|
&& this.passOK == true) {
|
||||||
|
this.loginButtonDisabled = false;
|
||||||
|
} else {
|
||||||
|
this.loginButtonDisabled = true;
|
||||||
|
}
|
||||||
|
this.error = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
checkLogin(_newValue:string):void {
|
||||||
|
this.login = _newValue;
|
||||||
|
if (this.login == null) {
|
||||||
|
this.loginOK = false;
|
||||||
|
this.loginHelp = "";
|
||||||
|
this.updateButtonVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.login.length < 6) {
|
||||||
|
this.loginOK = false;
|
||||||
|
this.loginHelp = "Need 6 characters";
|
||||||
|
this.loginType = "Username/E-mail";
|
||||||
|
this.updateButtonVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (checkLoginValidity(this.login) == true) {
|
||||||
|
this.loginOK = true;
|
||||||
|
this.loginHelp = "";
|
||||||
|
this.loginType = "Username";
|
||||||
|
} else {
|
||||||
|
if (checkEmailValidity(this.login) == true) {
|
||||||
|
this.loginOK = true;
|
||||||
|
this.loginHelp = "";
|
||||||
|
this.loginType = "E-mail";
|
||||||
|
} else {
|
||||||
|
this.loginOK = false;
|
||||||
|
this.loginHelp = 'Not valid: characters, numbers, "_-." and email format: you@example.com';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.updateButtonVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkPassword(_newValue:string):void {
|
||||||
|
this.password = _newValue;
|
||||||
|
if (this.password == null) {
|
||||||
|
this.passOK = false;
|
||||||
|
this.passHelp = "";
|
||||||
|
this.updateButtonVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.password.length < 6) {
|
||||||
|
this.passOK = false;
|
||||||
|
this.passHelp = "Need 6 characters";
|
||||||
|
} else {
|
||||||
|
if (checkPasswordValidity(this.password) == true) {
|
||||||
|
this.passOK = true;
|
||||||
|
this.passHelp = "";
|
||||||
|
} else {
|
||||||
|
this.passOK = false;
|
||||||
|
this.passHelp = 'Not valid: characters, numbers and "_-:;.,?!*+=}{([|)]% @&~#/\<>"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.updateButtonVisibility();
|
||||||
|
}
|
||||||
|
onLogin():void {
|
||||||
|
this.sessionService.destroy();
|
||||||
|
let self = this
|
||||||
|
this.userService.login(this.login, this.password)
|
||||||
|
.then(function(response) {
|
||||||
|
self.error = "Login ...";
|
||||||
|
self.sessionService.create(response['sessionId'],
|
||||||
|
response['login'],
|
||||||
|
response['email'],
|
||||||
|
response['role'],
|
||||||
|
response['avatar']);
|
||||||
|
if (self.rememberMe == true) {
|
||||||
|
self.cookiesService.set("yota-login", response['login'], 365);
|
||||||
|
self.cookiesService.set("yota-password", SHA512(self.password), 365);
|
||||||
|
}
|
||||||
|
self.router.navigate(['home']);
|
||||||
|
}).catch(function(response) {
|
||||||
|
self.error = "Wrong e-mail/login or password";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onCancel():void {
|
||||||
|
console.log("onCancel ... '" + this.login + "':'" + this.password + "'");
|
||||||
|
this.locate.back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
15
front/src/app/saison.service.spec.ts
Normal file
15
front/src/app/saison.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { SaisonService } from './saison.service';
|
||||||
|
|
||||||
|
describe('SaisonService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [SaisonService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([SaisonService], (service: SaisonService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
39
front/src/app/saison.service.ts
Normal file
39
front/src/app/saison.service.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpWrapperService } from 'app/http-wrapper.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SaisonService {
|
||||||
|
// 0: Not hide password; 1 hide password;
|
||||||
|
private identificationVersion: number = 1;
|
||||||
|
|
||||||
|
constructor(private http: HttpWrapperService) {
|
||||||
|
console.log("Start SaisonService");
|
||||||
|
}
|
||||||
|
|
||||||
|
get(_id:number):any {
|
||||||
|
console.log("Get All data from types");
|
||||||
|
const httpOption = { 'Content-Type': 'application/json' };
|
||||||
|
let url = "saison/" + _id;
|
||||||
|
console.log("call GET " + url);
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.http.get(url, httpOption, {})
|
||||||
|
.then(function(response: any) {
|
||||||
|
if (response.status == 200) {
|
||||||
|
resolve(response.data);
|
||||||
|
console.log("get data from type : " + response.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reject("An error occured");
|
||||||
|
}, function(response: any) {
|
||||||
|
if (typeof response.data === 'undefined') {
|
||||||
|
reject("return ERROR undefined");
|
||||||
|
} else {
|
||||||
|
reject("return ERROR " + JSON.stringify(response.data, null, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
15
front/src/app/session.service.spec.ts
Normal file
15
front/src/app/session.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { SessionService } from './session.service';
|
||||||
|
|
||||||
|
describe('SessionService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [SessionService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([SessionService], (service: SessionService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
90
front/src/app/session.service.ts
Normal file
90
front/src/app/session.service.ts
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Injectable, Output, EventEmitter } from '@angular/core'
|
||||||
|
|
||||||
|
enum USER_ROLES {
|
||||||
|
admin = 10000,
|
||||||
|
user = 1,
|
||||||
|
guest = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class SessionService {
|
||||||
|
public id = null;
|
||||||
|
public userId = null;
|
||||||
|
public userRole = null;
|
||||||
|
public userEMail = null;
|
||||||
|
public userAvatar = null;
|
||||||
|
//public tocken = null;
|
||||||
|
|
||||||
|
@Output() change: EventEmitter<boolean> = new EventEmitter();
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Create a new session.
|
||||||
|
*/
|
||||||
|
create(sessionId,
|
||||||
|
userId,
|
||||||
|
userEMail:string,
|
||||||
|
userRole:string,
|
||||||
|
userAvatar:string) {
|
||||||
|
console.log("Session Create");
|
||||||
|
this.id = sessionId;
|
||||||
|
this.userId = userId;
|
||||||
|
this.userRole = userRole;
|
||||||
|
this.userEMail = userEMail;
|
||||||
|
this.userAvatar = userAvatar;
|
||||||
|
this.change.emit(true);
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @brief destroy the current session.
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
console.log("Session REMOVE");
|
||||||
|
//Cookies.remove("yota-login");
|
||||||
|
//Cookies.remove("yota-password");
|
||||||
|
let last = this.id;
|
||||||
|
this.id = null;
|
||||||
|
this.userId = null;
|
||||||
|
this.userRole = null;
|
||||||
|
this.userEMail = null;
|
||||||
|
this.userAvatar = null;
|
||||||
|
this.change.emit(false);
|
||||||
|
};
|
||||||
|
islogged() {
|
||||||
|
return this.id != null;
|
||||||
|
}
|
||||||
|
hasRight(type) {
|
||||||
|
if (type == USER_ROLES.admin) {
|
||||||
|
return this.userRole == USER_ROLES.admin;
|
||||||
|
}
|
||||||
|
if (type == USER_ROLES.user) {
|
||||||
|
return this.userRole == USER_ROLES.admin
|
||||||
|
|| this.userRole == USER_ROLES.user;
|
||||||
|
}
|
||||||
|
if (type == USER_ROLES.guest) {
|
||||||
|
return this.userRole == USER_ROLES.admin
|
||||||
|
|| this.userRole == USER_ROLES.user
|
||||||
|
|| this.userRole == USER_ROLES.guest;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
hasNotRight(type) {
|
||||||
|
return !this.hasRight(type);
|
||||||
|
}
|
||||||
|
getLogin() {
|
||||||
|
return this.userId;
|
||||||
|
}
|
||||||
|
getAvatar() {
|
||||||
|
if (this.userAvatar == "") {
|
||||||
|
return "assets/images/avatar_generic.svg";
|
||||||
|
}
|
||||||
|
return this.userAvatar;
|
||||||
|
}
|
||||||
|
}
|
3
front/src/app/settings/settings.component.html
Normal file
3
front/src/app/settings/settings.component.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<p>
|
||||||
|
settings works!
|
||||||
|
</p>
|
0
front/src/app/settings/settings.component.less
Normal file
0
front/src/app/settings/settings.component.less
Normal file
25
front/src/app/settings/settings.component.spec.ts
Normal file
25
front/src/app/settings/settings.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { SettingsComponent } from './settings.component';
|
||||||
|
|
||||||
|
describe('SettingsComponent', () => {
|
||||||
|
let component: SettingsComponent;
|
||||||
|
let fixture: ComponentFixture<SettingsComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ SettingsComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(SettingsComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
21
front/src/app/settings/settings.component.ts
Normal file
21
front/src/app/settings/settings.component.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-settings',
|
||||||
|
templateUrl: './settings.component.html',
|
||||||
|
styleUrls: ['./settings.component.less']
|
||||||
|
})
|
||||||
|
export class SettingsComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
63
front/src/app/sign-up/sign-up.component.html
Normal file
63
front/src/app/sign-up/sign-up.component.html
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<div class="left">
|
||||||
|
<div class="global-help">
|
||||||
|
<div class="comment"><label class="unselectable">Rate and comment your medias</label></div>
|
||||||
|
<div class="share"><label class="unselectable">Shared personal media at home</label></div>
|
||||||
|
<div class="time"><label>Keep last view position</label></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<div class="modal-content color-background-vignette container-global">
|
||||||
|
<div class="logo">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<label for="login_field" ><b>Login</b></label>
|
||||||
|
<input id="username"
|
||||||
|
name="username"
|
||||||
|
class="{{loginIcon}}"
|
||||||
|
type="text"
|
||||||
|
required=""
|
||||||
|
placeholder="Pick a Username"
|
||||||
|
[value]="login"
|
||||||
|
(input)="checkLogin($event.target.value)"
|
||||||
|
/>
|
||||||
|
<div class="error color-shadow-black" *ngIf="loginHelp">{{loginHelp}}</div>
|
||||||
|
<label for="login_field" ><b>E-mail</b></label>
|
||||||
|
<input id="email"
|
||||||
|
name="e-mail"
|
||||||
|
class="{{emailIcon}}"
|
||||||
|
type="text"
|
||||||
|
required=""
|
||||||
|
placeholder="you@example.com"
|
||||||
|
[value]="email"
|
||||||
|
(input)="checkEmail($event.target.value)"
|
||||||
|
/>
|
||||||
|
<div class="error color-shadow-black" *ngIf="emailHelp">{{emailHelp}}</div>
|
||||||
|
<label for="password"><b>Password</b></label>
|
||||||
|
<input type="password"
|
||||||
|
id="password"
|
||||||
|
name="password"
|
||||||
|
class="{{passIcon}}"
|
||||||
|
placeholder="Enter Password"
|
||||||
|
required=""
|
||||||
|
[value]="password"
|
||||||
|
(input)="checkPassword($event.target.value)"
|
||||||
|
/>
|
||||||
|
<div class="error color-shadow-black" *ngIf="passHelp">{{passHelp}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<button class="button fill-x color-button-validate color-shadow-black" id="onSignUp-button" [disabled]="signUpButtonDisabled" (click)="onSignUp()" type="submit"><i class="material-icons">mode_edit</i> Sign up for Karideo</button>
|
||||||
|
</div>
|
||||||
|
<div class="container commmon-policy">
|
||||||
|
By clicking "Sign up for Karideo", you agree to our <a class="" href="https://help.karideo.com/terms" target="_blank">terms of service</a> and <a class="" href="https://help.karideo.com/privacy" target="_blank">privacy policy</a>.<br/>
|
||||||
|
Well occasionally send you account related emails.
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<a class="forgot" href="#">Forgot password?</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
{{error}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
162
front/src/app/sign-up/sign-up.component.less
Normal file
162
front/src/app/sign-up/sign-up.component.less
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
|
||||||
|
.right{
|
||||||
|
width:50%;
|
||||||
|
height:100%;
|
||||||
|
right:0;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
border:0;
|
||||||
|
float:right;
|
||||||
|
display:block;
|
||||||
|
}
|
||||||
|
.left{
|
||||||
|
width:50%;
|
||||||
|
height:100%;
|
||||||
|
left:0;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
border:0;
|
||||||
|
float:left;
|
||||||
|
display:block;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
.comment {
|
||||||
|
background-image: url("../../assets/images/comments.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 45px;
|
||||||
|
/*background-attachment: fixed;*/
|
||||||
|
background-position: 0% 50%;
|
||||||
|
padding: 0 0 0 58px;
|
||||||
|
margin: 17px 0 17px 0;
|
||||||
|
text-shadow:0px 0px 4px #2b3137;
|
||||||
|
}
|
||||||
|
.share {
|
||||||
|
background-image: url("../../assets/images/share.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 45px;
|
||||||
|
/*background-attachment: fixed;*/
|
||||||
|
background-position: 0% 50%;
|
||||||
|
padding: 0 0 0 58px;
|
||||||
|
margin: 17px 0 17px 0;
|
||||||
|
text-shadow:0px 0px 4px #2b3137;
|
||||||
|
}
|
||||||
|
.time {
|
||||||
|
background-image: url("../../assets/images/time.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 45px;
|
||||||
|
/*background-attachment: fixed;*/
|
||||||
|
background-position: 0% 50%;
|
||||||
|
padding: 0 0 0 58px;
|
||||||
|
margin: 17px 0 17px 0;
|
||||||
|
text-shadow:0px 0px 4px #2b3137;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input[type=text], input[type=password] {
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px 35px 12px 15px;
|
||||||
|
margin: 8px 0;
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.global-help {
|
||||||
|
position:relative;
|
||||||
|
max-width:500px;
|
||||||
|
padding: 16px 32px 16px 32px;
|
||||||
|
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: ~"translate(-50%, -50%)";
|
||||||
|
font-size: 30px;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: left;
|
||||||
|
line-height: 200%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container-global {
|
||||||
|
position:relative;
|
||||||
|
max-width:400px;
|
||||||
|
padding: 16px 32px 16px 32px;
|
||||||
|
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: ~"translate(-50%, -50%)";
|
||||||
|
box-shadow: 0px 8px 20px 0 rgba(0, 0, 0, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
padding: 16px 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.psw {
|
||||||
|
float: right;
|
||||||
|
padding-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.help {
|
||||||
|
color: #E44;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.forgot {
|
||||||
|
color: #00B;
|
||||||
|
font-size: 14px;
|
||||||
|
float: right;
|
||||||
|
buttum: 0;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.commmon-policy {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 300;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.icon-right-load {
|
||||||
|
background: white url("../../assets/images/load.svg") right no-repeat;
|
||||||
|
background-size: 35px;
|
||||||
|
padding-right: 17px;
|
||||||
|
}
|
||||||
|
.icon-right-validate {
|
||||||
|
background: white url("../../assets/images/validate.svg") right no-repeat;
|
||||||
|
background-size: 35px;
|
||||||
|
padding-right: 17px;
|
||||||
|
}
|
||||||
|
.icon-right-not-validate {
|
||||||
|
background: white url("../../assets/images/validate-not.svg") right no-repeat;
|
||||||
|
background-size: 35px;
|
||||||
|
padding-right: 17px;
|
||||||
|
}
|
||||||
|
.error {
|
||||||
|
background-color: #f44336;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 10;
|
||||||
|
display: block;
|
||||||
|
max-width: 450px;
|
||||||
|
padding: 5px 8px;
|
||||||
|
margin: 2px 0 0;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
&:after, &:before {
|
||||||
|
bottom: 100%;
|
||||||
|
left: 25px;
|
||||||
|
border: solid transparent;
|
||||||
|
content: " ";
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
border-bottom-color: #f44336;
|
||||||
|
border-width: 10px;
|
||||||
|
margin-left: -10px;
|
||||||
|
}
|
||||||
|
}
|
25
front/src/app/sign-up/sign-up.component.spec.ts
Normal file
25
front/src/app/sign-up/sign-up.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { SignUpComponent } from './sign-up.component';
|
||||||
|
|
||||||
|
describe('SignUpComponent', () => {
|
||||||
|
let component: SignUpComponent;
|
||||||
|
let fixture: ComponentFixture<SignUpComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ SignUpComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(SignUpComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
234
front/src/app/sign-up/sign-up.component.ts
Normal file
234
front/src/app/sign-up/sign-up.component.ts
Normal file
@ -0,0 +1,234 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
import { checkLoginValidity, checkEmailValidity, checkPasswordValidity } from '../login/login.component';
|
||||||
|
import { fadeInAnimation } from '../_animations/index';
|
||||||
|
import { UserService } from '../user.service';
|
||||||
|
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-sign-up',
|
||||||
|
templateUrl: './sign-up.component.html',
|
||||||
|
styleUrls: ['./sign-up.component.less'],
|
||||||
|
animations: [fadeInAnimation],
|
||||||
|
host: { '[@fadeInAnimation]': '' }
|
||||||
|
})
|
||||||
|
|
||||||
|
export class SignUpComponent implements OnInit {
|
||||||
|
|
||||||
|
private signUp_iconWrong:string = "icon-right-not-validate";
|
||||||
|
private signUp_iconWait:string = "icon-right-load";
|
||||||
|
private signUp_iconRight:string = "icon-right-validate";
|
||||||
|
|
||||||
|
public login:string = "";
|
||||||
|
public loginOK:boolean = false;
|
||||||
|
public loginHelp:string = "";
|
||||||
|
public loginIcon:string = "";
|
||||||
|
|
||||||
|
public email:string = "";
|
||||||
|
public emailOK:boolean = false;
|
||||||
|
public emailHelp:string = "";
|
||||||
|
public emailIcon:string = "";
|
||||||
|
|
||||||
|
public password:string = "";
|
||||||
|
public passOK:boolean = false;
|
||||||
|
public passHelp:string = "";
|
||||||
|
public passIcon:string = "";
|
||||||
|
|
||||||
|
public signUpButtonDisabled:boolean = true;
|
||||||
|
public error:string = "";
|
||||||
|
|
||||||
|
public rememberMe:boolean = true;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(private userService: UserService,
|
||||||
|
private router: Router) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
updateButtonVisibility():void {
|
||||||
|
if ( this.loginOK == true
|
||||||
|
&& this.passOK == true
|
||||||
|
&& this.emailOK == true) {
|
||||||
|
this.signUpButtonDisabled = false;
|
||||||
|
} else {
|
||||||
|
this.signUpButtonDisabled = true;
|
||||||
|
}
|
||||||
|
this.error = "";
|
||||||
|
}
|
||||||
|
checkLogin(_newValue:string):void {
|
||||||
|
//this.userService.loginSha("loooogin", "ekljkj", true);
|
||||||
|
this.login = _newValue;
|
||||||
|
if ( this.login == null
|
||||||
|
|| this.login.length == 0) {
|
||||||
|
this.loginOK = false;
|
||||||
|
this.loginIcon = "";
|
||||||
|
this.loginHelp = "";
|
||||||
|
this.updateButtonVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.login.length < 6) {
|
||||||
|
this.loginOK = false;
|
||||||
|
this.loginHelp = "Need 6 characters";
|
||||||
|
this.loginIcon = "";
|
||||||
|
this.updateButtonVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (checkLoginValidity(this.login) == true) {
|
||||||
|
this.loginOK = false;
|
||||||
|
//this.loginHelp = "check in progress...";
|
||||||
|
this.loginIcon = this.signUp_iconWait;
|
||||||
|
let self = this;
|
||||||
|
this.userService.checkLogin(this.login).then(function() {
|
||||||
|
// check if the answer is correct with the question
|
||||||
|
if (_newValue != self.login) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// the login exist ... ==> it is found...
|
||||||
|
self.loginOK = false;
|
||||||
|
self.loginHelp = "Login already used ...";
|
||||||
|
self.loginIcon = self.signUp_iconWrong;
|
||||||
|
self.updateButtonVisibility();
|
||||||
|
}, function(error: number) {
|
||||||
|
console.log("1 " + self);
|
||||||
|
// check if the answer is correct with the question
|
||||||
|
if (_newValue != self.login) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (error == 404) {
|
||||||
|
self.loginOK = true;
|
||||||
|
self.loginHelp = "";
|
||||||
|
self.loginIcon = self.signUp_iconRight;
|
||||||
|
self.updateButtonVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("Status " + error);
|
||||||
|
self.loginOK = false;
|
||||||
|
self.loginHelp = "Login already used ...";
|
||||||
|
self.loginIcon = self.signUp_iconWrong;
|
||||||
|
self.updateButtonVisibility();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.loginOK = false;
|
||||||
|
this.loginHelp = 'Not valid: characters, numbers and "_-."';
|
||||||
|
}
|
||||||
|
this.updateButtonVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEmail(_newValue:string):void {
|
||||||
|
this.email = _newValue
|
||||||
|
if ( this.email == null
|
||||||
|
|| this.email.length == 0) {
|
||||||
|
this.emailOK = false;
|
||||||
|
this.updateButtonVisibility();
|
||||||
|
this.emailIcon = "";
|
||||||
|
this.emailHelp = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.email.length < 6) {
|
||||||
|
this.emailOK = false;
|
||||||
|
this.emailHelp = "Need 6 characters";
|
||||||
|
this.updateButtonVisibility();
|
||||||
|
this.passIcon = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (checkEmailValidity(this.email) == true) {
|
||||||
|
this.emailOK = false;
|
||||||
|
this.emailHelp = "";
|
||||||
|
//this.loginHelp = "check in progress...";
|
||||||
|
this.emailIcon = this.signUp_iconWait;
|
||||||
|
let self = this;
|
||||||
|
this.userService.checkEMail(this.email).then(function() {
|
||||||
|
// check if the answer is correct with the question
|
||||||
|
if (_newValue != self.email) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// the email exist ... ==> it is found...
|
||||||
|
self.emailOK = false;
|
||||||
|
self.emailHelp = "email already used ...";
|
||||||
|
self.emailIcon = self.signUp_iconWrong;
|
||||||
|
self.updateButtonVisibility();
|
||||||
|
}, function(error: number) {
|
||||||
|
// check if the answer is correct with the question
|
||||||
|
if (_newValue != self.email) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (error == 404) {
|
||||||
|
self.emailOK = true;
|
||||||
|
self.emailHelp = "";
|
||||||
|
self.emailIcon = self.signUp_iconRight;
|
||||||
|
self.updateButtonVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("Status " + error);
|
||||||
|
self.emailOK = false;
|
||||||
|
self.emailHelp = "email already used ...";
|
||||||
|
self.emailIcon = self.signUp_iconWrong;
|
||||||
|
self.updateButtonVisibility();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.emailOK = false;
|
||||||
|
this.emailHelp = 'Not valid: characters, numbers, "_-." and email format: you@example.com';
|
||||||
|
}
|
||||||
|
this.updateButtonVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkPassword(_newValue:string):void {
|
||||||
|
this.password = _newValue
|
||||||
|
console.log("ooooooooooooooo " + this.password);
|
||||||
|
if (this.password == null) {
|
||||||
|
this.passOK = false;
|
||||||
|
this.passHelp = "";
|
||||||
|
this.updateButtonVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.password.length < 6) {
|
||||||
|
this.passOK = false;
|
||||||
|
this.passHelp = "Need 6 characters";
|
||||||
|
} else {
|
||||||
|
if (checkPasswordValidity(this.password) == true) {
|
||||||
|
this.passOK = true;
|
||||||
|
this.passHelp = "";
|
||||||
|
} else {
|
||||||
|
this.passOK = false;
|
||||||
|
this.passHelp = 'Not valid: characters, numbers and "_-:;.,?!*+=}{([|)]% @&~#/\<>"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.updateButtonVisibility();
|
||||||
|
}
|
||||||
|
onSignUp():void {
|
||||||
|
console.log("Validate ... ");
|
||||||
|
if (this.signUpButtonDisabled == true) {
|
||||||
|
// TODO: ... notify user ...
|
||||||
|
console.log("Not permited action ... ==> control does not validate this action ...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let self = this;
|
||||||
|
// disable the currect button
|
||||||
|
this.signUpButtonDisabled = true;
|
||||||
|
this.userService.create(this.login, this.email, this.password).then(
|
||||||
|
function(value) {
|
||||||
|
console.log("User created");
|
||||||
|
self.router.navigate(['login']);
|
||||||
|
//TODO : send a generic message in the pop-up enevts... self.emailHelp = "email already used ... (error 2)";
|
||||||
|
}, function(value) {
|
||||||
|
console.log("User NOT created");
|
||||||
|
//TODO : send a generic message in the pop-up enevts... self.emailHelp = "email already used ... (error 2)";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onCancel():void {
|
||||||
|
console.log("onCancel ... '" + this.login + "':'" + this.password + "'");
|
||||||
|
//$rootScope.currentModal = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
43
front/src/app/top-menu/top-menu.component.html
Normal file
43
front/src/app/top-menu/top-menu.component.html
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<div class="top">
|
||||||
|
<div id="main-menu" class="main-menu color-menu-background">
|
||||||
|
<button class="item"
|
||||||
|
(click)="onHome()">
|
||||||
|
<i class="material-icons">home</i> Home
|
||||||
|
</button>
|
||||||
|
<button class="item"
|
||||||
|
*ngIf="login == null"
|
||||||
|
style="float:right;"
|
||||||
|
(click)="onSignIn()">
|
||||||
|
<i class="material-icons">add_circle_outline</i> Sign-up
|
||||||
|
</button>
|
||||||
|
<button class="item"
|
||||||
|
*ngIf="login == null"
|
||||||
|
style="float:right;"
|
||||||
|
(click)="onLogin()"> <!-- [routerLink]="['./login']" routerLinkActive="active" -->
|
||||||
|
<i class="material-icons">account_circle</i> Sign-in
|
||||||
|
</button>
|
||||||
|
<button class="item"
|
||||||
|
*ngIf="login != null"
|
||||||
|
style="float:right; height:56px;"
|
||||||
|
(click)="onAvatar()">
|
||||||
|
<img class="avatar" src="{{avatar}}"/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="fill-all" *ngIf="login != null && displayUserMenu == true" (click)="onOutUserProperty()">
|
||||||
|
<!-- (click)="onOutUserProperty()" -->
|
||||||
|
<div class="user-menu color-menu-background">
|
||||||
|
<button class="item" disabled="disabled">
|
||||||
|
Sign in as <b>{{login}}</b>
|
||||||
|
</button>
|
||||||
|
<button class="item" (click)="onHelp()" >
|
||||||
|
<i class="material-icons">help_outline</i> Help
|
||||||
|
</button>
|
||||||
|
<button class="item" (click)="onSetting()" >
|
||||||
|
<i class="material-icons">settings</i> Settings
|
||||||
|
</button>
|
||||||
|
<button class="item" (click)="onLogout()" >
|
||||||
|
<i class="material-icons">exit_to_app</i> Sign out
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
123
front/src/app/top-menu/top-menu.component.less
Normal file
123
front/src/app/top-menu/top-menu.component.less
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
.top {
|
||||||
|
.user-menu {
|
||||||
|
|
||||||
|
position: fixed;
|
||||||
|
top:75px;
|
||||||
|
right:15px;
|
||||||
|
|
||||||
|
min-width:150px;
|
||||||
|
min-height:70px;
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
|
box-shadow: none;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 3px 0 3px;
|
||||||
|
border: none;
|
||||||
|
z-index: 300;
|
||||||
|
box-shadow: 0px 2px 4px 0 rgba(0, 0, 0, 0.6);
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display:block;
|
||||||
|
float: top;
|
||||||
|
line-height: 56px;
|
||||||
|
z-index: 4;
|
||||||
|
margin: 3px 0px 3px 0px;
|
||||||
|
/*padding: 0px 3px 0px 3px;*/
|
||||||
|
border: 0px; /*0px 3px 0px 3px solid transparent;*/
|
||||||
|
/*text-transform: uppercase;*/
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 17px;
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-icons {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
/* Create an Arraw on the top ob the box ... */
|
||||||
|
&:after, &:before {
|
||||||
|
bottom: 100%;
|
||||||
|
right: 13px;
|
||||||
|
border: solid transparent;
|
||||||
|
content: " ";
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
border-color: rgba(136, 183, 213, 0);
|
||||||
|
border-bottom-color: #263238;
|
||||||
|
border-width: 15px;
|
||||||
|
margin-left: -15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.fill-all {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
/*
|
||||||
|
background-color: #0F0;
|
||||||
|
*/
|
||||||
|
z-index:400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-menu {
|
||||||
|
position: fixed;
|
||||||
|
top:0px;
|
||||||
|
left:0px;
|
||||||
|
|
||||||
|
display: block;
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
|
box-shadow: none;
|
||||||
|
min-height: 56px;
|
||||||
|
flex-direction: column;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 12px 0 12px;
|
||||||
|
border: none;
|
||||||
|
max-height: 1000px;
|
||||||
|
z-index: 3;
|
||||||
|
box-shadow: 0px 2px 4px 0 rgba(0, 0, 0, 0.6);
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display:block;
|
||||||
|
float: left;
|
||||||
|
line-height: 56px;
|
||||||
|
z-index: 4;
|
||||||
|
margin: 0 3px 0 3px;
|
||||||
|
border: 0;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-icons {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
height:42px;
|
||||||
|
width:42px;
|
||||||
|
border-radius: 50%;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
front/src/app/top-menu/top-menu.component.spec.ts
Normal file
25
front/src/app/top-menu/top-menu.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { TopMenuComponent } from './top-menu.component';
|
||||||
|
|
||||||
|
describe('TopMenuComponent', () => {
|
||||||
|
let component: TopMenuComponent;
|
||||||
|
let fixture: ComponentFixture<TopMenuComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ TopMenuComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(TopMenuComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
165
front/src/app/top-menu/top-menu.component.ts
Normal file
165
front/src/app/top-menu/top-menu.component.ts
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
import { Injectable, Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
//import { AppRoutingModule } from "../app-routing.module";
|
||||||
|
|
||||||
|
import { Router } from "@angular/router";
|
||||||
|
import { ActivatedRoute, Params } from '@angular/router';
|
||||||
|
import { SessionService } from '../session.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-top-menu',
|
||||||
|
templateUrl: './top-menu.component.html',
|
||||||
|
styleUrls: ['./top-menu.component.less']
|
||||||
|
})
|
||||||
|
@Injectable()
|
||||||
|
export class TopMenuComponent implements OnInit {
|
||||||
|
public login: string = null;//Session.getLogin();
|
||||||
|
public avatar: string = null;//Session.getAvatar();
|
||||||
|
public displayUserMenu: boolean = false;
|
||||||
|
|
||||||
|
constructor(private router: Router,
|
||||||
|
private sessionService: SessionService) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.sessionService.change.subscribe(isConnected => {
|
||||||
|
console.log("receive event from session ..." + isConnected);
|
||||||
|
if (isConnected == false) {
|
||||||
|
this.login = null;
|
||||||
|
this.avatar = null;
|
||||||
|
this.displayUserMenu = false;
|
||||||
|
} else {
|
||||||
|
this.login = this.sessionService.getLogin();
|
||||||
|
this.avatar = this.sessionService.getAvatar();
|
||||||
|
this.displayUserMenu = false;
|
||||||
|
console.log(" login:" + this.sessionService.getLogin());
|
||||||
|
console.log(" avatar:" + this.avatar);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onAvatar(): void {
|
||||||
|
console.log("onAvatar() " + this.displayUserMenu);
|
||||||
|
this.displayUserMenu = !this.displayUserMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
onHome(): void {
|
||||||
|
console.log("onHome()");
|
||||||
|
this.router.navigate(['home']);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSignIn(): void {
|
||||||
|
console.log("onSignIn()");
|
||||||
|
//Session.destroy();
|
||||||
|
this.router.navigate(['signup']);
|
||||||
|
}
|
||||||
|
|
||||||
|
onLogin(): void {
|
||||||
|
console.log("onLogin()");
|
||||||
|
//Session.destroy();
|
||||||
|
this.router.navigate(['login']);
|
||||||
|
this.displayUserMenu = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onLogout(): void {
|
||||||
|
console.log("onLogout()");
|
||||||
|
this.sessionService.destroy();
|
||||||
|
this.router.navigate(['home']);
|
||||||
|
this.displayUserMenu = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSetting(): void {
|
||||||
|
console.log("onSetting()");
|
||||||
|
this.router.navigate(['settings']);
|
||||||
|
this.displayUserMenu = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onHelp(): void {
|
||||||
|
console.log("onHelp()");
|
||||||
|
this.router.navigate(['help']);
|
||||||
|
this.displayUserMenu = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onOutUserProperty(): void {
|
||||||
|
console.log("onOutUserProperty ==> event...");
|
||||||
|
this.displayUserMenu = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
app.controller("controlerTop", function($scope, $rootScope, SESSION_EVENTS, Session, USER_ROLES) {
|
||||||
|
|
||||||
|
$rootScope.$on(SESSION_EVENTS.login, function(event) {
|
||||||
|
console.log("event ... " + SESSION_EVENTS.login);
|
||||||
|
$scope.login = Session.getLogin();
|
||||||
|
$scope.avatar = Session.getAvatar();
|
||||||
|
$scope.displayUserMenu = false;
|
||||||
|
$rootScope.currentDisplay = "home.html";
|
||||||
|
$rootScope.currentModal = "";
|
||||||
|
$rootScope.currentModalCanRemove = false;
|
||||||
|
});
|
||||||
|
$rootScope.$on(SESSION_EVENTS.logout, function(event) {
|
||||||
|
console.log("event ... " + SESSION_EVENTS.login);
|
||||||
|
$scope.login = Session.getLogin();
|
||||||
|
$scope.avatar = Session.getAvatar();
|
||||||
|
$scope.displayUserMenu = false;
|
||||||
|
$rootScope.currentDisplay = "home.html";
|
||||||
|
$rootScope.currentModal = "";
|
||||||
|
$rootScope.currentModalCanRemove = false;
|
||||||
|
});
|
||||||
|
$scope.login = Session.getLogin();
|
||||||
|
$scope.avatar = Session.getAvatar();
|
||||||
|
$scope.displayUserMenu = false;
|
||||||
|
|
||||||
|
$scope.onAvatar = function() {
|
||||||
|
$scope.displayUserMenu = !$scope.displayUserMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.onHome = function() {
|
||||||
|
$rootScope.currentDisplay = "home.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.onSignIn = function() {
|
||||||
|
Session.destroy();
|
||||||
|
$rootScope.currentDisplay = "signUp.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.onLogin = function() {
|
||||||
|
Session.destroy();
|
||||||
|
$rootScope.currentModal = "login.html";
|
||||||
|
$scope.displayUserMenu = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.onLogout = function() {
|
||||||
|
Session.destroy();
|
||||||
|
$rootScope.currentDisplay = "home.html";
|
||||||
|
$scope.displayUserMenu = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.onSetting = function() {
|
||||||
|
$rootScope.currentModal = "";
|
||||||
|
$rootScope.currentDisplay = "setting.html";
|
||||||
|
$scope.displayUserMenu = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.onHelp = function() {
|
||||||
|
$rootScope.currentModal = "";
|
||||||
|
$rootScope.currentDisplay = "help.html";
|
||||||
|
$scope.displayUserMenu = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.onOutUserProperty = function() {
|
||||||
|
console.log("onOutUserProperty ==> event...");
|
||||||
|
$rootScope.currentModal = "";
|
||||||
|
$scope.displayUserMenu = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
*/
|
12
front/src/app/type-detail/type-detail.component.html
Normal file
12
front/src/app/type-detail/type-detail.component.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<div class="main-reduce">
|
||||||
|
<div class="fill-all">
|
||||||
|
<div *ngFor="let data of groups" class="item" (click)="onSelectGroup(data)">
|
||||||
|
<app-element-group [id_type]="type_id" [id_group]="data"></app-element-group>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="fill-all">
|
||||||
|
<div *ngFor="let data of videos" class="item item-video" (click)="onSelectVideo(data)">
|
||||||
|
<app-element-video [id_video]="data"></app-element-video>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
62
front/src/app/type-detail/type-detail.component.less
Normal file
62
front/src/app/type-detail/type-detail.component.less
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
.fill-all{
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
border:0;
|
||||||
|
background-color:#0F0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
font-size: 20px;
|
||||||
|
height: 21%;
|
||||||
|
width: 23%;
|
||||||
|
margin: 1%;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
//box-shadow: 0 1px 1.5px 0 rgba(0,0,0,.12),0 1px 1px 0 rgba(0,0,0,.24);
|
||||||
|
box-shadow: 0px 2px 4px 0 rgba(0, 0, 0, 0.6);
|
||||||
|
line-height: normal;
|
||||||
|
border: none;
|
||||||
|
font-family: "Roboto","Helvetica","Arial",sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0;
|
||||||
|
will-change: box-shadow;
|
||||||
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
transition-duration: 0.4s;
|
||||||
|
float:left;
|
||||||
|
display:block;
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #F00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-icons {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-icons {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: ~"translate(-12px,-12px)";
|
||||||
|
line-height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-video {
|
||||||
|
&:hover {
|
||||||
|
background-color: #0F0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
25
front/src/app/type-detail/type-detail.component.spec.ts
Normal file
25
front/src/app/type-detail/type-detail.component.spec.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { TypeDetailComponent } from './type-detail.component';
|
||||||
|
|
||||||
|
describe('TypeDetailComponent', () => {
|
||||||
|
let component: TypeDetailComponent;
|
||||||
|
let fixture: ComponentFixture<TypeDetailComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ TypeDetailComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(TypeDetailComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
71
front/src/app/type-detail/type-detail.component.ts
Normal file
71
front/src/app/type-detail/type-detail.component.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
|
||||||
|
import { Location } from '@angular/common';
|
||||||
|
import { fadeInAnimation } from '../_animations/index';
|
||||||
|
|
||||||
|
import { TypeService } from '../type.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-type-detail',
|
||||||
|
templateUrl: './type-detail.component.html',
|
||||||
|
styleUrls: ['./type-detail.component.less'],
|
||||||
|
animations: [fadeInAnimation],
|
||||||
|
host: { '[@fadeInAnimation]': '' }
|
||||||
|
})
|
||||||
|
|
||||||
|
export class TypeDetailComponent implements OnInit {
|
||||||
|
type_id = -1;
|
||||||
|
groups_error = "";
|
||||||
|
groups = [{name:"group1"}, {name:"group2"}, {name:"group3"}];
|
||||||
|
videos_error = "";
|
||||||
|
videos = [{name:"video1"}, {name:"video2"}, {name:"video3"}];
|
||||||
|
constructor(private route: ActivatedRoute,
|
||||||
|
private router: Router,
|
||||||
|
private locate: Location,
|
||||||
|
private typeService: TypeService) {
|
||||||
|
/*
|
||||||
|
this.route.params.subscribe(params => {
|
||||||
|
console.log(params);
|
||||||
|
if (params["id"]) {
|
||||||
|
this.doSearch(params["id"]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.type_id = parseInt(this.route.snapshot.paramMap.get('id'));
|
||||||
|
let self = this;
|
||||||
|
console.log("get parameter id: " + this.type_id);
|
||||||
|
this.typeService.getSubGroup(this.type_id)
|
||||||
|
.then(function(response) {
|
||||||
|
self.groups_error = "";
|
||||||
|
self.groups = response
|
||||||
|
}).catch(function(response) {
|
||||||
|
self.groups_error = "Wrong e-mail/login or password";
|
||||||
|
self.groups = []
|
||||||
|
});
|
||||||
|
this.typeService.getSubVideoNoGroup(this.type_id)
|
||||||
|
.then(function(response) {
|
||||||
|
self.videos_error = "";
|
||||||
|
self.videos = response
|
||||||
|
}).catch(function(response) {
|
||||||
|
self.videos_error = "Wrong e-mail/login or password";
|
||||||
|
self.videos = []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onSelectGroup(_idSelected: number):void {
|
||||||
|
this.router.navigate(['group/' + _idSelected ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelectVideo(_idSelected: number):void {
|
||||||
|
this.router.navigate(['video/' + _idSelected ]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
15
front/src/app/type.service.spec.ts
Normal file
15
front/src/app/type.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { UserService } from './user.service';
|
||||||
|
|
||||||
|
describe('TypeService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [testService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([TypeService], (service: TypeService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
131
front/src/app/type.service.ts
Normal file
131
front/src/app/type.service.ts
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpWrapperService } from 'app/http-wrapper.service';
|
||||||
|
//import { SHA512 } from 'assets/js_3rd_party/sha512';
|
||||||
|
|
||||||
|
export interface MessageLogIn {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
declare function SHA512(param1: any): any;
|
||||||
|
declare function dateFormat(param1: any, param2: any): any;
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TypeService {
|
||||||
|
// 0: Not hide password; 1 hide password;
|
||||||
|
private identificationVersion: number = 1;
|
||||||
|
|
||||||
|
constructor(private http: HttpWrapperService) {
|
||||||
|
console.log("Start TypeService");
|
||||||
|
}
|
||||||
|
|
||||||
|
getData():any {
|
||||||
|
console.log("Get All data from types");
|
||||||
|
let currentDate:number = dateFormat(new Date(), 'm-d-Y h:i:s ms');
|
||||||
|
const httpOption = { 'Content-Type': 'application/json' };
|
||||||
|
let url = "type";
|
||||||
|
console.log("call GET " + url);
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.http.get(url, httpOption, {})
|
||||||
|
.then(function(response: any) {
|
||||||
|
if (response.status == 200) {
|
||||||
|
resolve(response.data);
|
||||||
|
console.log("get data from type : " + response.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reject("An error occured");
|
||||||
|
}, function(response: any) {
|
||||||
|
if (typeof response.data === 'undefined') {
|
||||||
|
reject("return ERROR undefined");
|
||||||
|
} else {
|
||||||
|
reject("return ERROR " + JSON.stringify(response.data, null, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
get(_id:number):any {
|
||||||
|
console.log("Get All data from types");
|
||||||
|
let currentDate:number = dateFormat(new Date(), 'm-d-Y h:i:s ms');
|
||||||
|
const httpOption = { 'Content-Type': 'application/json' };
|
||||||
|
let url = "type/" + _id;
|
||||||
|
console.log("call GET " + url);
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.http.get(url, httpOption, {})
|
||||||
|
.then(function(response: any) {
|
||||||
|
if (response.status == 200) {
|
||||||
|
resolve(response.data);
|
||||||
|
console.log("get data from type : " + response.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reject("An error occured");
|
||||||
|
}, function(response: any) {
|
||||||
|
if (typeof response.data === 'undefined') {
|
||||||
|
reject("return ERROR undefined");
|
||||||
|
} else {
|
||||||
|
reject("return ERROR " + JSON.stringify(response.data, null, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
getSubGroup(_id: number):any {
|
||||||
|
console.log("Get All data from types");
|
||||||
|
let currentDate:number = dateFormat(new Date(), 'm-d-Y h:i:s ms');
|
||||||
|
const httpOption = { 'Content-Type': 'application/json' };
|
||||||
|
let url = "type/" + _id + "/group";
|
||||||
|
console.log("call GET " + url);
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.http.get(url, httpOption, {})
|
||||||
|
.then(function(response: any) {
|
||||||
|
if (response.status == 200) {
|
||||||
|
resolve(response.data);
|
||||||
|
console.log("get data from type : " + response.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reject("An error occured");
|
||||||
|
}, function(response: any) {
|
||||||
|
if (typeof response.data === 'undefined') {
|
||||||
|
reject("return ERROR undefined");
|
||||||
|
} else {
|
||||||
|
reject("return ERROR " + JSON.stringify(response.data, null, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
getSubVideoNoGroup(_id: number):any {
|
||||||
|
console.log("Get All data from types");
|
||||||
|
let currentDate:number = dateFormat(new Date(), 'm-d-Y h:i:s ms');
|
||||||
|
const httpOption = { 'Content-Type': 'application/json' };
|
||||||
|
let url = "type/" + _id + "/video_no_group";
|
||||||
|
console.log("call GET " + url);
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.http.get(url, httpOption, {})
|
||||||
|
.then(function(response: any) {
|
||||||
|
if (response.status == 200) {
|
||||||
|
resolve(response.data);
|
||||||
|
console.log("get data from type : " + response.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reject("An error occured");
|
||||||
|
}, function(response: any) {
|
||||||
|
if (typeof response.data === 'undefined') {
|
||||||
|
reject("return ERROR undefined");
|
||||||
|
} else {
|
||||||
|
reject("return ERROR " + JSON.stringify(response.data, null, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
15
front/src/app/user.service.spec.ts
Normal file
15
front/src/app/user.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { UserService } from './user.service';
|
||||||
|
|
||||||
|
describe('UserService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [UserService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([UserService], (service: UserService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
162
front/src/app/user.service.ts
Normal file
162
front/src/app/user.service.ts
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpWrapperService } from 'app/http-wrapper.service';
|
||||||
|
//import { SHA512 } from 'assets/js_3rd_party/sha512';
|
||||||
|
|
||||||
|
interface MessageLogIn {
|
||||||
|
login: string;
|
||||||
|
methode: string;
|
||||||
|
time: number;
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface MessageAnswer_USER_CONNECT {
|
||||||
|
sessionId: string,
|
||||||
|
login: string,
|
||||||
|
eMail: string,
|
||||||
|
role: string,
|
||||||
|
avatar: string
|
||||||
|
};
|
||||||
|
|
||||||
|
declare function SHA512(param1: any): any;
|
||||||
|
declare function dateFormat(param1: any, param2: any): any;
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class UserService {
|
||||||
|
// 0: Not hide password; 1 hide password;
|
||||||
|
private identificationVersion: number = 1;
|
||||||
|
|
||||||
|
constructor(private http: HttpWrapperService) {
|
||||||
|
console.log("Start UserService");
|
||||||
|
}
|
||||||
|
|
||||||
|
login(_login: string, _password: string):any {
|
||||||
|
return this.loginSha(_login, SHA512(_password));
|
||||||
|
}
|
||||||
|
|
||||||
|
loginSha(_login : string, _password : string) {
|
||||||
|
console.log("AuthService.login ... '" + _login + "':'" + _password + "'");
|
||||||
|
let currentDate:number = dateFormat(new Date(), 'm-d-Y h:i:s ms');
|
||||||
|
let data:MessageLogIn;
|
||||||
|
// create request:
|
||||||
|
if (this.identificationVersion == 0) {
|
||||||
|
data = {
|
||||||
|
login: _login,
|
||||||
|
methode: "v0",
|
||||||
|
time: currentDate,
|
||||||
|
password: _password
|
||||||
|
};
|
||||||
|
} else if (this.identificationVersion == 1) {
|
||||||
|
data = {
|
||||||
|
login: _login,
|
||||||
|
methode: "v1",
|
||||||
|
time: currentDate,
|
||||||
|
// we mix the password to be sure that it can not be used an other time ...
|
||||||
|
password: SHA512("login='" + _login + "';pass='" + _password + "';date='" + currentDate + "'")
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const httpOption = { 'Content-Type': 'application/json' };
|
||||||
|
console.log("call users/connect data=" + JSON.stringify(data, null, 2));
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.http.post("rest-auth/login", httpOption, data)
|
||||||
|
.then(function(response: any) {
|
||||||
|
if (response.status == 200) {
|
||||||
|
resolve(response.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reject("An error occured");
|
||||||
|
}, function(response: any) {
|
||||||
|
if (typeof response.data === 'undefined') {
|
||||||
|
reject("return ERROR undefined");
|
||||||
|
} else {
|
||||||
|
reject("return ERROR " + JSON.stringify(response.data, null, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
create(_login : string, _email : string, _password : string) {
|
||||||
|
return this.createSha(_login, _email, SHA512(_password));
|
||||||
|
}
|
||||||
|
createSha(_login : string, _email : string, _password : string, ) {
|
||||||
|
let data = {
|
||||||
|
"methode": "v?",
|
||||||
|
"login": _login,
|
||||||
|
"email": _email,
|
||||||
|
"password": _password
|
||||||
|
}
|
||||||
|
const httpOption = { 'Content-Type': 'application/json' };
|
||||||
|
console.log("call users data=" + JSON.stringify(data, null, 2));
|
||||||
|
|
||||||
|
if (this.identificationVersion == 0) {
|
||||||
|
data["methode"] = "v0"
|
||||||
|
} else if (this.identificationVersion == 1) {
|
||||||
|
data["methode"] = "v1"
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.http.post("users", httpOption, data)
|
||||||
|
.then(function(response: any) {
|
||||||
|
if (response.status == 200) {
|
||||||
|
resolve(response.data)
|
||||||
|
}
|
||||||
|
reject("An error occured");
|
||||||
|
}, function(response: any) {
|
||||||
|
if (typeof response.data === 'undefined') {
|
||||||
|
reject("return ERROR undefined");
|
||||||
|
} else {
|
||||||
|
reject("return ERROR " + JSON.stringify(response.data, null, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
isAuthenticated():boolean {
|
||||||
|
//return !!Session.userId;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
isAuthorized(_authorizedRoles: string): boolean {
|
||||||
|
/*
|
||||||
|
if (!angular.isArray(_authorizedRoles)) {
|
||||||
|
authorizedRoles = [_authorizedRoles];
|
||||||
|
}
|
||||||
|
return ( authService.isAuthenticated()
|
||||||
|
&& _authorizedRoles.indexOf(Session.userRole) !== -1
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
checkLogin(_login: string) {
|
||||||
|
let params = {
|
||||||
|
login: _login
|
||||||
|
};
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.http.get("users/check_login", {}, params).then(
|
||||||
|
(res: Response) => {
|
||||||
|
resolve()
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
reject(error.status);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEMail(_email: string) {
|
||||||
|
let params = {
|
||||||
|
"email": _email
|
||||||
|
};
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.http.get("users/check_email", {}, params).then(
|
||||||
|
(res: Response) => {
|
||||||
|
resolve()
|
||||||
|
},
|
||||||
|
error => {
|
||||||
|
reject(error.status);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
14
front/src/app/validate-email/validate-email.component.html
Normal file
14
front/src/app/validate-email/validate-email.component.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<div class="sign" ng-controller="controlerValidateEmail">
|
||||||
|
<div class="full-back">
|
||||||
|
<div class="global-help">
|
||||||
|
<i class="material-icons big-one">email</i>
|
||||||
|
<div>Waiting email validation ...</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="button sender color-button-validate color-shadow-light" ng-disabled="syncButtonDisabled" (click)="onSend()">
|
||||||
|
<i class="material-icons">send</i> re-send the validation code.
|
||||||
|
</button>
|
||||||
|
<button class="button last-update color-button-normal color-shadow-light" ng-disabled="sendButtonDisabled" (click)="onCheck()">
|
||||||
|
<i class="material-icons">loop</i> 18h15
|
||||||
|
</button>
|
||||||
|
</div>
|
122
front/src/app/validate-email/validate-email.component.less
Normal file
122
front/src/app/validate-email/validate-email.component.less
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
sign {
|
||||||
|
.full-back{
|
||||||
|
position:absolute;
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
right:100;
|
||||||
|
background-color:#2b3137;
|
||||||
|
|
||||||
|
background-image: url("../../assets/images/ikon_gray.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
/*
|
||||||
|
background-size: contain;
|
||||||
|
*/
|
||||||
|
background-size: 80%;
|
||||||
|
background-attachment: fixed;
|
||||||
|
background-position: 50% 50%;
|
||||||
|
|
||||||
|
z-index:-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left{
|
||||||
|
width:50%;
|
||||||
|
height:100%;
|
||||||
|
left:0;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
border:0;
|
||||||
|
float:left;
|
||||||
|
display:block;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
.comment {
|
||||||
|
background-image: url("../../assets/images/comments.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 45px;
|
||||||
|
background-attachment: fixed;
|
||||||
|
background-position: 0% 50%;
|
||||||
|
padding: 0 0 0 58px;
|
||||||
|
margin: 17px 0 17px 0;
|
||||||
|
text-shadow:0px 0px 4px #2b3137;
|
||||||
|
}
|
||||||
|
.share {
|
||||||
|
background-image: url("../../assets/images/share.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 45px;
|
||||||
|
background-attachment: fixed;
|
||||||
|
background-position: 0% 50%;
|
||||||
|
padding: 0 0 0 58px;
|
||||||
|
margin: 17px 0 17px 0;
|
||||||
|
text-shadow:0px 0px 4px #2b3137;
|
||||||
|
}
|
||||||
|
.forget {
|
||||||
|
background-image: url("../../assets/images/erase.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 45px;
|
||||||
|
background-attachment: fixed;
|
||||||
|
background-position: 0% 50%;
|
||||||
|
padding: 0 0 0 58px;
|
||||||
|
margin: 17px 0 17px 0;
|
||||||
|
text-shadow:0px 0px 4px #2b3137;
|
||||||
|
}
|
||||||
|
.time {
|
||||||
|
background-image: url("../../assets/images/time.svg");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 45px;
|
||||||
|
background-attachment: fixed;
|
||||||
|
background-position: 0% 50%;
|
||||||
|
padding: 0 0 0 58px;
|
||||||
|
margin: 17px 0 17px 0;
|
||||||
|
text-shadow:0px 0px 4px #2b3137;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.global-help {
|
||||||
|
color: white;
|
||||||
|
text-shadow:0px 0px 4px #2b3137;
|
||||||
|
position:relative;
|
||||||
|
max-width:500px;
|
||||||
|
padding: 16px 32px 16px 32px;
|
||||||
|
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
font-size: 30px;
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 200%;
|
||||||
|
.big-one {
|
||||||
|
font-size: 90px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.sender {
|
||||||
|
position: fixed;
|
||||||
|
display: block;
|
||||||
|
float: buttom;
|
||||||
|
top: 80%;
|
||||||
|
left:50%;
|
||||||
|
transform: translate(-50%, 0%);
|
||||||
|
//background-color: #4CAF50;
|
||||||
|
//padding: 14px 20px;
|
||||||
|
margin: 1%;
|
||||||
|
vertical-align: middle;
|
||||||
|
width:350px;
|
||||||
|
}
|
||||||
|
.last-update {
|
||||||
|
position: fixed;
|
||||||
|
display: block;
|
||||||
|
float: buttom;
|
||||||
|
top: 90%;
|
||||||
|
left:50%;
|
||||||
|
transform: translate(-50%, 0%);
|
||||||
|
//background-color: transparent;
|
||||||
|
//background-color: #2b3137;
|
||||||
|
//padding: 14px 20px;
|
||||||
|
margin: 1%;
|
||||||
|
vertical-align: middle;
|
||||||
|
width:350px;
|
||||||
|
color:white;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ValidateEmailComponent } from './validate-email.component';
|
||||||
|
|
||||||
|
describe('ValidateEmailComponent', () => {
|
||||||
|
let component: ValidateEmailComponent;
|
||||||
|
let fixture: ComponentFixture<ValidateEmailComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ ValidateEmailComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ValidateEmailComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
248
front/src/app/validate-email/validate-email.component.ts
Normal file
248
front/src/app/validate-email/validate-email.component.ts
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-validate-email',
|
||||||
|
templateUrl: './validate-email.component.html',
|
||||||
|
styleUrls: ['./validate-email.component.less']
|
||||||
|
})
|
||||||
|
export class ValidateEmailComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
app.controller("controlerValidateEmail", function($scope, $http, $rootScope, AuthService) {
|
||||||
|
$scope.sendButtonDisabled = false;
|
||||||
|
$scope.syncButtonDisabled = false;
|
||||||
|
$scope.error = "";
|
||||||
|
|
||||||
|
$scope.rememberMe = true;
|
||||||
|
|
||||||
|
$rootScope.currentModalCanRemove = true;
|
||||||
|
|
||||||
|
$scope.updateButtonVisibility = function() {
|
||||||
|
if ( $scope.loginOK == true
|
||||||
|
&& $scope.passOK == true
|
||||||
|
&& $scope.emailOK == true) {
|
||||||
|
$scope.signUpButtonDisabled = false;
|
||||||
|
} else {
|
||||||
|
$scope.signUpButtonDisabled = true;
|
||||||
|
}
|
||||||
|
$scope.error = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.checkLogin = function() {
|
||||||
|
if ( $scope.login == null
|
||||||
|
|| $scope.login.length == 0) {
|
||||||
|
$scope.loginOK = false;
|
||||||
|
$scope.loginIcon = "";
|
||||||
|
$scope.loginHelp = "";
|
||||||
|
$scope.updateButtonVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($scope.login.length < 6) {
|
||||||
|
$scope.loginOK = false;
|
||||||
|
$scope.loginHelp = "Need 6 characters";
|
||||||
|
$scope.loginIcon = "";
|
||||||
|
$scope.updateButtonVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (checkLoginValidity($scope.login) == true) {
|
||||||
|
$scope.loginOK = false;
|
||||||
|
//$scope.loginHelp = "check in progress...";
|
||||||
|
$scope.loginIcon = signUp_iconWait;
|
||||||
|
let data = {
|
||||||
|
"login": $scope.login
|
||||||
|
}
|
||||||
|
let connectionAdresse = createRESTCall("user/check/login");
|
||||||
|
let config = {
|
||||||
|
params: data
|
||||||
|
};
|
||||||
|
let tmpLogin = "" + $scope.login;
|
||||||
|
console.log("call " + connectionAdresse + " data=" + JSON.stringify(data, null, 2));
|
||||||
|
$http.get(connectionAdresse, config)
|
||||||
|
.then(function(response) {
|
||||||
|
// check if the answer is correct with the question
|
||||||
|
if (tmpLogin != $scope.login) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("Status " + response.status);
|
||||||
|
console.log("data " + JSON.stringify(response.data, null, 2));
|
||||||
|
if (response.status == 200) {
|
||||||
|
// the login exist ... ==> it is found...
|
||||||
|
$scope.loginOK = false;
|
||||||
|
$scope.loginHelp = "Login already used ...";
|
||||||
|
$scope.loginIcon = signUp_iconWrong;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$scope.loginOK = false;
|
||||||
|
$scope.loginHelp = "Login already used ... (error 2)";
|
||||||
|
}, function(response) {
|
||||||
|
// check if the answer is correct with the question
|
||||||
|
if (tmpLogin != $scope.login) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (response.status == 404) {
|
||||||
|
$scope.loginOK = true;
|
||||||
|
$scope.loginHelp = "";
|
||||||
|
$scope.loginIcon = signUp_iconRight;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("Status " + response.status);
|
||||||
|
console.log("data " + JSON.stringify(response.data, null, 2));
|
||||||
|
$scope.loginOK = false;
|
||||||
|
$scope.loginHelp = "Login already used ...";
|
||||||
|
$scope.loginIcon = signUp_iconWrong;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$scope.loginOK = false;
|
||||||
|
$scope.loginHelp = 'Not valid: characters, numbers and "_-."';
|
||||||
|
}
|
||||||
|
$scope.updateButtonVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.checkEmail = function() {
|
||||||
|
if ( $scope.email == null
|
||||||
|
|| $scope.email.length == 0) {
|
||||||
|
$scope.emailOK = false;
|
||||||
|
$scope.updateButtonVisibility();
|
||||||
|
$scope.emailIcon = "";
|
||||||
|
$scope.emailHelp = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($scope.email.length < 6) {
|
||||||
|
$scope.emailOK = false;
|
||||||
|
$scope.emailHelp = "Need 6 characters";
|
||||||
|
$scope.updateButtonVisibility();
|
||||||
|
$scope.passIcon = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (checkEmailValidity($scope.email) == true) {
|
||||||
|
$scope.emailOK = true;
|
||||||
|
$scope.emailHelp = "";
|
||||||
|
//$scope.loginHelp = "check in progress...";
|
||||||
|
$scope.emailIcon = signUp_iconWait;
|
||||||
|
let data = {
|
||||||
|
"e-mail": $scope.email
|
||||||
|
}
|
||||||
|
let connectionAdresse = createRESTCall("user/check/email");
|
||||||
|
let config = {
|
||||||
|
params: data
|
||||||
|
};
|
||||||
|
let tmpEmail = "" + $scope.email;
|
||||||
|
console.log("call " + connectionAdresse + " data=" + JSON.stringify(data, null, 2));
|
||||||
|
$http.get(connectionAdresse, config)
|
||||||
|
.then(function(response) {
|
||||||
|
// check if the answer is correct with the question
|
||||||
|
if (tmpEmail != $scope.email) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("Status " + response.status);
|
||||||
|
console.log("data " + JSON.stringify(response.data, null, 2));
|
||||||
|
if (response.status == 200) {
|
||||||
|
// the email exist ... ==> it is found...
|
||||||
|
$scope.emailOK = false;
|
||||||
|
$scope.emailHelp = "email already used ...";
|
||||||
|
$scope.emailIcon = signUp_iconWrong;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$scope.emailOK = false;
|
||||||
|
$scope.emailHelp = "email already used ... (error 2)";
|
||||||
|
}, function(response) {
|
||||||
|
// check if the answer is correct with the question
|
||||||
|
if (tmpEmail != $scope.email) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (response.status == 404) {
|
||||||
|
$scope.emailOK = true;
|
||||||
|
$scope.emailHelp = "";
|
||||||
|
$scope.emailIcon = signUp_iconRight;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log("Status " + response.status);
|
||||||
|
console.log("data " + JSON.stringify(response.data, null, 2));
|
||||||
|
$scope.emailOK = false;
|
||||||
|
$scope.emailHelp = "email already used ...";
|
||||||
|
$scope.emailIcon = signUp_iconWrong;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$scope.emailOK = false;
|
||||||
|
$scope.emailHelp = 'Not valid: characters, numbers, "_-." and email format: you@example.com';
|
||||||
|
}
|
||||||
|
$scope.updateButtonVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.checkPassword = function() {
|
||||||
|
if ($scope.password == null) {
|
||||||
|
$scope.passOK = false;
|
||||||
|
$scope.passHelp = "";
|
||||||
|
$scope.updateButtonVisibility();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($scope.password.length < 6) {
|
||||||
|
$scope.passOK = false;
|
||||||
|
$scope.passHelp = "Need 6 characters";
|
||||||
|
} else {
|
||||||
|
if (checkPasswordValidity($scope.password) == true) {
|
||||||
|
$scope.passOK = true;
|
||||||
|
$scope.passHelp = "";
|
||||||
|
} else {
|
||||||
|
$scope.passOK = false;
|
||||||
|
$scope.passHelp = 'Not valid: characters, numbers and "_-:;.,?!*+=}{([|)]% @&~#/\<>"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$scope.updateButtonVisibility();
|
||||||
|
}
|
||||||
|
$scope.onSignUp = function() {
|
||||||
|
if ($scope.signUpButtonDisabled == true) {
|
||||||
|
// TODO: ... notify user ...
|
||||||
|
console.log("Not permited action ... ==> control does not validate this action ...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let data = {
|
||||||
|
"methode": "v0",
|
||||||
|
"login": $scope.login,
|
||||||
|
"e-mail": $scope.email,
|
||||||
|
"password": btoa(CryptoJS.SHA1($scope.password)) // btoa encode i base64
|
||||||
|
}
|
||||||
|
let connectionAdresse = createRESTCall("user/add");
|
||||||
|
let config = {
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let tmpEmail = "" + $scope.email;
|
||||||
|
console.log("call " + connectionAdresse + " data=" + JSON.stringify(data, null, 2));
|
||||||
|
$http.post(connectionAdresse, data, config)
|
||||||
|
.then(function(response) {
|
||||||
|
console.log("Status " + response.status);
|
||||||
|
console.log("data " + JSON.stringify(response.data, null, 2));
|
||||||
|
if (response.status == 200) {
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$scope.emailOK = false;
|
||||||
|
$scope.emailHelp = "email already used ... (error 2)";
|
||||||
|
}, function(response) {
|
||||||
|
console.log("Status " + response.status);
|
||||||
|
console.log("data " + JSON.stringify(response.data, null, 2));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$scope.onCancel = function() {
|
||||||
|
console.log("onCancel ... '" + $scope.login + "':'" + $scope.password + "'");
|
||||||
|
$rootScope.currentModal = "";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
15
front/src/app/video.service.spec.ts
Normal file
15
front/src/app/video.service.spec.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { TestBed, inject } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { VideoService } from './video.service';
|
||||||
|
|
||||||
|
describe('VideoService', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [VideoService]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', inject([VideoService], (service: VideoService) => {
|
||||||
|
expect(service).toBeTruthy();
|
||||||
|
}));
|
||||||
|
});
|
38
front/src/app/video.service.ts
Normal file
38
front/src/app/video.service.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpWrapperService } from 'app/http-wrapper.service';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class VideoService {
|
||||||
|
// 0: Not hide password; 1 hide password;
|
||||||
|
private identificationVersion: number = 1;
|
||||||
|
|
||||||
|
constructor(private http: HttpWrapperService) {
|
||||||
|
console.log("Start VideoService");
|
||||||
|
}
|
||||||
|
|
||||||
|
get(_id:number):any {
|
||||||
|
const httpOption = { 'Content-Type': 'application/json' };
|
||||||
|
let url = "video/" + _id;
|
||||||
|
console.log("call GET " + url);
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.http.get(url, httpOption, {})
|
||||||
|
.then(function(response: any) {
|
||||||
|
if (response.status == 200) {
|
||||||
|
resolve(response.data);
|
||||||
|
console.log("get data from type : " + response.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reject("An error occured");
|
||||||
|
}, function(response: any) {
|
||||||
|
if (typeof response.data === 'undefined') {
|
||||||
|
reject("return ERROR undefined");
|
||||||
|
} else {
|
||||||
|
reject("return ERROR " + JSON.stringify(response.data, null, 2));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
0
front/src/assets/.gitkeep
Normal file
0
front/src/assets/.gitkeep
Normal file
24
front/src/assets/aaa_interfaceCloud.js
Normal file
24
front/src/assets/aaa_interfaceCloud.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* @brief create the rest call element of the link
|
||||||
|
*/
|
||||||
|
let createRESTCall = function(api, options) {
|
||||||
|
// http://localhost/exercice
|
||||||
|
let basePage = "" + window.location;
|
||||||
|
if (basePage.endsWith("index.xhtml") == true) {
|
||||||
|
basePage = basePage.substring(0, basePage.length - 11);
|
||||||
|
}
|
||||||
|
if (basePage.endsWith("index.php") == true) {
|
||||||
|
basePage = basePage.substring(0, basePage.length - 10);
|
||||||
|
}
|
||||||
|
let addressServerRest =basePage + "/api/v1/index.php";
|
||||||
|
if (typeof options === 'undefined') {
|
||||||
|
options = [];
|
||||||
|
}
|
||||||
|
let out = addressServerRest + "?REST=" + api;
|
||||||
|
for (let iii=0; iii<options.length; iii++) {
|
||||||
|
out += "&" + options[iii];
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
26
front/src/assets/images/avatar_generic.svg
Normal file
26
front/src/assets/images/avatar_generic.svg
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="499"
|
||||||
|
height="498"
|
||||||
|
viewBox="0 0 499 498">
|
||||||
|
<rect
|
||||||
|
style="fill:#4c83e5;fill-opacity:1;stroke:none;stroke-width:8.82841587;stroke-opacity:1"
|
||||||
|
width="500"
|
||||||
|
height="500"
|
||||||
|
x="0"
|
||||||
|
y="-1.9999847" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1"
|
||||||
|
d="m 204.04675,299.92172 64.38231,-8.25011 84.38034,95.33059 -50.65607,144.5704 -137.27461,10.07178 -8.02011,-145.66775 z"/>
|
||||||
|
<path
|
||||||
|
d="m 151.70726,153.48377 98.32028,-57.471057 56.94703,21.629237 42.18786,87.1369 -8.8547,99.27952 c 0,0 -50.49799,16.08876 -49.46915,20.02305 1.64608,6.29463 -6.63579,19.542 -19.42333,31.06884 -11.04013,9.95169 -21.88069,22.4832 -25.78302,29.80472 -1.77209,3.32477 -3.61064,6.04503 -4.08568,6.04503 -0.47504,0 -2.26404,-4.6125 -3.97555,-10.25 -7.0054,-23.07485 -5.43752,-20.34841 -16.04346,-27.89857 -14.90382,-10.60973 -22.13256,-19.44659 -23.88228,-29.19518 l -0.74599,-4.15625 -49.90362,-18.10466 z"
|
||||||
|
style="fill:#fbd0a6"/>
|
||||||
|
<path
|
||||||
|
d="m 55.528901,495.75001 c 0.527163,-1.2375 3.024666,-9.9 5.550006,-19.25 8.980498,-33.25004 20.717058,-73.14872 24.415208,-83 7.96468,-21.21664 17.411415,-36.82083 25.634775,-42.3437 3.46578,-2.32765 7.75343,-3.40938 27.99561,-7.063 24.83316,-4.48226 37.7984,-7.72387 44.43556,-11.10989 2.13829,-1.09087 4.2852,-1.98341 4.77091,-1.98341 0.48571,0 0.25824,3.0375 -0.50549,6.75 -1.50052,7.29402 -2.99983,49.3173 -1.91392,53.64393 0.99077,3.94752 2.8969,3.16745 7.07154,-2.89393 3.53084,-5.12662 5.54444,-6.78317 5.54444,-4.56129 0,2.60045 5.3114,31.27728 8.05039,43.46495 5.98108,26.61396 16.76339,62.48393 20.54452,68.34634 l 1.4512,2.25 H 141.57203 54.570422 Z m 210.460079,-0.0508 c 2.17179,-3.31457 8.92419,-24.36077 12.96435,-40.40789 4.43614,-17.61992 8.08383,-37.40934 10.50604,-56.99725 1.05232,-8.50988 2.1619,-15.72111 2.46573,-16.02495 0.64309,-0.64309 2.6928,1.66469 9.7848,11.01675 3.42759,4.51989 5.47957,6.45222 6.14506,5.78673 1.18368,-1.18368 -0.68453,-30.51729 -2.75684,-43.28638 -1.74071,-10.72592 -4.37632,-21.1576 -6.74023,-26.67774 -1.03434,-2.41534 -1.68984,-4.5823 -1.45667,-4.81547 0.23317,-0.23317 3.05697,0.90265 6.27513,2.52404 9.1322,4.60104 20.99201,7.95377 45.19529,12.77659 12.28926,2.44879 23.57308,5.08787 25.07515,5.86462 9.57196,4.94985 22.94665,28.40208 32.96941,57.8111 2.76841,8.12314 10.28609,32.19814 16.70596,53.5 6.41986,21.30186 11.88553,39.29316 12.14592,39.98066 0.37646,0.99395 -17.06674,1.25 -85.1566,1.25 H 264.48143 Z M 292.3029,319.27575 c -3.48342,-3.65128 -4.45897,-6.45791 -5.83264,-16.7804 l -1.14521,-8.60577 5.12567,-8.35825 c 7.3769,-12.02924 13.35778,-24.49549 17.52649,-36.53131 3.20476,-9.25271 4.17092,-10.95875 8.13338,-14.36186 5.35782,-4.60148 8.85325,-11.11418 11.48239,-21.39399 2.20459,-8.6199 2.40904,-13.47419 0.83135,-19.73974 -2.07703,-8.24867 -6.91023,-9.75732 -10.39679,-3.24531 -1.1,2.05452 -2.31639,3.73671 -2.70308,3.7382 -0.3867,0.001 -1.47529,-1.6246 -2.41909,-3.61352 -3.45146,-7.2734 -12.43759,-11.95743 -37.37783,-19.4832 -36.97908,-11.15851 -50.57658,-17.84965 -64.69138,-31.83371 -7.11369,-7.0478 -9.1226,-7.45885 -17.07813,-3.49444 -6.3577,3.16818 -14.21568,11.58946 -17.71356,18.98336 -3.59507,7.59935 -6.48828,19.31308 -7.21077,29.19421 -0.33177,4.5375 -0.80892,8.25 -1.06034,8.25 -0.25141,0 -1.79409,-1.125 -3.42819,-2.5 -3.73675,-3.14427 -4.36211,-3.12484 -6.54282,0.20333 -2.23258,3.40736 -2.43946,17.43846 -0.3656,24.79667 2.41169,8.55685 6.77334,16.1351 11.61665,20.18361 3.60598,3.01423 4.89833,4.96775 6.16195,9.31445 2.92343,10.05624 10.27022,26.25548 16.96068,37.3973 l 6.60969,11.0073 -0.6645,10.04867 c -0.74861,11.32069 -1.9804,16.16987 -4.42377,17.41502 -1.56622,0.79815 -24.35316,-0.0941 -35.85864,-1.40416 -6.56738,-0.74777 -11.84347,-4.46271 -17.76801,-12.51063 -12.10229,-16.43979 -15.71037,-32.44915 -13.58553,-60.28013 4.7534,-62.25964 27.2222,-120.24856 52.91047,-136.55478 2.54749,-1.61707 7.03281,-3.64203 9.96737,-4.49991 3.87995,-1.13423 6.9751,-3.07768 11.34521,-7.123635 12.46712,-11.54236 25.74733,-15.92105 46.31922,-15.27215 11.32895,0.35735 14.13371,0.80718 21.81973,3.49945 16.5524,5.798 31.67451,16.565115 46.03801,32.779585 14.3084,16.15227 22.61268,30.83521 30.69285,54.26859 16.39981,47.56123 14.10848,112.15599 -4.86138,137.04726 -4.08556,5.36086 -8.18764,6.77337 -26.3982,9.08991 -9.18994,1.16905 -17.30716,2.35507 -18.03825,2.63562 -0.7311,0.28055 -2.52093,-0.73899 -3.9774,-2.26565 z"
|
||||||
|
style="fill:#4e4e4d" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.6 KiB |
59
front/src/assets/images/comments.svg
Normal file
59
front/src/assets/images/comments.svg
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="svg2"
|
||||||
|
width="1600"
|
||||||
|
height="1600"
|
||||||
|
viewBox="0 0 1600 1600"
|
||||||
|
sodipodi:docname="comments.svg"
|
||||||
|
inkscape:version="0.92.2 2405546, 2018-03-11">
|
||||||
|
<metadata
|
||||||
|
id="metadata8">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs6" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1598"
|
||||||
|
inkscape:window-height="858"
|
||||||
|
id="namedview4"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="0.417193"
|
||||||
|
inkscape:cx="564.95647"
|
||||||
|
inkscape:cy="689.55475"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="20"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg2" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1"
|
||||||
|
d="M 1450,1300 H 970.49559 L 800,1470 629.50441,1300 H 150 V 300 H 1450 Z M 1350,400 H 250 v 800 H 670.50581 L 800,1329 929.49419,1200 H 1350 Z M 450,950 h 500 v 100 H 450 Z m 0,-200 h 700 V 850 H 450 Z M 1036,650 H 450 V 550 h 586 z"
|
||||||
|
id="path4520"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="ccccccccccccccccccccccccccccccc" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
63
front/src/assets/images/erase.svg
Normal file
63
front/src/assets/images/erase.svg
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
version="1.1"
|
||||||
|
id="svg2"
|
||||||
|
width="128"
|
||||||
|
height="128"
|
||||||
|
viewBox="0 0 128 128"
|
||||||
|
sodipodi:docname="erase.svg"
|
||||||
|
inkscape:version="0.92.2 2405546, 2018-03-11">
|
||||||
|
<metadata
|
||||||
|
id="metadata8">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<defs
|
||||||
|
id="defs6" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1"
|
||||||
|
objecttolerance="10"
|
||||||
|
gridtolerance="10"
|
||||||
|
guidetolerance="10"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:window-width="1598"
|
||||||
|
inkscape:window-height="858"
|
||||||
|
id="namedview4"
|
||||||
|
showgrid="false"
|
||||||
|
inkscape:zoom="1.0091185"
|
||||||
|
inkscape:cx="-283.45157"
|
||||||
|
inkscape:cy="33.728592"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="20"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg2" />
|
||||||
|
<path
|
||||||
|
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:9.22393036;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
|
||||||
|
d="M 78.057715,6.7629418 74.781278,10.009583 7.1140977,77.061429 41.377799,111.63957 l 24.704188,0.002 58.479833,-57.94805 z M 50.017286,47.533394 83.536922,81.36064 62.286619,102.4177 45.22373,102.41662 20.158146,77.121007 Z"
|
||||||
|
id="rect1639"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
<path
|
||||||
|
style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:6.53187132;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||||
|
d="M 0.12387033,120.4439 H 66.02296"
|
||||||
|
id="path1656"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.3 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user