From 3a23aa59d2b62afbad261f59ca3e60fd7750baaf Mon Sep 17 00:00:00 2001 From: Anca Iordache Date: Thu, 5 Mar 2020 19:02:53 +0100 Subject: [PATCH] add react-java-mysql application sample Signed-off-by: Anca Iordache --- samples/react-java-mysql/backend/Dockerfile | 11 + samples/react-java-mysql/backend/pom.xml | 71 ++++ .../java/com/company/project/Application.java | 16 + .../project/controllers/HomeController.java | 16 + .../src/main/resources/application.properties | 1 + .../src/main/resources/templates/home.ftl | 9 + samples/react-java-mysql/db/password.txt | 1 + samples/react-java-mysql/docker-compose.yaml | 26 ++ samples/react-java-mysql/frontend/.babelrc | 23 + .../react-java-mysql/frontend/.browserslistrc | 5 + .../react-java-mysql/frontend/.dockerignore | 2 + .../react-java-mysql/frontend/.eslintignore | 1 + samples/react-java-mysql/frontend/.eslintrc | 36 ++ samples/react-java-mysql/frontend/.gitignore | 4 + samples/react-java-mysql/frontend/Dockerfile | 9 + .../frontend/Dockerfile.production | 12 + samples/react-java-mysql/frontend/README.md | 1 + .../frontend/config/nginx.conf | 9 + .../react-java-mysql/frontend/jest.config.js | 15 + .../react-java-mysql/frontend/package.json | 72 ++++ .../react-java-mysql/frontend/src/app/app.jsx | 22 + .../layout/ApplicationContainer.jsx | 15 + .../src/app/components/layout/index.js | 5 + .../src/app/core/styles/normalize.scss | 396 ++++++++++++++++++ .../frontend/src/app/core/styles/reset.css | 48 +++ .../frontend/src/app/entry.jsx | 39 ++ .../frontend/src/app/pages/home/HomePage.jsx | 26 ++ .../frontend/src/app/pages/home/home.scss | 6 + .../frontend/src/app/pages/home/index.js | 7 + .../frontend/src/app/reducers.js | 10 + .../src/app/redux/whales/action-creators.js | 4 + .../src/app/redux/whales/action-types.js | 4 + .../frontend/src/app/redux/whales/index.js | 3 + .../frontend/src/app/redux/whales/reducer.js | 16 + .../src/app/redux/whales/selectors.js | 0 .../frontend/src/app/routes.jsx | 10 + .../frontend/src/app/sagas.js | 9 + .../frontend/src/app/store.js | 37 ++ .../react-java-mysql/frontend/src/index.ejs | 10 + .../frontend/src/test/mocks/imageMock.js | 3 + .../frontend/src/test/mocks/styleMock.js | 2 + .../frontend/webpack.config.js | 1 + .../frontend/webpack/config-builder.js | 231 ++++++++++ .../frontend/webpack/dev-server.js | 38 ++ 44 files changed, 1282 insertions(+) create mode 100755 samples/react-java-mysql/backend/Dockerfile create mode 100755 samples/react-java-mysql/backend/pom.xml create mode 100755 samples/react-java-mysql/backend/src/main/java/com/company/project/Application.java create mode 100755 samples/react-java-mysql/backend/src/main/java/com/company/project/controllers/HomeController.java create mode 100755 samples/react-java-mysql/backend/src/main/resources/application.properties create mode 100755 samples/react-java-mysql/backend/src/main/resources/templates/home.ftl create mode 100644 samples/react-java-mysql/db/password.txt create mode 100644 samples/react-java-mysql/docker-compose.yaml create mode 100755 samples/react-java-mysql/frontend/.babelrc create mode 100755 samples/react-java-mysql/frontend/.browserslistrc create mode 100755 samples/react-java-mysql/frontend/.dockerignore create mode 100755 samples/react-java-mysql/frontend/.eslintignore create mode 100755 samples/react-java-mysql/frontend/.eslintrc create mode 100755 samples/react-java-mysql/frontend/.gitignore create mode 100755 samples/react-java-mysql/frontend/Dockerfile create mode 100755 samples/react-java-mysql/frontend/Dockerfile.production create mode 100755 samples/react-java-mysql/frontend/README.md create mode 100755 samples/react-java-mysql/frontend/config/nginx.conf create mode 100755 samples/react-java-mysql/frontend/jest.config.js create mode 100755 samples/react-java-mysql/frontend/package.json create mode 100755 samples/react-java-mysql/frontend/src/app/app.jsx create mode 100755 samples/react-java-mysql/frontend/src/app/components/layout/ApplicationContainer.jsx create mode 100755 samples/react-java-mysql/frontend/src/app/components/layout/index.js create mode 100755 samples/react-java-mysql/frontend/src/app/core/styles/normalize.scss create mode 100755 samples/react-java-mysql/frontend/src/app/core/styles/reset.css create mode 100755 samples/react-java-mysql/frontend/src/app/entry.jsx create mode 100755 samples/react-java-mysql/frontend/src/app/pages/home/HomePage.jsx create mode 100755 samples/react-java-mysql/frontend/src/app/pages/home/home.scss create mode 100755 samples/react-java-mysql/frontend/src/app/pages/home/index.js create mode 100755 samples/react-java-mysql/frontend/src/app/reducers.js create mode 100755 samples/react-java-mysql/frontend/src/app/redux/whales/action-creators.js create mode 100755 samples/react-java-mysql/frontend/src/app/redux/whales/action-types.js create mode 100755 samples/react-java-mysql/frontend/src/app/redux/whales/index.js create mode 100755 samples/react-java-mysql/frontend/src/app/redux/whales/reducer.js create mode 100755 samples/react-java-mysql/frontend/src/app/redux/whales/selectors.js create mode 100755 samples/react-java-mysql/frontend/src/app/routes.jsx create mode 100755 samples/react-java-mysql/frontend/src/app/sagas.js create mode 100755 samples/react-java-mysql/frontend/src/app/store.js create mode 100755 samples/react-java-mysql/frontend/src/index.ejs create mode 100755 samples/react-java-mysql/frontend/src/test/mocks/imageMock.js create mode 100755 samples/react-java-mysql/frontend/src/test/mocks/styleMock.js create mode 100755 samples/react-java-mysql/frontend/webpack.config.js create mode 100755 samples/react-java-mysql/frontend/webpack/config-builder.js create mode 100755 samples/react-java-mysql/frontend/webpack/dev-server.js diff --git a/samples/react-java-mysql/backend/Dockerfile b/samples/react-java-mysql/backend/Dockerfile new file mode 100755 index 0000000..265d758 --- /dev/null +++ b/samples/react-java-mysql/backend/Dockerfile @@ -0,0 +1,11 @@ +FROM maven:3.5-jdk-9 AS build +COPY pom.xml . +RUN mvn --batch-mode dependency:resolve +COPY . . +RUN mvn --batch-mode package +RUN cp target/*jar target/app.jar + +FROM openjdk:9-jre +VOLUME /tmp +COPY --from=build target/app.jar app.jar +ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] diff --git a/samples/react-java-mysql/backend/pom.xml b/samples/react-java-mysql/backend/pom.xml new file mode 100755 index 0000000..aeef767 --- /dev/null +++ b/samples/react-java-mysql/backend/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + + com.company + project + 0.0.1-SNAPSHOT + jar + + New App + My new SpringBoot app + + + org.springframework.boot + spring-boot-starter-parent + 2.0.3.RELEASE + + + + + UTF-8 + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-jersey + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.session + spring-session-core + + + org.springframework.boot + spring-boot-devtools + + + org.springframework.boot + spring-boot-starter-freemarker + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + + + javax.xml.bind + jaxb-api + 2.3.0 + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + diff --git a/samples/react-java-mysql/backend/src/main/java/com/company/project/Application.java b/samples/react-java-mysql/backend/src/main/java/com/company/project/Application.java new file mode 100755 index 0000000..16b8c45 --- /dev/null +++ b/samples/react-java-mysql/backend/src/main/java/com/company/project/Application.java @@ -0,0 +1,16 @@ +package com.company.project; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@EnableAutoConfiguration +@ComponentScan(basePackages = {"com.company.project"}) +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/samples/react-java-mysql/backend/src/main/java/com/company/project/controllers/HomeController.java b/samples/react-java-mysql/backend/src/main/java/com/company/project/controllers/HomeController.java new file mode 100755 index 0000000..966839d --- /dev/null +++ b/samples/react-java-mysql/backend/src/main/java/com/company/project/controllers/HomeController.java @@ -0,0 +1,16 @@ +package com.company.project.controllers; + +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@Controller +public class HomeController { + + @GetMapping("/") + public String showHome(String name, Model model) { + return "home"; + } + +} diff --git a/samples/react-java-mysql/backend/src/main/resources/application.properties b/samples/react-java-mysql/backend/src/main/resources/application.properties new file mode 100755 index 0000000..8b13789 --- /dev/null +++ b/samples/react-java-mysql/backend/src/main/resources/application.properties @@ -0,0 +1 @@ + diff --git a/samples/react-java-mysql/backend/src/main/resources/templates/home.ftl b/samples/react-java-mysql/backend/src/main/resources/templates/home.ftl new file mode 100755 index 0000000..daba182 --- /dev/null +++ b/samples/react-java-mysql/backend/src/main/resources/templates/home.ftl @@ -0,0 +1,9 @@ + + + + Getting Started: Serving Web Content + + + +

Hello from Docker!

+ diff --git a/samples/react-java-mysql/db/password.txt b/samples/react-java-mysql/db/password.txt new file mode 100644 index 0000000..e9031c9 --- /dev/null +++ b/samples/react-java-mysql/db/password.txt @@ -0,0 +1 @@ +db-57xsl \ No newline at end of file diff --git a/samples/react-java-mysql/docker-compose.yaml b/samples/react-java-mysql/docker-compose.yaml new file mode 100644 index 0000000..f2621d6 --- /dev/null +++ b/samples/react-java-mysql/docker-compose.yaml @@ -0,0 +1,26 @@ +version: "3.7" +services: + backend: + build: backend + db: + environment: + MYSQL_DATABASE: example + MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db-password + image: mysql:5.7 + restart: always + secrets: + - db-password + volumes: + - db-data:/var/lib/mysql + frontend: + build: frontend + ports: + - 80:9000 + volumes: + - ./frontend:/project + - /project/node_modules +volumes: + db-data: {} +secrets: + db-password: + file: db/password.txt diff --git a/samples/react-java-mysql/frontend/.babelrc b/samples/react-java-mysql/frontend/.babelrc new file mode 100755 index 0000000..75f783d --- /dev/null +++ b/samples/react-java-mysql/frontend/.babelrc @@ -0,0 +1,23 @@ +{ + "presets": [ + [ + "env", + { + "loose": true, + "modules": false + } + ], + "react" + ], + "plugins": [ + "react-hot-loader/babel", + "transform-runtime", + "transform-object-rest-spread", + "lodash" + ], + "env": { + "test": { + "plugins": ["transform-es2015-modules-commonjs"] + } + } +} diff --git a/samples/react-java-mysql/frontend/.browserslistrc b/samples/react-java-mysql/frontend/.browserslistrc new file mode 100755 index 0000000..7e8de1c --- /dev/null +++ b/samples/react-java-mysql/frontend/.browserslistrc @@ -0,0 +1,5 @@ +> 1% +last 3 versions +Firefox ESR +Opera 12.1 +IE >= 10 \ No newline at end of file diff --git a/samples/react-java-mysql/frontend/.dockerignore b/samples/react-java-mysql/frontend/.dockerignore new file mode 100755 index 0000000..e1d19f6 --- /dev/null +++ b/samples/react-java-mysql/frontend/.dockerignore @@ -0,0 +1,2 @@ +node_modules +.happypack diff --git a/samples/react-java-mysql/frontend/.eslintignore b/samples/react-java-mysql/frontend/.eslintignore new file mode 100755 index 0000000..ba224b4 --- /dev/null +++ b/samples/react-java-mysql/frontend/.eslintignore @@ -0,0 +1 @@ +webpack/* diff --git a/samples/react-java-mysql/frontend/.eslintrc b/samples/react-java-mysql/frontend/.eslintrc new file mode 100755 index 0000000..d61ab73 --- /dev/null +++ b/samples/react-java-mysql/frontend/.eslintrc @@ -0,0 +1,36 @@ +{ + "extends": [ + "standard", + "standard-react", + "plugin:jsx-a11y/recommended" + ], + "env": { + "es6" : true, + "browser" : true, + "node" : true, + "jest" : true + }, + "plugins": [ + "react", + "import" + ], + "parser": "babel-eslint", + "parserOptions": { + "sourceType": "module" + }, + "rules" : { + "no-eq-null" : 0, + "quotes": 0, + "eol-last": 0, + "semi": [2, "always"], + "key-spacing": [1, {"beforeColon": true, "afterColon": true, "mode": "minimum", "align": "colon"}], + "padded-blocks": [1, { "switches": "never", "classes" : "always"}], + "space-before-function-paren": ["error", "never"], + "indent": [1, 4] + }, + "globals" : { + "__DEV__" : false, + "__filename" : false, + "__dirname" : false + } +} diff --git a/samples/react-java-mysql/frontend/.gitignore b/samples/react-java-mysql/frontend/.gitignore new file mode 100755 index 0000000..1285d59 --- /dev/null +++ b/samples/react-java-mysql/frontend/.gitignore @@ -0,0 +1,4 @@ +node_modules +.happypack +build/* +dist/* diff --git a/samples/react-java-mysql/frontend/Dockerfile b/samples/react-java-mysql/frontend/Dockerfile new file mode 100755 index 0000000..26ed305 --- /dev/null +++ b/samples/react-java-mysql/frontend/Dockerfile @@ -0,0 +1,9 @@ +FROM node:10 + +RUN mkdir /project +WORKDIR /project + +COPY . . + +RUN yarn install +CMD ["yarn", "run", "start"] diff --git a/samples/react-java-mysql/frontend/Dockerfile.production b/samples/react-java-mysql/frontend/Dockerfile.production new file mode 100755 index 0000000..85b11ed --- /dev/null +++ b/samples/react-java-mysql/frontend/Dockerfile.production @@ -0,0 +1,12 @@ +FROM node:10 as build + +RUN mkdir /project +WORKDIR /project +COPY . . +RUN yarn install +RUN yarn run package + +FROM nginx:1.13-alpine + +COPY config/nginx.conf /etc/nginx/conf.d/default.conf +COPY --from=build /project/dist /usr/share/nginx/html diff --git a/samples/react-java-mysql/frontend/README.md b/samples/react-java-mysql/frontend/README.md new file mode 100755 index 0000000..7ddbcd4 --- /dev/null +++ b/samples/react-java-mysql/frontend/README.md @@ -0,0 +1 @@ +# Sample App diff --git a/samples/react-java-mysql/frontend/config/nginx.conf b/samples/react-java-mysql/frontend/config/nginx.conf new file mode 100755 index 0000000..2a3646c --- /dev/null +++ b/samples/react-java-mysql/frontend/config/nginx.conf @@ -0,0 +1,9 @@ +server { + listen 9000; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + } +} diff --git a/samples/react-java-mysql/frontend/jest.config.js b/samples/react-java-mysql/frontend/jest.config.js new file mode 100755 index 0000000..2b518a6 --- /dev/null +++ b/samples/react-java-mysql/frontend/jest.config.js @@ -0,0 +1,15 @@ +module.exports = { + "moduleFileExtensions": [ + "js", + "jsx", + "json" + ], + "moduleDirectories": [ + "node_modules", + "src" + ], + "moduleNameMapper": { + "^.+\\.(css|scss)$": "/test/mocks/styleMock.js", + "^.+\\.(jpg|jpeg|gif|png|svg|eot|ttf|woff|woff2|)$": "/test/mocks/imageMock.js" + } +}; diff --git a/samples/react-java-mysql/frontend/package.json b/samples/react-java-mysql/frontend/package.json new file mode 100755 index 0000000..ed2ef83 --- /dev/null +++ b/samples/react-java-mysql/frontend/package.json @@ -0,0 +1,72 @@ +{ + "name": "react-app", + "version": "0.1.0", + "private": true, + "scripts": { + "clean": "rimraf ./dist/* && rimraf ./build/*", + "start": "cross-env NODE_ENV=development node webpack/dev-server.js", + "build": "cross-env NODE_ENV=development webpack --config webpack.config.js", + "package": "cross-env NODE_ENV=production webpack --config webpack.config.js", + "test": "cross-env NODE_ENV=test jest", + "lint:js": "eslint ./src" + }, + "dependencies": { + "express": "4.16.3", + "axios": "0.18.0", + "classnames": "2.2.5", + "lodash": "4.17.5", + "moment": "2.20.0", + "history": "4.7.2", + "react": "^16.8.6", + "react-dom": "^16.8.6", + "react-redux": "^5.1.1", + "react-router-dom": "^4.3.1", + "react-router-redux": "5.0.0-alpha.8", + "redux": "^3.7.2", + "redux-actions": "^2.6.5", + "redux-saga": "0.16.0", + "reselect": "3.0.1", + "query-string": "6.0.0" + }, + "devDependencies": { + "rimraf": "2.6.1", + "cross-env": "5.1.4", + "webpack": "4.5.0", + "webpack-cli": "3.3.1", + "webpack-dev-server": "3.1.3", + "html-webpack-plugin": "3.2.0", + "mini-css-extract-plugin": "0.4.0", + "react-hot-loader": "3.1.3", + "node-sass": "^4.11.0", + "babel-core": "6.26.0", + "babel-runtime": "6.26.0", + "babel-loader": "7.1.4", + "babel-preset-env": "^1.7.0", + "babel-eslint": "8.2.2", + "babel-preset-react": "6.24.1", + "babel-plugin-transform-runtime": "6.23.0", + "babel-plugin-transform-object-rest-spread": "6.26.0", + "babel-plugin-lodash": "3.3.2", + "css-loader": "^2.1.1", + "sass-loader": "6.0.7", + "style-loader": "0.20.3", + "file-loader": "1.1.11", + "postcss-loader": "2.1.3", + "autoprefixer": "8.2.0", + "cssnano": "4.1.10", + "identity-obj-proxy": "3.0.0", + "jest": "^20.0.4", + "jest-cli": "^20.0.4", + "babel-jest": "20.0.3", + "eslint": "4.19.1", + "eslint-config-standard": "^10.2.1", + "eslint-config-standard-react": "^5.0.0", + "eslint-loader": "^1.9.0", + "eslint-plugin-import": "^2.7.0", + "eslint-plugin-node": "^5.1.1", + "eslint-plugin-promise": "^3.3.0", + "eslint-plugin-react": "7.1.0", + "eslint-plugin-jsx-a11y": "6.0.2", + "eslint-plugin-standard": "3.0.1" + } +} diff --git a/samples/react-java-mysql/frontend/src/app/app.jsx b/samples/react-java-mysql/frontend/src/app/app.jsx new file mode 100755 index 0000000..46b085d --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/app.jsx @@ -0,0 +1,22 @@ +import * as React from "react" +import { Switch } from "react-router-dom" +import { renderRoutes } from "./routes" + +import { ApplicationContainer } from "app/components/layout" + +require("./core/styles/reset.css"); +require("./core/styles/normalize.scss"); +//require("./core/styles/main.scss"); + +export class App extends React.Component { + render() { + return ( + + + {renderRoutes()} + + + ) + } +} + diff --git a/samples/react-java-mysql/frontend/src/app/components/layout/ApplicationContainer.jsx b/samples/react-java-mysql/frontend/src/app/components/layout/ApplicationContainer.jsx new file mode 100755 index 0000000..b80df40 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/components/layout/ApplicationContainer.jsx @@ -0,0 +1,15 @@ +import * as React from "react"; + +export default class ApplicationContainer extends React.Component { + + render() { + return ( +
+
+ {this.props.children} +
+
+ ); + } + +} diff --git a/samples/react-java-mysql/frontend/src/app/components/layout/index.js b/samples/react-java-mysql/frontend/src/app/components/layout/index.js new file mode 100755 index 0000000..0274124 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/components/layout/index.js @@ -0,0 +1,5 @@ +import ApplicationContainer from "./ApplicationContainer"; + +export { + ApplicationContainer, +} diff --git a/samples/react-java-mysql/frontend/src/app/core/styles/normalize.scss b/samples/react-java-mysql/frontend/src/app/core/styles/normalize.scss new file mode 100755 index 0000000..a2e9c64 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/core/styles/normalize.scss @@ -0,0 +1,396 @@ +/*! normalize.css v2.1.0 | MIT License | git.io/normalize */ + +// ========================================================================== +// HTML5 display definitions +// ========================================================================== + +// +// Correct `block` display not defined in IE 8/9. +// + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} + +// +// Correct `inline-block` display not defined in IE 8/9. +// + +audio, +canvas, +video { + display: inline-block; +} + +// +// Prevent modern browsers from displaying `audio` without controls. +// Remove excess height in iOS 5 devices. +// + +audio:not([controls]) { + display: none; + height: 0; +} + +// +// Address styling not present in IE 8/9. +// + +[hidden] { + display: none; +} + +// ========================================================================== +// Base +// ========================================================================== + +// +// 1. Set default font family to sans-serif. +// 2. Prevent iOS text size adjust after orientation change, without disabling +// user zoom. +// + +html { + font-family: sans-serif; // 1 + -webkit-text-size-adjust: 100%; // 2 + -ms-text-size-adjust: 100%; // 2 +} + +// +// Remove default margin. +// + +body { + margin: 0; +} + +// ========================================================================== +// Links +// ========================================================================== + +// +// Address `outline` inconsistency between Chrome and other browsers. +// + +a:focus { + outline: thin dotted; +} + +// +// Improve readability when focused and also mouse hovered in all browsers. +// + +a:active, +a:hover { + outline: 0; +} + +// ========================================================================== +// Typography +// ========================================================================== + +// +// Address variable `h1` font-size and margin within `section` and `article` +// contexts in Firefox 4+, Safari 5, and Chrome. +// + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +// +// Address styling not present in IE 8/9, Safari 5, and Chrome. +// + +abbr[title] { + border-bottom: 1px dotted; +} + +// +// Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome. +// + +b, +strong { + font-weight: bold; +} + +// +// Address styling not present in Safari 5 and Chrome. +// + +dfn { + font-style: italic; +} + +// +// Address differences between Firefox and other browsers. +// + +hr { + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} + +// +// Address styling not present in IE 8/9. +// + +mark { + background: #ff0; + color: #000; +} + +// +// Correct font family set oddly in Safari 5 and Chrome. +// + +code, +kbd, +pre, +samp { + font-family: monospace, serif; + font-size: 1em; +} + +// +// Improve readability of pre-formatted text in all browsers. +// + +pre { + white-space: pre-wrap; +} + +// +// Set consistent quote types. +// + +q { + quotes: "\201C" "\201D" "\2018" "\2019"; +} + +// +// Address inconsistent and variable font size in all browsers. +// + +small { + font-size: 80%; +} + +// +// Prevent `sub` and `sup` affecting `line-height` in all browsers. +// + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +// ========================================================================== +// Embedded content +// ========================================================================== + +// +// Remove border when inside `a` element in IE 8/9. +// + +img { + border: 0; +} + +// +// Correct overflow displayed oddly in IE 9. +// + +svg:not(:root) { + overflow: hidden; +} + +// ========================================================================== +// Figures +// ========================================================================== + +// +// Address margin not present in IE 8/9 and Safari 5. +// + +figure { + margin: 0; +} + +// ========================================================================== +// Forms +// ========================================================================== + +// +// Define consistent border, margin, and padding. +// + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +// +// 1. Correct `color` not being inherited in IE 8/9. +// 2. Remove padding so people aren't caught out if they zero out fieldsets. +// + +legend { + border: 0; // 1 + padding: 0; // 2 +} + +// +// 1. Correct font family not being inherited in all browsers. +// 2. Correct font size not being inherited in all browsers. +// 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome. +// + +button, +input, +select, +textarea { + font-family: inherit; // 1 + font-size: 100%; // 2 + margin: 0; // 3 +} + +// +// Address Firefox 4+ setting `line-height` on `input` using `!important` in +// the UA stylesheet. +// + +button, +input { + line-height: normal; +} + +// +// Address inconsistent `text-transform` inheritance for `button` and `select`. +// All other form control elements do not inherit `text-transform` values. +// Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+. +// Correct `select` style inheritance in Firefox 4+ and Opera. +// + +button, +select { + text-transform: none; +} + +// +// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` +// and `video` controls. +// 2. Correct inability to style clickable `input` types in iOS. +// 3. Improve usability and consistency of cursor style between image-type +// `input` and others. +// + +button, +html input[type="button"], // 1 +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; // 2 + cursor: pointer; // 3 +} + +// +// Re-set default cursor for disabled elements. +// + +button[disabled], +html input[disabled] { + cursor: default; +} + +// +// 1. Address box sizing set to `content-box` in IE 8/9. +// 2. Remove excess padding in IE 8/9. +// + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; // 1 + padding: 0; // 2 +} + +// +// 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome. +// 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome +// (include `-moz` to future-proof). +// + +input[type="search"] { + -webkit-appearance: textfield; // 1 + -moz-box-sizing: content-box; + -webkit-box-sizing: content-box; // 2 + box-sizing: content-box; +} + +// +// Remove inner padding and search cancel button in Safari 5 and Chrome +// on OS X. +// + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +// +// Remove inner padding and border in Firefox 4+. +// + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +// +// 1. Remove default vertical scrollbar in IE 8/9. +// 2. Improve readability and alignment in all browsers. +// + +textarea { + overflow: auto; // 1 + vertical-align: top; // 2 +} + +// ========================================================================== +// Tables +// ========================================================================== + +// +// Remove most spacing between table cells. +// + +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/samples/react-java-mysql/frontend/src/app/core/styles/reset.css b/samples/react-java-mysql/frontend/src/app/core/styles/reset.css new file mode 100755 index 0000000..d9f27b5 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/core/styles/reset.css @@ -0,0 +1,48 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/samples/react-java-mysql/frontend/src/app/entry.jsx b/samples/react-java-mysql/frontend/src/app/entry.jsx new file mode 100755 index 0000000..d3360fa --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/entry.jsx @@ -0,0 +1,39 @@ +import * as React from "react"; +import { render, unmountComponentAtNode } from "react-dom" +import { AppContainer } from "react-hot-loader" +import { Provider } from 'react-redux'; +import { ConnectedRouter } from "react-router-redux" +import { createBrowserHistory } from "history" + +import { configureStore, sagaMiddleware } from "./store" +import { runApplicationSagas } from "./sagas" + +const history = createBrowserHistory(); +const store = configureStore(history); + +const getAppContainer = () => document.getElementById('app-container'); + +const renderApp = () => { + const App = require('./app').App; + render( + + + + + + + + , getAppContainer()); +}; + +if (__DEV__ && module.hot) { + const hotReloadApp = () => renderApp(); + module.hot.accept('./app', () => { + // Preventing the hot reloading error from react-router + unmountComponentAtNode(getAppContainer()); + hotReloadApp(); + }) +} + +// runApplicationSagas(sagaMiddleware); +renderApp(); diff --git a/samples/react-java-mysql/frontend/src/app/pages/home/HomePage.jsx b/samples/react-java-mysql/frontend/src/app/pages/home/HomePage.jsx new file mode 100755 index 0000000..3b383b8 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/pages/home/HomePage.jsx @@ -0,0 +1,26 @@ +import * as React from "react"; +import { connect } from "react-redux"; + +require("./home.scss"); + +const mapStateToProps = (state, props) => { + return {}; +}; + +const mapDispatchToProps = (dispatch) => { + return {}; +}; + +class HomePage extends React.Component { + + render() { + return ( +
+

My New React App

+
+ ) + } + +} + +export default connect(mapStateToProps, mapDispatchToProps)(HomePage) diff --git a/samples/react-java-mysql/frontend/src/app/pages/home/home.scss b/samples/react-java-mysql/frontend/src/app/pages/home/home.scss new file mode 100755 index 0000000..66f9f24 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/pages/home/home.scss @@ -0,0 +1,6 @@ + + +.home-page { + background-color: blue; + color: red; +} diff --git a/samples/react-java-mysql/frontend/src/app/pages/home/index.js b/samples/react-java-mysql/frontend/src/app/pages/home/index.js new file mode 100755 index 0000000..7f0bbf7 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/pages/home/index.js @@ -0,0 +1,7 @@ +import * as React from "react"; +import { Route } from "react-router-dom"; +import HomePage from './HomePage'; + +const route = ; + +export default route; diff --git a/samples/react-java-mysql/frontend/src/app/reducers.js b/samples/react-java-mysql/frontend/src/app/reducers.js new file mode 100755 index 0000000..67fce7e --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/reducers.js @@ -0,0 +1,10 @@ +import { combineReducers } from 'redux'; +import { routerReducer } from 'react-router-redux'; + +import whalesReducer from 'app/redux/whales'; + +export const rootReducer = combineReducers({ + router: routerReducer, + + whales: whalesReducer, +}); diff --git a/samples/react-java-mysql/frontend/src/app/redux/whales/action-creators.js b/samples/react-java-mysql/frontend/src/app/redux/whales/action-creators.js new file mode 100755 index 0000000..afcb792 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/redux/whales/action-creators.js @@ -0,0 +1,4 @@ +import { createAction } from 'redux-actions'; +import * as ActionTypes from "./action-types"; + +export const fetchWhales = createAction(ActionTypes.FETCH_WHALES); diff --git a/samples/react-java-mysql/frontend/src/app/redux/whales/action-types.js b/samples/react-java-mysql/frontend/src/app/redux/whales/action-types.js new file mode 100755 index 0000000..ac21c38 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/redux/whales/action-types.js @@ -0,0 +1,4 @@ + +const prefix = 'WHALES'; + +export const FETCH_WHALES = `${prefix}/FETCH`; diff --git a/samples/react-java-mysql/frontend/src/app/redux/whales/index.js b/samples/react-java-mysql/frontend/src/app/redux/whales/index.js new file mode 100755 index 0000000..db0e338 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/redux/whales/index.js @@ -0,0 +1,3 @@ +import Reducer from './reducer'; + +export default Reducer; diff --git a/samples/react-java-mysql/frontend/src/app/redux/whales/reducer.js b/samples/react-java-mysql/frontend/src/app/redux/whales/reducer.js new file mode 100755 index 0000000..eb24c92 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/redux/whales/reducer.js @@ -0,0 +1,16 @@ +import * as ActionTypes from "./action-types"; +import { handleActions } from "redux-actions"; + +const defaultState = { + list: [], +}; + +const handleFetchWhales = (state, {payload}) => { + return state; +}; + +const reducer = handleActions({ + [ActionTypes.FETCH_WHALES] : handleFetchWhales +}, defaultState); + +export default reducer; diff --git a/samples/react-java-mysql/frontend/src/app/redux/whales/selectors.js b/samples/react-java-mysql/frontend/src/app/redux/whales/selectors.js new file mode 100755 index 0000000..e69de29 diff --git a/samples/react-java-mysql/frontend/src/app/routes.jsx b/samples/react-java-mysql/frontend/src/app/routes.jsx new file mode 100755 index 0000000..ee9f643 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/routes.jsx @@ -0,0 +1,10 @@ +import * as React from "react"; +import Home from "./pages/home" + +const routes = [ + Home, +]; + +export const renderRoutes = () => { + return routes; +}; diff --git a/samples/react-java-mysql/frontend/src/app/sagas.js b/samples/react-java-mysql/frontend/src/app/sagas.js new file mode 100755 index 0000000..772f08a --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/sagas.js @@ -0,0 +1,9 @@ +//import { templatesSaga } from "./data/templates/sagas"; +//import { appWizardSaga } from "./data/app-wizard/sagas"; + +const startupSagas = [ +]; + +export const runApplicationSagas = (sagaMiddleware) => { + startupSagas.forEach(sagaMiddleware.run); +}; diff --git a/samples/react-java-mysql/frontend/src/app/store.js b/samples/react-java-mysql/frontend/src/app/store.js new file mode 100755 index 0000000..c5bdc31 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/app/store.js @@ -0,0 +1,37 @@ +import { routerMiddleware } from 'react-router-redux'; +import { createStore, applyMiddleware, compose } from 'redux'; +import createSagaMiddleware from "redux-saga"; +import { rootReducer } from "./reducers"; + +export const sagaMiddleware = createSagaMiddleware(); + +export const configureStore = (history, initialState = {}) => { + + const middlewares = [ + routerMiddleware(history), + sagaMiddleware + ]; + + const enhancers = [ + applyMiddleware(...middlewares), + ]; + + if(__DEV__) { + const devToolEnhancer = () => { + return typeof window === 'object' && typeof window.devToolsExtension !== 'undefined' + ? window.devToolsExtension() : f => f; + }; + enhancers.push(devToolEnhancer()) + } + + const store = createStore(rootReducer, initialState, compose(...enhancers)); + + if(__DEV__ && module.hot) { + module.hot.accept('./reducers', () => { + const nextReducer = require('./reducers').default; + store.replaceReducer(nextReducer); + }) + } + + return store; +}; diff --git a/samples/react-java-mysql/frontend/src/index.ejs b/samples/react-java-mysql/frontend/src/index.ejs new file mode 100755 index 0000000..e1bfc09 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/index.ejs @@ -0,0 +1,10 @@ + + + + + Sample application + + +
+ + diff --git a/samples/react-java-mysql/frontend/src/test/mocks/imageMock.js b/samples/react-java-mysql/frontend/src/test/mocks/imageMock.js new file mode 100755 index 0000000..6b78380 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/test/mocks/imageMock.js @@ -0,0 +1,3 @@ +// Return an empty string or other mock path to emulate the url that +// Webpack provides via the file-loader +module.exports = 'mocked-image.jpg'; \ No newline at end of file diff --git a/samples/react-java-mysql/frontend/src/test/mocks/styleMock.js b/samples/react-java-mysql/frontend/src/test/mocks/styleMock.js new file mode 100755 index 0000000..f1eb8f5 --- /dev/null +++ b/samples/react-java-mysql/frontend/src/test/mocks/styleMock.js @@ -0,0 +1,2 @@ +// Return a Proxy to emulate css modules (if you are using them) +module.exports = require('identity-obj-proxy'); \ No newline at end of file diff --git a/samples/react-java-mysql/frontend/webpack.config.js b/samples/react-java-mysql/frontend/webpack.config.js new file mode 100755 index 0000000..91f9355 --- /dev/null +++ b/samples/react-java-mysql/frontend/webpack.config.js @@ -0,0 +1 @@ +module.exports = require("./webpack/config-builder")(process.env.NODE_ENV || 'production'); diff --git a/samples/react-java-mysql/frontend/webpack/config-builder.js b/samples/react-java-mysql/frontend/webpack/config-builder.js new file mode 100755 index 0000000..c07bc69 --- /dev/null +++ b/samples/react-java-mysql/frontend/webpack/config-builder.js @@ -0,0 +1,231 @@ +'use strict'; + +const path = require('path'), + webpack = require('webpack'), + HtmlWebpackPlugin = require('html-webpack-plugin'), + MiniCssExtractPlugin = require("mini-css-extract-plugin"); + +const PROJECT_ROOT = path.resolve(__dirname, ".."); + +module.exports = (env) => { + const isDev = env === 'development'; + const isTest = env === 'test'; + const isProd = !isDev && !isTest; + + const getAppEntry = () => { + const appEntry = path.resolve(PROJECT_ROOT, "src/app/entry.jsx"); + if(isDev) { + return [ + 'react-hot-loader/patch', + 'webpack-dev-server/client?http://localhost:9000', + 'webpack/hot/only-dev-server', + appEntry + ] + } else { + return [appEntry] + } + }; + + const getPlugins = () => { + + // common plugins + let plugins = [ + // Global variables + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify(env), + '__DEV__': isDev, + '__PROD__': isProd, + '__TEST__': isTest, + }), + // ignore moment locale files + new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), + // extract styles to css file + new MiniCssExtractPlugin({ + filename: "[name].[contenthash].css", + chunkFilename: "[id].css", + disable: isDev, + }), + // makes index.html + new HtmlWebpackPlugin({ + template: path.resolve(PROJECT_ROOT, 'src/index.ejs'), + }) + ]; + + // development plugins + if(isDev) { + plugins.push( + // Hot Reload (HMR) + new webpack.HotModuleReplacementPlugin(), + // Named Modules + new webpack.NamedModulesPlugin() + ); + } + + // production plugins + if(isProd) { + plugins.push( + new webpack.optimize.ModuleConcatenationPlugin() + ); + } + + return plugins; + }; + + return { + target: 'web', + mode: isProd ? "production" : "development", + context: PROJECT_ROOT, + + entry: { + app: getAppEntry() + }, + + output: { + path: path.resolve(PROJECT_ROOT, isProd ? 'dist' : 'build'), + filename: isProd ? '[name].[chunkhash:8].js' : '[name].js', + publicPath: '/', + sourceMapFilename: '[file].map', + chunkFilename: isProd ? '[name].[chunkhash:8].js' : '[name].js', + pathinfo: isDev + + }, + + devtool: isProd ? "hidden-sourcemap" : 'eval', + + resolve: { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + modules: ["node_modules", "src"], + alias: {} + }, + + module: { + rules: [ + // JS / JSX files + { + test: /\.(js|jsx)$/, + exclude: /(node_modules)/, + use: [ + { + loader: 'babel-loader', + options: { + cacheDirectory: true + } + } + ] + }, + // SASS files + { + test: /\.scss$/, + exclude: /(node_modules|bower_components)/, + use: [ + isDev ? "style-loader" : MiniCssExtractPlugin.loader, + { + loader: "css-loader", + options: { + importLoaders: 2, + url: true, + import: false, + sourceMap: isDev + } + }, + { + loader: "postcss-loader", + options: { + sourceMap: isDev, + plugins: isDev ? [] : [ + require("autoprefixer"), + require("cssnano")({ + safe: true, + zindex: false, + discardComments: { + removeAll: true + } + }) + ] + } + }, + { + loader: "sass-loader", + options: { + sourceMap: isDev, + includePaths: [".", path.join(process.cwd(), "src/app/core/styles")] + } + } + ] + }, + // Plain CSS files + { + test: /\.css$/, + use: [ + isDev ? "style-loader" : MiniCssExtractPlugin.loader, + { + loader: "css-loader", + options: { + importLoaders: 1, + url: true, + import: false, + sourceMap: isDev + } + }, + { + loader: "postcss-loader", + options: { + sourceMap: isDev, + plugins: isDev ? [] : [ + require("autoprefixer"), + require("cssnano")({ + safe: true, + zindex: false, + discardComments: { + removeAll: true + } + }) + ] + } + } + ] + }, + // images loader + { + test: /\.(png|jpe?g|gif|svg|ico)(\?.*)?$/, + use: [ + { + loader: 'file-loader', + options: { + name: "[name].[ext]", + outputPath: isProd ? "../images/" : "images/" + } + } + ] + }, + // font loader + { + test: /\.(woff|woff2|ttf|eot)(\?.*)?$/, + use: [ + { + loader: 'file-loader', + options: { + name: "[name].[ext]", + publicPath: isProd ? "" : "/webpack/", + useRelativePath: isProd, + outputPath: isProd ? "../fonts/" : "fonts/" + } + } + ] + } + ] + }, + + plugins: getPlugins(), + + node: { + __filename: true, + __dirname: true, + fs: 'empty', + vm: 'empty', + net: 'empty', + tls: 'empty', + } + + }; +}; diff --git a/samples/react-java-mysql/frontend/webpack/dev-server.js b/samples/react-java-mysql/frontend/webpack/dev-server.js new file mode 100755 index 0000000..f40ec11 --- /dev/null +++ b/samples/react-java-mysql/frontend/webpack/dev-server.js @@ -0,0 +1,38 @@ +'use strict'; + +const webpack = require('webpack'), + WebpackDevServer = require('webpack-dev-server'), + makeConfig = require("./config-builder"); + +const startWebpackServer = () => { + const config = makeConfig('development'); + + const SERVER_PORT = 9000; + + new WebpackDevServer(webpack(config), { + publicPath : config.output.publicPath, + hot : true, + historyApiFallback : true, + contentBase : "./build/", + + watchOptions: { // no file events on D4W + aggregateTimeout: 300, + poll: 1000 + }, + + proxy : { + "/api/*" : "http://127.0.0.1:8080" // proxy to backend + }, + + before : function(app) { + // manually configure app `app.use(...)` + } + }).listen(SERVER_PORT, '0.0.0.0', function (err, result) { + if (err) { + console.log(err); + } + console.log('Webpack dev server listening at localhost:' + SERVER_PORT); + }); +}; + +startWebpackServer();