Beginning of travel form
This commit is contained in:
@@ -3,20 +3,24 @@ import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { OAuthModule } from 'angular-oauth2-oidc';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { RouterModule, ExtraOptions } from '@angular/router';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { APP_ROUTES } from './app.routes';
|
||||
import { USER_API_URL, TRAVEL_API_URL } from './app.config';
|
||||
import { HomeComponent } from './home/home.component';
|
||||
import { TravelComponent } from './travel/travel.component';
|
||||
import { SharedModule } from './shared/shared.module';
|
||||
import { RouterModule, ExtraOptions } from '@angular/router';
|
||||
import { useHash } from '../flags';
|
||||
import { HeaderComponent } from './header/header.component';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ListComponent } from './list/list.component';
|
||||
import { MaterialModule } from './material/material.module';
|
||||
|
||||
import { HomeComponent } from './pages/home/home.component';
|
||||
import { TravelComponent } from './pages/travel/travel.component';
|
||||
import { EditTravelComponent } from './pages/edit-travel/edit-travel.component';
|
||||
|
||||
import { HeaderComponent } from './views/header/header.component';
|
||||
import { ListComponent } from './views/list/list.component';
|
||||
import { TravelFormComponent } from './views/travel-form/travel-form.component';
|
||||
|
||||
const ROUTING_OPTIONS: ExtraOptions = {
|
||||
// preloadingStrategy: CustomPreloadingStrategy,
|
||||
useHash,
|
||||
@@ -44,8 +48,10 @@ const ROUTING_OPTIONS: ExtraOptions = {
|
||||
AppComponent,
|
||||
HomeComponent,
|
||||
TravelComponent,
|
||||
EditTravelComponent,
|
||||
HeaderComponent,
|
||||
ListComponent
|
||||
ListComponent,
|
||||
TravelFormComponent
|
||||
],
|
||||
providers: [
|
||||
// (useHash) ? { provide: LocationStrategy, useClass: HashLocationStrategy } : [],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Routes } from '@angular/router';
|
||||
import { HomeComponent } from './home/home.component';
|
||||
import { TravelComponent } from './travel/travel.component';
|
||||
import { EditTravelComponent } from './pages/edit-travel/edit-travel.component';
|
||||
import { HomeComponent } from './pages/home/home.component';
|
||||
import { TravelComponent } from './pages/travel/travel.component';
|
||||
|
||||
export let APP_ROUTES: Routes = [
|
||||
{
|
||||
@@ -16,6 +17,14 @@ export let APP_ROUTES: Routes = [
|
||||
path: 'travel/:id',
|
||||
component: TravelComponent
|
||||
},
|
||||
{
|
||||
path: 'travel/new',
|
||||
component: EditTravelComponent
|
||||
},
|
||||
{
|
||||
path: 'travel/:id/edit',
|
||||
component: EditTravelComponent
|
||||
},
|
||||
{
|
||||
path: '**',
|
||||
redirectTo: 'home'
|
||||
|
||||
@@ -37,7 +37,7 @@ export const authConfig: AuthConfig = {
|
||||
|
||||
useSilentRefresh: useSilentRefreshForCodeFlow,
|
||||
|
||||
showDebugInformation: true,
|
||||
showDebugInformation: false,
|
||||
|
||||
sessionChecksEnabled: true,
|
||||
sessionCheckIntervall: 10000,
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { User } from './user';
|
||||
import { UserInfo } from './user-info';
|
||||
|
||||
export type TravelId = number;
|
||||
|
||||
export interface Travel {
|
||||
id: Travel;
|
||||
driver: User;
|
||||
travelers: User[];
|
||||
driverInfo: UserInfo;
|
||||
travelersInfo: UserInfo[];
|
||||
departureDate: string;
|
||||
origin: string;
|
||||
destination: string;
|
||||
availablePlaces: number;
|
||||
places: number;
|
||||
description?: string;
|
||||
matrixRoomId: string;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
export type UserId = string;
|
||||
|
||||
export interface User {
|
||||
export interface UserInfo {
|
||||
id: UserId;
|
||||
matrixId?: string;
|
||||
name: string;
|
||||
4
src/app/pages/edit-travel/edit-travel.component.html
Normal file
4
src/app/pages/edit-travel/edit-travel.component.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<div>
|
||||
<h1>Editar</h1>
|
||||
|
||||
</div>
|
||||
25
src/app/pages/edit-travel/edit-travel.component.spec.ts
Normal file
25
src/app/pages/edit-travel/edit-travel.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { EditTravelComponent } from './edit-travel.component';
|
||||
|
||||
describe('EditTravelComponent', () => {
|
||||
let component: EditTravelComponent;
|
||||
let fixture: ComponentFixture<EditTravelComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ EditTravelComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(EditTravelComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
35
src/app/pages/edit-travel/edit-travel.component.ts
Normal file
35
src/app/pages/edit-travel/edit-travel.component.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { PUBLIC_API_URL } from '../../app.config';
|
||||
import { Travel, TravelId } from '../../entities/travel';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-edit-travel',
|
||||
templateUrl: './edit-travel.component.html',
|
||||
styleUrls: ['./edit-travel.component.css']
|
||||
})
|
||||
export class EditTravelComponent implements OnInit {
|
||||
travel: Travel;
|
||||
|
||||
constructor(
|
||||
private apiService: ApiService,
|
||||
private route: ActivatedRoute
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
this.route.queryParams.subscribe(params => {
|
||||
const travelId = this.route.snapshot.paramMap.get('id') as unknown as TravelId;
|
||||
|
||||
this.apiService.call<Travel>(PUBLIC_API_URL + '/travel', { travelId })
|
||||
.subscribe(res => {
|
||||
if (res.success) {
|
||||
this.travel = res.data;
|
||||
}
|
||||
else {
|
||||
console.error('Error getting travel ' + travelId + ': ' + res.error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { OAuthService } from 'angular-oauth2-oidc';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { ApiService } from '../services/api.service';
|
||||
import { Travel } from '../entities/travel';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { Travel } from '../../entities/travel';
|
||||
|
||||
@Component({
|
||||
templateUrl: './home.component.html',
|
||||
@@ -3,11 +3,11 @@
|
||||
{{ travel.origin }} - {{ travel.destination }}
|
||||
</mat-card-title>
|
||||
<mat-card-subtitle>
|
||||
{{ travel.departureDate }} Plazas libres: {{ travel.availablePlaces }}
|
||||
{{ travel.departureDate }} Plazas: {{ travel.places - travel.travelersInfo.length }}/{{ travel.places }}
|
||||
</mat-card-subtitle>
|
||||
<mat-card-content>
|
||||
<p>ID: {{ travel.id }}</p>
|
||||
<p>Conductor: {{ travel.driver.name }}</p><br>
|
||||
<p>Conductor: {{ travel.driverInfo.name }}</p><br>
|
||||
<p>{{ travel.description }}</p>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Router, ActivatedRoute, ParamMap } from '@angular/router';
|
||||
import { PUBLIC_API_URL } from '../app.config';
|
||||
import { Travel, TravelId } from '../entities/travel';
|
||||
import { ApiService } from '../services/api.service';
|
||||
import { PUBLIC_API_URL } from '../../app.config';
|
||||
import { Travel, TravelId } from '../../entities/travel';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-travel',
|
||||
0
src/app/views/header/header.component.css
Normal file
0
src/app/views/header/header.component.css
Normal file
@@ -1,6 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { OAuthService } from 'angular-oauth2-oidc';
|
||||
import { authConfig } from '../auth.config';
|
||||
import { authConfig } from '../../auth.config';
|
||||
|
||||
@Component({
|
||||
selector: 'app-header',
|
||||
@@ -13,7 +13,7 @@ import { MatPaginator } from '@angular/material/paginator';
|
||||
import { MatSort } from '@angular/material/sort';
|
||||
import { debounceTime, distinctUntilChanged, tap } from 'rxjs/operators';
|
||||
import { merge, fromEvent, Observable, Subscriber } from 'rxjs';
|
||||
import { ApiService } from '../services/api.service';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
import { ListDataSource } from './list.datasource';
|
||||
import { emit } from 'process';
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { CollectionViewer, DataSource } from '@angular/cdk/collections';
|
||||
import { Observable, BehaviorSubject, of } from 'rxjs';
|
||||
import { Observable, BehaviorSubject, of, throwError } from 'rxjs';
|
||||
import { catchError, finalize } from 'rxjs/operators';
|
||||
import { ApiResponse } from '../entities/api-response';
|
||||
import { ListDto } from '../entities/list-dto';
|
||||
import { ApiService } from '../services/api.service';
|
||||
import { ApiResponse } from '../../entities/api-response';
|
||||
import { ListDto } from '../../entities/list-dto';
|
||||
import { ApiService } from '../../services/api.service';
|
||||
|
||||
export class ListDataSource<T> implements DataSource<T> {
|
||||
private listSubject = new BehaviorSubject<T[]>([]);
|
||||
@@ -11,7 +11,7 @@ export class ListDataSource<T> implements DataSource<T> {
|
||||
public loading$ = this.loadingSubject.asObservable();
|
||||
public total = 0;
|
||||
|
||||
constructor(private apiService: ApiService, private url: string) {}
|
||||
constructor(private apiService: ApiService, private url: string) { }
|
||||
|
||||
load(
|
||||
filter: string,
|
||||
@@ -23,21 +23,27 @@ export class ListDataSource<T> implements DataSource<T> {
|
||||
this.loadingSubject.next(true);
|
||||
|
||||
this.apiService.call<ListDto<T>>(this.url, {
|
||||
filter,
|
||||
sortColumn,
|
||||
sortAscending,
|
||||
pageIndex,
|
||||
pageSize,
|
||||
})
|
||||
filter,
|
||||
sortColumn,
|
||||
sortAscending,
|
||||
pageIndex,
|
||||
pageSize,
|
||||
})
|
||||
.pipe(
|
||||
catchError(() => of([])),
|
||||
catchError(() => throwError('Error al obtener datos de la lista.')),
|
||||
finalize(() => this.loadingSubject.next(false))
|
||||
)
|
||||
.subscribe((res) => {
|
||||
const listDto = (res as ApiResponse<ListDto<T>>).data;
|
||||
const list = listDto.list;
|
||||
this.total = listDto.total;
|
||||
this.listSubject.next(list);
|
||||
const apiResponse = res as ApiResponse<ListDto<T>>;
|
||||
if (apiResponse.success) {
|
||||
const listDto = (res as ApiResponse<ListDto<T>>).data;
|
||||
const list = listDto.list;
|
||||
this.total = listDto.total;
|
||||
this.listSubject.next(list);
|
||||
}
|
||||
else {
|
||||
console.error('Error en list.datasource.ts: ' + apiResponse.error.code + ' ' + apiResponse.error.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
0
src/app/views/travel-form/travel-form.component.css
Normal file
0
src/app/views/travel-form/travel-form.component.css
Normal file
44
src/app/views/travel-form/travel-form.component.html
Normal file
44
src/app/views/travel-form/travel-form.component.html
Normal file
@@ -0,0 +1,44 @@
|
||||
<form (ngSubmit)="onSubmit()" #travelForm="ngForm">
|
||||
<div>
|
||||
<label for="origin">Origen</label>
|
||||
<input type="text" id="origin" required [(ngModel)]="travel.origin" name="origin" #origin="ngModel">
|
||||
<div [hidden]="origin.valid || origin.pristine" class="alert alert-danger">
|
||||
El origen es obligatorio
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="destination">Destino</label>
|
||||
<input type="text" id="destination" required [(ngModel)]="travel.destination" name="destination" #destination="ngModel">
|
||||
<div [hidden]="destination.valid || destination.pristine" class="alert alert-danger">
|
||||
El destino es obligatorio
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="places">Plazas</label>
|
||||
<input type="number" id="places" required [(ngModel)]="travel.places" name="places" #places="ngModel">
|
||||
<div [hidden]="places.valid || places.pristine" class="alert alert-danger">
|
||||
El destino es obligatorio
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="description">Descripción</label>
|
||||
<input type="text" id="description" required [(ngModel)]="travel.description" name="description" #description="ngModel">
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- <div>
|
||||
<label for="power">Hero Power</label>
|
||||
<select id="power" required [(ngModel)]="model.power" name="power" #power="ngModel">
|
||||
<option *ngFor="let pow of powers" [value]="pow">{{pow}}</option>
|
||||
</select>
|
||||
<div [hidden]="power.valid || power.pristine" class="alert alert-danger">
|
||||
Power is required
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<button type="submit" class="btn btn-success" [disabled]="!travelForm.form.valid">Submit</button>
|
||||
</form>
|
||||
25
src/app/views/travel-form/travel-form.component.spec.ts
Normal file
25
src/app/views/travel-form/travel-form.component.spec.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { TravelFormComponent } from './travel-form.component';
|
||||
|
||||
describe('TravelFormComponent', () => {
|
||||
let component: TravelFormComponent;
|
||||
let fixture: ComponentFixture<TravelFormComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ TravelFormComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(TravelFormComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
21
src/app/views/travel-form/travel-form.component.ts
Normal file
21
src/app/views/travel-form/travel-form.component.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Travel } from 'src/app/entities/travel';
|
||||
|
||||
@Component({
|
||||
selector: 'app-travel-form',
|
||||
templateUrl: './travel-form.component.html',
|
||||
styleUrls: ['./travel-form.component.css']
|
||||
})
|
||||
export class TravelFormComponent implements OnInit {
|
||||
travel: Travel;
|
||||
submitted = false;
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
onSubmit(): void {
|
||||
this.submitted = true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user