Skip to content

Commit

Permalink
Merge pull request #74 from baoduy/develop
Browse files Browse the repository at this point in the history
Improvement
  • Loading branch information
baoduy authored Aug 23, 2018
2 parents b9e69de + 1a95fb0 commit 5e72fca
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 49 deletions.
42 changes: 23 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ The PRD really sttarted kit for **ReactJs** with hot module replacement (HMR) fo

Based on the best practises of the Single-Page-Application development with NodeJS. I added the nice font-end component [Material-Dashboard-React](https://github.com/creativetimofficial/material-dashboard-react) and Redux store integration.

Beside of that I also developped some useful compoment as Message box, Notification to make the Started-kit to be a **Production ready** SPA.
Beside of that I also developped some useful compoment as Message box, Notification to make the Started-kit to be a **Production ready** SPA kit.

## Support Features

Expand Down Expand Up @@ -61,15 +61,13 @@ async function getDataFromServer() {
}
```

### Installation
## Installation

1. Clone/download repo
2. `npm install`
3. Replace the CodeCov.io token to your one in the `package.json` file.
4. Run `npm start` to run the project.

---

## Usage

### Development
Expand All @@ -92,12 +90,12 @@ async function getDataFromServer() {

- Analysis served @ `http://localhost:8888`

---

## New Compoments

1. **Message Box and Notification**: Allow to show Info, Confirm, Success and Error message and notification. Refer to the MessageBox in Views folder so sample that using Redux store to manage the state.

## Environment Supports

### Docker Support

1. Build Image `docker build`.
Expand All @@ -106,36 +104,42 @@ async function getDataFromServer() {
3. Push inage to Docker hub `docker push [YOUR_ID]/react-materialui-started-kit:latest`
Example `docker push baoduy2412/react-materialui-started-kit:latest`.

The application will running port 3000 in Docker.
The application will running port 80 and 443 in Docker.
The image can be found in Docker hub [here](https://hub.docker.com/r/baoduy2412/react-materialui-started-kit/).

**If you are using Docker the `Docker` folder in this project can be deleted without any impact.**

---
However if you are not using Docker just simply remove the submodule **sm-react-docker-nginx** There is no impact to the application.

### IIS Support

The `Web.config` file had been added for IIS hosting purpose. When build the application this file will be copied to dist folder automatically and make the package ready for IIS.
The `Web.config` file in **sm-react-iis** had been added for IIS hosting purpose. This file should be copy along with all files in dist folder when hosting in IIS.

However if you are not hosting this app in IIS just simply delete this file.or leave if there. There is no impact to the application.
However if you are not hosting this app in IIS just simply remove the submodule **sm-react-iis** There is no impact to the application.

### Azure Service Fabric Support

All stuffs in `service-fabric` folder are using for **[Azure Service Fabric](https://azure.microsoft.com/en-us/services/service-fabric/)** hosting purpose.
The project inside this folder will copy all files in dist folder and host as a static side in Azure Service Fabric.
I'm using .Net Core 2.0 to make the project is flexible enough to host on any platforms.
All stuffs in `sm-react-service-fabric` folder are using for **[Azure Service Fabric](https://azure.microsoft.com/en-us/services/service-fabric/)** hosting purpose.

The C# project inside this folder will copy all files from dist folder to wwwroot folder and host them as a static side in Azure Service Fabric.

Currently, I'm using .Net Core 2.1 to make the project is flexible enough to host on any platforms.

When build the Service Fabric application it will copy all files in `dist` folder to `wwwroot` folder. So ensure you run the `npm build` before deploy the Service Fabric app.

Defiantly, If you are not using **Azure Service Fabric**. This folder shall be deleted.
However if you are not using Service Fabric just simply remove the submodule **sm-react-service-fabric** There is no impact to the application.

### Node Js Hosting

There is a sub module contains the Express.js configuration to host the application in the Node Js environment.
The application will running port 3000 and 3001 in NodeJs and the port is configurable in the Js file.

If you are not using Node Js hosting just simply remove the submodule **sm-react-node-express** There is no impact to the application.
But, please note that the `npm run start-prod` is using this submodule to hosting the dist folder as a static side. Please be considered before removing this module.

### GZIP and SSL

The **GZIP** and **SSL** had been applied for all hosting environments above.

---

### All commands
## All commands

| Command | Description |
| ------------------------ | ------------------------------------------------------------------------ |
Expand Down
2 changes: 1 addition & 1 deletion configs/jest
Submodule jest updated from 9b59a4 to 5195b1
2 changes: 1 addition & 1 deletion sm-react-service-fabric
34 changes: 28 additions & 6 deletions src/commons/commonFuncs.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,43 @@
/*eslint no-console: ["off", { allow: ["warn", "error"] }] */

import linq from 'linq';
import uuidv4 from 'uuid/v4';
//correct URL for Reserved proxy
//Get the millisecond of current time.

export function GetBaseUrl() {
const key = 'BASE_URL';
let base = window.sessionStorage.getItem(key);

if (base === undefined || base === null) {
base = document.getElementsByTagName('base')[0].getAttribute('href');
window.sessionStorage.setItem(key, base);

console.log(`base URL is ${base}`);
}

return base;
}

export function newGuid() {
return uuidv4();
}

/**
*getImgSrc for both normal hosting and Reverse proxy
*
* @export
* @param {string} url the relative image url
* @returns real url
*/
export function getImgSrc(url) {
if (typeof url !== 'string') return url;
const base = window._base;

if (!base || base === '/') return url;
if (url.indexOf(base) >= 0) return url;
const base = GetBaseUrl();

return `${base}/${url}`;
return !base || base === '/' || url.indexOf(base) >= 0
? url
: `${base}/${url}`;
}

/**
*Merge second array to first array if existed then update.
*
Expand Down
11 changes: 5 additions & 6 deletions src/index.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/*eslint no-console: ["off", { allow: ["warn", "error"] }] */
import React from 'react';
import ReactDOM from 'react-dom';
import { createBrowserHistory } from 'history';
import { Router, Route, Switch, BrowserRouter } from 'react-router-dom';
import Provider from 'react-redux-thunk-store';
import ExceptionHandler from './layouts/ExceptionHandler';

import { GetBaseUrl } from './commons/commonFuncs';
//Style-sheets
import './assets/less/material-dashboard-react.less';

Expand All @@ -15,14 +16,12 @@ import indexRoutes from 'routes/index.jsx';
const isPrd = process.env.NODE_ENV === 'production';

//Update for Reserved proxy
window._base = document.getElementsByTagName('base')[0].getAttribute('href');
console.log(`base URL ${window._base}`);

const hist = createBrowserHistory({ basename: window._base });
const base = GetBaseUrl();
const hist = createBrowserHistory({ basename: base });

const createRouter = () => {
return (
<BrowserRouter basename={window._base || '/'}>
<BrowserRouter basename={base || '/'}>
<Router history={hist}>
<Switch>
{indexRoutes.map((prop, key) => {
Expand Down
33 changes: 17 additions & 16 deletions tests/commons/commonFuncs.test.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
import { getImgSrc, newGuid } from "../../src/commons/commonFuncs";
import { getImgSrc, newGuid } from '../../src/commons/commonFuncs';

test("2 GUID must be difference", () => {
window.sessionStorage.setItem('BASE_URL', '/ReactJs');

test('2 GUID must be difference', () => {
const g1 = newGuid();
const g2 = newGuid();

expect(g1).not.toBe(g2);
});

test("getImgSrc should add basename to url", () => {
window._base = "/ReactJs";
expect(getImgSrc("/img/a.png")).toContain(window._base);
test('getImgSrc should add basename to url', () => {
expect(getImgSrc('/img/a.png')).toContain('/ReactJs');
});

test("getImgSrc should not add basename to url", () => {
window._base = "/ReactJs";
expect(getImgSrc("/ReactJs/img/a.png")).toBe("/ReactJs/img/a.png");
test('getImgSrc should not add basename to url', () => {
expect(getImgSrc('/ReactJs/img/a.png')).toBe('/ReactJs/img/a.png');
});

test("getImgSrc should return original object", () => {
window._base = "/ReactJs";
test('getImgSrc should return original object', () => {
const url = { a: 1 };
expect(getImgSrc(url)).toBe(url);
});

test("getImgSrc should return original string", () => {
window._base = "/";
const url = "123";
test('getImgSrc should return original string', () => {
const url = '123';
window.sessionStorage.setItem('BASE_URL', '/');

expect(getImgSrc(url)).toBe(url);
});

test("getImgSrc should do nothing", () => {
window._base = undefined;
const url = "123";
test('getImgSrc should do nothing', () => {
const url = '123';
window.sessionStorage.setItem('BASE_URL', '');

expect(getImgSrc(url)).toBe(url);
});

0 comments on commit 5e72fca

Please sign in to comment.