diff --git a/barker/routes.py b/barker/routes.py index 644bcb7..c4741f9 100644 --- a/barker/routes.py +++ b/barker/routes.py @@ -80,11 +80,11 @@ def includeme(config): config.add_route("v1_taxes_list", "/v1/taxes") config.add_route('v1_users_new', '/v1/users/new') - config.add_route('v1_users_list', '/v1/users/list') config.add_route('v1_users_id', '/v1/users/{id}') + config.add_route('v1_users_list', '/v1/users') config.add_route('users_new', '/users/new') - config.add_route('users_list', '/users/list') config.add_route('users_id', '/users/{id}') + config.add_route('users_list', '/users') config.add_route('v1_roles_new', '/v1/roles/new') config.add_route('v1_roles_id', '/v1/roles/{id}') diff --git a/barker/views/user.py b/barker/views/user.py index 350438e..8863192 100644 --- a/barker/views/user.py +++ b/barker/views/user.py @@ -9,7 +9,7 @@ from barker.exceptions import ValidationFailure from barker.models import Role, User -@view_config(request_method='PUT', route_name='v1_users_new', renderer='json', permission='Users', trans=True) +@view_config(request_method='POST', route_name='v1_users_new', renderer='json', permission='Users', trans=True) def save(request): json = request.json_body item = User(json['name'], json['password'], json['lockedOut']) @@ -21,15 +21,15 @@ def save(request): return user_info(item, roles) -@view_config(request_method='POST', route_name='v1_users_id', renderer='json', permission='Users', trans=True) +@view_config(request_method='PUT', route_name='v1_users_id', renderer='json', permission='Users', trans=True) def update(request): json = request.json_body - id = request.matchdict['id'] + id_ = request.matchdict['id'] p = re.compile('^[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$') - if p.match(id): - item = request.dbsession.query(User).filter(User.id == uuid.UUID(id)).one() + if p.match(id_): + item = request.dbsession.query(User).filter(User.id == uuid.UUID(id_)).one() else: - item = request.dbsession.query(User).filter(User.name.ilike(id)).first() + item = request.dbsession.query(User).filter(User.name.ilike(id_)).first() if item is None: raise ValidationFailure('User name / id not found') if request.has_permission('Users'): diff --git a/bookie/src/app/app-routing.module.ts b/bookie/src/app/app-routing.module.ts index 16d4800..1b8081f 100644 --- a/bookie/src/app/app-routing.module.ts +++ b/bookie/src/app/app-routing.module.ts @@ -37,6 +37,10 @@ const routes: Routes = [ path: 'taxes', loadChildren: () => import('./taxes/taxes.module').then(mod => mod.TaxesModule) }, + { + path: 'users', + loadChildren: () => import('./users/users.module').then(mod => mod.UsersModule) + }, {path: 'login', component: LoginComponent}, {path: 'logout', component: LogoutComponent}, {path: '', component: HomeComponent}, diff --git a/bookie/src/app/app.module.ts b/bookie/src/app/app.module.ts index 1c74faa..51c487e 100644 --- a/bookie/src/app/app.module.ts +++ b/bookie/src/app/app.module.ts @@ -21,7 +21,6 @@ import { HomeComponent } from "./home/home.component"; import {CoreModule} from "./core/core.module"; import {ReactiveFormsModule} from "@angular/forms"; import {SharedModule} from "./shared/shared.module"; -import {UserModule} from "./user/user.module"; @NgModule({ declarations: [ @@ -47,8 +46,7 @@ import {UserModule} from "./user/user.module"; LayoutModule, ReactiveFormsModule, CoreModule, - SharedModule, - UserModule + SharedModule ], providers: [], bootstrap: [AppComponent] diff --git a/bookie/src/app/auth/auth-guard.service.ts b/bookie/src/app/auth/auth-guard.service.ts index 85c748b..505276e 100644 --- a/bookie/src/app/auth/auth-guard.service.ts +++ b/bookie/src/app/auth/auth-guard.service.ts @@ -1,10 +1,10 @@ -import {Injectable} from '@angular/core'; -import {ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot} from '@angular/router'; -import {AuthService} from './auth.service'; -import {Observable} from 'rxjs/internal/Observable'; -import {map} from 'rxjs/operators'; -import {ToasterService} from '../core/toaster.service'; -import {User} from '../user/user'; +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router'; +import { AuthService } from './auth.service'; +import { Observable } from 'rxjs/internal/Observable'; +import { map } from 'rxjs/operators'; +import { ToasterService } from '../core/toaster.service'; +import { User } from '../core/user'; @Injectable({ providedIn: 'root' diff --git a/bookie/src/app/auth/auth.service.ts b/bookie/src/app/auth/auth.service.ts index eeeaeb1..9e6a6e4 100644 --- a/bookie/src/app/auth/auth.service.ts +++ b/bookie/src/app/auth/auth.service.ts @@ -1,10 +1,10 @@ -import {Injectable} from '@angular/core'; -import {HttpClient, HttpHeaders} from '@angular/common/http'; -import {Observable} from 'rxjs/internal/Observable'; -import {catchError, tap} from 'rxjs/operators'; -import {Subject} from 'rxjs/internal/Subject'; -import {ErrorLoggerService} from '../core/error-logger.service'; -import {User} from '../user/user'; +import { Injectable } from '@angular/core'; +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Observable } from 'rxjs/internal/Observable'; +import { catchError, tap } from 'rxjs/operators'; +import { Subject } from 'rxjs/internal/Subject'; +import { ErrorLoggerService } from '../core/error-logger.service'; +import { User } from '../core/user'; const httpOptions = { diff --git a/bookie/src/app/user/user.ts b/bookie/src/app/core/user.ts similarity index 100% rename from bookie/src/app/user/user.ts rename to bookie/src/app/core/user.ts diff --git a/bookie/src/app/roles/role-list/role-list.component.html b/bookie/src/app/roles/role-list/role-list.component.html index c0b1826..2e4363e 100644 --- a/bookie/src/app/roles/role-list/role-list.component.html +++ b/bookie/src/app/roles/role-list/role-list.component.html @@ -7,17 +7,17 @@ - + - Name + Name {{row.name}} - Permissions + Permissions
  • {{permission}}
  • @@ -28,12 +28,5 @@ - - - diff --git a/bookie/src/app/user/user-list/user-list-datasource.ts b/bookie/src/app/user/user-list/user-list-datasource.ts deleted file mode 100644 index 9ea6b54..0000000 --- a/bookie/src/app/user/user-list/user-list-datasource.ts +++ /dev/null @@ -1,59 +0,0 @@ -import {DataSource} from '@angular/cdk/collections'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import {map} from 'rxjs/operators'; -import {merge, Observable, of as observableOf} from 'rxjs'; -import {User} from '../user'; - -export class UserListDataSource extends DataSource { - - constructor(private paginator: MatPaginator, private sort: MatSort, public data: User[]) { - super(); - } - - connect(): Observable { - const dataMutations = [ - observableOf(this.data), - this.paginator.page, - this.sort.sortChange - ]; - - // Set the paginators length - this.paginator.length = this.data.length; - - return merge(...dataMutations).pipe(map(() => { - return this.getPagedData(this.getSortedData([...this.data])); - })); - } - - disconnect() { - } - - private getPagedData(data: User[]) { - const startIndex = this.paginator.pageIndex * this.paginator.pageSize; - return data.splice(startIndex, this.paginator.pageSize); - } - - private getSortedData(data: User[]) { - if (!this.sort.active || this.sort.direction === '') { - return data; - } - - return data.sort((a, b) => { - const isAsc = this.sort.direction === 'asc'; - switch (this.sort.active) { - case 'name': - return compare(a.name, b.name, isAsc); - case 'id': - return compare(+a.id, +b.id, isAsc); - default: - return 0; - } - }); - } -} - -/** Simple sort comparator for example ID/Name columns (for user-side sorting). */ -function compare(a, b, isAsc) { - return (a < b ? -1 : 1) * (isAsc ? 1 : -1); -} diff --git a/bookie/src/app/user/user-detail/user-detail.component.css b/bookie/src/app/users/user-detail/user-detail.component.css similarity index 100% rename from bookie/src/app/user/user-detail/user-detail.component.css rename to bookie/src/app/users/user-detail/user-detail.component.css diff --git a/bookie/src/app/user/user-detail/user-detail.component.html b/bookie/src/app/users/user-detail/user-detail.component.html similarity index 88% rename from bookie/src/app/user/user-detail/user-detail.component.html rename to bookie/src/app/users/user-detail/user-detail.component.html index 2baf013..61c05eb 100644 --- a/bookie/src/app/user/user-detail/user-detail.component.html +++ b/bookie/src/app/users/user-detail/user-detail.component.html @@ -25,11 +25,11 @@ Is Locked Out? -
    -
    +
    - {{r.name}} + {{g.name}}
    diff --git a/bookie/src/app/users/user-detail/user-detail.component.spec.ts b/bookie/src/app/users/user-detail/user-detail.component.spec.ts new file mode 100644 index 0000000..4fb876e --- /dev/null +++ b/bookie/src/app/users/user-detail/user-detail.component.spec.ts @@ -0,0 +1,25 @@ +import {async, ComponentFixture, TestBed} from '@angular/core/testing'; + +import {UserDetailComponent} from './user-detail.component'; + +describe('UserDetailComponent', () => { + let component: UserDetailComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [UserDetailComponent] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(UserDetailComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/bookie/src/app/user/user-detail/user-detail.component.ts b/bookie/src/app/users/user-detail/user-detail.component.ts similarity index 95% rename from bookie/src/app/user/user-detail/user-detail.component.ts rename to bookie/src/app/users/user-detail/user-detail.component.ts index 289c494..ddb5365 100644 --- a/bookie/src/app/user/user-detail/user-detail.component.ts +++ b/bookie/src/app/users/user-detail/user-detail.component.ts @@ -2,7 +2,7 @@ import {AfterViewInit, Component, ElementRef, OnInit, ViewChild} from '@angular/ import {ActivatedRoute, Router} from '@angular/router'; import {UserService} from '../user.service'; -import {User} from '../user'; +import {User} from '../../core/user'; import {ToasterService} from '../../core/toaster.service'; import {ConfirmDialogComponent} from '../../shared/confirm-dialog/confirm-dialog.component'; import { MatDialog } from '@angular/material/dialog'; @@ -73,7 +73,7 @@ export class UserDetailComponent implements OnInit, AfterViewInit { .subscribe( (result) => { this.toaster.show('Success', ''); - this.router.navigateByUrl('/users/list'); + this.router.navigateByUrl('/users'); }, (error) => { this.toaster.show('Danger', error.error); @@ -86,7 +86,7 @@ export class UserDetailComponent implements OnInit, AfterViewInit { .subscribe( (result) => { this.toaster.show('Success', ''); - this.router.navigateByUrl('/Users'); + this.router.navigateByUrl('/users'); }, (error) => { this.toaster.show('Danger', error.error); diff --git a/bookie/src/app/users/user-list-resolver.service.spec.ts b/bookie/src/app/users/user-list-resolver.service.spec.ts new file mode 100644 index 0000000..ddbdc9d --- /dev/null +++ b/bookie/src/app/users/user-list-resolver.service.spec.ts @@ -0,0 +1,15 @@ +import {inject, TestBed} from '@angular/core/testing'; + +import {UserListResolver} from './user-list-resolver.service'; + +describe('UserListResolver', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [UserListResolver] + }); + }); + + it('should be created', inject([UserListResolver], (service: UserListResolver) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/bookie/src/app/user/user-list-resolver.service.ts b/bookie/src/app/users/user-list-resolver.service.ts similarity index 93% rename from bookie/src/app/user/user-list-resolver.service.ts rename to bookie/src/app/users/user-list-resolver.service.ts index 44ddc1a..64b0f55 100644 --- a/bookie/src/app/user/user-list-resolver.service.ts +++ b/bookie/src/app/users/user-list-resolver.service.ts @@ -1,6 +1,6 @@ import {Injectable} from '@angular/core'; import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from '@angular/router'; -import {User} from './user'; +import {User} from '../core/user'; import {Observable} from 'rxjs/internal/Observable'; import {UserService} from './user.service'; diff --git a/bookie/src/app/users/user-list/user-list-datasource.ts b/bookie/src/app/users/user-list/user-list-datasource.ts new file mode 100644 index 0000000..ff5a495 --- /dev/null +++ b/bookie/src/app/users/user-list/user-list-datasource.ts @@ -0,0 +1,17 @@ +import { DataSource } from '@angular/cdk/collections'; +import { Observable, of as observableOf } from 'rxjs'; +import { User } from '../../core/user'; + +export class UserListDataSource extends DataSource { + + constructor(public data: User[]) { + super(); + } + + connect(): Observable { + return observableOf(this.data); + } + + disconnect() { + } +} diff --git a/bookie/src/app/user/user-list/user-list.component.css b/bookie/src/app/users/user-list/user-list.component.css similarity index 100% rename from bookie/src/app/user/user-list/user-list.component.css rename to bookie/src/app/users/user-list/user-list.component.css diff --git a/bookie/src/app/user/user-list/user-list.component.html b/bookie/src/app/users/user-list/user-list.component.html similarity index 69% rename from bookie/src/app/user/user-list/user-list.component.html rename to bookie/src/app/users/user-list/user-list.component.html index 547613f..069e92f 100644 --- a/bookie/src/app/user/user-list/user-list.component.html +++ b/bookie/src/app/users/user-list/user-list.component.html @@ -7,17 +7,17 @@ - + - Name + Name {{row.name}} - Is Locked Out? + Is Locked Out? {{row.lockedOut}} @@ -34,12 +34,5 @@ - - - diff --git a/bookie/src/app/user/user-list/user-list.component.ts b/bookie/src/app/users/user-list/user-list.component.ts similarity index 52% rename from bookie/src/app/user/user-list/user-list.component.ts rename to bookie/src/app/users/user-list/user-list.component.ts index 253889b..90855b9 100644 --- a/bookie/src/app/user/user-list/user-list.component.ts +++ b/bookie/src/app/users/user-list/user-list.component.ts @@ -1,9 +1,7 @@ -import {Component, OnInit, ViewChild} from '@angular/core'; -import { MatPaginator } from '@angular/material/paginator'; -import { MatSort } from '@angular/material/sort'; -import {UserListDataSource} from './user-list-datasource'; -import {User} from '../user'; -import {ActivatedRoute} from '@angular/router'; +import { Component, OnInit } from '@angular/core'; +import { UserListDataSource } from './user-list-datasource'; +import { User } from '../../core/user'; +import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-user-list', @@ -11,8 +9,6 @@ import {ActivatedRoute} from '@angular/router'; styleUrls: ['./user-list.component.css'] }) export class UserListComponent implements OnInit { - @ViewChild(MatPaginator, { static: true }) paginator: MatPaginator; - @ViewChild(MatSort, { static: true }) sort: MatSort; dataSource: UserListDataSource; list: User[]; /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ @@ -26,6 +22,6 @@ export class UserListComponent implements OnInit { .subscribe((data: { list: User[] }) => { this.list = data.list; }); - this.dataSource = new UserListDataSource(this.paginator, this.sort, this.list); + this.dataSource = new UserListDataSource(this.list); } } diff --git a/bookie/src/app/users/user-resolver.service.spec.ts b/bookie/src/app/users/user-resolver.service.spec.ts new file mode 100644 index 0000000..d37f38e --- /dev/null +++ b/bookie/src/app/users/user-resolver.service.spec.ts @@ -0,0 +1,15 @@ +import {inject, TestBed} from '@angular/core/testing'; + +import {UserResolver} from './user-resolver.service'; + +describe('UserResolver', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [UserResolver] + }); + }); + + it('should be created', inject([UserResolver], (service: UserResolver) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/bookie/src/app/user/user-resolver.service.ts b/bookie/src/app/users/user-resolver.service.ts similarity index 94% rename from bookie/src/app/user/user-resolver.service.ts rename to bookie/src/app/users/user-resolver.service.ts index e9dbbac..98fa1c8 100644 --- a/bookie/src/app/user/user-resolver.service.ts +++ b/bookie/src/app/users/user-resolver.service.ts @@ -1,6 +1,6 @@ import {Injectable} from '@angular/core'; import {ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot} from '@angular/router'; -import {User} from './user'; +import {User} from '../core/user'; import {Observable} from 'rxjs/internal/Observable'; import {UserService} from './user.service'; diff --git a/bookie/src/app/users/user.service.spec.ts b/bookie/src/app/users/user.service.spec.ts new file mode 100644 index 0000000..1727f7f --- /dev/null +++ b/bookie/src/app/users/user.service.spec.ts @@ -0,0 +1,15 @@ +import {inject, TestBed} from '@angular/core/testing'; + +import {UserService} from './user.service'; + +describe('UserService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [UserService] + }); + }); + + it('should be created', inject([UserService], (service: UserService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/bookie/src/app/user/user.service.ts b/bookie/src/app/users/user.service.ts similarity index 83% rename from bookie/src/app/user/user.service.ts rename to bookie/src/app/users/user.service.ts index 9b6a4ae..b983b0b 100644 --- a/bookie/src/app/user/user.service.ts +++ b/bookie/src/app/users/user.service.ts @@ -3,7 +3,7 @@ import {HttpClient, HttpHeaders, HttpParams} from '@angular/common/http'; import {ErrorLoggerService} from '../core/error-logger.service'; import {catchError} from 'rxjs/operators'; import {Observable} from 'rxjs/internal/Observable'; -import {User} from './user'; +import {User} from '../core/user'; const httpOptions = { headers: new HttpHeaders({'Content-Type': 'application/json'}) @@ -28,7 +28,7 @@ export class UserService { list(): Observable { const options = {params: new HttpParams().set('l', '')}; - return >this.http.get(`${url}/list`, options) + return >this.http.get(url, options) .pipe( catchError(this.log.handleError(serviceName, 'list')) ); @@ -36,21 +36,21 @@ export class UserService { listOfNames(): Observable { const options = {params: new HttpParams().set('n', '')}; - return >this.http.get(`${url}/list`, options) + return >this.http.get(url, options) .pipe( catchError(this.log.handleError(serviceName, 'list')) ); } save(user: User): Observable { - return >this.http.put(`${url}/new`, user, httpOptions) + return >this.http.post(`${url}/new`, user, httpOptions) .pipe( catchError(this.log.handleError(serviceName, 'save')) ); } update(user: User): Observable { - return >this.http.post(`${url}/${user.id}`, user, httpOptions) + return >this.http.put(`${url}/${user.id}`, user, httpOptions) .pipe( catchError(this.log.handleError(serviceName, 'update')) ); diff --git a/bookie/src/app/users/users-routing.module.spec.ts b/bookie/src/app/users/users-routing.module.spec.ts new file mode 100644 index 0000000..16641c0 --- /dev/null +++ b/bookie/src/app/users/users-routing.module.spec.ts @@ -0,0 +1,13 @@ +import {UsersRoutingModule} from './users-routing.module'; + +describe('UsersRoutingModule', () => { + let userRoutingModule: UsersRoutingModule; + + beforeEach(() => { + userRoutingModule = new UsersRoutingModule(); + }); + + it('should create an instance', () => { + expect(userRoutingModule).toBeTruthy(); + }); +}); diff --git a/bookie/src/app/user/user-routing.module.ts b/bookie/src/app/users/users-routing.module.ts similarity index 91% rename from bookie/src/app/user/user-routing.module.ts rename to bookie/src/app/users/users-routing.module.ts index d36d4fe..3240afa 100644 --- a/bookie/src/app/user/user-routing.module.ts +++ b/bookie/src/app/users/users-routing.module.ts @@ -9,7 +9,7 @@ import {AuthGuard} from '../auth/auth-guard.service'; const userRoutes: Routes = [ { - path: 'users/list', + path: '', component: UserListComponent, canActivate: [AuthGuard], data: { @@ -20,7 +20,7 @@ const userRoutes: Routes = [ } }, { - path: 'users/new', + path: 'new', component: UserDetailComponent, canActivate: [AuthGuard], data: { @@ -31,7 +31,7 @@ const userRoutes: Routes = [ } }, { - path: 'users/:id', + path: ':id', component: UserDetailComponent, canActivate: [AuthGuard], resolve: { @@ -54,5 +54,5 @@ const userRoutes: Routes = [ UserResolver ] }) -export class UserRoutingModule { +export class UsersRoutingModule { } diff --git a/bookie/src/app/users/users.module.spec.ts b/bookie/src/app/users/users.module.spec.ts new file mode 100644 index 0000000..b0809d7 --- /dev/null +++ b/bookie/src/app/users/users.module.spec.ts @@ -0,0 +1,13 @@ +import {UsersModule} from './users.module'; + +describe('UsersModule', () => { + let userModule: UsersModule; + + beforeEach(() => { + userModule = new UsersModule(); + }); + + it('should create an instance', () => { + expect(userModule).toBeTruthy(); + }); +}); diff --git a/bookie/src/app/user/user.module.ts b/bookie/src/app/users/users.module.ts similarity index 93% rename from bookie/src/app/user/user.module.ts rename to bookie/src/app/users/users.module.ts index 467f5f5..eeeeb67 100644 --- a/bookie/src/app/user/user.module.ts +++ b/bookie/src/app/users/users.module.ts @@ -3,7 +3,7 @@ import {CommonModule} from '@angular/common'; import {UserListComponent} from './user-list/user-list.component'; import {UserDetailComponent} from './user-detail/user-detail.component'; -import {UserRoutingModule} from './user-routing.module'; +import {UsersRoutingModule} from './users-routing.module'; import { MatButtonModule } from '@angular/material/button'; import { MatCardModule } from '@angular/material/card'; import { MatCheckboxModule } from '@angular/material/checkbox'; @@ -36,12 +36,12 @@ import {FlexLayoutModule} from '@angular/flex-layout'; MatTableModule, ReactiveFormsModule, SharedModule, - UserRoutingModule + UsersRoutingModule ], declarations: [ UserListComponent, UserDetailComponent ] }) -export class UserModule { +export class UsersModule { }