Commit ec05fa46 authored by Matija Obreza's avatar Matija Obreza
Browse files

Merge branch '3-entry-page' into 'master'

Resolve web application with expressjs

Closes #3

See merge request grin-global/grin-global-ui!3
parents e20d79da 01171422
......@@ -31,3 +31,22 @@ sudo apt install yarn
```
## Running dev server with hot reload
To start the web application with live-reload server and work on the application, run either `yarn run web.start:dev`
in root directory, or `yarn run start:dev` in _packages/ui-express_ module directory
This starts the _webpack-dev-server_ on port 3000: <http://localhost:3000/>
## Running SSR server
To start express server with server side rendering and test application as in staging environment run either `yarn run web.start:prod` in root directory, or `yarn run start:dev` in _packages/ui-express_ module directory
This starts the express server on port 3000: <http://localhost:3000/>
## Running tests
To start test `yarn run web.test:dev` in root directory, or `yarn run test` in _packages/ui-core_ module directory
This starts jest test runner with code coverage statistics
......@@ -11,11 +11,15 @@
"scripts": {
"clean": "lerna run clean",
"postinstall": "lerna bootstrap && lerna run setup && lerna link",
"build": "lerna run build"
"build": "lerna run build",
"web.start:dev": "cd packages/ui-express && yarn run start:dev",
"web.start:prod": "yarn run clean && lerna run build --stream && cd ./target/app/server && node server.js ",
"web.test:dev": "lerna run test --stream"
},
"workspaces": [
"packages/i18n",
"packages/client"
"packages/client",
"packages/ui-express"
],
"devDependencies": {
"lerna": "^3.0.0"
......
{
"p": {
"welcome": {
"title": "Grin global application"
}
"appName": "GRIN-Global CE",
"validations": {
"required": "Required"
}
}
}
\ No newline at end of file
{
"action": {
"back": "Back",
"login": "Login",
"logout": "Logout",
"submit": "Submit"
},
"label": {
"loadingData": null
}
......
import { UPDATE_HISTORY } from '@gringlobal/client/constants/history';
export const updateHistory = (lastLocation: string) => (dispatch) => {
dispatch({ type: UPDATE_HISTORY, payload: lastLocation });
};
......@@ -72,13 +72,13 @@ export const logoutUserAction = () => ({
});
function* logoutUserSaga() {
const token = yield select((state) => state.login.access_token);
yield call(LoginService.logout, token);
// const token = yield select((state) => state.login.access_token);
// yield call(LoginService.logout, token);
clearCookies();
const appTokenData = yield call(loginAppAction);
const appTokenData = yield call(LoginService.loginApp);
const apiUrl = yield select((state) => state.applicationConfig.apiUrl);
saveCookies(appTokenData, appTokenData.exp * 1000 || new Date().getTime() + appTokenData.expires_in * 1000, apiUrl);
saveCookies({ ...appTokenData, ...jwt.decode(appTokenData.access_token) }, appTokenData.exp * 1000 || new Date().getTime() + appTokenData.expires_in * 1000, apiUrl);
window.location.replace('/');
}
......
export const UPDATE_HISTORY = 'UPDATE_HISTORY';
class ApiCall<T> {
public loading: boolean;
public error: string;
public timestamp: Date | number; // last successful execution (helps with invalidating cached data)
public data: T;
public progress?: number;
public static start = () => ({
loading: true,
error: null,
})
public static progress = (progress) => ({
loading: true,
error: null,
progress,
})
public static success = (data) => ({
loading: false,
data,
timestamp: Date.now(),
error: null,
})
public static error = (error) => {
console.log('ApiCall error', error);
return {
loading: false,
data: null,
timestamp: Date.now(),
error: `${error.message} ${error.response && error.response.data && error.response.data.error || ''}`,
};
}
}
export default ApiCall;
......@@ -5,3 +5,4 @@ export { default as IVersionedEntity } from '@gringlobal/client/model/common/IVe
export { default as VersionedModel } from '@gringlobal/client/model/common/VersionedModel';
export { default as AuditedVersionedModel } from '@gringlobal/client/model/common/AuditedVersionedModel';
export { default as UuidModel } from '@gringlobal/client/model/common/UuidModel';
export { default as ApiCall } from '@gringlobal/client/model/common/ApiCall';
import Geography from '@gringlobal/client/model/gringlobal/Geography';
import Site from '@gringlobal/client/model/gringlobal/Site';
import SysLang from '@gringlobal/client/model/gringlobal/SysLang';
import WebCooperator from '@gringlobal/client/model/gringlobal/WebCooperator';
/**
* Cooperator
*
* GRIN-Global CE API
*/
class Cooperator {
public createdBy: number;
public createdDate: Date;
public modifiedBy: number;
public modifiedDate: Date;
public ownedBy: Cooperator;
public ownedDate: Date;
public addressLine1: string;
public addressLine2: string;
public addressLine3: string;
public categoryCode: string;
public city: string;
public currentCooperator: number;
public disciplineCode: string;
public email: string;
public fax: string;
public firstName: string;
public geography: Geography;
public id: number;
public job: string;
public lastName: string;
public note: string;
public organization: string;
public organizationAbbrev: string;
public organizationRegionCode: string;
public postalIndex: string;
public primaryPhone: string;
public secondaryAddressLine1: string;
public secondaryAddressLine2: string;
public secondaryAddressLine3: string;
public secondaryCity: string;
public secondaryEmail: string;
public secondaryGeography: Geography;
public secondaryOrganization: string;
public secondaryOrganizationAbbrev: string;
public secondaryPhone: string;
public secondaryPostalIndex: string;
public site: Site;
public statusCode: string;
public sysLang: SysLang;
public title: string;
public webCooperator: WebCooperator;
}
export default Cooperator;
import DateFilter from '@gringlobal/client/model/gringlobal/DateFilter';
import SiteFilter from '@gringlobal/client/model/gringlobal/SiteFilter';
import StringFilter from '@gringlobal/client/model/gringlobal/StringFilter';
/**
* CooperatorFilter
*
* GRIN-Global CE API
*/
class CooperatorFilter {
public NOT: CooperatorFilter;
public NULL: string[];
public NOTNULL: string[];
public createdBy: CooperatorFilter;
public createdDate: DateFilter;
public modifiedBy: CooperatorFilter;
public modifiedDate: DateFilter;
public ownedBy: CooperatorFilter;
public ownedDate: DateFilter;
public id: number[];
public addressLine1: StringFilter;
public addressLine2: StringFilter;
public addressLine3: StringFilter;
public categoryCode: StringFilter;
public city: StringFilter;
public current: boolean;
public disciplineCode: StringFilter;
public email: StringFilter;
public fax: StringFilter;
public firstName: StringFilter;
public job: StringFilter;
public lastName: StringFilter;
public note: StringFilter;
public organization: StringFilter;
public organizationAbbrev: StringFilter;
public organizationRegionCode: StringFilter;
public postalIndex: StringFilter;
public primaryPhone: StringFilter;
public secondaryAddressLine1: StringFilter;
public secondaryAddressLine2: StringFilter;
public secondaryAddressLine3: StringFilter;
public secondaryCity: StringFilter;
public secondaryEmail: StringFilter;
public secondaryOrganization: StringFilter;
public secondaryOrganizationAbbrev: StringFilter;
public secondaryPhone: StringFilter;
public secondaryPostalIndex: StringFilter;
public site: SiteFilter;
public statusCode: StringFilter;
public title: StringFilter;
}
export default CooperatorFilter;
/**
* DateFilter
*
* GRIN-Global CE API
*/
class DateFilter {
public ge: Date;
public gt: Date;
public le: Date;
public lt: Date;
public between: Date[];
}
export default DateFilter;
import Cooperator from '@gringlobal/client/model/gringlobal/Cooperator';
/**
* Geography
*
* GRIN-Global CE API
*/
class Geography {
public createdBy: number;
public createdDate: Date;
public modifiedBy: number;
public modifiedDate: Date;
public ownedBy: Cooperator;
public ownedDate: Date;
public adm1: string;
public adm1Abbrev: string;
public adm1TypeCode: string;
public adm2: string;
public adm2Abbrev: string;
public adm2TypeCode: string;
public adm3: string;
public adm3Abbrev: string;
public adm3TypeCode: string;
public adm4: string;
public adm4Abbrev: string;
public adm4TypeCode: string;
public changedDate: Date;
public countryCode: string;
public currentGeography: number;
public id: number;
public isValid: string;
public note: string;
}
export default Geography;
import Cooperator from '@gringlobal/client/model/gringlobal/Cooperator';
/**
* Site
*
* GRIN-Global CE API
*/
class Site {
public createdBy: number;
public createdDate: Date;
public modifiedBy: number;
public modifiedDate: Date;
public ownedBy: Cooperator;
public ownedDate: Date;
public faoInstituteNumber: string;
public id: number;
public isDistributionSite: string;
public isInternal: string;
public note: string;
public organizationAbbrev: string;
public providerIdentifier: string;
public siteLongName: string;
public siteShortName: string;
public typeCode: string;
}
export default Site;
import CooperatorFilter from '@gringlobal/client/model/gringlobal/CooperatorFilter';
import DateFilter from '@gringlobal/client/model/gringlobal/DateFilter';
import StringFilter from '@gringlobal/client/model/gringlobal/StringFilter';
/**
* SiteFilter
*
* GRIN-Global CE API
*/
class SiteFilter {
public NOT: SiteFilter;
public NULL: string[];
public NOTNULL: string[];
public createdBy: CooperatorFilter;
public createdDate: DateFilter;
public modifiedBy: CooperatorFilter;
public modifiedDate: DateFilter;
public ownedBy: CooperatorFilter;
public ownedDate: DateFilter;
public id: number[];
public faoInstituteNumber: StringFilter;
public distributionSite: boolean;
public internal: boolean;
public note: StringFilter;
public organizationAbbrev: StringFilter;
public providerIdentifier: StringFilter;
public siteLongName: StringFilter;
public siteShortName: StringFilter;
public typeCode: StringFilter;
}
export default SiteFilter;
/**
* StringFilter
*
* GRIN-Global CE API
*/
class StringFilter {
public eq: string;
public contains: string;
public sw: string;
}
export default StringFilter;
import Cooperator from '@gringlobal/client/model/gringlobal/Cooperator';
/**
* SysLang
*
* GRIN-Global CE API
*/
class SysLang {
public createdBy: number;
public createdDate: Date;
public modifiedBy: number;
public modifiedDate: Date;
public ownedBy: Cooperator;
public ownedDate: Date;
public description: string;
public id: number;
public ietfTag: string;
public iso6393Tag: string;
public scriptDirection: string;
public title: string;
}
export default SysLang;
import Geography from '@gringlobal/client/model/gringlobal/Geography';
import WebUser from '@gringlobal/client/model/gringlobal/WebUser';
/**
* WebCooperator
*
* GRIN-Global CE API
*/
class WebCooperator {
public addressLine1: string;
public addressLine2: string;
public addressLine3: string;
public categoryCode: string;
public city: string;
public createdBy: WebUser;
public createdDate: Date;
public discipline: string;
public email: string;
public fax: string;
public firstName: string;
public geography: Geography;
public id: number;
public initials: string;
public isActive: string;
public job: string;
public lastName: string;
public modifiedBy: WebUser;
public modifiedDate: Date;
public note: string;
public organization: string;
public organizationCode: string;
public organizationRegion: string;
public ownedBy: WebUser;
public ownedDate: Date;
public postalIndex: string;
public primaryPhone: string;
public secondaryPhone: string;
public title: string;
}
export default WebCooperator;
import SysLang from '@gringlobal/client/model/gringlobal/SysLang';
import WebCooperator from '@gringlobal/client/model/gringlobal/WebCooperator';
/**
* WebUser
*
* GRIN-Global CE API
*/
class WebUser {
public createdDate: Date;
public id: number;
public isEnabled: string;
public lastLoginDate: Date;
public modifiedDate: Date;
public password: string;
public sysLang: SysLang;
public userName: string;
public webCooperator: WebCooperator;
}
export default WebUser;
import { Page, SortDirection } from '@gringlobal/client/model/page';
/*
* Defined in OpenAPI as '#/definitions/Page<T>'
*/
class FilteredPage<T> extends Page<T> {
public filterCode?: string;
public filter?: any;
public static reSort(paged: FilteredPage<any>, property?: string, direction?: SortDirection): FilteredPage<any> {
const resorted: FilteredPage<any> = {
filterCode: paged ? paged.filterCode : undefined,
// number: undefined, // because loadMore defaults to 0
size: paged ? paged.size : undefined,
sort: [ {
property: property ? property : undefined,
direction: direction ? direction : undefined,
} ],
};
console.log(`reSort for prop=${property} dir=${direction}`, resorted);
return resorted;
}
public static merge(oldPaged: FilteredPage<any>, newPaged: FilteredPage<any>): FilteredPage<any> {
if (!oldPaged) {
return newPaged;
}
if (! newPaged) {
return oldPaged;
}
const { filterCode, filter, ...other } = newPaged; // other helps with properties of subclasses
return {
...other,
...Page.merge(oldPaged, newPaged),
filterCode: filterCode === '' ? '' : filterCode || oldPaged.filterCode,
filter: filter || oldPaged.filter,
};
}
}
export default FilteredPage;
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