Commit b5ff07ad authored by Josue's avatar Josue

Merge branch 'developer'

parents 7620f738 2112d188
Pipeline #353 failed with stages

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
FROM nginx:1.17-alpine
LABEL maintainer "mortiz@bytesw.com"
RUN apk --no-cache add curl
RUN curl -L https://github.com/a8m/envsubst/releases/download/v1.1.0/envsubst-`uname -s`-`uname -m` -o envsubst && \
chmod +x envsubst && \
mv envsubst /usr/local/bin
EXPOSE 80
COPY ./nginx.config /etc/nginx/nginx.template
CMD ["/bin/sh", "-c", "envsubst < /etc/nginx/nginx.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"]
COPY dist/bytebot-html /usr/share/nginx/html
pipeline {
environment {
imagename = "bytesw/bytebot-html"
url = "http://192.168.27.148:5000"
tag_name = "192.168.27.148:5000"
credentials = "admin-docker-hub"
dockerImage = ''
PACKAGE_VERSION = '2.5.0'
}
agent any
parameters {
string(defaultValue: 'no', description: 'Ejecuta los procesos docker', name: 'include_docker')
}
stages {
stage('Install') {
steps {
echo "Branch is ${env.BRANCH_NAME}..."
nodejs(nodeJSInstallationName: 'NodeJS13', configId: '77600a18-f968-4cca-83e4-a9f76d165336') {
sh 'PACKAGE_VERSION=$(node -p -e "require(\'./package.json\').version")'
sh 'npm config ls'
sh 'npm install'
sh 'npm i -D typescript@3.4.3'
}
}
}
stage('Test') {
parallel {
stage('Static code analysis') {
steps {
nodejs(nodeJSInstallationName: 'NodeJS13', configId: '77600a18-f968-4cca-83e4-a9f76d165336') {
sh 'npm run-script lint'
}
}
}
}
}
stage('Build') {
steps {
nodejs(nodeJSInstallationName: 'NodeJS13', configId: '77600a18-f968-4cca-83e4-a9f76d165336') {
sh 'ng build'
}
}
}
stage('Build Docker Image') {
when {
expression { params.include_docker == 'yes' }
}
steps {
nodejs(nodeJSInstallationName: 'NodeJS13', configId: '77600a18-f968-4cca-83e4-a9f76d165336') {
sh 'PACKAGE_VERSION=$(node -p -e "require(\'./package.json\').version")'
}
script {
dockerImage = docker.build imagename
}
}
}
stage('Deploy Image') {
when {
expression { params.include_docker == 'yes' }
}
steps{
script {
docker.withRegistry(url, credentials ) {
dockerImage.push("$PACKAGE_VERSION")
dockerImage.push('latest')
}
}
}
}
stage('Remove Unused docker image') {
when {
expression { params.include_docker == 'yes' }
}
steps{
sh "docker rmi $tag_name/$imagename:$PACKAGE_VERSION"
sh "docker rmi $tag_name/$imagename:latest"
}
}
}
post {
always {
echo 'Confirmación de ejecución!'
emailext body: "${currentBuild.currentResult}: Job ${env.JOB_NAME} build ${env.BUILD_NUMBER}\n More info at: ${env.BUILD_URL}",
recipientProviders: [[$class: 'DevelopersRecipientProvider'], [$class: 'RequesterRecipientProvider']],
subject: "Jenkins Build ${currentBuild.currentResult}: Job ${env.JOB_NAME}",
to: '$DEFAULT_RECIPIENTS'
}
}
}
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
server {
listen ${PORT:-80};
server_name _;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $$uri /index.html;
}
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; frame-ancestors 'none'; connect-src 'self' https://*.okta.com https://*.herokuapp.com";
add_header Referrer-Policy "no-referrer, strict-origin-when-cross-origin";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
add_header Feature-Policy "accelerometer 'none'; camera 'none'; microphone 'none'";
}
\ No newline at end of file
This diff is collapsed.
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { BaseLayoutComponent, NotFoundComponent, CustomLayoutComponent } from '@xdf/layouts';
import { BaseLayoutComponent, CustomLayoutComponent, NotFoundComponent } from '@xdf/layouts';
import { AuthGuard, LoginComponent } from '@xdf/security';
import { HomeComponent } from './views/home/home.component';
......@@ -25,6 +25,34 @@ const routes: Routes = [
path: 'configuration', data: { breadcrumb: 'Agentes' }, canLoad: [AuthGuard],
loadChildren: () => import('./modules/agent/agent.module').then(m => m.AgentModule)
},
{
path: "airport", data: { breadcrumb: "Aeropuertos" }, canLoad: [AuthGuard],
loadChildren: () => import("./modules/airport/airport.module").then( m => m.AirportModule)
},
{
path: "passenger", data: { breadcrumb: "Pasajeros" }, canLoad: [AuthGuard],
loadChildren: () => import("./modules/passenger/passenger.module").then( m => m.PassengerModule)
},
{
path: "agent", data: { breadcrumb: "Agentes" }, canLoad: [AuthGuard],
loadChildren: () => import("./modules/booking-agent/booking-agent.module").then( m => m.BookingAgentModule)
},
{
path: "payment", data: { breadcrumb: "Pagos" }, canLoad: [AuthGuard],
loadChildren: () => import("./modules/payment/payment.module").then( m => m.PaymentModule)
},
{
path: "payment-reservation", data: {breadcrumb: "Pagos Reserva"}, canLoad: [AuthGuard],
loadChildren: () => import("./modules/payment-reservation/payment-reservation.module").then( m => m.PaymentReservationModule)
},
{
path: "flight", data: { breadcrumb: "Vuelos" }, canLoad: [AuthGuard],
loadChildren: () => import("./modules/flight/flight.module").then( m => m.FlightModule)
},
{
path: "reservation", data: { breadcrumb: "Reservaciones" }, canLoad: [AuthGuard],
loadChildren: () => import("./modules/reservation/reservation.module").then( m => m.ReservationModule)
}
],
canActivate: [AuthGuard]
},
......
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
......@@ -11,18 +11,22 @@ import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-transla
// XDF
import { XdfLayoutsModule, SettingsService, ByteSettingsService, SettingsFakeBackendInterceptor } from '@xdf/layouts';
import { XdfSecurityModule, ByteAuthenticationService, AuthGuard, OAuthGuard, OAuthAuthenticationService, ResourceAuthGuard, AuthenticationFakeBackendInterceptor, ProgramsFakeBackendInterceptor } from '@xdf/security';
import { XdfCommonsModule, NotificationService, ToastNotificationService, AuthenticationService, INITSERVICE_OPTIONS, InitCommonsService, ErrorsHandler } from '@xdf/commons';
import { XdfSecurityModule, ByteAuthenticationService, AuthGuard, OAuthGuard, OAuthAuthenticationService } from '@xdf/security';
import { ResourceAuthGuard, AuthenticationFakeBackendInterceptor, ProgramsFakeBackendInterceptor } from '@xdf/security';
import { XdfCommonsModule, NotificationService, ToastNotificationService, AuthenticationService } from '@xdf/commons';
import { INITSERVICE_OPTIONS, InitCommonsService, ErrorsHandler } from '@xdf/commons';
//Components
// Components
import { AppComponent } from './app.component';
import { HomeComponent } from './views/home/home.component';
import { ToastrModule } from 'ngx-toastr';
import localeEs from '@angular/common/locales/es-PE';
import localeEn from '@angular/common/locales/en';
import { MAT_DATE_LOCALE, MatDialog, MatButtonModule, MatDialogModule, MatPaginatorIntl, DateAdapter, MAT_DATE_FORMATS, MatIconModule } from '@angular/material';
import { XdfGalleryModule, CustomMatPaginatorIntl, DATERANGEPICKER_LOCALE, DaterangepickerLocaleService, ConflictErrorDialogService, HttpErrorHandleInterceptor } from '@xdf/gallery';
import { MAT_DATE_LOCALE, MatDialog, MatButtonModule, MatDialogModule, MatPaginatorIntl, DateAdapter } from '@angular/material';
import { MAT_DATE_FORMATS, MatIconModule } from '@angular/material';
import { XdfGalleryModule, CustomMatPaginatorIntl, DATERANGEPICKER_LOCALE, DaterangepickerLocaleService } from '@xdf/gallery';
import { ConflictErrorDialogService, HttpErrorHandleInterceptor } from '@xdf/gallery';
import { BytebotSettingsService } from './services/bytebot-settings-service';
import { MultiTranslateHttpLoader } from 'ngx-translate-multi-http-loader';
......@@ -37,6 +41,16 @@ import {
} from '@angular/material-moment-adapter';
import { CustomProgramsFakeBackendInterceptor } from './interceptors/custom-programs-fake-backend.interceptor';
import { AgentFakeBackendInterceptor } from './interceptors/agent-fake-backend.interceptor';
import { OperativeDashboardFakeBackendInterceptor } from './interceptors/operative-dashboard-fake-backend.interceptor';
import { AirportFakeBackendInterceptor } from './interceptors/airport-fake-backend.interceptor';
import { PassengerFakeBackendInterceptor } from './interceptors/passenger-fake-backend.interceptor';
import { PaymentFakeBackendInterceptor } from './interceptors/payment-fake-backend.interceptor';
import { BookingAgentFakeBackendInterceptor } from './interceptors/booking-agent-fake-backend.interceptor';
//import { AirportFakeBackendInterceptor } from './interceptors/airport-fake-backend.interceptor';
//import { PassengerFakeBackendInterceptor } from './interceptors/passenger-fake-backend.interceptor';
//import { BookingAgentFakeBackendInterceptor } from './interceptors/booking-agent-fake-backend.interceptor';
//import { PaymentFakeBackendInterceptor } from './interceptors/payment-fake-backend.interceptor';
const INITIAL_LANGUAGE = 'es';
......@@ -111,20 +125,24 @@ export function createTranslateLoader(http: HttpClient) {
{ provide: ResourceAuthGuard, useClass: ResourceAuthGuard },
// descomentar estas lineas para OAUTH
{ provide: AuthGuard, useClass: OAuthGuard },
{ provide: AuthenticationService, useClass: OAuthAuthenticationService },
{ provide: APP_INITIALIZER, useFactory: loginLoaderFactory, deps: [AuthenticationService], multi: true },
//{ provide: AuthGuard, useClass: OAuthGuard },
//{ provide: AuthenticationService, useClass: OAuthAuthenticationService },
//{ provide: APP_INITIALIZER, useFactory: loginLoaderFactory, deps: [AuthenticationService], multi: true },
// Para probar mantenimientos
// comentar estas lineas para OAUTH
// { provide: AuthGuard, useClass: AuthGuard},
// { provide: AuthenticationService, useClass: ByteAuthenticationService },
// { provide: HTTP_INTERCEPTORS, useClass: AuthenticationFakeBackendInterceptor, multi: true},
{ provide: AuthGuard, useClass: AuthGuard},
{ provide: AuthenticationService, useClass: ByteAuthenticationService },
{ provide: HTTP_INTERCEPTORS, useClass: AuthenticationFakeBackendInterceptor, multi: true},
{ provide: HTTP_INTERCEPTORS, useClass: SettingsFakeBackendInterceptor, multi: true },
//{ provide: HTTP_INTERCEPTORS, useClass: CustomProgramsFakeBackendInterceptor, multi: true },
// { provide: HTTP_INTERCEPTORS, useClass: AgentFakeBackendInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: CustomProgramsFakeBackendInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: AgentFakeBackendInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: OperativeDashboardFakeBackendInterceptor, multi: true },
//{ provide: HTTP_INTERCEPTORS, useClass: AirportFakeBackendInterceptor, multi: true },
//{ provide: HTTP_INTERCEPTORS, useClass: PassengerFakeBackendInterceptor, multi: true },
//{ provide: HTTP_INTERCEPTORS, useClass: BookingAgentFakeBackendInterceptor, multi: true },
//{ provide: HTTP_INTERCEPTORS, useClass: PaymentFakeBackendInterceptor, multi: true },
{ provide: APP_INITIALIZER, useFactory: init_app, deps: [InitCommonsService, TranslateService], multi: true }
],
......@@ -144,4 +162,4 @@ export function init_app(appLoaderService: InitCommonsService) {
// Para OAUTH
export function loginLoaderFactory(provider: OAuthAuthenticationService) {
return () => provider.login(null, null).toPromise();
}
\ No newline at end of file
}
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable, of, throwError } from "rxjs";
import * as source from '../../assets/fake-data/airport-data.json';
import { delay, dematerialize, materialize, mergeMap } from "rxjs/operators";
import { DIRECTION, SortField } from "@xdf/commons";
const basePath = './service/airport';
@Injectable()
export class AirportFakeBackendInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const {url, method, headers, body} = req;
const data = (source as any).default;
return of(null)
.pipe(mergeMap(handleRoute))
.pipe(materialize())
.pipe(delay(50))
.pipe(dematerialize());
function handleRoute() {
switch(true) {
case url.endsWith(basePath + '/page') && method === 'POST':
return pagination(body);
case url.match(".*" + basePath) && method === 'GET':
console.log(url);
return getOne(url);
default:
return next.handle(req);
}
}
function pagination(body) {
body.totalPages = 1;
body.totalItems = 2;
const page_number = body.currentPage;
const page_size = body.itemsPerPage ? body.itemsPerPage : 5;
if(body.sortFields.length > 0) {
const sortField: SortField = body.sortFields[0];
const sign = sortField.direction === DIRECTION.asc ? 1: -1;
data.sort(function (a, b){
if((typeof a[sortField.field] === 'number') && (typeof b[sortField.field] === 'number')) {
if(a[sortField.field] > b[sortField.field]) {
return 1 * sign;
} else if (a[sortField.field] < b[sortField.field]) {
return -1 * sign;
}
return 0;
} else {
return a[sortField.field].localeCompare(b[sortField.field]) * sign;
}
});
}
body.data = data.slice(page_number * page_size, (page_number + 1) * page_size);
return ok(body);
}
function getData() {
return ok(data);
}
function ok(bodyContent?) {
return of(new HttpResponse({ status: 200, body: bodyContent}));
}
function error(message: string) {
return throwError({error: {message}});
}
function getOne(url: string) {
return ok(data);
}
}
}
\ No newline at end of file
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable, of, throwError } from "rxjs";
import * as source from '../../assets/fake-data/agent-data.json';
import { delay, dematerialize, materialize, mergeMap } from "rxjs/operators";
import { DIRECTION, SortField } from "@xdf/commons";
const basePath = './service/agent';
@Injectable()
export class BookingAgentFakeBackendInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const {url, method, headers, body} = req;
const data = (source as any).default;
return of(null)
.pipe(mergeMap(handleRoute))
.pipe(materialize())
.pipe(delay(50))
.pipe(dematerialize());
function handleRoute() {
switch(true) {
case url.endsWith(basePath + '/page') && method === 'POST':
return pagination(body);
case url.match(".*" + basePath) && method === 'GET':
console.log(url);
return getOne(url);
default:
return next.handle(req);
}
}
function pagination(body) {
body.totalPages = 1;
body.totalItems = 2;
const page_number = body.currentPage;
const page_size = body.itemsPerPage ? body.itemsPerPage : 5;
if(body.sortFields.length > 0) {
const sortField: SortField = body.sortFields[0];
const sign = sortField.direction === DIRECTION.asc ? 1: -1;
data.sort(function (a, b){
if((typeof a[sortField.field] === 'number') && (typeof b[sortField.field] === 'number')) {
if(a[sortField.field] > b[sortField.field]) {
return 1 * sign;
} else if (a[sortField.field] < b[sortField.field]) {
return -1 * sign;
}
return 0;
} else {
return a[sortField.field].localeCompare(b[sortField.field]) * sign;
}
});
}
body.data = data.slice(page_number * page_size, (page_number + 1) * page_size);
return ok(body);
}
function getData() {
return ok(data);
}
function ok(bodyContent?) {
return of(new HttpResponse({ status: 200, body: bodyContent}));
}
function error(message: string) {
return throwError({error: {message}});
}
function getOne(url: string) {
return ok(data);
}
}
}
\ No newline at end of file
import {
HttpRequest,
HttpResponse,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpErrorResponse
} from '@angular/common/http';
import { Observable, throwError, of, EMPTY } from 'rxjs';
import { Injectable } from '@angular/core';
import { catchError, tap, map } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core';
import { NotificationService, NotificationType, AuthenticationService } from '@xdf/commons';
import { Router } from '@angular/router';
import { ConflictErrorDialogService } from '@xdf/gallery';
@Injectable()
export class CustomErrorHandlerInterceptor implements HttpInterceptor {
constructor(
private router: Router,
private translate: TranslateService,
private authenticationService: AuthenticationService,
private notificationService: NotificationService,
private conflictErrorDialogService: ConflictErrorDialogService) {
}
intercept(
req: HttpRequest<any>, next: HttpHandler): Observable<any> {
return next.handle(req).pipe(
catchError((error: HttpErrorResponse) => {
switch (error.status) {
case 401:
const message = this.translate.instant('message.error.unauthorized');
this.notificationService.showMessage(message, this.translate.instant('title.error'), NotificationType.error);
break;
case 404:
const messageError = error.error ? error.error : error.message;
this.notificationService.showMessage(messageError, this.translate.instant('title.error'), NotificationType.error);
break;
case 409:
const messageDuplicate = this.translate.instant('message.error.duplicated');
this.notificationService.showMessage(messageDuplicate, this.translate.instant('title.error'), NotificationType.error);
break;
case 419: // validar cual es el código correcto
this.conflictErrorDialogService.loadComponent(
null,
'title.error.conflict',
'message.error.conflict',
error.error);
break;
default:
if (error.status === 0) {
this.authenticationService.login(null, null).subscribe(
data => {
window.location.href = './';
});
} else {
let messageDefault = '';
if (error.error) {
if (error.error.params) {
const params = [];
error.error.params.forEach(element => {
params.push(this.translate.instant(element));
});
messageDefault = this.translate.instant(error.error.message, params);
} else {
if (error.error.message) {
messageDefault = this.translate.instant(error.error.message);
} else {
messageDefault = this.translate.instant(error.error);
}
}
} else {
messageDefault = this.translate.instant(error.message);
}
this.notificationService.showMessage(messageDefault, this.translate.instant('title.error'), NotificationType.error);
}
}
return throwError(error);
})
);
}
}
......@@ -28,7 +28,7 @@ export class CustomProgramsFakeBackendInterceptor implements HttpInterceptor {
case url.match('.*' + basePath) && method === 'GET':
return getList();
case url.match('.*'+ basePathCotnrols + '.*') && method === 'GET':
case url.match('.*' + basePathCotnrols + '.*') && method === 'GET':
return getControls();
default:
// pass through any requests not handled above
......
import { HttpResponse } from '@angular/common/http';
import { of, throwError } from "rxjs";
export function ok(bodyContent?) {
return of(new HttpResponse({ status: 200, body: bodyContent }));
}
export function error(message: string) {
return throwError({ error: { message } });
}
\ No newline at end of file
import { HttpRequest, HttpResponse, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Observable, of, throwError } from 'rxjs';
import { delay, mergeMap, materialize, dematerialize } from 'rxjs/operators';
import { Injectable } from '@angular/core';
import * as source from '../../assets/fake-data/operative-dashboard-data.json';
const basePath = '/test';
@Injectable()
export class OperativeDashboardFakeBackendInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const { url, method, headers, body } = request;
const data = (source as any).default;
return of(null)
.pipe(mergeMap(handleRoute))
.pipe(materialize())
.pipe(delay(50))
.pipe(dematerialize());
function handleRoute() {
switch (true) {
case url.match('.*' + basePath) && method === 'POST':
return getData();
default:
// pass through any requests not handled above
return next.handle(request);
}
}
function getData() {
return ok(data);
}
// helper functions
function ok(bodyContent?) {
return of(new HttpResponse({ status: 200, body: bodyContent }));
}
function error(message: string) {
return throwError({ error: { message } });
}
}
}
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable, of, throwError } from "rxjs";
import * as source from '../../assets/fake-data/passenger-data.json';
import { delay, dematerialize, materialize, mergeMap } from "rxjs/operators";
import { DIRECTION, SortField } from "@xdf/commons";
const basePath = './service/passenger';
@Injectable()
export class PassengerFakeBackendInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const {url, method, headers, body} = req;
const data = (source as any).default;
return of(null)
.pipe(mergeMap(handleRoute))
.pipe(materialize())
.pipe(delay(50))
.pipe(dematerialize());
function handleRoute() {
switch(true) {
case url.endsWith(basePath + '/page') && method === 'POST':
return pagination(body);
case url.match(".*" + basePath) && method === 'GET':
console.log(url);
return getOne(url);
default:
return next.handle(req);
}
}
function pagination(body) {
body.totalPages = 1;
body.totalItems = 2;
const page_number = body.currentPage;
const page_size = body.itemsPerPage ? body.itemsPerPage : 5;
if(body.sortFields.length > 0) {
const sortField: SortField = body.sortFields[0];
const sign = sortField.direction === DIRECTION.asc ? 1: -1;
data.sort(function (a, b){
if((typeof a[sortField.field] === 'number') && (typeof b[sortField.field] === 'number')) {
if(a[sortField.field] > b[sortField.field]) {
return 1 * sign;
} else if (a[sortField.field] < b[sortField.field]) {
return -1 * sign;
}
return 0;
} else {
return a[sortField.field].localeCompare(b[sortField.field]) * sign;
}
});
}
body.data = data.slice(page_number * page_size, (page_number + 1) * page_size);
return ok(body);
}
function getData() {
return ok(data);
}
function ok(bodyContent?) {
return of(new HttpResponse({ status: 200, body: bodyContent}));
}
function error(message: string) {
return throwError({error: {message}});
}
function getOne(url: string) {
return ok(data);
}
}
}
\ No newline at end of file
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { Observable, of, throwError } from "rxjs";
import * as source from '../../assets/fake-data/payment-data.json';
import { delay, dematerialize, materialize, mergeMap } from "rxjs/operators";
import { DIRECTION, SortField } from "@xdf/commons";
const basePath = './service/payment';
@Injectable()
export class PaymentFakeBackendInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const {url, method, headers, body} = req;
const data = (source as any).default;
return of(null)
.pipe(mergeMap(handleRoute))
.pipe(materialize())
.pipe(delay(50))
.pipe(dematerialize());
function handleRoute() {
switch(true) {
case url.endsWith(basePath + '/page') && method === 'POST':
return pagination(body);
case url.match(".*" + basePath) && method === 'GET':
console.log(url);
return getOne(url);
default:
return next.handle(req);
}
}
function pagination(body) {
body.totalPages = 1;
body.totalItems = 2;
const page_number = body.currentPage;
const page_size = body.itemsPerPage ? body.itemsPerPage : 5;
if(body.sortFields.length > 0) {
const sortField: SortField = body.sortFields[0];
const sign = sortField.direction === DIRECTION.asc ? 1: -1;
data.sort(function (a, b){
if((typeof a[sortField.field] === 'number') && (typeof b[sortField.field] === 'number')) {
if(a[sortField.field] > b[sortField.field]) {
return 1 * sign;
} else if (a[sortField.field] < b[sortField.field]) {
return -1 * sign;
}
return 0;
} else {
return a[sortField.field].localeCompare(b[sortField.field]) * sign;
}
});
}
body.data = data.slice(page_number * page_size, (page_number + 1) * page_size);
return ok(body);
}
function getData() {
return ok(data);
}
function ok(bodyContent?) {
return of(new HttpResponse({ status: 200, body: bodyContent}));
}
function error(message: string) {
return throwError({error: {message}});
}
function getOne(url: string) {
return ok(data);
}
}
}
\ No newline at end of file
......@@ -12,7 +12,7 @@ import { CountryDataForWizardResolver } from './resolver/country-data-wizard.res
const routes: Routes = [
{
path: 'agent', component: AgentListComponent, canActivate: [AuthGuard, ResourceAuthGuard],
path: 'agent', component: AgentListComponent, canActivate: [AuthGuard, ResourceAuthGuard],
data: {
program: 'CONVERSATIONAL_AGENT',
// breadcrumb: ''
......@@ -20,7 +20,7 @@ const routes: Routes = [
},
{
path: 'agent/detail/new',
//component: AgentDetailComponent,
// component: AgentDetailComponent,
component: AgentComponent,
resolve: {
countryData : CountryDataForWizardResolver
......@@ -36,7 +36,7 @@ const routes: Routes = [
},
{
path: 'agent/detail/edit/:code',
//component: AgentDetailComponent,
// component: AgentDetailComponent,
component: AgentComponent,
resolve: {
agentDetail: AgentDetailResolver,
......@@ -50,9 +50,9 @@ const routes: Routes = [
breadcrumb: 'Agentes',
backButton: true
}
},{
}, {
path: 'agent/detail/view/:code',
//component: AgentDetailComponent,
// component: AgentDetailComponent,
component: AgentComponent,
resolve: {
agentDetail: AgentDetailResolver,
......
......@@ -6,7 +6,15 @@ import {NgxTributeModule} from 'ngx-tribute';
import { MaterialFileInputModule } from 'ngx-material-file-input';
import { XdfGalleryModule } from '@xdf/gallery';
import { MatProgressSpinnerModule, MatDividerModule, MatSidenavModule, MatListModule, MatStepperModule, MatDialogModule, MatMenuModule, MatIconModule, MatSlideToggleModule, MatCheckboxModule, MatRippleModule, MatNativeDateModule, MatChipsModule, MatExpansionModule, MatTooltipModule, MatToolbarModule, MatTabsModule, MatTableModule, MatSortModule, MatSelectModule, MatRadioModule, MatPaginatorModule, MatInputModule, MatFormFieldModule, MatButtonToggleModule, MatButtonModule, MatCardModule, MatAutocompleteModule, MatSnackBarModule, MatProgressBarModule } from '@angular/material';
import { MatProgressSpinnerModule, MatDividerModule, MatSidenavModule, MatListModule } from '@angular/material';
import { MatStepperModule, MatDialogModule, MatMenuModule, MatIconModule } from '@angular/material';
import { MatSlideToggleModule, MatCheckboxModule, MatRippleModule, MatNativeDateModule } from '@angular/material';
import { MatChipsModule, MatExpansionModule, MatTooltipModule, MatToolbarModule } from '@angular/material';
import { MatTabsModule, MatTableModule, MatSortModule, MatSelectModule, MatRadioModule } from '@angular/material';
import { MatPaginatorModule, MatInputModule, MatFormFieldModule, MatButtonToggleModule } from '@angular/material';
import { MatButtonModule, MatCardModule, MatAutocompleteModule, MatSnackBarModule } from '@angular/material';
import { MatProgressBarModule } from '@angular/material';
import { SlickCarouselModule } from 'ngx-slick-carousel';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
......@@ -23,17 +31,15 @@ import { CaDeploymentChannelsModalComponent } from './view/components/ca-deploym
import { AgentStatusPipe } from './pipe/agent-status.pipe';
import { CaFileUploadModalComponent } from './view/components/ca-file-upload-modal/ca-file-upload-modal.component';
@NgModule({
entryComponents: [
CaDeploymentChannelsModalComponent,
CaFileUploadModalComponent
],
declarations: [
AgentComponent,
AgentListComponent,
AgentDetailComponent,
declarations: [
AgentComponent,
AgentListComponent,
AgentDetailComponent,
DynamicTranslatePipe,
CaGeneralInformationComponent,
CaFrequentQuestionsComponent,
......
......@@ -11,7 +11,7 @@ export class DynamicTranslatePipe implements PipeTransform {
}
transform(value: any, ...args: any[]): any {
let lang = this.translateService.currentLang ? this.translateService.currentLang : this.translateService.defaultLang;
const lang = this.translateService.currentLang ? this.translateService.currentLang : this.translateService.defaultLang;
let traductions;
......
......@@ -5,7 +5,7 @@ import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class AgentDataForWizardResolver implements Resolve<any> {
constructor(private service: AgentService) {}
resolve(
......@@ -13,8 +13,8 @@ export class AgentDataForWizardResolver implements Resolve<any> {
state: RouterStateSnapshot
): Observable<any>|Promise<any>|any {
let code = route.paramMap.get('code');
const code = route.paramMap.get('code');
return this.service.getDataForWizard(parseInt(code));
return this.service.getDataForWizard(parseInt(code, 10));
}
}
......@@ -5,7 +5,7 @@ import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class AgentDetailResolver implements Resolve<any> {
constructor(private service: AgentService) {}
resolve(
......@@ -13,8 +13,8 @@ export class AgentDetailResolver implements Resolve<any> {
state: RouterStateSnapshot
): Observable<any>|Promise<any>|any {
let code = route.paramMap.get('code');
const code = route.paramMap.get('code');
return this.service.getResult(code);
}
}
......@@ -5,7 +5,7 @@ import { Observable } from 'rxjs';
@Injectable({ providedIn: 'root' })
export class CountryDataForWizardResolver implements Resolve<any> {
constructor(private service: AgentService) {}
resolve(
......
......@@ -21,7 +21,7 @@ export class AgentService extends DynaDataService {
};
}
return this.httpClient.get(this.serviceURL + '/connection/data', {
params: params
params
});
}
......@@ -40,7 +40,7 @@ export class AgentService extends DynaDataService {
return this.httpClient.get(this.serviceURL + '/channels');
}
synchronize(id: number, user:string) {
synchronize(id: number, user: string) {
return this.httpClient.get(this.serviceURL + '/synchronize/' + id, {
params: {
user
......
import { Component, OnInit, ViewChild, ViewContainerRef, Input } from '@angular/core';
import { Component, OnInit, ViewChild, ViewContainerRef, Input, AfterViewInit } from '@angular/core';
import { MatPaginator, MatSort } from '@angular/material';
import { ColumnTemplate, DynaDataSource, ConfirmationDialogService, extractRSQL, FieldFilter } from '@xdf/gallery';
import { Pagination, SortField, NotificationType, NotificationService, AuthenticationService } from '@xdf/commons';
......@@ -135,7 +135,9 @@ const columnTemplateArray = [
const fieldFilters = [
new FieldFilter('agent_code', 'id', 'id', 'number', undefined),
new FieldFilter('agent_name', 'name', 'name', 'string', undefined),
new FieldFilter('agent_status', 'status', 'status', 'valpos', ({ 'DP': 'label.deployed', 'PS': 'label.sync-pending' }) as any),
new FieldFilter('agent_status', 'status', 'status', 'valpos', (
{ DP: 'label.deployed', PS: 'label.sync-pending' }
) as any),
];
@Component({
......@@ -143,7 +145,7 @@ const fieldFilters = [
templateUrl: './agent-list.component.html',
styleUrls: ['./agent-list.component.scss']
})
export class AgentListComponent implements OnInit {
export class AgentListComponent implements OnInit, AfterViewInit {
@ViewChild(MatPaginator, { static: false }) paginator: MatPaginator;
@ViewChild(MatSort, { static: false }) sort: MatSort;
......@@ -232,7 +234,7 @@ export class AgentListComponent implements OnInit {
this.pagination.currentPage = 0;
this.pagination.itemsPerPage = this.pagingSize;
this.pagination.filterExpression = "id != 0";
this.pagination.filterExpression = 'id != 0';
// Ordenación por defecto
if (this.sortColumn && this.sortDirection) {
......@@ -264,14 +266,14 @@ export class AgentListComponent implements OnInit {
for (let i = 0; i < tagsTemp.length; i++) {
if (tagsTemp[i].column !== 'id') {
tagsTemp[i].value = tagsTemp[i].value;
tagsTemp[i].value = tags[i].value;
}
}
this.pagination.filterExpression = extractRSQL(tagsTemp);
if (this.pagination.filterExpression == null || this.pagination.filterExpression == undefined) {
this.pagination.filterExpression = "id != 0";
if (this.pagination.filterExpression === null || this.pagination.filterExpression === undefined) {
this.pagination.filterExpression = 'id != 0';
}
this.dataSource.load(this.pagination);
......@@ -289,9 +291,10 @@ export class AgentListComponent implements OnInit {
if (result) {
this.agentService.delete(item.id).subscribe((rslt: any) => {
if (rslt.statusCode != 200) {
if (rslt.statusCode !== 200) {
this.notificationService.showMessage(
this.translateService.instant(rslt.message), this.translateService.instant('label.error.message.title'), NotificationType.error);
this.translateService.instant(rslt.message), this.translateService.instant('label.error.message.title'),
NotificationType.error);
} else {
this.dataSource.load(this.pagination);
}
......@@ -308,10 +311,10 @@ export class AgentListComponent implements OnInit {
}
synchronize(item) {
let user = (this.authenticationService.currentUserValue ? this.authenticationService.currentUserValue.username : 'admin');
const user = (this.authenticationService.currentUserValue ? this.authenticationService.currentUserValue.username : 'admin');
this.agentService.synchronize(item.id, user).pipe(first()).subscribe(() => {
this.notificationService.showMessage(this.translateService.instant("agent.synchronize.success"), undefined, NotificationType.success);
this.notificationService.showMessage(this.translateService.instant('agent.synchronize.success'), undefined, NotificationType.success);
this.onRefresh();
});
}
......
......@@ -15,7 +15,7 @@
{{'label.general-information.description' | translate}}
</div>
</ng-template>
<byte-ca-general-information [stepper]="stepper" (onNextPage)="updateDirtyStatus($event)"></byte-ca-general-information>
<byte-ca-general-information [stepper]="stepper" (nextPage)="updateDirtyStatus($event)"></byte-ca-general-information>
</mat-step>
<mat-step state="questions">
......@@ -25,7 +25,7 @@
{{'label.questions.description' | translate}}
</div>
</ng-template>
<byte-ca-frequent-questions [stepper]="stepper" (onNextPage)="updateDirtyStatus($event)"></byte-ca-frequent-questions>
<byte-ca-frequent-questions [stepper]="stepper" (nextPage)="updateDirtyStatus($event)"></byte-ca-frequent-questions>
</mat-step>
<mat-step state="deployment-channels">
......
import { Component, OnInit, ViewChild, Input, AfterContentChecked, AfterViewInit, ChangeDetectionStrategy, AfterContentInit, ViewContainerRef } from '@angular/core';
import { Component, OnInit, ViewChild, Input, AfterContentChecked, AfterViewInit } from '@angular/core';
import { ChangeDetectionStrategy, AfterContentInit, ViewContainerRef } from '@angular/core';
import { FormGroup, Validators, FormBuilder } from '@angular/forms';
import { CaGeneralInformationComponent } from '../components/ca-general-information/ca-general-information.component';
import { MAT_STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper';
import { STEPPER_GLOBAL_OPTIONS } from '@angular/cdk/stepper';
import { ActivatedRoute, Router } from '@angular/router';
import { NavigationService } from '@xdf/layouts';
import { IDirty } from '@xdf/gallery';
......@@ -14,7 +15,7 @@ import { CaDeploymentChannelsComponent } from '../components/ca-deployment-chann
templateUrl: './agent.component.html',
styleUrls: ['./agent.component.scss'],
providers: [{
provide: MAT_STEPPER_GLOBAL_OPTIONS, useValue: { displayDefaultIndicatorType: false }
provide: STEPPER_GLOBAL_OPTIONS, useValue: { displayDefaultIndicatorType: false }
}]
})
......@@ -38,18 +39,18 @@ export class AgentComponent implements OnInit, IDirty {
resourceAuth: any;
//dirty acumulado
generalDirty: boolean = false;
// dirty acumulado
generalDirty = false;
constructor(
private _vcRef: ViewContainerRef,
private _activatedRoute: ActivatedRoute,
private _backService: NavigationService,
private _router: Router
private vcRef: ViewContainerRef,
private activatedRoute: ActivatedRoute,
private backService: NavigationService,
private router: Router
) {
this._backService.backAnnounced$.subscribe(data => {
this._router.navigate(['/configuration/agent']);
this.backService.backAnnounced$.subscribe(data => {
this.router.navigate(['/configuration/agent']);
});
}
......@@ -60,21 +61,21 @@ export class AgentComponent implements OnInit, IDirty {
|| this.frequentQuestionsComponent.isDirty();
if (dirty) {
dirty = this.deploymentChannelsComponent.isDirty()
dirty = this.deploymentChannelsComponent.isDirty();
}
return dirty;
}
getRef(): ViewContainerRef {
return this._vcRef;
return this.vcRef;
}
ngOnInit() {
this.stepper.selectedIndex = 0;
const authList = this._activatedRoute.snapshot.paramMap['authorization'];
const authList = this.activatedRoute.snapshot.paramMap['authorization'];
this.resourceAuth = new Object();
......@@ -86,13 +87,13 @@ export class AgentComponent implements OnInit, IDirty {
console.log(this.resourceAuth);
this.isNew = this._activatedRoute.snapshot.data.mode === 'create';
this.isNew = this.activatedRoute.snapshot.data.mode === 'create';
if (this.isNew) {
this.agentDetail = {
};
} else {
this.agentDetail = this._activatedRoute.snapshot.data.agentDetail;
this.agentDetail = this.activatedRoute.snapshot.data.agentDetail;
}
......
......@@ -10,7 +10,7 @@ export class CaDeploymentChannelsModalComponent implements OnInit {
channels: Array<any>;
selectedChannel: any;
applicationSettings:any;
applicationSettings: any;
constructor(
public dialogRef: MatDialogRef<CaDeploymentChannelsModalComponent>,
......
......@@ -6,7 +6,8 @@ import { first } from 'rxjs/operators';
import { NotificationType, NotificationService } from '@xdf/commons';
import { TranslateService } from '@ngx-translate/core';
import { Router, ActivatedRoute } from '@angular/router';
import { Form, FormControl, FormGroup, FormGroupDirective, NgForm } from '@angular/forms';
import { Form, FormArray, FormControl, FormGroup, FormGroupDirective, NgForm, Validators } from '@angular/forms';
import { ValidatorUtils } from '@xdf/gallery';
@Component({
selector: 'byte-ca-deployment-channels',
......@@ -15,9 +16,11 @@ import { Form, FormControl, FormGroup, FormGroupDirective, NgForm } from '@angul
})
export class CaDeploymentChannelsComponent implements OnInit {
@Input() stepper: MatStepper;
@Input()
stepper: MatStepper;
@Input() changes: boolean = false;
@Input()
changes: boolean = false;
@ViewChild('fieldForm', {static: false})
fieldFormList: any;
......@@ -25,13 +28,15 @@ export class CaDeploymentChannelsComponent implements OnInit {
agentDetail: any;
channels: Array<any>;
deploymentChannels: Array<any> = new Array<any>();
dirty: boolean = true;
dirty = true;
step = -1;
viewMode: boolean = false;
isAvaliableChannels: boolean = false;
mode: string = 'new';
detailText: string = "Detail";
titleText: string = "Titulo"
viewMode = false;
isAvaliableChannels = false;
mode = 'new';
detailText = 'Detail';
titleText = 'Titulo';
isLoadingDataChannel = true;
formGroup: FormGroup;
constructor(
private activatedRoute: ActivatedRoute,
......@@ -39,12 +44,12 @@ export class CaDeploymentChannelsComponent implements OnInit {
private matDialog: MatDialog,
private translateService: TranslateService,
private notificationService: NotificationService,
private router: Router
private router: Router,
private validatorUtils: ValidatorUtils
) {
this.formGroup = new FormGroup({});
this.mode = this.activatedRoute.snapshot.data.mode;
this.viewMode = this.mode === 'view';
}
ngOnInit() {
......@@ -58,6 +63,9 @@ export class CaDeploymentChannelsComponent implements OnInit {
this.buildList();
this.buildAvaliableChannels();
this.isLoadingDataChannel = false;
}, error => {
this.isLoadingDataChannel = false;
});
}
......@@ -70,8 +78,8 @@ export class CaDeploymentChannelsComponent implements OnInit {
buildList() {
if (this.channels && this.deploymentChannels) {
for (let deploymentChannel of this.deploymentChannels) {
for (let channel of this.channels) {
for (const deploymentChannel of this.deploymentChannels) {
for (const channel of this.channels) {
if (channel.id === deploymentChannel.channelId) {
......@@ -81,17 +89,21 @@ export class CaDeploymentChannelsComponent implements OnInit {
deploymentChannel.suggestTitle = channel.suggestTitle;
deploymentChannel.suggestDetail = channel.suggestDetail;
this.formGroup.addControl(channel.name, new FormGroup({}));
for (let parameter of deploymentChannel.parameters) {
for (let field of channel.parameters) {
for (const parameter of deploymentChannel.parameters) {
for (const field of channel.parameters) {
if (parameter.channelParamName === field.name) {
const formArray = this.formGroup.controls[channel.name] as FormGroup;
parameter.label = field.label;
parameter.type = field.type;
parameter.required = field.required;
parameter.traductions = field.traductions;
parameter.maxlength = field.maxlength;
parameter.regex = field.regex;
formArray.addControl(field.name, new FormControl('', field.required ? [Validators.required] : []));
break;
}
......@@ -103,14 +115,15 @@ export class CaDeploymentChannelsComponent implements OnInit {
}
}
}
console.log(this.formGroup);
}
buildAvaliableChannels() {
this.isAvaliableChannels = false;
mainLoop: for (let channel of this.channels) {
mainLoop: for (const channel of this.channels) {
channel.disabled = false;
for (let deploymentChannel of this.deploymentChannels) {
for (const deploymentChannel of this.deploymentChannels) {
if (channel.id === deploymentChannel.channelId) {
channel.disabled = true;
continue mainLoop;
......@@ -123,7 +136,7 @@ export class CaDeploymentChannelsComponent implements OnInit {
}
addChannel() {
let dialog = this.matDialog.open(CaDeploymentChannelsModalComponent, {
const dialog = this.matDialog.open(CaDeploymentChannelsModalComponent, {
width: '500px',
data: {
message: '',
......@@ -133,7 +146,7 @@ export class CaDeploymentChannelsComponent implements OnInit {
dialog.afterClosed().subscribe(result => {
if (result) {
let selectedChannel = { ...result };
const selectedChannel = { ...result };
selectedChannel.channelId = selectedChannel.id;
selectedChannel.channelName = selectedChannel.name;
......@@ -163,7 +176,7 @@ export class CaDeploymentChannelsComponent implements OnInit {
}
save() {
let isValid: boolean = this.validate();
const isValid: boolean = this.validate();
if (!isValid) {
if (this.fieldFormList && this.fieldFormList.control) {
......@@ -172,7 +185,7 @@ export class CaDeploymentChannelsComponent implements OnInit {
return;
}
let agent: any = {};
const agent: any = {};
agent.id = this.agentDetail.id;
agent.name = this.agentDetail.name;
......@@ -186,8 +199,8 @@ export class CaDeploymentChannelsComponent implements OnInit {
agent.status = this.agentDetail.status;
agent.deploymentChannels = [];
for (let deploymentChannel of this.deploymentChannels) {
let deploymentChannelTmp: any = {};
for (const deploymentChannel of this.deploymentChannels) {
const deploymentChannelTmp: any = {};
deploymentChannelTmp.id = deploymentChannel.id;
deploymentChannelTmp.name = deploymentChannel.name;
......@@ -195,8 +208,8 @@ export class CaDeploymentChannelsComponent implements OnInit {
deploymentChannelTmp.channelId = deploymentChannel.channelId;
deploymentChannelTmp.parameters = [];
for (let parameter of deploymentChannel.parameters) {
let parameterTmp: any = {};
for (const parameter of deploymentChannel.parameters) {
const parameterTmp: any = {};
parameterTmp.id = parameter.id;
parameterTmp.value = parameter.value;
......@@ -238,22 +251,22 @@ export class CaDeploymentChannelsComponent implements OnInit {
validate(): boolean {
let valid = true;
mainLoop: for (let deploymentChannel of this.deploymentChannels) {
let deploymentChannelTmp: any = {};
mainLoop: for (const deploymentChannel of this.deploymentChannels) {
const deploymentChannelTmp: any = {};
// if (!deploymentChannel.name) {
// valid = false;
// break;
// }
for (let parameter of deploymentChannel.parameters) {
for (const parameter of deploymentChannel.parameters) {
parameter.error = false;
if (!parameter.value) {
valid = false;
break mainLoop;
}
if (parameter.regex) {
let regex = new RegExp(parameter.regex);
const regex = new RegExp(parameter.regex);
if (!regex.test(parameter.value)) {
parameter.error = true;
valid = false;
......@@ -271,4 +284,9 @@ export class CaDeploymentChannelsComponent implements OnInit {
return valid;
}
getErrors(channelName: string, name: string, placeholder: string) {
const channelFormGroup = (this.formGroup.controls[channelName] as FormGroup);
return channelFormGroup ? this.validatorUtils.getErrors(channelFormGroup.controls[name] as FormControl, name, placeholder) : [];
}
}
......@@ -12,9 +12,8 @@ table {
}
.title_header_popup {
i {
font-size: 28px;
padding-right: 20px;
color: red;
font-size: 28px;
padding-right: 20px;
color: red;
}
}
\ No newline at end of file
}
\ No newline at end of file
......@@ -39,19 +39,19 @@ export class CaFileUploadModalComponent implements OnInit {
dataSource = new MatTableDataSource([]);
displayedColumns: string[] = [];
applicationSettings:any;
applicationSettings: any;
constructor(
private formBuilder: FormBuilder,
private agentService: AgentService,
private _notificationService: NotificationService,
private _translateService: TranslateService,
private notificationService: NotificationService,
private translateService: TranslateService,
public dialogRef: MatDialogRef<CaFileUploadModalComponent>,
@Inject(MAT_DIALOG_DATA) public data: any
) {
this.formGroup = this.formBuilder.group({
description: new FormControl({ value: "", disabled: false }),
description: new FormControl({ value: '', disabled: false }),
file: new FormControl({ value: '', disabled: false }),
filename: new FormControl({ value: '', disabled: true })
});
......@@ -72,20 +72,20 @@ export class CaFileUploadModalComponent implements OnInit {
buildErrorDetail(status, detail) {
this.fileErrorDetail = undefined;
if ("CONTENT_ERROR" === status) {
if ('CONTENT_ERROR' === status) {
this.displayedColumns = ['line', 'type', 'value'];
if (detail) {
let fileErrorDetailTemp = [];
const fileErrorDetailTemp = [];
for (let line of Object.keys(detail)) {
let object = detail[line];
for (const line of Object.keys(detail)) {
const object = detail[line];
let type = Object.keys(object)[0];
const type = Object.keys(object)[0];
fileErrorDetailTemp.push({
line: line,
type: type,
line,
type,
value: object[type],
});
}
......@@ -97,18 +97,18 @@ export class CaFileUploadModalComponent implements OnInit {
}
} else if ("HEADER_ERROR" === status) {
} else if ('HEADER_ERROR' === status) {
this.displayedColumns = ['header', 'value'];
if (detail) {
let fileErrorDetailTemp = [];
const fileErrorDetailTemp = [];
for (let header of Object.keys(detail)) {
let value = detail[header];
for (const header of Object.keys(detail)) {
const value = detail[header];
fileErrorDetailTemp.push({
header: header,
value: value,
header,
value,
});
}
......@@ -131,17 +131,17 @@ export class CaFileUploadModalComponent implements OnInit {
if (event[i] instanceof File) {
const reader = new FileReader();
reader.onload = () => {
//this.formGroup.controls['imageAvatar'].setValue(reader.result as string);
// this.formGroup.controls['imageAvatar'].setValue(reader.result as string);
};
reader.readAsDataURL(event[i]);
let fileSelected = {
const fileSelected = {
data: event[i],
state: 'in',
inProgress: false,
progress: 0,
canRetry: false
}
};
this.validateFile(fileSelected);
}
......@@ -174,12 +174,12 @@ export class CaFileUploadModalComponent implements OnInit {
if (typeof (event) === 'object') {
this.fileErrorDetail = undefined;
this.enabledOK = false;
let info = event.body;
const info = event.body;
this.fileInfo = new FileUploadModel();
if (info) {
let status = info.fileValidationResult.status;
const status = info.fileValidationResult.status;
if ("OK" === status) {
if ('OK' === status) {
this.fileInfo.id = info.id;
this.fileInfo.description = this.formGroup.controls.description.value;
this.fileInfo.uuid = info.uuid;
......@@ -191,20 +191,21 @@ export class CaFileUploadModalComponent implements OnInit {
this.enabledOK = true;
this.fileErrorDetail = undefined;
} else if ("INCOMPATIBLE_EXTENSION" === status) {
} else if ('INCOMPATIBLE_EXTENSION' === status) {
this.formGroup.controls.file.setValue(null);
let message = "label.file.incompatible.extension";
const message = 'label.file.incompatible.extension';
this.enabledOK = false;
this.fileErrorDetail = undefined;
this._notificationService.showMessage(this._translateService.instant(message) + "[" + this.accept + "]", null, NotificationType.error);
this.notificationService.showMessage(this.translateService.instant(message)
+ '[' + this.accept + ']', null, NotificationType.error);
} else if ("CONTENT_ERROR" === status) {
} else if ('CONTENT_ERROR' === status) {
this.formGroup.controls.file.setValue(null);
this.enabledOK = false;
this.buildErrorDetail(status, info.fileValidationResult.recordsErrorMap);
} else if ("HEADER_ERROR" === status) {
} else if ('HEADER_ERROR' === status) {
this.formGroup.controls.file.setValue(null);
this.enabledOK = false;
......
......@@ -169,5 +169,4 @@ th.mat-header-cell {
::ng-deep .text-right > .mat-sort-header-container {
justify-content: flex-end !important;
}
\ No newline at end of file
}
\ No newline at end of file
import { Component, OnInit, Input, ViewContainerRef, ViewChild, Output, EventEmitter } from '@angular/core';
import { Component, OnInit, Input, ViewContainerRef, ViewChild, Output } from '@angular/core';
import { AfterViewInit, EventEmitter } from '@angular/core';
import { MatStepper, MatDialog, MatTableDataSource, MatSort } from '@angular/material';
import { ActivatedRoute, Router } from '@angular/router';
import { animate, trigger, state, transition, style } from '@angular/animations';
......@@ -19,13 +20,15 @@ import { CaFileUploadModalComponent, FileUploadModel } from '../ca-file-upload-m
])
]
})
export class CaFrequentQuestionsComponent implements OnInit {
export class CaFrequentQuestionsComponent implements OnInit, AfterViewInit {
@ViewChild(MatSort, { static: false }) sort: MatSort;
@Input() stepper: MatStepper;
@Input()
stepper: MatStepper;
@Output() onNextPage: EventEmitter<boolean> = new EventEmitter<boolean>();
@Output()
nextPage: EventEmitter<boolean> = new EventEmitter<boolean>();
public resourceAuth = new Object();
dirty: boolean = false;
......@@ -38,29 +41,30 @@ export class CaFrequentQuestionsComponent implements OnInit {
dataSource = new MatTableDataSource<FileUploadModel>([]);
mapStatus = {
"LO": {
"class": "label label-primary",
"text": "label.status.loaded"
LO: {
class: 'label label-primary',
text: 'label.status.loaded'
},
"PS": {
"class": "label label-warning",
"text": "label.status.pending"
PS: {
class: 'label label-warning',
text: 'label.status.pending'
}
};
files = [];
viewMode: boolean;
constructor(protected route: ActivatedRoute,
constructor(
protected route: ActivatedRoute,
protected router: Router,
protected vcRef: ViewContainerRef,
protected authorizationService: AuthorizationService,
private translate: TranslateService,
private _activatedRoute: ActivatedRoute,
private activatedRoute: ActivatedRoute,
private matDialog: MatDialog
) {
this.viewMode = this._activatedRoute.snapshot.data.mode === 'view';
this.viewMode = this.activatedRoute.snapshot.data.mode === 'view';
}
......@@ -89,7 +93,7 @@ export class CaFrequentQuestionsComponent implements OnInit {
}
setDataForWizard(result: any) {
console.log(result)
console.log(result);
/*
this.protocols = result.connectionProtocolOptions;
this.generalProperties = result.generalProperties;
......@@ -112,15 +116,15 @@ export class CaFrequentQuestionsComponent implements OnInit {
}
addFile() {
let dialog = this.matDialog.open(CaFileUploadModalComponent, {
const dialog = this.matDialog.open(CaFileUploadModalComponent, {
width: '600px',
data: null
});
dialog.afterClosed().subscribe(result => {
if (result) {
let fileAdded = { ...result };
let listTemp = this.dataSource.data;
const fileAdded = { ...result };
const listTemp = this.dataSource.data;
listTemp.push(fileAdded);
this.dataSource.data = listTemp;
this.dirty = true;
......@@ -131,27 +135,25 @@ export class CaFrequentQuestionsComponent implements OnInit {
onEditRecord(item, index) {
item.editable = true;
let dialog = this.matDialog.open(CaFileUploadModalComponent, {
const dialog = this.matDialog.open(CaFileUploadModalComponent, {
width: '500px',
data: item
});
dialog.afterClosed().subscribe(result => {
if (result) {
let fileEdited = { ...result };
let listTemp = this.dataSource.data;
if (result) {
const fileEdited = { ...result };
const listTemp = this.dataSource.data;
listTemp[index] = fileEdited;
this.dataSource.data = listTemp;
}
});
}
saveQuestions(validateForm: boolean) {
let success = true;
const success = true;
this.agentDetail.frequentQuestions = this.dataSource.data;
......@@ -159,7 +161,7 @@ export class CaFrequentQuestionsComponent implements OnInit {
}
onDeleteRecord(item, index) {
let listTemp = this.dataSource.data;
const listTemp = this.dataSource.data;
listTemp.splice(index, 1);
this.dataSource.data = listTemp;
this.dirty = true;
......@@ -176,7 +178,7 @@ export class CaFrequentQuestionsComponent implements OnInit {
}
if (this.saveQuestions(true)) {
this.onNextPage.emit(this.isDirty());
this.nextPage.emit(this.isDirty());
this.stepper.next();
}
}
......
......@@ -48,6 +48,9 @@
<mat-form-field class="amd-form-control">
<input matInput [placeholder]="'label.name' | translate" formControlName="name"
maxlength="50" required>
<!-- Borrar mat-error-->
<mat-error *ngFor="let error of getErrors('name', 'label.name')">{{ 'message.error.' + error.name | translate : error.prop}}
</mat-error>
</mat-form-field>
</div>
</div>
......@@ -58,6 +61,9 @@
[placeholder]="'label.description' | translate" maxlength="200"
formControlName="description" #autosize="cdkTextareaAutosize" cdkAutosizeMinRows="3"
cdkAutosizeMaxRows="6" required></textarea>
<!-- Borrar mat-error-->
<mat-error *ngFor="let error of getErrors('description', 'label.description')">{{ 'message.error.' + error.name | translate : error.prop}}
</mat-error>
</mat-form-field>
</div>
</div>
......@@ -67,6 +73,9 @@
<input matInput [placeholder]="'label.version' | translate" formControlName="version"
maxlength="15" required pattern="[0-9]{1,2}[.]{1}[0-9]{1,2}[.]{1}[0-9]{1,2}">
<mat-hint>##.##.##</mat-hint>
<!-- Borrar mat-error-->
<mat-error *ngFor="let error of getErrors('version', 'label.version')">{{ 'message.error.' + error.name | translate : error.prop}}
</mat-error>
</mat-form-field>
</div>
</div>
......@@ -79,6 +88,9 @@
{{country.name | translate}}
</mat-option>
</mat-select>
<!-- Borrar mat-error-->
<mat-error *ngFor="let error of getErrors('country', 'label.country')">{{ 'message.error.' + error.name | translate : error.prop}}
</mat-error>
</mat-form-field>
</div>
</div>
......@@ -91,6 +103,9 @@
{{timezone | translate}}
</mat-option>
</mat-select>
<!-- Borrar mat-error-->
<mat-error *ngFor="let error of getErrors('timezone', 'label.timezone')">{{ 'message.error.' + error.name | translate : error.prop}}
</mat-error>
</mat-form-field>
</div>
</div>
......@@ -102,6 +117,9 @@
{{language.name | translate}}
</mat-option>
</mat-select>
<!-- Borrar mat-error-->
<mat-error *ngFor="let error of getErrors('language', 'label.language')">{{ 'message.error.' + error.name | translate : error.prop}}
</mat-error>
</mat-form-field>
</div>
</div>
......@@ -113,6 +131,9 @@
{{type.name | translate}}
</mat-option>
</mat-select>
<!-- Borrar mat-error-->
<mat-error *ngFor="let error of getErrors('type', 'label.type')">{{ 'message.error.' + error.name | translate : error.prop}}
</mat-error>
</mat-form-field>
</div>
</div>
......
......@@ -5,6 +5,7 @@ import { ActivatedRoute } from '@angular/router';
import { animate, trigger, state, transition, style } from '@angular/animations';
import { NotificationService, NotificationType } from '@xdf/commons';
import { TranslateService } from '@ngx-translate/core';
import { ValidatorUtils } from '@xdf/gallery';
export const FILE_TYPE = {
image: /image.*/,
......@@ -25,17 +26,19 @@ export const FILE_TYPE = {
})
export class CaGeneralInformationComponent implements OnInit {
@Input() stepper: MatStepper;
@Input()
stepper: MatStepper;
@Output() onNextPage: EventEmitter<boolean> = new EventEmitter<boolean>();
@Output()
nextPage: EventEmitter<boolean> = new EventEmitter<boolean>();
agentDetail: any;
formGroup: FormGroup;
viewMode: boolean;
mode: string = 'new';
mode = 'new';
imageName = "imageAvatar";
imageName = 'imageAvatar';
urlBase = '';
countries = [];
......@@ -43,41 +46,42 @@ export class CaGeneralInformationComponent implements OnInit {
languages = [
{
"code": "ES",
"name": "Español"
code: 'ES',
name: 'Español'
}
];
types = [
{
"code": "FQ",
"name": "Agente de preguntas frecuentes"
code: 'FQ',
name: 'Agente de preguntas frecuentes'
}
];
acceptedImageTypes = ['image/png', 'image/jpeg', 'image/gif'];
acceptedTypes = "PNG, JPEG, GIF";
acceptedTypes = 'PNG, JPEG, GIF';
constructor(
private formBuilder: FormBuilder,
private _activatedRoute: ActivatedRoute,
private _notificationService: NotificationService,
private _translateService: TranslateService
private activatedRoute: ActivatedRoute,
private notificationService: NotificationService,
private translateService: TranslateService,
private validatorUtils: ValidatorUtils
) {
this.mode = this._activatedRoute.snapshot.data.mode;
this.mode = this.activatedRoute.snapshot.data.mode;
this.viewMode = this.mode === 'view';
this.countries = this._activatedRoute.snapshot.data.countryData;
this.countries = this.activatedRoute.snapshot.data.countryData;
this.formGroup = this.formBuilder.group({
name: new FormControl({ value: "", disabled: this.viewMode }),
description: new FormControl({ value: "", disabled: this.viewMode }),
version: new FormControl({ value: "", disabled: this.viewMode }),
imageAvatar: new FormControl({ value: "", disabled: this.viewMode }, { validators: [Validators.required] }),
country: new FormControl({ value: "", disabled: this.viewMode }),
timezone: new FormControl({ value: "", disabled: this.viewMode }),
language: new FormControl({ value: "", disabled: this.viewMode }),
type: new FormControl({ value: "", disabled: this.viewMode })
name: new FormControl({ value: '', disabled: this.viewMode }),
description: new FormControl({ value: '', disabled: this.viewMode }),
version: new FormControl({ value: '', disabled: this.viewMode }),
imageAvatar: new FormControl({ value: '', disabled: this.viewMode }, { validators: [Validators.required] }),
country: new FormControl({ value: '', disabled: this.viewMode }),
timezone: new FormControl({ value: '', disabled: this.viewMode }),
language: new FormControl({ value: '', disabled: this.viewMode }),
type: new FormControl({ value: '', disabled: this.viewMode })
});
}
......@@ -128,7 +132,7 @@ export class CaGeneralInformationComponent implements OnInit {
uploadFiles(event) {
for (const i in event) {
if (event[i] instanceof File) {
let eventTemp = event[i];
const eventTemp = event[i];
if (this.acceptedImageTypes.includes(eventTemp.type)) {
......@@ -138,15 +142,16 @@ export class CaGeneralInformationComponent implements OnInit {
};
reader.readAsDataURL(event[i]);
} else {
let message = "label.imageAvatar.incompatible.extension";
this._notificationService.showMessage(this._translateService.instant(message) + "[" + this.acceptedTypes + "]", null, NotificationType.error);
const message = 'label.imageAvatar.incompatible.extension';
this.notificationService.showMessage(this.translateService.instant(message) +
'[' + this.acceptedTypes + ']', null, NotificationType.error);
}
}
}
}
onCountryChange(obj, deleteTimeZone?: boolean) {
let selectedCountry = obj.value;
const selectedCountry = obj.value;
this.timezones = [];
if (deleteTimeZone) {
......@@ -154,7 +159,7 @@ export class CaGeneralInformationComponent implements OnInit {
}
if (selectedCountry) {
for (var index in this.countries) {
for (const index in this.countries) {
if (selectedCountry === this.countries[index].id) {
this.timezones = this.countries[index].timezones;
break;
......@@ -170,9 +175,13 @@ export class CaGeneralInformationComponent implements OnInit {
}
if (this.saveGeneralInformation(true)) {
this.onNextPage.emit(this.isDirty());
this.nextPage.emit(this.isDirty());
this.stepper.next();
}
}
getErrors(name: string, placeholder: string) {
return this.validatorUtils.getErrors(this.formGroup.controls[name] as FormControl, name, placeholder);
}
}
import { HttpClient, HttpEvent, HttpErrorResponse, HttpEventType } from '@angular/common/http';
import { map } from 'rxjs/operators';
import { HttpClient, HttpEvent, HttpErrorResponse, HttpEventType } from '@angular/common/http';
import { map } from 'rxjs/operators';
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class UploadService {
SERVER_URL: string = "./service/agent";
constructor(private httpClient: HttpClient) { }
public upload(formData) {
return this.httpClient.post<any>(this.SERVER_URL, formData, {
reportProgress: true,
observe: 'events'
});
@Injectable({
providedIn: 'root'
})
export class UploadService {
SERVER_URL = './service/agent';
constructor(private httpClient: HttpClient) { }
public upload(formData) {
return this.httpClient.post<any>(this.SERVER_URL, formData, {
reportProgress: true,
observe: 'events'
});
}
}
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { AuthGuard, ResourceAuthGuard } from '@xdf/security';
import { CrudDetailComponent, CrudGridComponent, DirtyGuard, RecordResolver, TemplateResolver } from '@xdf/gallery';
const routes: Routes = [
{
path: "airport",
component: CrudGridComponent,
canActivate: [AuthGuard, ResourceAuthGuard ],
resolve: {Template: TemplateResolver},
data: {
innerTemplate: 'none',
program: "airport",
breadcrumb: 'breadcrumb.airport'
},
},
{
path: 'airport/detail/:mode', component: CrudDetailComponent,
canActivate: [AuthGuard, ResourceAuthGuard],
canDeactivate: [DirtyGuard],
resolve: {record: RecordResolver},
data: {
program: 'airport',
breadcrumb: 'breadcrumb.airport.detail'
}
}
];
@NgModule({
imports: [
RouterModule.forChild(routes)
],
exports: [RouterModule]
})
export class AirportRoutingModule { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AirportRoutingModule } from './airport-routing.module';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { XdfGalleryModule } from '@xdf/gallery';
import { XdfSettingsModule } from '@xdf/settings';
@NgModule({
declarations: [],
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
TranslateModule,
XdfGalleryModule,
XdfSettingsModule,
AirportRoutingModule
]
})
export class AirportModule { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Routes } from '@angular/router';
import { CrudDetailComponent, CrudGridComponent, DirtyGuard, RecordResolver, TemplateResolver } from '@xdf/gallery';
import { AuthGuard, ResourceAuthGuard } from '@xdf/security';
const routes: Routes = [
{
path: "booking_agent", component: CrudGridComponent, canActivate: [AuthGuard, ResourceAuthGuard],
resolve: {Template: TemplateResolver},
data: {
innerTemplate: 'none',
program: "booking_agent",
breadcrumb: "breadcrumb.booking_agent"
},
},
{
path: 'booking_agent/detail/:mode', component: CrudDetailComponent, canActivate: [AuthGuard, ResourceAuthGuard], canDeactivate: [DirtyGuard],
resolve: {record: RecordResolver},
data: {
program: 'booking_agent',
breadcrumb: 'breadcrumb.booking_agent.detail'
}
}
]
@NgModule({
declarations: [],
imports: [
RouterModule.forChild(routes)
],
exports: [RouterModule]
})
export class BookingAgentRoutingModule { }
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { XdfGalleryModule } from '@xdf/gallery';
import { XdfSettingsModule } from '@xdf/settings';
import { BookingAgentRoutingModule } from './booking-agent-routing.module';
@NgModule({
declarations: [],
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
TranslateModule,
XdfGalleryModule,
XdfSettingsModule,
BookingAgentRoutingModule
]
})
export class BookingAgentModule { }
/*
* Inspinia js helpers:
*
* correctHeight() - fix the height of main wrapper
* detectBody() - detect windows size
* smoothlyMenu() - add smooth fade in/out on navigation show/ide
*
*/
// import * as jQuery_ from 'jquery';
// const jQuery = jQuery_;
declare var jQuery: any;
export function correctHeight() {
const pageWrapper = jQuery('#page-wrapper');
const navbarHeight = jQuery('nav.navbar-default').height();
const wrapperHeight = pageWrapper.height();
if (navbarHeight > wrapperHeight) {
pageWrapper.css('min-height', navbarHeight + 'px');
}
if (navbarHeight <= wrapperHeight) {
if (navbarHeight < jQuery(window).height()) {
pageWrapper.css('min-height', jQuery(window).height() + 'px');
} else {
pageWrapper.css('min-height', navbarHeight + 'px');
}
}
if (jQuery('body').hasClass('fixed-nav')) {
if (navbarHeight > wrapperHeight) {
pageWrapper.css('min-height', navbarHeight + 'px');
} else {
pageWrapper.css('min-height', jQuery(window).height() - 60 + 'px');
}
}
}
export function detectBody() {
if (jQuery(document).width() < 769) {
jQuery('body').addClass('body-small');
} else {
jQuery('body').removeClass('body-small');
}
}
export function smoothlyMenu() {
if (!jQuery('body').hasClass('mini-navbar') || jQuery('body').hasClass('body-small')) {
// Hide menu in order to smoothly turn on when maximize menu
jQuery('#side-menu').hide();
// For smoothly turn on menu
setTimeout(
() => {
jQuery('#side-menu').fadeIn(400);
}, 200);
} else if (jQuery('body').hasClass('fixed-sidebar')) {
jQuery('#side-menu').hide();
setTimeout(
() => {
jQuery('#side-menu').fadeIn(400);
}, 100);
} else {
// Remove all inline style from jquery fadeIn function to reset menu state
jQuery('#side-menu').removeAttr('style');
}
}
export function fixHeight() {
const heightWithoutNavbar = jQuery('body > #wrapper').height() - 62;
jQuery('.sidebar-panel').css('min-height', heightWithoutNavbar + 'px');
const navbarheight = jQuery('nav.navbar-default').height();
const wrapperHeight = jQuery('#page-wrapper').height();
if (navbarheight > wrapperHeight) {
jQuery('#page-wrapper').css('min-height', navbarheight + 'px');
}
if (navbarheight < wrapperHeight) {
jQuery('#page-wrapper').css('min-height', jQuery(window).height() + 'px');
}
if (jQuery('body').hasClass('fixed-nav')) {
if (navbarheight > wrapperHeight) {
jQuery('#page-wrapper').css('min-height', navbarheight + 'px');
} else {
jQuery('#page-wrapper').css('min-height', jQuery(window).height() - 60 + 'px');
}
}
}
import { NgModule } from '@angular/core';
import { DirtyGuard, XdfGalleryModule } from '@xdf/gallery';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { TranslateModule } from '@ngx-translate/core';
import { XdfSettingsModule } from '@xdf/settings';
import { BytebotLayoutComponent } from './bytebot-layout/bytebot-layout.component';
import { LayoutModule } from '@angular/cdk/layout';
@NgModule({
declarations: [
BytebotLayoutComponent
],
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
TranslateModule,
LayoutModule
],
entryComponents: [
],
exports: [
BytebotLayoutComponent
]
,
providers: [
{ provide: DirtyGuard, useClass: DirtyGuard }
]
})
export class BytebotLayoutModule { }
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { BytebotLayoutComponent } from './bytebot-layout.component';
describe('BytebotLayoutComponent', () => {
let component: BytebotLayoutComponent;
let fixture: ComponentFixture<BytebotLayoutComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ BytebotLayoutComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(BytebotLayoutComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, HostListener, OnInit } from '@angular/core';
import { detectBody } from '../app.helpers';
@Component({
selector: 'byte-bytebot-layout',
templateUrl: './bytebot-layout.component.html',
styleUrls: ['./bytebot-layout.component.scss']
})
export class BytebotLayoutComponent implements OnInit {
constructor(// protected toogleService: ToogleService
) { }
ngOnInit() {
detectBody();
}
@HostListener('window:resize')
public onResize() {
detectBody();
}
gotoTop() {
console.log('custom-layout');
}
onToggle() {
console.log('test');
// this.toogleService.onToggle(true);
}
}
<div [formGroup]="formGroup">
<mat-form-field class="form-control-full-width" style="width: 100%" hintLabel="{{ suggest | translate }}">
<mat-label>{{ placeholder | translate}}</mat-label>
<input matInput [matDatepicker]="picker" [formControlName]="name" [required]="required" [min]="this.minDate"
(dateInput)="changeValue($event.value)" [max]="this.maxDate" onpaste="return false">
<mat-datepicker-toggle id="{{name}}" matSuffix [for]="picker" [disabled]="disabled"></mat-datepicker-toggle>
<mat-datepicker #picker [disabled]="disabled"></mat-datepicker>
<mat-error *ngIf="formGroup.controls[this.name].hasError('required')
&& !formGroup.controls[this.name].hasError('matDatepickerMax')
&& !formGroup.controls[this.name].hasError('matDatepickerMin')
&& !formGroup.controls[this.name].hasError('matDatepickerParse')">
{{ 'message.error.required' | translate:{'label': placeholder | translate} }}
</mat-error>
<mat-error *ngIf="formGroup.controls[this.name].hasError('matDatepickerMax')">
{{ 'message.error.matDatepickerMax' | translate : {'max': getDateFormat(maxDate), 'label': placeholder | translate } }}
</mat-error>
<mat-error *ngIf="formGroup.controls[this.name].hasError('matDatepickerMin')">
{{ 'message.error.matDatepickerMin' | translate : {'min': getDateFormat(minDate), 'label': placeholder | translate } }}
</mat-error>
<mat-error *ngIf="formGroup.controls[this.name].hasError('matDatepickerParse')">
{{ 'message.error.matDatepickerParse' | translate : {'pattern': format } }}
</mat-error>
</mat-form-field>
</div>
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { DatepickerSelectComponent } from './datepicker-select.component';
describe('DatepickerSelectComponent', () => {
let component: DatepickerSelectComponent;
let fixture: ComponentFixture<DatepickerSelectComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DatepickerSelectComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DatepickerSelectComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { Component, EventEmitter, Input, OnInit, Output, SimpleChanges } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { FormGroupUtils } from '@xdf/gallery';
import * as moment from 'moment';
@Component({
selector: 'byte-datepicker-select',
templateUrl: './datepicker-select.component.html',
styleUrls: ['./datepicker-select.component.scss']
})
export class DatepickerSelectComponent implements OnInit {
@Input()
placeholder: string;
@Input()
name: string;
@Input()
suggest: string;
@Input()
disabled = false;
@Input()
required = false;
@Input()
minDate: Date;
@Input()
maxDate: Date;
@Input()
formGroup: FormGroup;
@Input()
format = 'DD/MM/YYYY';
@Output('changeDate') change = new EventEmitter<Date>();
constructor(
private formGroupUtils: FormGroupUtils) { }
ngOnChanges(changes: SimpleChanges): void {
this.disabled = (this.formGroup.controls[this.name] as FormControl).disabled;
}
ngOnInit(): void {
if (!this.formGroup) {
this.formGroup = this.formGroupUtils.createTemporalFormGroup(this.name, '', this.disabled);
}
if (!this.disabled) {
this.disabled = (this.formGroup.controls[this.name] as FormControl).disabled;
}
}
changeValue(value: any): void {
this.change.emit(value);
}
getDateFormat(date: Date): any {
if (date) {
const datem = moment(date);
return datem.utc().format(this.format);
}
return null;
}
}
<form [formGroup]="form" name="form" autocomplete="off" novalidate (ngSubmit)="submit()" class="form-content">
<div class="mail-box-header detail-header" [ngClass]="{'title-border-bottom': mode !='new'}">
<xdf-form-header [icon]="icon" [title]="'tax.title'" [recordIdentifier]="record?.id"
titleDesc="Gestionar Vuelos" [mode]="mode" [resourceAuth]="resourceAuth"
(optionEvent)="optionEvent($event)" [editing]="mode === 'edit'" [displaying]="mode === 'view'">
</xdf-form-header>
</div>
<div class="mail-box-content">
<div class="header-content">
<div class="col-12">
<div class="form-content">
<div class="legend">
<span class="group-title">Datos del Vuelo</span>
</div>
<div class="group-content">
<div class="row" style="margin-bottom: 15px;">
<div class="col-6 col-md-6">
<byte-datepicker-select name="departureDate" label="Fecha Salida"
placeholder="Fecha Salida" [formGroup]="form"
[disabled]="this.form.controls['departureDate'].disabled"
[minDate]="minDate">
</byte-datepicker-select>
</div>
<div class="col-6 col-md-6">
<byte-datepicker-select name="arrivalDate" label="Fecha Llegada"
placeholder="Fecha Llegada" [formGroup]="form"
[disabled]="this.form.controls['arrivalDate'].disabled"
[minDate]="minDate">
</byte-datepicker-select>
</div>
</div>
<div class="row" style="margin-bottom: 15px;">
<div class="col-6 col-md-6">
<xdf-input name="airlineCode" label="Codigo Aerolinea" type="text" [required]="true"
placeholder="Codigo Aerolinea" [formGroup]="form"
[options]="{maxLength: 12, showLength: true}">
</xdf-input>
</div>
<div class="col-6 col-md-6">
<xdf-input name="codeTypeAircraft" label="Codigo Aeronave" type="text" [required]="true"
placeholder="Codigo Aeronave" [formGroup]="form"
[options]="{maxLength: 50, showLength: true}">
</xdf-input>
</div>
</div>
<div class="row" style="margin-bottom: 15px;">
<div class="col-6 col-md-6">
<mat-form-field style="width: 100%;">
<mat-label>Aeropuerto origen</mat-label>
<mat-select formControlName="codeAirportOrigin">
<mat-option *ngFor="let airport of airports" [value]="airport.id">
{{airport.airportCode}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-6 col-md-6">
<mat-form-field style="width: 100%;">
<mat-label>Aeropuerto Destino</mat-label>
<mat-select formControlName="codeAirportDestination">
<mat-option *ngFor="let airport of airports" [value]="airport.id">
{{airport.airportCode}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
<div class="row" style="margin-bottom: 15px;">
<div class="col-6 col-md-6">
<xdf-input name="flightCost" label="Costo" type="text" [required]="true"
placeholder="Costo" [formGroup]="form"
[options]="{maxLength: 12, showLength: true}">
</xdf-input>
</div>
</div>
</div>
<div class="hr-line-dashed" style="margin-bottom: 20px"></div>
<div class="legend">
<span class="group-title">Escalas</span>
</div>
<div class="group-content">
<byte-flight-legs-grid #taxRatesGrid [mode]="mode"></byte-flight-legs-grid>
</div>
</div>
</div>
</div>
<div class="footer-content">
<div class="col-lg-12" *ngIf="mode !== 'view'">
<div class="form-status-bar border-top">
<button type="submit" mat-stroked-button class="btn btn-primary pull-right" style="margin-top: 10px;"
[disabled]="form?.invalid || processing || form.pending || taxRatesGrid.dataSource.data.length === 0">
<i class="fa fa-save" aria-hidden="true" style="padding-right: 3px; padding-bottom: 3px;">
</i>{{'btn.save' | translate }}
</button>
</div>
</div>
</div>
</div>
</form>
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FlightFormComponent } from './flight-form.component';
describe('FlightFormComponent', () => {
let component: FlightFormComponent;
let fixture: ComponentFixture<FlightFormComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ FlightFormComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(FlightFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
import { AfterViewInit, ChangeDetectorRef, Component, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
import { AsyncValidatorFn, FormBuilder, FormControl, FormGroup, ValidationErrors, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { IFormView, DynaDataService, AuditDialogService, ConfirmationDialogService, RequiredValidator } from '@xdf/gallery';
import { InitCommonsService, NotificationService, NotificationType } from '@xdf/commons';
import { FlightService } from '../../services/flight.service';
import { FlightLegsGridComponent } from '../flight-legs-grid/flight-legs-grid.component';
@Component({
selector: 'byte-flight-form',
templateUrl: './flight-form.component.html',
styleUrls: ['./flight-form.component.scss']
})
export class FlightFormComponent extends IFormView implements OnInit, AfterViewInit {
airports: any[] = [];
form: FormGroup;
private taxRatesGrid: FlightLegsGridComponent;
@ViewChild('taxRatesGrid', {static: false})
set content (
content: FlightLegsGridComponent
) {
if (content) {
this.taxRatesGrid = content;
} else {
this.taxRatesGrid = undefined;
}
}
constructor(
protected formBuilder: FormBuilder,
protected vcRef: ViewContainerRef,
protected activatedRoute: ActivatedRoute,
protected router: Router,
protected dynaDataService: DynaDataService,
protected translate: TranslateService,
protected notificationService: NotificationService,
protected auditDialogService: AuditDialogService,
protected confirmationDialogService: ConfirmationDialogService,
protected init: InitCommonsService,
protected changeDetector: ChangeDetectorRef,
private flightService: FlightService ) {
super(vcRef, activatedRoute, router, dynaDataService,
translate, notificationService, auditDialogService,
confirmationDialogService, init);
}
ngAfterViewInit(): void {
if(this.mode !== 'new' && this.record) {
this.taxRatesGrid.dataSource.data = this.taxRatesGrid.autoSort(this.record.legs);
}
this.changeDetector.detectChanges();
}
ngOnInit(): void {
this.listAirports();
super.ngOnInit();
}
listAirports() {
this.flightService.getAirports().subscribe(
res => {
this.airports = res;
}
)
}
addLegsToFlight(idFlight: number) {
for(let i = 0; i < this.taxRatesGrid.dataSource.data.length; i++) {
this.taxRatesGrid.dataSource.data[i].flightCode = idFlight;
this.flightService.addLeg(this.taxRatesGrid.dataSource.data[i])
.subscribe(res => {})
}
}
protected getFields(): FormGroup {
let form;
form = this.formBuilder.group({
airlineCode: this.createFormControl('airlineCode', (this.mode !== 'new' && this.record),
true, '', [RequiredValidator.isRequired]),
codeTypeAircraft: this.createFormControl('codeTypeAircraft', (this.mode !== 'new' && this.record), true),
codeAirportOrigin: this.createFormControl('codeAirportOrigin', (this.mode !== 'new' && this.record),
true, '', [RequiredValidator.isRequired]),
codeAirportDestination: this.createFormControl('codeAirportDestination', (this.mode !== 'new' && this.record),
true, '', [RequiredValidator.isRequired]),
flightCost: this.createFormControl('flightCost', (this.mode !== 'new' && this.record), true, '', [RequiredValidator.isRequired]),
departureDate: this.createFormControl('departureDate', (this.mode !== 'new' && this.record),
true, '', [RequiredValidator.isRequired]),
arrivalDate: this.createFormControl('arrivalDate', (this.mode !== 'new' && this.record), true, '', [RequiredValidator.isRequired]),
});
return form;
}
private createFormControl(
name: string, existRecord?: boolean,
required?: boolean, defaultValue?: string,
validators?: Array<ValidationErrors>, asyncValidators?: Array<AsyncValidatorFn>): FormControl {
if(!defaultValue) {
defaultValue = '';
}
let validatorList = [];
if(validators) {
validatorList = validators;
}
if(required) {
validatorList.push(Validators.required);
}
if(name === 'code') return new FormControl(
{ value: existRecord ? this.record[name]: '', disabled: this.mode !== 'new'},
validatorList, asyncValidators
);
return new FormControl(
{ value: existRecord ? this. record[name] : '', disabled: this.mode === 'view'},
validatorList, asyncValidators);
}
submit() {
this.processing = true;
let result = {
id: this.mode != 'new' ? this.record.id: 0,
airlineCode: this.form.value['airlineCode'],
codeTypeAircraft: this.form.value['codeTypeAircraft'],
codeAirportOrigin: this.form.value['codeAirportOrigin'],
codeAirportDestination: this.form.value['codeAirportDestination'],
flightCost: this.form.value['flightCost'],
departureDate: this.form.value['departureDate'],
arrivalDate: this.form.value['arrivalDate']
}
if(this.mode == 'new') {
this.dynaDataService.create(result).subscribe(
(res) => {
this.addLegsToFlight(res['id']);
this.notificationService.showMessage(
this.translate.instant('message.create.succesful'),
this.translate.instant('title.information'),
NotificationType.success
);
this.record = new Object();
this.form.markAsPristine();
this.router.navigate([this.returnUrl]);
this.processing = false;
},
error => {
this.processing = false;
}
);
}
}
}
<div class="popup-general">
<div class="row">
<div class="col-lg-12">
<div class="dialog-title">
<img src="{{ logoSrc }}" with="25" height="25">
<span class="header-popup-text">Agregar una escala</span>
<div class="pull-right">
<button type="button" class="close" (click)="close()"></button>
</div>
</div>
</div>
</div>
<div mat-dialog-content class="dialog-content">
<form [formGroup]="form" name="form" autocomplete="off" novalidate>
<div class="group-content">
<div class="row" style="margin-top: 15px; margin-bottom: 15px;">
<div class="col-5" style="margin-inline: auto;">
<byte-datepicker-select name="arrivalDate" label="Fecha Salida" placeholder="Fecha Salida"
[formGroup]="form" [disabled]="this.form.controls['arrivalDate'].disabled"
[minDate]="minDate">
</byte-datepicker-select>
</div>
<div class="col-5" style="margin-inline: auto;">
<byte-datepicker-select name="departureDate" label="Fecha Llegada" placeholder="Fecha Llegada"
[formGroup]="form" [disabled]="this.form.controls['departureDate'].disabled"
[minDate]="minDate">
</byte-datepicker-select>
</div>
</div>
<div class="row" style="margin-top: 15px; margin-bottom: 15px;">
<div class="col-5" style="margin-inline: auto;">
<mat-form-field style="width: 100%;">
<mat-label>Aeropuerto Origen</mat-label>
<mat-select formControlName="codeAirportOrigin">
<mat-option *ngFor="let airport of airports" [value]="airport.id">
{{airport.airportCode}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-5" style="margin-inline: auto;">
<mat-form-field style="width: 100%;">
<mat-label>Aeropuerto Destino</mat-label>
<mat-select formControlName="codeAirportDestination">
<mat-option *ngFor="let airport of airports" [value]="airport.id">
{{airport.airportCode}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
</div>
</div>
</form>
</div>
<div class="dialog-footer">
<div>
<button type="button" class="btn btn-primary pull-right" (click)="save()" *ngIf="mode !== 'view'"
[disabled]="record ? ((form?.invalid && form?.touched) || processing) : (form?.invalid || processing)">
<span><i class="fa fa-floppy-o"></i>&nbsp;{{ 'btn.save' | translate }}</span>
</button>
&nbsp;
<button class="btn btn-default pull-left" (click)="close()">
<span>{{ 'btn.cancel' | translate }}</span>
</button>
</div>
</div>
</div>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
This diff is collapsed.
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
This diff is collapsed.
This diff is collapsed.
File mode changed from 100644 to 100755
This diff is collapsed.
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment