Commit 593ea1d2 by Tuomas Riihimäki

Merge branch 'graphql-for-frontend' into 'master'

Graphql backend fixes and Apollo graphql -api for frontend

See merge request !416
2 parents 6ee7b5b9 7d108edd
Showing with 196 additions and 143 deletions
package-lock=false
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"version": 1, "version": 1,
"newProjectRoot": "projects", "newProjectRoot": "projects",
"projects": { "projects": {
"angular6testi": { "moya-angular": {
"root": "", "root": "",
"sourceRoot": "src", "sourceRoot": "src",
"projectType": "application", "projectType": "application",
...@@ -48,18 +48,18 @@ ...@@ -48,18 +48,18 @@
"serve": { "serve": {
"builder": "@angular-devkit/build-angular:dev-server", "builder": "@angular-devkit/build-angular:dev-server",
"options": { "options": {
"browserTarget": "angular6testi:build" "browserTarget": "moya-angular:build"
}, },
"configurations": { "configurations": {
"production": { "production": {
"browserTarget": "angular6testi:build:production" "browserTarget": "moya-angular:build:production"
} }
} }
}, },
"extract-i18n": { "extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n", "builder": "@angular-devkit/build-angular:extract-i18n",
"options": { "options": {
"browserTarget": "angular6testi:build" "browserTarget": "moya-angular:build"
} }
}, },
"test": { "test": {
...@@ -93,7 +93,8 @@ ...@@ -93,7 +93,8 @@
} }
} }
}, },
"angular6testi-e2e": {
"moya-angular-e2e": {
"root": "e2e", "root": "e2e",
"sourceRoot": "e2e", "sourceRoot": "e2e",
"projectType": "application", "projectType": "application",
...@@ -102,7 +103,7 @@ ...@@ -102,7 +103,7 @@
"builder": "@angular-devkit/build-angular:protractor", "builder": "@angular-devkit/build-angular:protractor",
"options": { "options": {
"protractorConfig": "./protractor.conf.js", "protractorConfig": "./protractor.conf.js",
"devServerTarget": "angular6testi:serve" "devServerTarget": "moya-angular:serve"
} }
}, },
"lint": { "lint": {
...@@ -119,7 +120,7 @@ ...@@ -119,7 +120,7 @@
} }
} }
}, },
"defaultProject": "angular6testi", "defaultProject": "moya-angular",
"schematics": { "schematics": {
"@schematics/angular:component": { "@schematics/angular:component": {
"prefix": "moya", "prefix": "moya",
...@@ -129,4 +130,4 @@ ...@@ -129,4 +130,4 @@
"prefix": "moya" "prefix": "moya"
} }
} }
} }
\ No newline at end of file
...@@ -29,15 +29,21 @@ ...@@ -29,15 +29,21 @@
"@angular/router": "6.1.1", "@angular/router": "6.1.1",
"@ngx-translate/core": "^9.0.0", "@ngx-translate/core": "^9.0.0",
"@ngx-translate/http-loader": "^2.0.0", "@ngx-translate/http-loader": "^2.0.0",
"apollo-angular": "^1.1.2",
"apollo-angular-link-http": "^1.1.1",
"apollo-cache-inmemory": "^1.2.6",
"apollo-client": "^2.3.7",
"bootstrap": "^4.0.0", "bootstrap": "^4.0.0",
"core-js": "^2.5.1", "core-js": "^2.5.1",
"graphql": "^0.13.2",
"graphql-tag": "^2.9.2",
"ngx-bootstrap": "^2.0.2", "ngx-bootstrap": "^2.0.2",
"rxjs": "^6.2.2", "rxjs": "^6.2.2",
"ts-helpers": "^1.1.1", "ts-helpers": "^1.1.1",
"zone.js": "^0.8.26" "zone.js": "^0.8.26"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "~0.7.0", "@angular-devkit/build-angular": "~0.7.2",
"@angular/cdk": "^6.4.2", "@angular/cdk": "^6.4.2",
"@angular/cli": "6.1.2", "@angular/cli": "6.1.2",
"@angular/compiler-cli": "6.1.1", "@angular/compiler-cli": "6.1.1",
......
...@@ -16,6 +16,9 @@ import { NgModule } from '@angular/core'; ...@@ -16,6 +16,9 @@ import { NgModule } from '@angular/core';
import {LoginModule} from './modules/login/login.module'; import {LoginModule} from './modules/login/login.module';
import {LeftMenuModule} from './menu/left-menu/left-menu.module'; import {LeftMenuModule} from './menu/left-menu/left-menu.module';
import { FrontpageComponent } from './components/frontpage/frontpage.component'; import { FrontpageComponent } from './components/frontpage/frontpage.component';
import {HttpLink, HttpLinkModule} from 'apollo-angular-link-http';
import {APOLLO_OPTIONS, ApolloModule} from 'apollo-angular';
import {createApollo} from './shared/config/moya.config';
@NgModule({ @NgModule({
declarations: [ declarations: [
...@@ -32,6 +35,9 @@ import { FrontpageComponent } from './components/frontpage/frontpage.component'; ...@@ -32,6 +35,9 @@ import { FrontpageComponent } from './components/frontpage/frontpage.component';
LoginModule, LoginModule,
LeftMenuModule, LeftMenuModule,
ApolloModule,
HttpLinkModule,
AlertModule.forRoot(), AlertModule.forRoot(),
...@@ -50,6 +56,7 @@ import { FrontpageComponent } from './components/frontpage/frontpage.component'; ...@@ -50,6 +56,7 @@ import { FrontpageComponent } from './components/frontpage/frontpage.component';
LocaleService, LocaleService,
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
UserService, UserService,
{ provide: APOLLO_OPTIONS, useFactory: createApollo, deps: [HttpLink]},
], ],
bootstrap: [AppComponent] bootstrap: [AppComponent]
......
...@@ -3,10 +3,10 @@ import {map, catchError} from 'rxjs/operators'; ...@@ -3,10 +3,10 @@ import {map, catchError} from 'rxjs/operators';
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import {Observable, of } from 'rxjs'; import {Observable, of } from 'rxjs';
import {MoyaLocale} from './moya-locale.model'; import {MoyaLocale} from './moya-locale.model';
import {MOYA_BASE_URL} from '../../shared/tools/moya-rest.tool';
import {HttpClient} from '@angular/common/http'; import {HttpClient} from '@angular/common/http';
import {TranslateService} from '@ngx-translate/core'; import {TranslateService} from '@ngx-translate/core';
import {MOYA_REST_URL} from '../../shared/config/moya.config';
export const ENGLISH = 'en'; export const ENGLISH = 'en';
...@@ -71,7 +71,7 @@ export class LocaleService { ...@@ -71,7 +71,7 @@ export class LocaleService {
return new Observable<string>(x => x.next(this.selectedLocale)); return new Observable<string>(x => x.next(this.selectedLocale));
} }
return this.http.get<MoyaLocale>(MOYA_BASE_URL + '/v3/locale/').pipe( return this.http.get<MoyaLocale>(MOYA_REST_URL + '/v3/locale/').pipe(
catchError(x => catchError(x =>
of({} as MoyaLocale) of({} as MoyaLocale)
), ),
...@@ -109,7 +109,7 @@ export class LocaleService { ...@@ -109,7 +109,7 @@ export class LocaleService {
}; };
// let's save locale to database, if it fails, we save it into localstorage. No errors to show for user. // let's save locale to database, if it fails, we save it into localstorage. No errors to show for user.
this.http.post(MOYA_BASE_URL + '/v3/locale/', newLocale).pipe(catchError(x => { this.http.post(MOYA_REST_URL + '/v3/locale/', newLocale).pipe(catchError(x => {
localStorage.setItem(LOCALSTORAGE_NAME, locale); localStorage.setItem(LOCALSTORAGE_NAME, locale);
return 'ok'; return 'ok';
})).subscribe(); })).subscribe();
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<mat-table #table [dataSource]="vips | async"> <mat-table #table [dataSource]="vips | async">
<ng-container matColumnDef="host"> <ng-container matColumnDef="host">
<mat-header-cell *matHeaderCellDef translate >vip.host </mat-header-cell> <mat-header-cell *matHeaderCellDef translate >vip.host </mat-header-cell>
<mat-cell *matCellDef="let v" > {{v.host.firstname}} {{ v.host.lastname}} </mat-cell> <mat-cell *matCellDef="let v" > {{v.host.user.firstname}} {{ v.host.user.lastname}} </mat-cell>
</ng-container> </ng-container>
<ng-container matColumnDef="shortdescr"> <ng-container matColumnDef="shortdescr">
......
/** /**
* Created by tuukka on 04/02/17. * Created by tuukka on 04/02/17.
*/ */
import gql from 'graphql-tag';
export class VipProductDelivery { export class VipProductDelivery {
/* static fragments = gql`
public Integer id; fragment vipProductDeliveryPrimitives on VipProductDelivery {
public Integer delivererId; deliverytime
public BigDecimal quantity; id
public Date deliveryTime; notes
public String notes; quantity
*/ }
`;
id: number; id: number;
delivererId: number; delivererId: number;
......
import {VipProductDelivery} from './vip-product-delivery.model'; import {VipProductDelivery} from './vip-product-delivery.model';
import gql from 'graphql-tag';
/** /**
* Created by tuukka on 04/02/17. * Created by tuukka on 04/02/17.
*/ */
...@@ -7,17 +8,14 @@ import {VipProductDelivery} from './vip-product-delivery.model'; ...@@ -7,17 +8,14 @@ import {VipProductDelivery} from './vip-product-delivery.model';
export class VipProduct { export class VipProduct {
/* static fragments = gql`
fragment vipProductPrimitives on VipProduct {
public Integer id; id
public String name; name
public Integer productId; notes
public String notes; quantity
public BigDecimal quantity; }
public BigDecimal delivered; `;
public List<VipProductDeliveryPojo> deliveries = new ArrayList<>();
*/
id: number; id: number;
name: string; name: string;
......
import {VipProduct} from './vip-product.model'; import {VipProduct} from './vip-product.model';
import {User} from '../../../shared/models/user.model'; import {User} from '../../../shared/models/user.model';
import gql from 'graphql-tag';
import {VipProductDelivery} from './vip-product-delivery.model';
/** /**
* Created by tuukka on 04/02/17. * Created by tuukka on 04/02/17.
*/ */
...@@ -8,17 +10,14 @@ import {User} from '../../../shared/models/user.model'; ...@@ -8,17 +10,14 @@ import {User} from '../../../shared/models/user.model';
export class Vip { export class Vip {
/* static fragments = gql`
fragment vipPrimitives on Vip {
public Integer id; created
public String description; description
public String shortdescr; id
public Date created; shortdescr
public Integer eventuserId; }
public Integer creatorId; `;
public Integer hostId;
public List<VipProductPojo> products = new ArrayList<>();
*/
id: number; id: number;
description: string; description: string;
...@@ -35,3 +34,9 @@ export class Vip { ...@@ -35,3 +34,9 @@ export class Vip {
} }
} }
export const VipFragmentsCombined = gql`
${Vip.fragments}
${VipProduct.fragments}
${VipProductDelivery.fragments}
`;
import {forkJoin as observableForkJoin, Observable} from 'rxjs'; import {forkJoin as observableForkJoin, Observable} from 'rxjs';
import {first, switchMap, map} from 'rxjs/operators';
import {Injectable} from '@angular/core'; import {Injectable} from '@angular/core';
import {Vip} from './models/vip.model'; import {Vip, VipFragmentsCombined} from './models/vip.model';
import {User} from '../../shared/models/user.model'; import {User} from '../../shared/models/user.model';
import {UserService} from '../../shared/services/user.service'; import {UserService} from '../../shared/services/user.service';
import {HttpClient} from '@angular/common/http';
import {MOYA_BASE_URL, MOYA_REST_URL} from '../../shared/config/moya.config';
import gql from 'graphql-tag';
import {EventUser} from '../../shared/models/event-user.model';
import {Apollo} from 'apollo-angular';
import {first, map} from 'rxjs/operators';
import {Error} from 'tslint/lib/error';
export const Q_VIPS_N_DATA = gql`
{
vips {
...vipPrimitives
products {
...vipProductPrimitives
deliveries {
...vipProductDeliveryPrimitives
}
}
creator {
...eventUserPrimitives
user {
...userPrimitives
}
}
host {
...eventUserPrimitives
user {
...userPrimitives
}
}
}
}
${VipFragmentsCombined}
${EventUser.fragments}
${User.fragments}
`;
class VipsQueryRoot {
vips: Array<Vip>;
}
import {HttpClient} from '@angular/common/http';
import {MOYA_BASE_URL} from '../../shared/tools/moya-rest.tool';
@Injectable() @Injectable()
export class ViplistService { export class ViplistService {
constructor(private http: HttpClient, private userService: UserService) {
constructor(private apollo: Apollo, private http: HttpClient, private userService: UserService) {
} }
/** /**
* get vips * get vips
* @param searchString: searchString, skip to return all vips
*/ */
public get(searchString?: string): Observable<Array<Vip>> { public get(): Observable<Array<Vip>> {
return this.apollo.watchQuery<VipsQueryRoot>({query: Q_VIPS_N_DATA}).valueChanges.pipe(map(x => x.data.vips));
if (!searchString) {
return this.http.get(MOYA_BASE_URL + 'v3/vip/all').pipe(
switchMap(res => observableForkJoin(...(res as Array<any>), map(apiRow => this.hostPopulator(apiRow)))));
}
return this.http.get(MOYA_BASE_URL + 'v3/vip/search/' + searchString).pipe(
switchMap(v => observableForkJoin(...(v as Array<any>), map(x => this.hostPopulator(x)))));
} }
...@@ -49,9 +80,7 @@ export class ViplistService { ...@@ -49,9 +80,7 @@ export class ViplistService {
throw new Error('TODO: errori, tyhmä vippi'); throw new Error('TODO: errori, tyhmä vippi');
} }
const res: any = await this.http.delete(MOYA_BASE_URL + 'v3/vip/' + vip.id).pipe( const res: any = await this.http.delete(MOYA_BASE_URL + 'v3/vip/' + vip.id).pipe(first()).toPromise();
first())
.toPromise();
return res.ok; return res.ok;
} }
...@@ -59,21 +88,13 @@ export class ViplistService { ...@@ -59,21 +88,13 @@ export class ViplistService {
public getWithId(id: number): Observable<Vip> { public getWithId(id: number): Observable<Vip> {
return this.http.get(MOYA_BASE_URL + 'v3/vip/' + id).pipe(map(x => x as Vip)); return this.http.get(MOYA_BASE_URL + 'v3/vip/' + id).pipe(map(x => x as Vip));
} }
public create(vip: Vip): Observable<Vip> { public create(vip: Vip): Observable<Vip> {
return this.http.post(MOYA_BASE_URL + 'v3/vip/create', vip).pipe(map(x => x as Vip)); return this.http.post(MOYA_BASE_URL + 'v3/vip/create', vip).pipe(map(x => x as Vip));
} }
private hostPopulator(rawVip: any): Observable<Vip> {
return this.userService.get(rawVip.hostId).pipe(
map((u: User) => {rawVip.host = u; return <Vip> rawVip; }), map(x => x as Vip), );
}
} }
......
import {InMemoryCache} from 'apollo-cache-inmemory';
import {HttpLink} from 'apollo-angular-link-http';
export const MOYA_BASE_URL = '/MoyaWeb/';
export const MOYA_REST_URL = MOYA_BASE_URL + 'rest/';
export function createApollo(httpLink: HttpLink) {
return {
link: httpLink.create({uri: MOYA_BASE_URL + 'graphql'}),
cache: new InMemoryCache(),
};
}
import {User} from './user.model';
import gql from 'graphql-tag';
export enum UserGender {
MALE,
FEMALE,
UNSPECIFIED
}
export class EventUser {
static fragments = gql`
fragment eventUserPrimitives on EventUser {
id
eventusercreated
}
`;
id: number;
eventusercreated: Date;
user: User;
constructor() { }
}
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
// vim magic: %s/^\s*\w\+\s\+\(\w\+\)\s\+\(\w\+\)\s*.*;$/ \2: \L\1;/ // vim magic: %s/^\s*\w\+\s\+\(\w\+\)\s\+\(\w\+\)\s*.*;$/ \2: \L\1;/
import gql from 'graphql-tag';
export enum UserGender { export enum UserGender {
MALE, MALE,
FEMALE, FEMALE,
...@@ -12,10 +14,33 @@ export enum UserGender { ...@@ -12,10 +14,33 @@ export enum UserGender {
export class User { export class User {
static fragments = gql`
fragment userPrimitives on User {
address
allergiesFreetext
birthday
email
firstnames
gender
id:
lastname
login
nick
phone
town
shirtSize
town
zip
}
`;
nick: string; nick: string;
login: string; login: string;
eventuserId: number; id: number;
userId: number;
firstname: string; firstname: string;
lastname: string; lastname: string;
password: string; password: string;
...@@ -23,12 +48,12 @@ export class User { ...@@ -23,12 +48,12 @@ export class User {
birthday: Date; birthday: Date;
gender: UserGender; gender: UserGender;
phoneNumber: string; phone: string;
email: string; email: string;
streetAddress: string; streetAddress: string;
zipCode: string; zip: string;
postOffice: string; town: string;
constructor() { } constructor() { }
......
...@@ -4,7 +4,7 @@ import {Injectable} from '@angular/core'; ...@@ -4,7 +4,7 @@ import {Injectable} from '@angular/core';
import {User} from '../models/user.model'; import {User} from '../models/user.model';
import {CacheService} from './cache.service'; import {CacheService} from './cache.service';
import {HttpClient} from '@angular/common/http'; import {HttpClient} from '@angular/common/http';
import {MOYA_BASE_URL} from '../tools/moya-rest.tool'; import {MOYA_REST_URL} from '../config/moya.config';
@Injectable() @Injectable()
...@@ -18,7 +18,7 @@ export class UserService { ...@@ -18,7 +18,7 @@ export class UserService {
return observableThrowError('There should be userid'); return observableThrowError('There should be userid');
} }
const path = MOYA_BASE_URL + 'v2/user/' + id; const path = MOYA_REST_URL + 'v2/user/' + id;
return this.cacheService.cacheObservable('moya:UserService', path, return this.cacheService.cacheObservable('moya:UserService', path,
this.http.get<User>(path).pipe(tap(v => {console.log('getting user outside of cache', path); }))); this.http.get<User>(path).pipe(tap(v => {console.log('getting user outside of cache', path); })));
......
export const MOYA_BASE_URL = '/MoyaWeb/rest/';
export abstract class MoyaRestTool {
/*
genUrl(subUrl: string, urlParams?: Map<string, string>): string {
let suffix = '';
if (urlParams) {
urlParams.forEach(function(value: string, key: string) {
if (suffix.length <= 0) {
suffix = '?';
} else {
suffix += '&';
}
suffix += key + '=' + value;
});
}
return '/MoyaWeb/rest/' + subUrl + suffix; // <-- TODO: kauneista
} */
}
...@@ -12,10 +12,11 @@ ...@@ -12,10 +12,11 @@
"node_modules/@types" "node_modules/@types"
], ],
"lib": [ "lib": [
"es2017", "es2018",
"dom" "dom",
"esnext.asynciterable"
], ],
"module": "es2015", "module": "es2015",
"baseUrl": "./" "baseUrl": "./"
} }
} }
\ No newline at end of file
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
"label-position": true, "label-position": true,
"max-line-length": [ "max-line-length": [
true, true,
140 200
], ],
"member-access": false, "member-access": false,
"member-ordering": [ "member-ordering": [
......
...@@ -626,6 +626,11 @@ public class BootstrapBean implements BootstrapBeanLocal { ...@@ -626,6 +626,11 @@ public class BootstrapBean implements BootstrapBeanLocal {
"ALTER TABLE compo_voting_roles ADD CONSTRAINT FK_compo_voting_roles_scheme_id FOREIGN KEY (scheme_id) REFERENCES compo_voting_schemes (id)", "ALTER TABLE compo_voting_roles ADD CONSTRAINT FK_compo_voting_roles_scheme_id FOREIGN KEY (scheme_id) REFERENCES compo_voting_schemes (id)",
"ALTER TABLE compo_voting_roles ADD CONSTRAINT FK_compo_voting_roles_role_id FOREIGN KEY (role_id) REFERENCES roles (id)", "ALTER TABLE compo_voting_roles ADD CONSTRAINT FK_compo_voting_roles_role_id FOREIGN KEY (role_id) REFERENCES roles (id)",
}); });
dbUpdates.add(new String[]{
"ALTER TABLE users DROP COLUMN postal_town;"
});
} }
......
...@@ -131,7 +131,6 @@ public class TestDataBean implements TestDataBeanLocal { ...@@ -131,7 +131,6 @@ public class TestDataBean implements TestDataBeanLocal {
u.resetPassword("kavija"); u.resetPassword("kavija");
u.setPhone("123-45679854"); u.setPhone("123-45679854");
u.setTown("Keikyän MLK"); u.setTown("Keikyän MLK");
u.setPostalTown("Keykyä");
u.setZip("393929"); u.setZip("393929");
userFacade.create(u); userFacade.create(u);
return u; return u;
...@@ -157,7 +156,6 @@ public class TestDataBean implements TestDataBeanLocal { ...@@ -157,7 +156,6 @@ public class TestDataBean implements TestDataBeanLocal {
u.resetPassword("admin"); u.resetPassword("admin");
u.setPhone("1337"); u.setPhone("1337");
u.setTown("Adminila"); u.setTown("Adminila");
u.setPostalTown("Adminila ");
u.setZip("6666"); u.setZip("6666");
// u.setSuperadmin(true); // u.setSuperadmin(true);
userFacade.create(u); userFacade.create(u);
......
...@@ -194,9 +194,6 @@ public class UserFacade extends IntegerPkGenericFacade<User> { ...@@ -194,9 +194,6 @@ public class UserFacade extends IntegerPkGenericFacade<User> {
case "zip": case "zip":
sort = User_.zip; sort = User_.zip;
break; break;
case "postalTown":
sort = User_.postalTown;
break;
case "town": case "town":
sort = User_.town; sort = User_.town;
break; break;
......
...@@ -421,14 +421,6 @@ public class EventUser extends GenericEntity { ...@@ -421,14 +421,6 @@ public class EventUser extends GenericEntity {
return user.isSuperadmin(); return user.isSuperadmin();
} }
public void setPostalTown(String postalTown) {
user.setPostalTown(postalTown);
}
public String getPostalTown() {
return user.getPostalTown();
}
public void setGender(Gender gender) { public void setGender(Gender gender) {
user.setGender(gender); user.setGender(gender);
} }
......
...@@ -112,10 +112,6 @@ public interface IUser { ...@@ -112,10 +112,6 @@ public interface IUser {
public abstract boolean isSuperadmin(); public abstract boolean isSuperadmin();
public abstract void setPostalTown(String postalTown);
public abstract String getPostalTown();
public abstract void setGender(Gender gender); public abstract void setGender(Gender gender);
public abstract Gender getGender(); public abstract Gender getGender();
......
...@@ -96,9 +96,6 @@ public class User extends GenericEntity implements IUser { ...@@ -96,9 +96,6 @@ public class User extends GenericEntity implements IUser {
@Column(name = "zip") @Column(name = "zip")
private String zip = ""; private String zip = "";
@Column(name = "postal_town")
private String postalTown = "";
@Column(name = "town") @Column(name = "town")
private String town = ""; private String town = "";
...@@ -349,15 +346,6 @@ public class User extends GenericEntity implements IUser { ...@@ -349,15 +346,6 @@ public class User extends GenericEntity implements IUser {
return superadmin; return superadmin;
} }
@Override
public void setPostalTown(String postalTown) {
this.postalTown = postalTown;
}
@Override
public String getPostalTown() {
return postalTown;
}
@Override @Override
public void setGender(Gender gender) { public void setGender(Gender gender) {
......
...@@ -29,7 +29,7 @@ public class VipProduct extends GenericEntity { ...@@ -29,7 +29,7 @@ public class VipProduct extends GenericEntity {
/** /**
* If product is null this is used as the name of the product * If product is null this is used as the name of the product
*/ */
private String name; private String name = "";
@ManyToOne() @ManyToOne()
@JoinColumn(nullable = true) @JoinColumn(nullable = true)
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
<hr /> <hr />
<h:outputText value="#{user.address}" /> <h:outputText value="#{user.address}" />
<br /> <br />
<h:outputText value="#{user.zip} #{user.postalTown}" /> <h:outputText value="#{user.zip} #{user.town}" />
<br /> <br />
<br /> <br />
<h:outputText value="#{user.phone}" /> <h:outputText value="#{user.phone}" />
......
...@@ -48,8 +48,8 @@ ...@@ -48,8 +48,8 @@
<rewriteservlet.version>3.4.2.Final</rewriteservlet.version> <rewriteservlet.version>3.4.2.Final</rewriteservlet.version>
<iudex.standalone>1.0.23</iudex.standalone> <iudex.standalone>1.0.23</iudex.standalone>
<js.node.version>v8.11.3</js.node.version> <js.node.version>v10.8.0</js.node.version>
<js.npm.version>6.3.0</js.npm.version> <js.npm.version>6.2.0</js.npm.version>
<eirslett.frontend.version>1.4</eirslett.frontend.version> <eirslett.frontend.version>1.4</eirslett.frontend.version>
<payara.version>4.1.2.181</payara.version> <payara.version>4.1.2.181</payara.version>
</properties> </properties>
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!