Repository: hipster-labs/generator-jhipster-react
Branch: master
Commit: 0a25d7f55229
Files: 74
Total size: 173.0 KB
Directory structure:
gitextract_jhdj0bxz/
├── .editorconfig
├── .eslintignore
├── .eslintrc.json
├── .gitattributes
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── generators/
│ ├── app/
│ │ ├── index.js
│ │ └── prompts.js
│ └── client/
│ ├── USAGE
│ ├── files.js
│ ├── index.js
│ ├── prompts.js
│ └── templates/
│ ├── _.babelrc
│ ├── _.editorconfig
│ ├── _.eslintrc.json
│ ├── _package.json
│ ├── _postcss.config.js
│ ├── src/
│ │ └── main/
│ │ └── webapp/
│ │ ├── 404.html
│ │ ├── app/
│ │ │ ├── app.js
│ │ │ ├── app.scss
│ │ │ ├── config/
│ │ │ │ ├── constants.js
│ │ │ │ ├── devtools.js
│ │ │ │ ├── promise-middleware.js
│ │ │ │ ├── store.js
│ │ │ │ ├── theme.js
│ │ │ │ └── translation.js
│ │ │ ├── index.js
│ │ │ ├── modules/
│ │ │ │ ├── account/
│ │ │ │ │ ├── password/
│ │ │ │ │ │ └── password.js
│ │ │ │ │ └── settings/
│ │ │ │ │ └── settings.js
│ │ │ │ ├── administration/
│ │ │ │ │ ├── audits/
│ │ │ │ │ │ └── audits.js
│ │ │ │ │ ├── configuration/
│ │ │ │ │ │ └── configuration.js
│ │ │ │ │ ├── docs/
│ │ │ │ │ │ └── docs.js
│ │ │ │ │ ├── gateway/
│ │ │ │ │ │ └── gateway.js
│ │ │ │ │ ├── health/
│ │ │ │ │ │ ├── health-detail/
│ │ │ │ │ │ │ ├── health-detail.js
│ │ │ │ │ │ │ ├── health-modal.js
│ │ │ │ │ │ │ └── index.js
│ │ │ │ │ │ └── health.js
│ │ │ │ │ ├── logs/
│ │ │ │ │ │ └── logs.js
│ │ │ │ │ ├── metrics/
│ │ │ │ │ │ ├── metrics-detail/
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── metrics-detail.js
│ │ │ │ │ │ │ └── metrics-modal.js
│ │ │ │ │ │ └── metrics.js
│ │ │ │ │ └── user-management/
│ │ │ │ │ └── user-management.js
│ │ │ │ ├── home/
│ │ │ │ │ ├── home.js
│ │ │ │ │ ├── home.scss
│ │ │ │ │ └── index.js
│ │ │ │ └── login/
│ │ │ │ ├── index.js
│ │ │ │ ├── login-modal.js
│ │ │ │ └── login.js
│ │ │ ├── reducers/
│ │ │ │ ├── account.js
│ │ │ │ ├── administration.js
│ │ │ │ ├── authentication.js
│ │ │ │ ├── index.js
│ │ │ │ └── locale.js
│ │ │ ├── routes.js
│ │ │ └── shared/
│ │ │ ├── components/
│ │ │ │ ├── footer/
│ │ │ │ │ └── footer.js
│ │ │ │ ├── header/
│ │ │ │ │ ├── header.js
│ │ │ │ │ └── header.scss
│ │ │ │ └── private-route/
│ │ │ │ └── private-route.js
│ │ │ ├── interceptors/
│ │ │ │ └── axios.js
│ │ │ ├── util/
│ │ │ │ ├── global-style.js
│ │ │ │ └── log-util.js
│ │ │ └── variables.scss
│ │ ├── index.html
│ │ ├── robots.txt
│ │ └── swagger-ui/
│ │ └── _index.html
│ └── webpack/
│ ├── webpack.common.js
│ ├── webpack.dev.js
│ └── webpack.prod.js
├── gulpfile.js
├── package.json
└── test/
└── app.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
================================================
FILE: .eslintignore
================================================
generators/**/templates
travis
================================================
FILE: .eslintrc.json
================================================
{
"env": {
"node": true,
"es6": true
},
"extends": ["airbnb-base"],
"rules": {
"indent": [2, 2],
"linebreak-style": 0,
"eol-last": 2,
"quotes": [2, "single"],
"semi": [2, "always"],
"eqeqeq": [2, "smart"],
"no-use-before-define": [2, "nofunc"],
"no-unused-vars": [2, {"vars": "local", "args": "none"}],
"no-multi-str": 2,
"no-irregular-whitespace": 2,
"comma-dangle": "off",
"max-len": "off",
"func-names": "off",
"class-methods-use-this": "off",
"no-underscore-dangle": "off",
"no-plusplus": "off",
"no-multi-assign": "off",
"no-param-reassign": "off",
"no-shadow": "off"
}
}
================================================
FILE: .gitattributes
================================================
* text=auto
================================================
FILE: .gitignore
================================================
node_modules
coverage
.DS_Store
.vscode/
.idea
*.iml
*.ipr
*.iws
atlassian-ide-plugin.xml
/.project
test/temp/
*debug.log*
.vscode
yarn.lock
================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
- v6
================================================
FILE: LICENSE
================================================
Copyright 2016 Deepu KS <d4udts@gmail.com> (http://deepu105.github.io) <d4udts@gmail.com> (http://deepu105.github.io)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# DEPRECATED
This module is now integrated into `generator-jhipster` repository as React support is now planned in the core generator.
Work is being done on https://github.com/jhipster/generator-jhipster/tree/jh-react
See [this issue](https://github.com/jhipster/generator-jhipster/issues/6044) for details
# generator-jhipster-react [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url]
> A Jhipster based generator to create awesome react + spring boot applications
<img src="https://raw.githubusercontent.com/hipster-labs/generator-jhipster-react/master/logo-jhipster-react.png" height="200px" alt="jhipster-react logo" />
## Installation
TODO:
- Migrate Account modules
- Migrate Admin modules
- support no i18n properly
- support no-sass option
- Add entity sub generator
- Add import-jdl sub generator
- Migrate protractor tests
- Add generator tests
- Add generator travis builds
First, install [Yeoman](http://yeoman.io) and [JHipster](http://jhipster.github.io/), then install generator-jhipster-react using [npm](https://www.npmjs.com/) (we assume you have pre-installed [node.js](https://nodejs.org/)).
```bash
npm install -g yo
npm install -g generator-jhipster
```
Clone [JHipster](https://github.com/jhipster/generator-jhipster) and run `npm link` inside it.
Clone this project and run `npm link` and `npm link generator-jhipster` inside it.
Now all the projects are pointing to latest master versions
Now generate your new awesome project:
```bash
yo jhipster-react
```
Make sure to run `npm link generator-jhipster-react` within the generated project if you are regenerating it again.
As this is a generator which runs on top of [JHipster](http://jhipster.github.io/), we expect you have [JHipster and its related tools already installed](http://jhipster.github.io/installation.html).
This generator requires Jhipster version 4.1 or greater in order to work
## Development-mode
Frontend is working through [webpack-dev-server](webpack-dev-server-url) proxy mode feature in order to have an ability to use both frontend & backend server simultaneously. All requests from frontend would be proxied to backend server.
To start frontend server please run the following command:
```bash
yarn start
```
## Contributing
Contributions are welcome.
we follow the same contribution guidelines as JHipster, [check it out here](https://github.com/jhipster/generator-jhipster/blob/master/CONTRIBUTING.md)
## License
Apache-2.0 © [Deepu KS](http://deepu105.github.io)
[webpack-dev-server-url]: https://webpack.github.io/docs/webpack-dev-server.html
[npm-image]: https://badge.fury.io/js/generator-jhipster-react.svg
[npm-url]: https://npmjs.org/package/generator-jhipster-react
[travis-image]: https://travis-ci.org/deepu105/generator-jhipster-react.svg?branch=master
[travis-url]: https://travis-ci.org/deepu105/generator-jhipster-react
[daviddm-image]: https://david-dm.org/hipster-labs/generator-jhipster-react.svg?theme=shields.io
[daviddm-url]: https://david-dm.org/hipster-labs/generator-jhipster-react
================================================
FILE: generators/app/index.js
================================================
const util = require('util');
const generator = require('yeoman-generator');
const chalk = require('chalk');
const BaseGenerator = require('generator-jhipster/generators/generator-base');
const cleanup = require('generator-jhipster/generators/cleanup');
const prompts = require('./prompts');
const packagejs = require('../../package.json');
const constants = require('generator-jhipster/generators/generator-constants');
const JhipsterGenerator = generator.extend({});
util.inherits(JhipsterGenerator, BaseGenerator);
module.exports = JhipsterGenerator.extend({
constructor: function (...args) { // eslint-disable-line object-shorthand
generator.apply(this, args);
this.configOptions = {};
// This adds support for a `--skip-server` flag
this.option('skip-server', {
desc: 'Skip the server-side application generation',
type: Boolean,
defaults: false
});
// This adds support for a `--skip-user-management` flag
this.option('skip-user-management', {
desc: 'Skip the user management module during app generation',
type: Boolean,
defaults: false
});
// This adds support for a `--[no-]i18n` flag
this.option('i18n', {
desc: 'Disable or enable i18n when skipping client side generation, has no effect otherwise',
type: Boolean,
defaults: true
});
// This adds support for a `--with-entities` flag
this.option('with-entities', {
desc: 'Regenerate the existing entities if any',
type: Boolean,
defaults: false
});
// This adds support for a `--skip-checks` flag
this.option('skip-checks', {
desc: 'Check the status of the required tools',
type: Boolean,
defaults: false
});
// This adds support for a `--npm` flag
this.option('npm', {
desc: 'Use npm instead of yarn',
type: Boolean,
defaults: false
});
this.currentQuestion = 0;
this.totalQuestions = constants.QUESTIONS;
this.skipServer = this.configOptions.skipServer = this.options['skip-server'] || this.config.get('skipServer');
this.skipUserManagement = this.configOptions.skipUserManagement = this.options['skip-user-management'] || this.config.get('skipUserManagement');
this.jhiPrefix = this.configOptions.jhiPrefix || this.config.get('jhiPrefix') || this.options['jhi-prefix'];
this.withEntities = this.options['with-entities'];
this.skipChecks = this.options['skip-checks'];
this.useYarn = this.configOptions.useYarn = !this.options.npm;
this.isDebugEnabled = this.configOptions.isDebugEnabled = this.options.debug;
},
initializing: {
displayLogo() {
this.printJHipsterLogo();
},
checkJava() {
this.checkJava();
},
checkNode() {
this.checkNode();
},
checkGit() {
this.checkGit();
},
checkGitConnection() {
this.checkGitConnection();
},
checkYarn() {
this.checkYarn();
},
validate() {
if (this.skipServer && this.skipClient) {
this.error(chalk.red(`You can not pass both ${chalk.yellow('--skip-client')} and ${chalk.yellow('--skip-server')} together`));
}
},
setupconsts() {
this.applicationType = this.config.get('applicationType');
if (!this.applicationType) {
this.applicationType = 'monolith';
}
this.baseName = this.config.get('baseName');
this.jhipsterVersion = packagejs.version;
if (this.jhipsterVersion === undefined) {
this.jhipsterVersion = this.config.get('jhipsterVersion');
}
this.otherModules = this.config.get('otherModules');
this.testFrameworks = this.config.get('testFrameworks');
this.enableTranslation = this.config.get('enableTranslation');
this.nativeLanguage = this.config.get('nativeLanguage');
this.languages = this.config.get('languages');
const configFound = this.baseName !== undefined && this.applicationType !== undefined;
if (configFound) {
this.existingProject = true;
// If translation is not defined, it is enabled by default
if (this.enableTranslation === undefined) {
this.enableTranslation = true;
}
}
this.clientPackageManager = this.config.get('clientPackageManager');
if (!this.clientPackageManager) {
if (this.useYarn) {
this.clientPackageManager = 'yarn';
} else {
this.clientPackageManager = 'npm';
}
}
}
},
prompting: {
askForInsightOptIn: prompts.askForInsightOptIn,
askForApplicationType: prompts.askForApplicationType,
askForModuleName: prompts.askForModuleName,
},
configuring: {
setup() {
this.configOptions.skipI18nQuestion = true;
this.configOptions.baseName = this.baseName;
this.configOptions.logo = false;
this.configOptions.otherModules = this.otherModules;
this.configOptions.lastQuestion = this.currentQuestion;
this.generatorType = 'app';
if (this.applicationType === 'microservice') {
this.skipClient = true;
this.generatorType = 'server';
this.skipUserManagement = this.configOptions.skipUserManagement = true;
}
if (this.applicationType === 'uaa') {
this.skipClient = true;
this.generatorType = 'server';
this.skipUserManagement = this.configOptions.skipUserManagement = false;
this.authenticationType = this.configOptions.authenticationType = 'uaa';
}
if (this.skipClient) {
// defaults to use when skipping client
this.generatorType = 'server';
this.configOptions.enableTranslation = this.options.i18n;
}
if (this.skipServer) {
this.generatorType = 'client';
// defaults to use when skipping server
}
this.configOptions.clientPackageManager = this.clientPackageManager;
},
composeServer() {
if (this.skipServer) return;
this.composeWith(require.resolve('generator-jhipster/generators/server'), {
'client-hook': !this.skipClient,
configOptions: this.configOptions,
force: this.options.force
});
},
composeClient() {
if (this.skipClient) return;
this.composeWith(require.resolve('../client'), {
'skip-install': this.options['skip-install'],
configOptions: this.configOptions,
force: this.options.force
});
},
askFori18n: prompts.askFori18n
},
default: {
askForTestOpts: prompts.askForTestOpts,
setSharedConfigOptions() {
this.configOptions.lastQuestion = this.currentQuestion;
this.configOptions.totalQuestions = this.totalQuestions;
this.configOptions.testFrameworks = this.testFrameworks;
this.configOptions.enableTranslation = this.enableTranslation;
this.configOptions.nativeLanguage = this.nativeLanguage;
this.configOptions.languages = this.languages;
this.configOptions.clientPackageManager = this.clientPackageManager;
},
/* insight() {
const insight = this.insight();
insight.trackWithEvent('generator', 'app');
insight.track('app/applicationType', this.applicationType);
insight.track('app/testFrameworks', this.testFrameworks);
insight.track('app/otherModules', this.otherModules);
insight.track('app/clientPackageManager', this.clientPackageManager);
},*/
composeLanguages() {
if (this.skipI18n) return;
this.composeLanguagesSub(this, this.configOptions, this.generatorType);
},
saveConfig() {
this.config.set('jhipsterVersion', packagejs.version);
this.config.set('applicationType', this.applicationType);
this.config.set('baseName', this.baseName);
this.config.set('testFrameworks', this.testFrameworks);
this.config.set('jhiPrefix', this.jhiPrefix);
this.config.set('otherModules', this.otherModules);
if (this.skipClient) this.config.set('skipClient', true);
if (this.skipServer) this.config.set('skipServer', true);
if (this.skipUserManagement) this.config.set('skipUserManagement', true);
this.config.set('enableTranslation', this.enableTranslation);
if (this.enableTranslation) {
this.config.set('nativeLanguage', this.nativeLanguage);
this.config.set('languages', this.languages);
}
this.config.set('clientPackageManager', this.clientPackageManager);
}
},
writing: {
cleanup() {
cleanup.cleanupOldFiles(this, this.javaDir, this.testDir);
},
// regenerateEntities() {
// if (this.withEntities) {
// this.getExistingEntities().forEach((entity) => {
// this.composeWith(require.resolve('../entity'), {
// regenerate: true,
// 'skip-install': true,
// force: this.options.force,
// debug: this.isDebugEnabled,
// arguments: [entity.name]
// });
// });
// }
// }
},
/* end: {
localInstall() {
if (this.skipClient) {
if (this.otherModules === undefined) {
this.otherModules = [];
}
// Generate a package.json file containing the current version
// of the generator as dependency
this.template('_skipClientApp.package.json', 'package.json');
if (!this.options['skip-install']) {
if (this.clientPackageManager === 'yarn') {
this.log(chalk.bold(`\nInstalling generator-jhipster@${this.jhipsterVersion} locally using yarn`));
this.spawnCommand('yarn', ['install']);
} else if (this.clientPackageManager === 'npm') {
this.log(chalk.bold(`\nInstalling generator-jhipster@${this.jhipsterVersion} locally using npm`));
this.npmInstall();
}
}
}
}
}*/
});
================================================
FILE: generators/app/prompts.js
================================================
const chalk = require('chalk');
module.exports = {
askForInsightOptIn,
askForApplicationType,
askForModuleName,
askFori18n,
askForTestOpts
};
function askForInsightOptIn() {
if (this.existingProject) return;
// const done = this.async();
// const insight = this.insight();
// this.prompt({
// when: () => insight.optOut === undefined,
// type: 'confirm',
// name: 'insight',
// message: `May ${chalk.cyan('JHipster')} anonymously report usage statistics to improve the tool over time?`,
// default: true
// }).then((prompt) => {
// if (prompt.insight !== undefined) {
// insight.optOut = !prompt.insight;
// }
// done();
// });
}
function askForApplicationType() {
if (this.existingProject) return;
const DEFAULT_APPTYPE = 'monolith';
if (this.skipServer) {
this.applicationType = this.configOptions.applicationType = DEFAULT_APPTYPE;
return;
}
const done = this.async();
this.prompt({
type: 'list',
name: 'applicationType',
message: response => this.getNumberedQuestion('Which *type* of application would you like to create?', true),
choices: [
{
value: DEFAULT_APPTYPE,
name: 'Monolithic application (recommended for simple projects)'
},
{
value: 'microservice',
name: 'Microservice application'
},
{
value: 'gateway',
name: 'Microservice gateway'
},
// {
// value: 'uaa',
// name: '[BETA] JHipster UAA server (for microservice OAuth2 authentication)'
// }
],
default: DEFAULT_APPTYPE
}).then((prompt) => {
this.applicationType = this.configOptions.applicationType = prompt.applicationType;
done();
});
}
function askForModuleName() {
if (this.existingProject) return;
this.askModuleName(this);
this.configOptions.lastQuestion = this.currentQuestion;
this.configOptions.totalQuestions = this.totalQuestions;
}
function askFori18n() {
this.currentQuestion = this.configOptions.lastQuestion;
this.totalQuestions = this.configOptions.totalQuestions;
if (this.skipI18n || this.existingProject) return;
this.aski18n(this);
}
function askForTestOpts() {
if (this.existingProject) return;
const choices = [];
const defaultChoice = [];
if (!this.skipServer) {
// all server side test frameworks should be added here
choices.push(
{ name: 'Gatling', value: 'gatling' },
{ name: 'Cucumber', value: 'cucumber' }
);
}
if (!this.skipClient) {
// all client side test frameworks should be added here
choices.push(
{ name: 'Protractor', value: 'protractor' }
);
}
const done = this.async();
this.prompt({
type: 'checkbox',
name: 'testFrameworks',
message: response => this.getNumberedQuestion('Besides JUnit and Karma, which testing frameworks would you like to use?', true),
choices,
default: defaultChoice
}).then((prompt) => {
this.testFrameworks = prompt.testFrameworks;
done();
});
}
================================================
FILE: generators/client/USAGE
================================================
Description:
Creates a new JHipster React client side application based on the selected options
Example:
yo jhipster-react:client
This will create an React client app
================================================
FILE: generators/client/files.js
================================================
const mkdirp = require('mkdirp');
const constants = require('generator-jhipster/generators/generator-constants');
/* Constants use throughout */
const MAIN_SRC_DIR = constants.CLIENT_MAIN_SRC_DIR;
// const TEST_SRC_DIR = constants.CLIENT_TEST_SRC_DIR;
const REACT_DIR = constants.ANGULAR_DIR;
/**
* The default is to use a file path string. It implies use of the template method.
* For any other config an object { file:.., method:.., template:.. } can be used
*/
const files = {
common: [
{
templates: [
'_package.json',
'_.eslintrc.json',
'_.babelrc',
'_.editorconfig',
'webpack/webpack.common.js',
'webpack/webpack.dev.js',
'webpack/webpack.prod.js'
]
}
],
sass: [
{
condition: generator => generator.useSass,
templates: [
{ file: '_postcss.config.js', method: 'copy' }
]
}
],
image: [
{
path: MAIN_SRC_DIR,
templates: [
{ file: 'static/images/logo-jhipster-react.svg', method: 'copy' }
]
}
],
swagger: [
{
path: MAIN_SRC_DIR,
templates: [
'swagger-ui/_index.html',
{ file: 'swagger-ui/images/_throbber.gif', method: 'copy' }
]
}
],
commonWeb: [
{
path: MAIN_SRC_DIR,
templates: [
{ file: 'favicon.ico', method: 'copy' },
'robots.txt',
'404.html',
'index.html'
]
}
],
reactApp: [
{
path: REACT_DIR,
templates: [
'app.js',
'index.js',
'routes.js',
'config/constants.js',
'config/theme.js',
'config/devtools.js',
'config/promise-middleware.js',
'config/store.js'
]
},
{
condition: generator => generator.enableTranslation,
path: REACT_DIR,
templates: [
'config/translation.js'
]
},
{
condition: generator => generator.useSass,
path: REACT_DIR,
templates: [
{ file: 'app.scss', method: 'copy' }
]
},
// {
// condition: generator => generator.authenticationType === 'oauth2' || generator.authenticationType === 'jwt' || generator.authenticationType === 'uaa',
// path: REACT_DIR,
// templates: [
// 'blocks/interceptor/_auth.interceptor.js'
// ]
// },
// {
// condition: generator => !generator.skipServer,
// path: REACT_DIR,
// templates: [
// 'blocks/interceptor/_auth-expired.interceptor.js'
// ]
// }
],
reactMain: [
{
path: REACT_DIR,
templates: [
// home module
'modules/home/index.js',
{ file: 'modules/home/home.js', method: 'processJsx' },
// login module
'modules/login/index.js',
{ file: 'modules/login/login.js', method: 'processJsx' },
{ file: 'modules/login/login-modal.js', method: 'processJsx' }
]
},
{
condition: generator => generator.useSass,
path: REACT_DIR,
templates: [
'modules/home/home.scss',
]
}
],
reducers: [
{
path: REACT_DIR,
templates: [
// home module
'reducers/index.js',
'reducers/administration.js',
'reducers/authentication.js'
]
},
{
condition: generator => generator.enableTranslation,
path: REACT_DIR,
templates: [
'reducers/locale.js'
]
}
],
// accountModule: [
// {
// path: REACT_DIR,
// templates: [
// 'account/_index.js',
// { file: 'account/_account.route.js', method: 'processJsx' },
// { file: 'account/activate/_activate.route.js', method: 'processJsx' },
// { file: 'account/activate/_activate.component.js', method: 'processJsx' },
// { file: 'account/password/_password.route.js', method: 'processJsx' },
// { file: 'account/password/_password.component.js', method: 'processJsx' },
// { file: 'account/register/_register.route.js', method: 'processJsx' },
// { file: 'account/register/_register.component.js', method: 'processJsx' },
// { file: 'account/password-reset/init/_password-reset-init.route.js', method: 'processJsx' },
// { file: 'account/password-reset/init/_password-reset-init.component.js', method: 'processJsx' },
// { file: 'account/password-reset/finish/_password-reset-finish.route.js', method: 'processJsx' },
// { file: 'account/password-reset/finish/_password-reset-finish.component.js', method: 'processJsx' },
// { file: 'account/settings/_settings.route.js', method: 'processJsx' },
// { file: 'account/settings/_settings.component.js', method: 'processJsx' }
// ]
// },
// {
// condition: generator => generator.authenticationType === 'session',
// path: REACT_DIR,
// templates: [
// { file: 'account/sessions/_sessions.route.js', method: 'processJsx' },
// 'account/sessions/_session.model.js',
// { file: 'account/sessions/_sessions.component.js', method: 'processJsx' }
// ]
// },
// {
// condition: generator => generator.enableSocialSignIn,
// path: REACT_DIR,
// templates: [
// { file: 'account/social/_social.route.js', method: 'processJsx' },
// { file: 'account/social/_social-register.component.js', method: 'processJsx' },
// { file: 'account/social/_social-register.component.html', method: 'processHtml' },
// { file: 'shared/social/_social.component.js', method: 'processJsx' },
// { file: 'shared/social/_social.component.html', method: 'processHtml' },
// 'shared/social/_social.service.js'
// ]
// },
// {
// condition: generator => generator.enableSocialSignIn && generator.authenticationType === 'jwt',
// path: REACT_DIR,
// templates: [
// { file: 'account/social/_social-auth.component.js', method: 'processJsx' },
// ]
// },
// {
// condition: generator => generator.useSass,
// path: REACT_DIR,
// templates: [
// 'account/password/_password-strength-bar.scss'
// ]
// },
// {
// condition: generator => !generator.useSass,
// path: REACT_DIR,
// templates: [
// 'account/password/_password-strength-bar.css'
// ]
// }
// ],
adminModule: [
{
path: REACT_DIR,
templates: [
// admin modules
{ file: 'modules/administration/audits/audits.js', method: 'processJsx' },
{ file: 'modules/administration/configuration/configuration.js', method: 'processJsx' },
{ file: 'modules/administration/docs/docs.js', method: 'processJsx' },
{ file: 'modules/administration/health/health.js', method: 'processJsx' },
{ file: 'modules/administration/health/health-detail/health-detail.js', method: 'processJsx' },
{ file: 'modules/administration/health/health-detail/health-modal.js', method: 'processJsx' },
{ file: 'modules/administration/health/health-detail/index.js', method: 'processJsx' },
{ file: 'modules/administration/logs/logs.js', method: 'processJsx' },
{ file: 'modules/administration/metrics/metrics.js', method: 'processJsx' },
{ file: 'modules/administration/metrics/metrics-detail/metrics-detail.js', method: 'processJsx' },
{ file: 'modules/administration/metrics/metrics-detail/metrics-modal.js', method: 'processJsx' },
{ file: 'modules/administration/metrics/metrics-detail/index.js', method: 'processJsx' },
]
},
// {
// condition: generator => generator.websocket === 'spring-websocket',
// path: REACT_DIR,
// templates: [
// { file: 'modules/administration/tracker/Tracker.js', method: 'processJsx' }
// ]
// },
{
condition: generator => !generator.skipUserManagement,
path: REACT_DIR,
templates: [
{ file: 'modules/administration/user-management/user-management.js', method: 'processJsx' },
// { file: 'modules/administration/user-management/UserManagementDetail.js', method: 'processJsx' },
// { file: 'modules/administration/user-management/UserManagementDialog.js', method: 'processJsx' },
// { file: 'modules/administration/user-management/UserManagementDeleteDialog.js', method: 'processJsx' }
]
},
{
condition: generator => generator.applicationType === 'gateway',
path: REACT_DIR,
templates: [
{ file: 'modules/administration/gateway/gateway.js', method: 'processJsx' }
]
}
],
angularShared: [
{
path: REACT_DIR,
templates: [
// layouts
'shared/components/footer/footer.js',
'shared/components/header/header.js',
'shared/components/private-route/private-route.js',
// interceptors
'shared/interceptors/axios.js',
// util
'shared/util/global-style.js',
'shared/util/log-util.js'
]
},
{
condition: generator => generator.useSass,
path: REACT_DIR,
templates: [
'shared/components/header/header.scss',
'shared/variables.scss'
]
},
// {
// condition: generator => generator.enableTranslation,
// path: REACT_DIR,
// templates: [
// 'shared/language/_language.pipe.js',
// 'shared/language/_language.constants.js',
// 'shared/language/_language.helper.js'
// ]
// },
// {
// condition: generator => !generator.skipUserManagement,
// path: REACT_DIR,
// templates: [
// 'shared/user/_user.model.js',
// 'shared/user/_user.service.js'
// ]
// }
],
// angularAuthService: [
// {
// path: REACT_DIR,
// templates: [
// 'shared/auth/_auth.service.js',
// 'shared/auth/_csrf.service.js',
// 'shared/auth/_state-storage.service.js',
// 'shared/auth/_principal.service.js',
// 'shared/auth/_has-any-authority.directive.js',
// 'shared/auth/_account.service.js',
// 'shared/auth/_user-route-access-service.js'
// ]
// },
// {
// condition: generator => generator.authenticationType === 'oauth2',
// path: REACT_DIR,
// templates: [
// 'shared/auth/_auth-oauth2.service.js'
// ]
// },
// {
// condition: generator => generator.authenticationType === 'jwt' || generator.authenticationType === 'uaa',
// path: REACT_DIR,
// templates: [
// 'shared/auth/_auth-jwt.service.js'
// ]
// },
// {
// condition: generator => generator.authenticationType === 'session',
// path: REACT_DIR,
// templates: [
// 'shared/auth/_auth-session.service.js'
// ]
// }
// ],
// clientTestFw: [
// {
// path: TEST_SRC_DIR,
// templates: [
// '_karma.conf.js',
// 'spec/_entry.js',
// 'spec/_test.module.js',
// 'spec/app/account/activate/_activate.component.spec.js',
// 'spec/app/account/password/_password.component.spec.js',
// 'spec/app/account/password/_password-strength-bar.component.spec.js',
// 'spec/app/account/password-reset/init/_password-reset-init.component.spec.js',
// 'spec/app/account/password-reset/finish/_password-reset-finish.component.spec.js',
// 'spec/app/account/register/_register.component.spec.js',
// 'spec/app/account/settings/_settings.component.spec.js',
// 'spec/app/admin/health/_health.component.spec.js',
// 'spec/app/admin/audits/_audits.component.spec.js',
// 'spec/helpers/_spyobject.js',
// 'spec/helpers/_mock-account.service.js',
// 'spec/helpers/_mock-principal.service.js',
// 'spec/helpers/_mock-route.service.js'
// ]
// },
// {
// condition: generator => generator.authenticationType === 'session',
// path: TEST_SRC_DIR,
// templates: [
// 'spec/app/account/sessions/_sessions.component.spec.js',
// ]
// },
// {
// condition: generator => generator.enableTranslation,
// path: TEST_SRC_DIR,
// templates: [
// 'spec/helpers/_mock-language.service.js'
// ]
// },
// {
// condition: generator => generator.websocket === 'spring-websocket',
// path: TEST_SRC_DIR,
// templates: [
// 'spec/helpers/_mock-tracker.service.js'
// ]
// },
// {
// condition: generator => generator.protractorTests,
// path: TEST_SRC_DIR,
// templates: [
// 'e2e/account/_account.spec.js',
// 'e2e/admin/_administration.spec.js',
// '_protractor.conf.js'
// ]
// }
// ]
};
module.exports = {
writeFiles,
files
};
function writeFiles() {
mkdirp(MAIN_SRC_DIR);
// write React files
this.writeFilesToDisk(files, this, false);
}
================================================
FILE: generators/client/index.js
================================================
const util = require('util');
const generator = require('yeoman-generator');
const chalk = require('chalk');
const _ = require('lodash');
const BaseGenerator = require('generator-jhipster/generators/generator-base');
const constants = require('generator-jhipster/generators/generator-constants');
const prompts = require('./prompts');
const writeFiles = require('./files').writeFiles;
const packagejs = require('../../package.json');
const JhipsterClientGenerator = generator.extend({});
util.inherits(JhipsterClientGenerator, BaseGenerator);
/* Constants used throughout */
const QUESTIONS = constants.CLIENT_QUESTIONS;
module.exports = JhipsterClientGenerator.extend({
constructor: function (...args) { // eslint-disable-line object-shorthand
generator.apply(this, args);
this.configOptions = this.options.configOptions || {};
// This adds support for a `--protractor` flag
this.option('protractor', {
desc: 'Enable protractor tests',
type: Boolean,
defaults: false
});
// This adds support for a `--auth` flag
this.option('auth', {
desc: 'Provide authentication type for the application',
type: String
});
// This adds support for a `--build` flag
this.option('build', {
desc: 'Provide build tool for the application',
type: String
});
// This adds support for a `--websocket` flag
this.option('websocket', {
desc: 'Provide websocket option for the application',
type: String
});
// This adds support for a `--dev-db` flag
this.option('dev-db', {
desc: 'Provide development DB option for the application',
type: String
});
// This adds support for a `--db` flag
this.option('db', {
desc: 'Provide DB type for the application',
type: String
});
// This adds support for a `--social` flag
this.option('social', {
desc: 'Provide development DB option for the application',
type: Boolean,
default: false
});
// This adds support for a `--search-engine` flag
this.option('search-engine', {
desc: 'Provide development DB option for the application',
type: String
});
// This adds support for a `--search-engine` flag
this.option('hb-cache', {
desc: 'Provide hibernate cache option for the application',
type: String
});
// This adds support for a `--jhi-prefix` flag
this.option('jhi-prefix', {
desc: 'Add prefix before services, controllers and states name',
type: String,
defaults: 'jhi'
});
// This adds support for a `--skip-user-management` flag
this.option('skip-user-management', {
desc: 'Skip the user management module during app generation',
type: Boolean,
defaults: false
});
// This adds support for a `--npm` flag
this.option('npm', {
desc: 'Use npm instead of yarn',
type: Boolean,
defaults: false
});
this.skipServer = this.configOptions.skipServer || this.config.get('skipServer');
this.skipUserManagement = this.configOptions.skipUserManagement || this.options['skip-user-management'] || this.config.get('skipUserManagement');
this.authenticationType = this.options.auth;
this.buildTool = this.options.build;
this.websocket = this.options.websocket;
this.devDatabaseType = this.options['dev-db'];
this.databaseType = this.options.db;
this.enableSocialSignIn = this.options.social;
this.searchEngine = this.options['search-engine'];
this.hibernateCache = this.options['hb-cache'];
this.otherModules = this.configOptions.otherModules || [];
this.jhiPrefix = this.configOptions.jhiPrefix || this.config.get('jhiPrefix') || this.options['jhi-prefix'];
this.jhiPrefixCapitalized = _.upperFirst(this.jhiPrefix);
this.testFrameworks = [];
if (this.options.protractor) this.testFrameworks.push('protractor');
this.currentQuestion = this.configOptions.lastQuestion ? this.configOptions.lastQuestion : 0;
this.totalQuestions = this.configOptions.totalQuestions ? this.configOptions.totalQuestions : QUESTIONS;
this.baseName = this.configOptions.baseName;
this.logo = this.configOptions.logo;
this.useYarn = this.configOptions.useYarn = !this.options.npm;
this.clientPackageManager = this.configOptions.clientPackageManager;
this.isDebugEnabled = this.configOptions.isDebugEnabled || this.options.debug;
// TODO chnage to process JSX
this.processJsx = (source, dest, generator, opt, template) => {
this.copyTemplate(source, dest, 'stripJs', generator, opt, template);
};
},
initializing: {
displayLogo() {
if (this.logo) {
this.printJHipsterLogo();
}
},
setupClientconsts() {
// Make constants available in templates
this.MAIN_SRC_DIR = constants.CLIENT_MAIN_SRC_DIR;
this.TEST_SRC_DIR = constants.CLIENT_TEST_SRC_DIR;
this.serverPort = this.config.get('serverPort') || this.configOptions.serverPort || 8080;
this.applicationType = this.config.get('applicationType') || this.configOptions.applicationType;
if (!this.applicationType) {
this.applicationType = 'monolith';
}
this.clientFramework = this.config.get('clientFramework') || 'react';
this.useSass = this.config.get('useSass');
this.enableTranslation = this.config.get('enableTranslation'); // this is enabled by default to avoid conflicts for existing applications
this.nativeLanguage = this.config.get('nativeLanguage');
this.languages = this.config.get('languages');
this.messageBroker = this.config.get('messageBroker');
this.packagejs = packagejs;
const baseName = this.config.get('baseName');
if (baseName) {
this.baseName = baseName;
}
const clientConfigFound = this.useSass !== undefined;
if (clientConfigFound) {
// If translation is not defined, it is enabled by default
if (this.enableTranslation === undefined) {
this.enableTranslation = true;
}
if (this.nativeLanguage === undefined) {
this.nativeLanguage = 'en';
}
if (this.languages === undefined) {
this.languages = ['en', 'fr'];
}
this.existingProject = true;
}
if (!this.clientPackageManager) {
if (this.useYarn) {
this.clientPackageManager = 'yarn';
} else {
this.clientPackageManager = 'npm';
}
}
}
},
prompting: {
askForModuleName: prompts.askForModuleName,
askForClientSideOpts: prompts.askForClientSideOpts,
askFori18n: prompts.askFori18n,
setSharedConfigOptions() {
this.configOptions.lastQuestion = this.currentQuestion;
this.configOptions.totalQuestions = this.totalQuestions;
this.configOptions.clientFramework = 'angular2'; // Hack to get server side to generate webpack stuff accordingly
this.configOptions.useSass = this.useSass;
}
},
configuring: {
insight() {
const insight = this.insight();
insight.trackWithEvent('generator', 'client');
insight.track('app/clientFramework', this.clientFramework);
insight.track('app/useSass', this.useSass);
insight.track('app/enableTranslation', this.enableTranslation);
insight.track('app/nativeLanguage', this.nativeLanguage);
insight.track('app/languages', this.languages);
},
configureGlobal() {
// Application name modified, using each technology's conventions
this.camelizedBaseName = _.camelCase(this.baseName);
this.angularAppName = this.getAngularAppName();
this.angular2AppName = this.getAngular2AppName();
this.capitalizedBaseName = _.upperFirst(this.baseName);
this.dasherizedBaseName = _.kebabCase(this.baseName);
this.lowercaseBaseName = this.baseName.toLowerCase();
if (!this.nativeLanguage) {
// set to english when translation is set to false
this.nativeLanguage = 'en';
}
},
saveConfig() {
this.config.set('clientFramework', this.clientFramework);
this.config.set('useSass', this.useSass);
this.config.set('enableTranslation', this.enableTranslation);
if (this.enableTranslation && !this.configOptions.skipI18nQuestion) {
this.config.set('nativeLanguage', this.nativeLanguage);
this.config.set('languages', this.languages);
}
this.config.set('clientPackageManager', this.clientPackageManager);
}
},
default: {
getSharedConfigOptions() {
if (this.configOptions.hibernateCache) {
this.hibernateCache = this.configOptions.hibernateCache;
}
if (this.configOptions.websocket !== undefined) {
this.websocket = this.configOptions.websocket;
}
if (this.configOptions.databaseType) {
this.databaseType = this.configOptions.databaseType;
}
if (this.configOptions.devDatabaseType) {
this.devDatabaseType = this.configOptions.devDatabaseType;
}
if (this.configOptions.prodDatabaseType) {
this.prodDatabaseType = this.configOptions.prodDatabaseType;
}
if (this.configOptions.messageBroker !== undefined) {
this.messageBroker = this.configOptions.messageBroker;
}
if (this.configOptions.searchEngine !== undefined) {
this.searchEngine = this.configOptions.searchEngine;
}
if (this.configOptions.buildTool) {
this.buildTool = this.configOptions.buildTool;
}
if (this.configOptions.enableSocialSignIn !== undefined) {
this.enableSocialSignIn = this.configOptions.enableSocialSignIn;
}
if (this.configOptions.authenticationType) {
this.authenticationType = this.configOptions.authenticationType;
}
if (this.configOptions.testFrameworks) {
this.testFrameworks = this.configOptions.testFrameworks;
}
this.protractorTests = this.testFrameworks.indexOf('protractor') !== -1;
if (this.configOptions.enableTranslation !== undefined) {
this.enableTranslation = this.configOptions.enableTranslation;
}
if (this.configOptions.nativeLanguage !== undefined) {
this.nativeLanguage = this.configOptions.nativeLanguage;
}
if (this.configOptions.languages !== undefined) {
this.languages = this.configOptions.languages;
}
if (this.configOptions.uaaBaseName !== undefined) {
this.uaaBaseName = this.configOptions.uaaBaseName;
}
// Make dist dir available in templates
if (this.configOptions.buildTool === 'maven') {
this.BUILD_DIR = 'target/';
} else {
this.BUILD_DIR = 'build/';
}
this.DIST_DIR = this.BUILD_DIR + constants.CLIENT_DIST_DIR;
},
composeLanguages() {
if (this.configOptions.skipI18nQuestion) return;
this.composeLanguagesSub(this, this.configOptions, 'client');
}
},
writing() {
return writeFiles.call(this);
},
install() {
const logMsg =
`To install your dependencies manually, run: ${chalk.yellow.bold(`${this.clientPackageManager} install`)}`;
const injectDependenciesAndConstants = (err) => {
if (err) {
this.warning('Install of dependencies failed!');
this.log(logMsg);
}
};
const installConfig = {
bower: false,
npm: this.clientPackageManager !== 'yarn',
yarn: this.clientPackageManager === 'yarn',
callback: injectDependenciesAndConstants
};
if (this.options['skip-install']) {
this.log(logMsg);
} else {
this.installDependencies(installConfig);
}
},
end() {
this.log(chalk.green.bold('\nClient application generated successfully.\n'));
const logMsg =
`Start your Webpack development server with:\n ${chalk.yellow.bold(`${this.clientPackageManager} start`)}\n`;
this.log(chalk.green(logMsg));
}
});
================================================
FILE: generators/client/prompts.js
================================================
module.exports = {
askForModuleName,
askForClientSideOpts,
askFori18n
};
function askForModuleName() {
if (this.baseName) return;
this.askModuleName(this);
}
function askForClientSideOpts() {
if (this.existingProject) return;
const done = this.async();
const prompts = [
{
type: 'confirm',
name: 'useSass',
message: response => this.getNumberedQuestion('Would you like to use the LibSass stylesheet preprocessor for your CSS?', true),
default: true
}
];
this.prompt(prompts).then((props) => {
this.useSass = props.useSass;
done();
});
}
function askFori18n() {
if (this.existingProject || this.configOptions.skipI18nQuestion) return;
this.aski18n(this);
}
================================================
FILE: generators/client/templates/_.babelrc
================================================
{
"presets": ["react", "es2015", "stage-1"],
"plugins": [
["babel-plugin-module-alias", [
{ "src": "./src/main/webapp/i18n", "expose": "i18n" }
]]
],
"env": {
"dev-watch": {
"presets": ["react-hmre"]
}
}
}
================================================
FILE: generators/client/templates/_.editorconfig
================================================
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
# Change these settings to your own preference
indent_style = space
indent_size = 4
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.js]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false
[{package,bower}.json]
indent_style = space
indent_size = 2
================================================
FILE: generators/client/templates/_.eslintrc.json
================================================
{
"extends": [
"airbnb",
"plugin:ava/recommended"
],
"parser": "babel-eslint",
"plugins": [
"ava"
],
"env": {
"browser": true,
"node": true,
"mocha": true
},
"ecmaFeatures": {
"jsx": true,
"es6": true,
"classes": true
},
"rules": {
"comma-dangle": [1, "never"],
"no-underscore-dangle" : "off",
"react/jsx-filename-extension": "off",
"max-len": [1, 180, 4],
"jsx-a11y/no-marquee" : "off",
"jsx-a11y/no-static-element-interactions" : "off",
"no-plusplus": "off",
// TODO to be removed after review
"no-nested-ternary": "off",
"arrow-body-style": "off",
"no-named-as-default": "off",
"react/jsx-no-bind": "off",
"react/prefer-stateless-function": "off",
"react/forbid-prop-types": "off",
"react/no-array-index-key": "off",
"no-param-reassign": "off",
"no-unused-vars": "off"
}
}
================================================
FILE: generators/client/templates/_package.json
================================================
{
"name": "react-client",
"version": "0.0.0",
"description": "React client app",
"private": true,
"cacheDirectories": [
"node_modules"
],
"dependencies": {
"axios": "^0.15.3",
"counterpart": "^0.17.2",
"deep-equal": "^1.0.1",
"flexboxgrid": "^6.3.1",
"lodash.debounce": "4.0.8",
"material-ui": "^0.17.0",
"react": "^15.3.1",
"react-bootstrap": "^0.30.8",
"react-dom": "^15.3.1",
"react-interpolate-component": "^0.10.0",
"react-redux": "^5.0.2",
"react-router": "^3.0.2",
"react-router-bootstrap": "^0.23.1",
"react-router-redux": "^4.0.2",
"react-tap-event-plugin": "^2.0.1",
"react-translate-component": "^0.13.2",
"redux": "^3.5.2",
"swagger-ui": "2.2.10"
},
"devDependencies": {
"babel": "^6.5.2",
"babel-core": "^6.17.0",
"babel-eslint": "^7.1.1",
"babel-loader": "^6.2.5",
"babel-plugin-module-alias": "^1.2.0",
"babel-plugin-react-transform": "^2.0.2",
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"babel-preset-react-hmre": "^1.1.1",
"babel-preset-stage-1": "^6.22.0",
"copy-webpack-plugin": "4.0.1",
"cross-env": "^3.1.4",
"css-loader": "^0.26.1",
"enzyme": "^2.2.0",
"eslint": "^3.1.1",
"eslint-config-airbnb": "^14.0.0",
"eslint-plugin-ava": "^4.0.1",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^4.0.0",
"eslint-plugin-react": "^6.9.0",
"expect": "^1.16.0",
"extract-text-webpack-plugin": "^2.0.0-rc.3",
"file-loader": "0.10.0",
"html-webpack-plugin": "^2.15.0",
"http-proxy-middleware": "^0.17.3",
"image-webpack-loader": "3.2.0",
"jsdom-global": "^2.1.1",
"json-loader": "^0.5.4",
"mocha": "^3.2.0",
"node-sass": "4.5.0",
"postcss-loader": "1.3.0",
"react-addons-test-utils": "^15.0.0",
"redux-devtools": "^3.2.0",
"redux-devtools-dock-monitor": "^1.1.1",
"redux-devtools-log-monitor": "^1.0.9",
"sass-loader": "6.0.0",
"stripcomment-loader": "^0.1.0",
"style-loader": "^0.13.1",
"webpack": "^2.2.1",
"webpack-dev-server": "2.3.0",
"webpack-merge": "2.6.1"
},
"engines": {
"node": ">=6.9.0"
},
"scripts": {
"lint": "eslint src webpack",
"lint:fix": "eslint src webpack --fix",
"start": "<%= clientPackageManager %> run webpack:dev",
"webpack:dev": "cross-env NODE_ENV=dev-watch webpack-dev-server --config webpack/webpack.dev.js --progress --inline --hot --profile --port=8000 --open",
"webpack:build": "<%= clientPackageManager %> run webpack:build:dev",
"webpack:build:dev": "webpack --config webpack/webpack.dev.js",
"webpack:prod": "cross-env NODE_ENV=production webpack --config webpack/webpack.prod.js",
"test": "cross-env NODE_ENV=test mocha",
<%_ if (protractorTests) { _%>
"e2e": "protractor <%= TEST_SRC_DIR %>protractor.conf.js",
"postinstall": "webdriver-manager update && <%= clientPackageManager %> run webpack:build"
<%_ } else { _%>
"postinstall": "<%= clientPackageManager %> run webpack:build"
<%_ } _%>
}
}
================================================
FILE: generators/client/templates/_postcss.config.js
================================================
module.exports = {
plugins: []
};
================================================
FILE: generators/client/templates/src/main/webapp/404.html
================================================
<!doctype html>
<html lang="<%= nativeLanguage %>">
<head>
<meta charset="utf-8">
<title>Page Not Found</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
line-height: 1.2;
margin: 0;
}
html {
color: #888;
display: table;
font-family: sans-serif;
height: 100%;
text-align: center;
width: 100%;
}
body {
display: table-cell;
vertical-align: middle;
margin: 2em auto;
}
h1 {
color: #555;
font-size: 2em;
font-weight: 400;
}
p {
margin: 0 auto;
width: 280px;
}
@media only screen and (max-width: 280px) {
body, p {
width: 95%;
}
h1 {
font-size: 1.5em;
margin: 0 0 0.3em;
}
}
</style>
</head>
<body>
<h1>Page Not Found</h1>
<p>Sorry, but the page you were trying to view does not exist.</p>
</body>
</html>
<!-- IE needs 512+ bytes: http://blogs.msdn.com/b/ieinternals/archive/2010/08/19/http-error-pages-in-internet-explorer.aspx -->
================================================
FILE: generators/client/templates/src/main/webapp/app/app.js
================================================
import 'flexboxgrid/dist/flexboxgrid.css';
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import { locales } from './config/translation';
import appTheme from './config/theme';
import { setLocale } from './reducers/locale';
import { getSession, logout } from './reducers/authentication';
import Header from './shared/components/header/header';
import Footer from './shared/components/footer/footer';
import './app.scss';
export class App extends Component {
static propTypes = {
isAuthenticated: PropTypes.bool,
currentLocale: PropTypes.string.isRequired,
getSession: PropTypes.func.isRequired,
setLocale: PropTypes.func.isRequired,
logout: PropTypes.func.isRequired,
children: PropTypes.node
};
static defaultProps = {
isAuthenticated: false,
children: null
};
constructor(props) {
super(props);
this.handleLogout = this.handleLogout.bind(this);
}
componentDidMount() {
this.props.getSession();
}
handleLogout() {
this.props.logout();
}
render() {
return (
<MuiThemeProvider muiTheme={appTheme}>
<div className="main-container" id="main-container">
<Header
currentLocale={this.props.currentLocale}
onLocaleChange={this.props.setLocale}
isAuthenticated={this.props.isAuthenticated}
handleLogout={this.handleLogout}
toggleSideBar={this.toggleSideBar}
/>
<div className="container">
{this.props.children}
</div>
<Footer />
</div>
</MuiThemeProvider>
);
}
}
export default connect(
store => ({ isAuthenticated: store.authentication.isAuthenticated, currentLocale: store.locale.currentLocale }),
{ getSession, setLocale, logout }
)(App);
================================================
FILE: generators/client/templates/src/main/webapp/app/app.scss
================================================
@import 'shared/variables';
body {
background: #fafafa;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
color: $text-color;
margin: 0;
}
* {
-moz-box-sizing: border-box;
box-sizing: border-box;
&:after, &::before {
-moz-box-sizing: border-box;
box-sizing: border-box;
}
}
a {
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
/* ==========================================================================
Browser Upgrade Prompt
========================================================================== */
.browserupgrade {
margin: 0.2em 0;
background: #ccc;
color: #000;
padding: 0.2em 0;
}
/* ==========================================================================
Generic styles
========================================================================== */
/* other generic styles */
.vertical {
flex-direction: column;
}
.card {
padding: 1.5%;
margin-top: 20px;
border: none;
}
.error {
color: white;
background-color: red;
}
.pad {
padding: 10px;
}
.break {
white-space: normal;
word-break:break-all;
}
.voffset { margin-top: 2px; }
.voffset1 { margin-top: 5px; }
.voffset2 { margin-top: 10px; }
.voffset3 { margin-top: 15px; }
.voffset4 { margin-top: 30px; }
.voffset5 { margin-top: 40px; }
.voffset6 { margin-top: 60px; }
.voffset7 { margin-top: 80px; }
.voffset8 { margin-top: 100px; }
.voffset9 { margin-top: 150px; }
.readonly {
background-color: #eee;
opacity: 1;
}
/* ==========================================================================
make sure browsers use the pointer cursor for anchors, even with no href
========================================================================== */
a:hover {
cursor: pointer;
}
.hand {
cursor: pointer;
}
button.anchorBtn {
background: none;
border: none;
padding: 0;
align-items: initial;
text-align: initial;
width: 100%;
}
a.anchorBtn:hover {
text-decoration: none;
}
/* ==========================================================================
Metrics and Health styles
========================================================================== */
#threadDump .popover, #healthCheck .popover {
top: inherit;
display: block;
font-size: 10px;
max-width: 1024px;
}
#healthCheck .popover {
margin-left: -50px;
}
.health-details {
min-width: 400px;
}
/* ==========================================================================
start Password strength bar style
========================================================================== */
ul#strengthBar {
display:inline;
list-style:none;
margin:0;
margin-left:15px;
padding:0;
vertical-align:2px;
}
.point:last {
margin:0 !important;
}
.point {
background:#DDD;
border-radius:2px;
display:inline-block;
height:5px;
margin-right:1px;
width:20px;
}
/* ==========================================================================
entity tables helpers
========================================================================== */
/* Remove Bootstrap padding from the element
http://stackoverflow.com/questions/19562903/remove-padding-from-columns-in-bootstrap-3 */
@mixin no-padding($side) {
@if $side == 'all' {
.no-padding {
padding: 0 !important;
}
} @else {
.no-padding-#{$side} {
padding-#{$side}: 0 !important;
}
}
}
@include no-padding("left");
@include no-padding("right");
@include no-padding("top");
@include no-padding("bottom");
@include no-padding("all");
/* bootstrap 3 input-group 100% width
http://stackoverflow.com/questions/23436430/bootstrap-3-input-group-100-width */
.width-min { width: 1% !important; }
/* Makes toolbar not wrap on smaller screens
http://www.sketchingwithcss.com/samplechapter/cheatsheet.html#right */
.flex-btn-group-container {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
-webkit-justify-content: flex-end;
justify-content: flex-end;
}
.jh-table > {
tbody > tr > td {
/* Align text in td verifically (top aligned by Bootstrap) */
vertical-align: middle;
}
thead > tr > th > {
.glyphicon-sort, .glyphicon-sort-by-attributes, .glyphicon-sort-by-attributes-alt {
/* less visible sorting icons */
opacity: 0.5;
&:hover {
/* full visible sorting icons and pointer when mouse is over them */
opacity: 1;
cursor: pointer;
}
}
}
}
/* jhipster-needle-css-add-main JHipster will add new css style */
================================================
FILE: generators/client/templates/src/main/webapp/app/config/constants.js
================================================
const config = {
version: '0.0.1-SNAPSHOT'
};
export default config;
================================================
FILE: generators/client/templates/src/main/webapp/app/config/devtools.js
================================================
import React from 'react';
/* eslint-disable */
import { createDevTools } from 'redux-devtools';
import LogMonitor from 'redux-devtools-log-monitor';
import DockMonitor from 'redux-devtools-dock-monitor';
/* eslint-enable */
// You can toggle visibility of devTools with ctrl + H
// and change their position with ctrl + Q
export default createDevTools(
<DockMonitor toggleVisibilityKey="ctrl-h" changePositionKey="ctrl-q" defaultIsVisible={false}>
<LogMonitor />
</DockMonitor>
);
================================================
FILE: generators/client/templates/src/main/webapp/app/config/promise-middleware.js
================================================
import axios from 'axios';
import { logError } from '../shared/util/log-util';
export default function promiseMiddleware({ dispatch, getState }) {
return next => (action) => {
if (typeof action === 'function') {
return action(dispatch, getState);
}
const { promise, types, afterSuccess, ...rest } = action;
if (!action.promise) {
return next(action);
}
const [REQUEST, SUCCESS, FAILURE] = types;
next({ ...rest, type: REQUEST });
const onFulfilled = (result) => {
next({ ...rest, result, type: SUCCESS });
if (afterSuccess) {
afterSuccess(dispatch, getState, result);
}
};
const onRejected = (error) => {
next({ ...rest, error, type: FAILURE });
};
return promise(axios)
.then(onFulfilled, onRejected)
.catch((error) => {
logError('MIDDLEWARE ERROR:', error);
onRejected(error);
});
};
}
================================================
FILE: generators/client/templates/src/main/webapp/app/config/store.js
================================================
import { createStore, applyMiddleware, compose } from 'redux';
import reducer from '../reducers';
import DevTools from './devtools';
import promiseMiddleware from './promise-middleware';
const middlewares = process.env.NODE_ENV === 'development' ?
[applyMiddleware(promiseMiddleware), DevTools.instrument()] :
[applyMiddleware(promiseMiddleware)];
const initialize = (initialState = {}) => {
const store = createStore(reducer, initialState, compose(...middlewares));
if (module.hot) {
// Enable Webpack hot module replacement for reducers
// TODO : see if reducers can be moved to feature modules and still get HMR working
module.hot.accept('../reducers', () => {
/* eslint-disable */
const nextReducer = require('../reducers');
/* eslint-enable */
store.replaceReducer(nextReducer);
});
}
return store;
};
export default initialize;
================================================
FILE: generators/client/templates/src/main/webapp/app/config/theme.js
================================================
import {
cyan500, cyan700,
pinkA200,
grey100, grey300, grey400, grey500,
white, darkBlack, fullBlack
} from 'material-ui/styles/colors';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
export default getMuiTheme({
palette: {
primary1Color: cyan500,
primary2Color: cyan700,
primary3Color: grey400,
accent1Color: pinkA200,
accent2Color: grey100,
accent3Color: grey500,
textColor: darkBlack,
alternateTextColor: white,
canvasColor: white,
borderColor: grey300,
pickerHeaderColor: cyan500,
shadowColor: fullBlack
}
});
================================================
FILE: generators/client/templates/src/main/webapp/app/config/translation.js
================================================
import counterpart from 'counterpart';
import { setLocale } from '../reducers/locale';
const mergeTranslations = (requireContext) => {
const merged = {};
requireContext.keys().forEach((key) => {
Object.assign(merged, requireContext(key));
});
return merged;
};
/* eslint-disable */
const translations = {
<%_ languages.forEach((lang, index) => { _%>
<%= lang %>: mergeTranslations(require.context('i18n/<%= lang %>', false, /.json$/))<%= index !== languages.length - 1 ? ',' : '' %>
<%_ }); _%>
};
/* eslint-enable */
let currentLocale;
const savedLocale = localStorage.getItem('locale') || '<%= nativeLanguage %>';
export const locales = Object.keys(translations);
export const registerLocales = (store) => {
locales.forEach((key) => {
counterpart.registerTranslations(key, translations[key]);
});
store.subscribe(() => {
const previousLocale = currentLocale;
currentLocale = store.getState().locale.currentLocale;
if (previousLocale !== currentLocale) {
localStorage.setItem('locale', currentLocale);
counterpart.setLocale(currentLocale);
}
});
store.dispatch(setLocale(savedLocale));
return savedLocale;
};
================================================
FILE: generators/client/templates/src/main/webapp/app/index.js
================================================
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { bindActionCreators } from 'redux';
import { hashHistory, Router } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import injectTapEventPlugin from 'react-tap-event-plugin';
import getRoutes from './routes';
import DevTools from './config/devtools';
import initStore from './config/store';
import { registerLocales } from './config/translation';
import setupAxiosInterceptors from './shared/interceptors/axios';
import { redirectToLoginWithMessage, clearAuthToken, logout } from './reducers/authentication';
// Needed for onTouchTap
// http://stackoverflow.com/a/34015469/988941
injectTapEventPlugin();
const devTools = process.env.NODE_ENV === 'development' ? <DevTools /> : null;
const store = initStore();
const history = syncHistoryWithStore(hashHistory, store);
registerLocales(store);
const actions = bindActionCreators({ redirectToLoginWithMessage, logout }, store.dispatch);
setupAxiosInterceptors(() => actions.redirectToLoginWithMessage('login.error.unauthorized'), clearAuthToken);
render(
<Provider store={store}>
<div>
{devTools}
<Router history={history} routes={getRoutes(actions.logout)} />
</div>
</Provider>,
document.getElementById('root')
);
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/account/password/password.js
================================================
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/account/settings/settings.js
================================================
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/audits/audits.js
================================================
import React, { Component } from 'react';
import { connect } from 'react-redux';
import Translate from 'react-translate-component';
import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table';
import { getAudits } from '../../../reducers/administration';
export class AuditsPage extends Component {
constructor(props) {
super(props);
this.getAuditList = this.getAuditList.bind(this);
}
componentDidMount() {
this.props.getAudits();
}
getAuditList() {
if (!this.props.isFetching) {
this.props.getAudits();
}
}
render() {
const showCheckboxes = false;
const { audits, isFetching } = this.props;
return (
<div className="well">
<div>
<h2 translate="audits.title">Audits</h2>
FIX ME pagination and filter by date and sorting
<hr />
<div className="row">
<div className="col-sm-12">
<Table>
<TableHeader
displaySelectAll={showCheckboxes}
adjustForCheckbox={showCheckboxes}>
<TableRow>
<TableHeaderColumn>Timestamp</TableHeaderColumn>
<TableHeaderColumn>Principal</TableHeaderColumn>
<TableHeaderColumn>Address</TableHeaderColumn>
<TableHeaderColumn>Type</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody displayRowCheckbox={showCheckboxes}>
{audits.map((row, index) => (
<TableRow key={index}>
<TableRowColumn>{row.timestamp}</TableRowColumn>
<TableRowColumn>{row.principal}</TableRowColumn>
<TableRowColumn>{row.data.remoteAddress}</TableRowColumn>
<TableRowColumn>{row.type}</TableRowColumn>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
</div>
</div>
);
}
}
export default connect(
({ administration }) => ({ audits: administration.audits, isFetching: administration.isFetching }),
{ getAudits }
)(AuditsPage);
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/configuration/configuration.js
================================================
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table';
import TextField from 'material-ui/TextField';
import { getConfigurations, getEnv } from '../../../reducers/administration';
export class ConfigurationPage extends Component {
constructor(props) {
super(props);
this.getConfigurationList = this.getConfigurationList.bind(this);
}
componentDidMount() {
this.props.getConfigurations();
this.props.getEnv();
}
getConfigurationList() {
if (!this.props.isFetching) {
this.props.getConfigurations();
this.props.getEnv();
}
}
render() {
const showCheckboxes = false;
const { configuration, isFetching } = this.props;
const configProps = (configuration && configuration.configProps) ? configuration.configProps : {};
const env = (configuration && configuration.env) ? configuration.env : {};
return (
<div className="well">
<div>
<h2 translate="configuration.title">Configuration</h2>
FIX ME add search function
<TextField hintText="Search by Prefix" fullWidth />
<hr />
<div className="row">
<div className="col-sm-12">
<Table>
<TableHeader
displaySelectAll={showCheckboxes}
adjustForCheckbox={showCheckboxes}
>
<TableRow>
<TableHeaderColumn>Prefix</TableHeaderColumn>
<TableHeaderColumn>Properties</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody displayRowCheckbox={showCheckboxes}>
{Object.keys(configProps).map((configPropKey, configPropIndex) => (
<TableRow key={configPropIndex}>
<TableRowColumn>{configProps[configPropKey].prefix}</TableRowColumn>
<TableRowColumn>
{Object.keys(configProps[configPropKey].properties).map((propKey, propIndex) => (
<div>
<p>
<b> {propKey} </b>
{JSON.stringify(configProps[configPropKey].properties[propKey])}
</p>
</div>
))}
</TableRowColumn>
</TableRow>
))}
</TableBody>
</Table>
</div>
<hr />
<div className="col-sm-12">
{Object.keys(env).map((envKey, envIndex) => (
<div>
<h4> {envKey} </h4>
<Table>
<TableHeader
displaySelectAll={showCheckboxes}
adjustForCheckbox={showCheckboxes}
>
<TableRow key={envIndex}>
<TableHeaderColumn>Prefix</TableHeaderColumn>
<TableHeaderColumn>Properties</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody displayRowCheckbox={showCheckboxes}>
{env[envKey] ?
typeof env[envKey] === 'object' ?
Object.keys(env[envKey]).map((propKey, propIndex) => (
<TableRow key={propIndex}>
<TableRowColumn>{propKey} </TableRowColumn>
<TableRowColumn>{JSON.stringify(env[envKey][propKey])}</TableRowColumn>
</TableRow>
))
: (<TableRow key={envKey}>
{JSON.stringify(env[envKey])}
</TableRow>)
: ''}
</TableBody>
</Table>
</div>
))}
</div>
</div>
</div>
</div>
);
}
}
export default connect(
({ administration }) => ({ configuration: administration.configuration, isFetching: administration.isFetching }),
{ getConfigurations, getEnv }
)(ConfigurationPage);
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/docs/docs.js
================================================
import React, { Component } from 'react';
import Translate from 'react-translate-component';
export class DocsPage extends Component {
render() {
return (
<div>
<iframe
src="../swagger-ui/index.html" width="100%" height="800"
target="_top" title="Swagger UI" seamless style={{ border: 'none' }}
/>
</div>
);
}
}
export default DocsPage;
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/gateway/gateway.js
================================================
import React, { Component } from 'react';
import { connect } from 'react-redux';
import Translate from 'react-translate-component';
import { gatewayRoutes } from '../../../reducers/administration';
export class GatewayPage extends Component {
constructor(props) {
super(props);
this.getRoutes = this.getRoutes.bind(this);
}
componentDidMount() {
this.props.gatewayRoutes();
}
getRoutes() {
if (!this.props.isFetching) {
this.props.gatewayRoutes();
}
}
render() {
const { gateway, isFetching } = this.props;
const routes = gateway ? gateway.routes : [];
return (
<div className="well">
<div>
<h2 data-translate="gateway.title">Gateway</h2>
<h3 data-translate="gateway.routes.title">Current routes</h3>
<p>
<button type="button" onClick={() => this.getRoutes()} className={isFetching ? 'btn btn-danger' : 'btn btn-primary'} disabled={isFetching}>
<span className="glyphicon glyphicon-refresh glyphicon-" />
<Translate component="span" content="gateway.refresh.button" />
</button>
</p>
<table className="table table-striped table-responsive">
<thead>
<tr>
<th><Translate content="gateway.routes.url" /></th>
<th><Translate content="gateway.routes.service" /></th>
<th><Translate content="gateway.routes.servers" /></th>
</tr>
</thead>
<tbody>
{
routes.map((route, i) =>
<tr key={`gateway-${i}`}>
<td>{route.path}</td>
<td>{route.serviceId}</td>
<td>
{
(route.serviceInstances && route.serviceInstances.length > 1) ?
(
<div className="label label-danger" aria-hidden="true"><Translate content="gateway.routes.error" /></div>
)
:
(
<table className="tabletable-responsive">
<tbody>
{route.serviceInstances.map((serviceInstance, j) =>
<tr key={`gateway-instance-${j}`}>
<td>{serviceInstance.uri}</td>
{
serviceInstance.instanceInfo.status === 'UP' ?
<td><div className="label label-success">{serviceInstance.instanceInfo.status}</div></td>
: <td ng-hide="true" aria-hidden="true"><div className="label label-danger">UP</div></td>
}
</tr>
)}
</tbody>
</table>
)
}
</td>
</tr>
)
}
</tbody>
</table>
</div>
</div>
);
}
}
export default connect(
({ administration }) => ({ gateway: administration.gateway, isFetching: administration.isFetching }),
{ gatewayRoutes }
)(GatewayPage);
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/health/health-detail/health-detail.js
================================================
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { hashHistory } from 'react-router';
import HealthModal from './health-modal';
export class Health extends Component {
static propTypes = {
isAuthenticated: PropTypes.bool.isRequired
};
constructor(props) {
super(props);
this.state = {
showModal: false
};
}
componentWillMount() {
this.setState({
showModal: true
});
}
componentWillReceiveProps(nextProps) {
this.setState({
showModal: !nextProps.isAuthenticated
});
}
handleClose = () => {
this.setState({ showModal: false });
hashHistory.push('/admin/health');
};
render() {
return (
<HealthModal showModal={this.state.showModal} handleClose={this.handleClose} health={this.props.health} />
);
}
}
export default connect(({ administration }) => ({ health: administration.health, isFetching: administration.isFetching }))(Health);
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/health/health-detail/health-modal.js
================================================
import React, { Component, PropTypes } from 'react';
import Dialog from 'material-ui/Dialog';
import FlatButton from 'material-ui/FlatButton';
import Translate from 'react-translate-component';
import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table';
class HealthModal extends Component {
static propTypes = {
handleClose: PropTypes.func.isRequired,
showModal: PropTypes.bool.isRequired
};
constructor(props, context) {
super(props, context);
}
render() {
const { handleClose, health } = this.props;
const showCheckboxes = false;
const actions = [
<FlatButton
label={<Translate content="entity.action.cancel" />}
onTouchTap={handleClose}
/>
];
return (
<Dialog
title={<h3><Translate content="health.title" /></h3>}
actions={actions}
modal autoScrollBodyContent
open={this.props.showModal}
onRequestClose={handleClose}
>
<h4>{health.name}</h4>
<div className="row">
<div className="col-md-12">
<Table>
<TableHeader
displaySelectAll={showCheckboxes}
adjustForCheckbox={showCheckboxes}
>
<TableRow>
<TableHeaderColumn>Name</TableHeaderColumn>
<TableHeaderColumn>Value</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody displayRowCheckbox={showCheckboxes}>
{Object.keys(health.details).map((key, index) => (
<TableRow key={index}>
<TableRowColumn>{key}</TableRowColumn>
<TableRowColumn>{health.details[key]}</TableRowColumn>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
</Dialog>
);
}
}
export default HealthModal;
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/health/health-detail/index.js
================================================
export const HealthRoute = {
path: 'admin/health-detail',
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('./health-detail'));
});
}
};
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/health/health.js
================================================
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link, hashHistory } from 'react-router';
import Translate from 'react-translate-component';
import RaisedButton from 'material-ui/RaisedButton';
import FlatButton from 'material-ui/FlatButton';
import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table';
import { NavigationRefresh, ImageRemoveRedEye } from 'material-ui/svg-icons';
import { systemHealth, systemHealthInfo } from '../../../reducers/administration';
export class HealthPage extends Component {
constructor(props) {
super(props);
this.getSystemHealth = this.getSystemHealth.bind(this);
this.getSystemHealthInfo = this.getSystemHealthInfo.bind(this);
this.transformHealthData = this.transformHealthData.bind(this);
}
componentDidMount() {
this.props.systemHealth();
}
getSystemHealth() {
if (!this.props.isFetching) {
this.props.systemHealth();
}
}
getSystemHealthInfo(healthObject) {
this.props.systemHealthInfo(healthObject);
hashHistory.push('/admin/health-detail');
}
getModuleName(path, name) {
let result;
if (path && name) {
result = path + this.separator + name;
} else if (path) {
result = path;
} else if (name) {
result = name;
} else {
result = '';
}
return result;
}
addHealthObject(result, isLeaf, healthObject, name) {
let status;
let error;
const healthData = {
name,
error,
status
};
const details = {};
let hasDetails = false;
Object.keys(healthObject).forEach((key) => {
if (healthObject[key]) {
const value = healthObject[key];
if (key === 'status' || key === 'error') {
healthData[key] = value;
} else {
if (!this.isHealthObject(value)) {
details[key] = value;
hasDetails = true;
}
}
}
});
// Add the details
if (hasDetails) {
healthData.details = details;
}
// Only add nodes if they provide additional information
if (isLeaf || hasDetails || healthData.error) {
result.push(healthData);
}
return healthData;
}
flattenHealthData(result, path, data): any {
Object.keys(data).forEach((key) => {
if (data[key]) {
const value = data[key];
if (this.isHealthObject(value)) {
if (this.hasSubSystem(value)) {
this.addHealthObject(result, false, value, this.getModuleName(path, key));
this.flattenHealthData(result, this.getModuleName(path, key), value);
} else {
this.addHealthObject(result, true, value, this.getModuleName(path, key));
}
}
}
});
return result;
}
transformHealthData(data) {
const response = [];
this.flattenHealthData(response, null, data);
return response;
}
getBaseName(name) {
if (name) {
const split = name.split('.');
return split[0];
}
return '';
}
getSubSystemName() {
if (this.name) {
const split = this.name.split('.');
split.splice(0, 1);
const remainder = split.join('.');
return remainder ? ` - ${remainder}` : '';
}
return '';
}
hasSubSystem(healthObject) {
let result = false;
Object.keys(healthObject).forEach((key) => {
if (healthObject[key]) {
const value = healthObject[key];
if (value && value.status) {
result = true;
}
}
});
return result;
}
isHealthObject(healthObject) {
let result = false;
Object.keys(healthObject).forEach((key) => {
if (healthObject[key]) {
if (key === 'status') {
result = true;
}
}
});
return result;
}
render() {
const { health, isFetching } = this.props;
const showCheckboxes = false;
const data = this.transformHealthData(health) || {};
return (
<div className="well">
<div>
<h2 translate="health.title">Health Checks</h2>
<p>
<RaisedButton
label={<Translate content="health.refresh.button" />}
onClick={() => this.getSystemHealth()} primary
disabled={isFetching} icon={<NavigationRefresh />}
/>
</p>
<hr />
<div className="row">
<div className="col-sm-12">
<Table>
<TableHeader
displaySelectAll={showCheckboxes}
adjustForCheckbox={showCheckboxes}
>
<TableRow>
<TableHeaderColumn>ServiceName</TableHeaderColumn>
<TableHeaderColumn>Status</TableHeaderColumn>
<TableHeaderColumn>Details</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody displayRowCheckbox={showCheckboxes}>
{data.map((row, index) => (
<TableRow key={index}>
<TableRowColumn>{row.name}</TableRowColumn>
<TableRowColumn>
<RaisedButton
label={row.status}
primary={row.status === 'UP'}
secondary={row.status !== 'UP'}
/>
</TableRowColumn>
<TableRowColumn>
<FlatButton
icon={<ImageRemoveRedEye />}
onClick={() => this.getSystemHealthInfo(row)}
/>
</TableRowColumn>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
</div>
</div>
);
}
}
export default connect(
({ administration }) => ({ health: administration.health, isFetching: administration.isFetching }),
{ systemHealth, systemHealthInfo }
)(HealthPage);
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/logs/logs.js
================================================
import React, { Component } from 'react';
import { connect } from 'react-redux';
import Translate from 'react-translate-component';
import { getLoggers, changeLogLevel } from '../../../reducers/administration';
export class LogsPage extends Component {
constructor(props) {
super(props);
this.getLogs = this.getLogs.bind(this);
this.changeLevel = this.changeLevel.bind(this);
}
componentDidMount() {
this.props.getLoggers();
}
getLogs() {
if (!this.props.isFetching) {
this.props.getLoggers();
}
}
changeLevel(loggerName, level) {
this.props.changeLogLevel(loggerName, level);
}
render() {
const { logs, isFetching } = this.props;
const loggers = logs ? logs.loggers : {};
return (
<div className="well ng-scope">
<div className="table-responsive">
<h2>Logs</h2>
<p>There are { loggers.length } loggers.</p>
<span>Filter</span>
<input type="text" className="form-control" disabled={isFetching} />
<table className="table table-condensed table-striped table-bordered" >
<thead>
<tr title="click to order">
<th><span>Name</span></th>
<th><span>Level</span></th>
</tr>
</thead>
<tbody>
{
loggers.map((logger, i) =>
<tr>
<td><small>{logger.name}</small></td>
<td>
<button disabled={isFetching} onClick={() => this.changeLevel(logger.name, 'TRACE')} className={`btn btn-default btn-xs ${(logger.level == 'TRACE') ? 'btn-danger' : 'btn-default'}`}>TRACE</button>
<button disabled={isFetching} onClick={() => this.changeLevel(logger.name, 'DEBUG')} className={`btn btn-default btn-xs ${(logger.level == 'DEBUG') ? 'btn-warning' : 'btn-default'}`}>DEBUG</button>
<button disabled={isFetching} onClick={() => this.changeLevel(logger.name, 'INFO')} className={`btn btn-default btn-xs ${(logger.level == 'INFO') ? 'btn-info' : 'btn-default'}`}>INFO</button>
<button disabled={isFetching} onClick={() => this.changeLevel(logger.name, 'WARN')} className={`btn btn-default btn-xs ${(logger.level == 'WARN') ? 'btn-success' : 'btn-default'}`}>WARN</button>
<button disabled={isFetching} onClick={() => this.changeLevel(logger.name, 'ERROR')} className={`btn btn-default btn-xs ${(logger.level == 'WARN') ? 'btn-primary' : 'btn-default'}`}>ERROR</button>
</td>
</tr>
)
}
</tbody>
</table>
</div>
</div>
);
}
}
export default connect(
({ administration }) => ({ logs: administration.logs, isFetching: administration.isFetching }),
{ getLoggers, changeLogLevel }
)(LogsPage);
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/metrics/metrics-detail/index.js
================================================
export const MetricsRoute = {
path: 'admin/metrics-detail',
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('./metrics-detail'));
});
}
};
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/metrics/metrics-detail/metrics-detail.js
================================================
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { hashHistory } from 'react-router';
import MetricsModal from './metrics-modal';
export class Metrics extends Component {
static propTypes = {
isAuthenticated: PropTypes.bool.isRequired
};
constructor(props) {
super(props);
this.state = {
showModal: false
};
}
componentWillMount() {
this.setState({
showModal: true
});
}
componentWillReceiveProps(nextProps) {
this.setState({
showModal: !nextProps.isAuthenticated
});
}
handleClose = () => {
this.setState({ showModal: false });
hashHistory.push('/admin/metrics');
};
render() {
return (
<MetricsModal showModal={this.state.showModal} handleClose={this.handleClose} threadDump={this.props.threadDump} />
);
}
}
export default connect(({ administration }) => ({ threadDump: administration.threadDump, isFetching: administration.isFetching }))(Metrics);
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/metrics/metrics-detail/metrics-modal.js
================================================
import React, { Component, PropTypes } from 'react';
import Dialog from 'material-ui/Dialog';
import FlatButton from 'material-ui/FlatButton';
import Translate from 'react-translate-component';
import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table';
class MetricsModal extends Component {
static propTypes = {
handleClose: PropTypes.func.isRequired,
showModal: PropTypes.bool.isRequired
};
constructor(props, context) {
super(props, context);
}
render() {
const { handleClose, threadDump } = this.props;
const showCheckboxes = false;
// FIX show / hide stacktrace function & filter & Labels
const actions = [
<FlatButton
label={<Translate content="entity.action.cancel" />}
onTouchTap={handleClose}
/>
];
return (
<Dialog
title={<h3><Translate content="metrics.title" /></h3>}
actions={actions}
modal autoScrollBodyContent
open={this.props.showModal}
onRequestClose={handleClose}
>
<div className="container">
{threadDump.map(threadDumpInfo => (
<div>
<h5>{threadDumpInfo.threadState} {threadDumpInfo.threadName} (ID {threadDumpInfo.threadId})</h5>
<FlatButton
label="Show StackTrace"
onTouchTap={() => this.setState({ showStack: !this.state.showStack })}
/>
<div className="row" >
<div className="col-md-12">
{Object.keys(threadDumpInfo.stackTrace).map((stK, stV) => (
<p>
{threadDumpInfo.stackTrace[stK].className}.{threadDumpInfo.stackTrace[stK].methodName}
({threadDumpInfo.stackTrace[stK].fileName}:{threadDumpInfo.stackTrace[stK].lineNumber})
</p>
))}
</div>
</div>
<div className="row">
<div className="col-md-12">
<Table>
<TableHeader
displaySelectAll={showCheckboxes}
adjustForCheckbox={showCheckboxes}
>
<TableRow>
<TableHeaderColumn>Blocked Time</TableHeaderColumn>
<TableHeaderColumn>Blocked Count</TableHeaderColumn>
<TableHeaderColumn>Waited Time</TableHeaderColumn>
<TableHeaderColumn>Waited Count</TableHeaderColumn>
<TableHeaderColumn>Lock Name</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody displayRowCheckbox={showCheckboxes}>
<TableRow key={threadDumpInfo}>
<TableRowColumn>{threadDumpInfo.blockedTime}</TableRowColumn>
<TableRowColumn>{threadDumpInfo.blockedCount}</TableRowColumn>
<TableRowColumn>{threadDumpInfo.waitedTime}</TableRowColumn>
<TableRowColumn>{threadDumpInfo.waitedCount}</TableRowColumn>
<TableRowColumn>{threadDumpInfo.lockName}</TableRowColumn>
</TableRow>
</TableBody>
</Table>
</div>
</div>
</div>
))}
</div>
</Dialog>
);
}
}
export default MetricsModal;
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/metrics/metrics.js
================================================
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { hashHistory } from 'react-router';
import LinearProgress from 'material-ui/LinearProgress';
import RaisedButton from 'material-ui/RaisedButton';
import FlatButton from 'material-ui/FlatButton';
import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table';
import { NavigationRefresh, ImageRemoveRedEye } from 'material-ui/svg-icons';
import Translate from 'react-translate-component';
import { systemMetrics, systemThreadDump } from '../../../reducers/administration';
export class MetricsPage extends Component {
constructor(props) {
super(props);
this.getMetrics = this.getMetrics.bind(this);
this.getStats = this.getStats.bind(this);
this.getThreadDump = this.getThreadDump.bind(this);
}
componentDidMount() {
this.props.systemMetrics();
}
getMetrics() {
if (!this.props.isFetching) {
this.props.systemMetrics();
}
}
getThreadDump() {
this.props.systemThreadDump();
hashHistory.push('/admin/metrics-detail');
}
getStats(metrics) {
const stat = {
servicesStats: {},
cachesStats: {}
};
if (!this.props.isFetching && metrics) {
Object.keys(metrics.timers).forEach((key, indexNm) => {
if (key.indexOf('web.rest') !== -1 || key.indexOf('service') !== -1) {
stat.servicesStats[key] = metrics.timers[key];
}
if (key.indexOf('net.sf.ehcache.Cache') !== -1) {
// remove gets or puts
const index = key.lastIndexOf('.');
const newKey = key.substr(0, index);
// Keep the name of the domain
stat.cachesStats[newKey] = {
name: newKey,
value: metrics.timers[key]
};
}
});
return stat;
}
}
render() {
const showCheckboxes = false;
const { metrics, isFetching } = this.props;
const data = metrics || {};
const { servicesStats, cachesStats } = this.getStats(data);
return (
<div className="well">
<div>
<h2 translate="metrics.title">Application Metrics</h2>
<p>
<RaisedButton
label={<Translate content="metrics.refresh.button" />}
onClick={() => this.getMetrics()} primary
disabled={isFetching} icon={<NavigationRefresh />}
/>
</p>
FIX ME Coloring the progressbar
<hr />
<div className="row">
<div className="col-sm-12">
<h3>JVM Metrics</h3>
<div className="row">
<div className="col-md-4">
<b>Memory</b>
<p>
<span>Total Memory</span>
({metrics.gauges['jvm.memory.total.used'].value / 1000000 || 0}M / {metrics.gauges['jvm.memory.total.max'].value / 1000000 || 0}M)
</p>
<LinearProgress
mode="determinate"
value={metrics.gauges['jvm.memory.total.used'].value}
min="0"
max={metrics.gauges['jvm.memory.total.max'].value}
/>
<span>{((metrics.gauges['jvm.memory.total.used'].value * 100) / metrics.gauges['jvm.memory.total.max'].value) || 0}%</span>
<p>
<span>Heap Memory</span>
({metrics.gauges['jvm.memory.heap.used'].value / 1000000 || 0}M / {metrics.gauges['jvm.memory.heap.max'].value / 1000000 || 0}M)
</p>
<LinearProgress
mode="determinate"
min="0"
max={metrics.gauges['jvm.memory.heap.max'].value}
value={metrics.gauges['jvm.memory.heap.used'].value}
/>
<span>{((metrics.gauges['jvm.memory.heap.used'].value * 100) / metrics.gauges['jvm.memory.heap.max'].value) || 0}%</span>
<p>
<span>Non-Heap Memory</span>
({metrics.gauges['jvm.memory.non-heap.used'].value / 1000000 || 0}M / {metrics.gauges['jvm.memory.non-heap.committed'].value / 1000000 || 0}M)
</p>
<LinearProgress
mode="determinate"
min="0"
max={metrics.gauges['jvm.memory.non-heap.committed'].value}
value={metrics.gauges['jvm.memory.non-heap.used'].value}
/>
<span>{((metrics.gauges['jvm.memory.non-heap.used'].value * 100) / metrics.gauges['jvm.memory.non-heap.committed'].value) || 0}%</span>
</div>
<div className="col-md-4">
<b>Threads</b> (Total: {metrics.gauges['jvm.threads.count'].value})
<FlatButton
icon={<ImageRemoveRedEye />}
onClick={() => this.getThreadDump()}
/>
<p><span>Runnable</span> {metrics.gauges['jvm.threads.runnable.count'].value}</p>
<LinearProgress mode="determinate" min="0" value={metrics.gauges['jvm.threads.runnable.count'].value} max={metrics.gauges['jvm.threads.count'].value} />
<span>{((metrics.gauges['jvm.threads.runnable.count'].value * 100) / metrics.gauges['jvm.threads.count'].value) || 0}%</span>
<p><span>Timed Waiting</span> ({metrics.gauges['jvm.threads.timed_waiting.count'].value})</p>
<LinearProgress mode="determinate" min="0" value={metrics.gauges['jvm.threads.timed_waiting.count'].value} max={metrics.gauges['jvm.threads.count'].value} />
<span>{((metrics.gauges['jvm.threads.timed_waiting.count'].value * 100) / metrics.gauges['jvm.threads.count'].value) || 0}%</span>
<p><span>Waiting</span> ({metrics.gauges['jvm.threads.waiting.count'].value})</p>
<LinearProgress mode="determinate" min="0" value={metrics.gauges['jvm.threads.waiting.count'].value} max={metrics.gauges['jvm.threads.count'].value} />
<span>{((metrics.gauges['jvm.threads.waiting.count'].value * 100) / metrics.gauges['jvm.threads.count'].value) || 0}%</span>
<p><span>Blocked</span> ({metrics.gauges['jvm.threads.blocked.count'].value})</p>
<LinearProgress mode="determinate" min="0" value={metrics.gauges['jvm.threads.blocked.count'].value} max={metrics.gauges['jvm.threads.count'].value} />
<span>{((metrics.gauges['jvm.threads.blocked.count'].value * 100) / metrics.gauges['jvm.threads.count'].value) || 0}%</span>
</div>
<div className="col-md-4">
<b>Garbage collections</b>
<div className="row">
<div className="col-md-9">Mark Sweep count</div>
<div className="col-md-3 text-right">{metrics.gauges['jvm.garbage.PS-MarkSweep.count'].value}</div>
</div>
<div className="row">
<div className="col-md-9">Mark Sweep time</div>
<div className="col-md-3 text-right">{metrics.gauges['jvm.garbage.PS-MarkSweep.time'].value}ms</div>
</div>
<div className="row">
<div className="col-md-9">Scavenge count</div>
<div className="col-md-3 text-right">{metrics.gauges['jvm.garbage.PS-Scavenge.count'].value}</div>
</div>
<div className="row">
<div className="col-md-9">Scavenge time</div>
<div className="col-md-3 text-right">{metrics.gauges['jvm.garbage.PS-Scavenge.time'].value}ms</div>
</div>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<h3>HTTP requests (events per second)</h3>
<p>
<span>Active requests</span>
<b>{metrics.counters['com.codahale.metrics.servlet.InstrumentedFilter.activeRequests'].count || 0}</b> -
<span>Total requests</span> <b>{metrics.timers['com.codahale.metrics.servlet.InstrumentedFilter.requests'].count || 0}</b>
</p>
<Table>
<TableHeader
displaySelectAll={showCheckboxes}
adjustForCheckbox={showCheckboxes}
>
<TableRow>
<TableHeaderColumn>Code</TableHeaderColumn>
<TableHeaderColumn>Count</TableHeaderColumn>
<TableHeaderColumn>Mean</TableHeaderColumn>
<TableHeaderColumn><span>Average</span> (1 min)</TableHeaderColumn>
<TableHeaderColumn><span>Average</span> (5 min)</TableHeaderColumn>
<TableHeaderColumn><span>Average</span> (15 min)</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody displayRowCheckbox={showCheckboxes}>
<TableRow key={0}>
<TableRowColumn>OK</TableRowColumn>
<TableRowColumn>
<LinearProgress
mode="determinate"
min="0"
max={metrics.timers['com.codahale.metrics.servlet.InstrumentedFilter.requests'].count}
value={metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].count}
/>
</TableRowColumn>
<TableRowColumn>
{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].mean_rate || 2}
</TableRowColumn>
<TableRowColumn>
{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].m1_rate || 2}
</TableRowColumn>
<TableRowColumn>
{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].m5_rate || 2}
</TableRowColumn>
<TableRowColumn>
{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.ok'].m15_rate || 2}
</TableRowColumn>
</TableRow>
<TableRow key={1}>
<TableRowColumn>Not Found</TableRowColumn>
<TableRowColumn>
<LinearProgress
mode="determinate"
min="0"
max={metrics.timers['com.codahale.metrics.servlet.InstrumentedFilter.requests'].count}
value={metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].count}
/>
</TableRowColumn>
<TableRowColumn>
{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].mean_rate || 2}
</TableRowColumn>
<TableRowColumn>
{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].m1_rate || 2}
</TableRowColumn>
<TableRowColumn>
{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].m5_rate || 2}
</TableRowColumn>
<TableRowColumn>
{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.notFound'].m15_rate || 2}
</TableRowColumn>
</TableRow>
<TableRow key={2}>
<TableRowColumn>Server Error</TableRowColumn>
<TableRowColumn>
<LinearProgress
mode="determinate"
min="0"
max={metrics.timers['com.codahale.metrics.servlet.InstrumentedFilter.requests'].count}
value={metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].count}
/>
</TableRowColumn>
<TableRowColumn>
{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].mean_rate || 2}
</TableRowColumn>
<TableRowColumn>
{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].m1_rate || 2}
</TableRowColumn>
<TableRowColumn>
{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].m5_rate || 2}
</TableRowColumn>
<TableRowColumn>
{metrics.meters['com.codahale.metrics.servlet.InstrumentedFilter.responseCodes.serverError'].m15_rate || 2}
</TableRowColumn>
</TableRow>
</TableBody>
</Table>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<h3>Services statistics (time in millisecond)</h3>
<Table>
<TableHeader
displaySelectAll={showCheckboxes}
adjustForCheckbox={showCheckboxes}
>
<TableRow>
<TableHeaderColumn>Name</TableHeaderColumn>
<TableHeaderColumn>Count</TableHeaderColumn>
<TableHeaderColumn>Mean</TableHeaderColumn>
<TableHeaderColumn>Min</TableHeaderColumn>
<TableHeaderColumn>p50</TableHeaderColumn>
<TableHeaderColumn>p75</TableHeaderColumn>
<TableHeaderColumn>p95</TableHeaderColumn>
<TableHeaderColumn>p99</TableHeaderColumn>
<TableHeaderColumn>Max</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody displayRowCheckbox={showCheckboxes}>
{Object.keys(servicesStats).map((key, index) => (
<TableRow key={key}>
<TableRowColumn>{key}</TableRowColumn>
<TableRowColumn>{servicesStats[key].count}</TableRowColumn>
<TableRowColumn>{servicesStats[key].mean * 1000 || 0}</TableRowColumn>
<TableRowColumn>{servicesStats[key].min * 1000 || 0}</TableRowColumn>
<TableRowColumn>{servicesStats[key].p50 * 1000 || 0}</TableRowColumn>
<TableRowColumn>{servicesStats[key].p75 * 1000 || 0}</TableRowColumn>
<TableRowColumn>{servicesStats[key].p95 * 1000 || 0}</TableRowColumn>
<TableRowColumn>{servicesStats[key].p99 * 1000 || 0}</TableRowColumn>
<TableRowColumn>{servicesStats[key].max * 1000 || 0}</TableRowColumn>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
<div className="row">
<div className="col-sm-12">
<h3>Ehcache statistics</h3>
<Table>
<TableHeader
displaySelectAll={showCheckboxes}
adjustForCheckbox={showCheckboxes}
>
<TableRow>
<TableHeaderColumn>Cache Name</TableHeaderColumn>
<TableHeaderColumn>Object</TableHeaderColumn>
<TableHeaderColumn>Misses</TableHeaderColumn>
<TableHeaderColumn>Eviction Count</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody displayRowCheckbox={showCheckboxes}>
{Object.keys(cachesStats).map((k, v) => (
<TableRow key={k}>
<TableRowColumn>{cachesStats.k.name}</TableRowColumn>
<TableRowColumn>{metrics.gauges[`${k}.objects`].value}</TableRowColumn>
<TableRowColumn>{metrics.gauges[`${k}.hits`].value}</TableRowColumn>
<TableRowColumn>{metrics.gauges[`${k}.misses`].value}</TableRowColumn>
<TableRowColumn>{metrics.gauges[`${k}.eviction-count`].value}</TableRowColumn>
</TableRow>
))}
</TableBody>
</Table>
</div>
</div>
{ metrics.gauges['HikariPool-1.pool.TotalConnections'].value > 0 ?
<div className="row">
<div className="col-sm-12">
<h3>DataSource statistics (time in millisecond)</h3>
<Table>
<TableHeader
displaySelectAll={showCheckboxes}
adjustForCheckbox={showCheckboxes}
>
<TableRow>
<TableHeaderColumn>
<span>Usage</span>
({metrics.gauges['HikariPool-1.pool.ActiveConnections'].value} / {metrics.gauges['HikariPool-1.pool.TotalConnections'].value})
</TableHeaderColumn>
<TableHeaderColumn>Count</TableHeaderColumn>
<TableHeaderColumn>Mean</TableHeaderColumn>
<TableHeaderColumn>Min</TableHeaderColumn>
<TableHeaderColumn>p50</TableHeaderColumn>
<TableHeaderColumn>p75</TableHeaderColumn>
<TableHeaderColumn>p95</TableHeaderColumn>
<TableHeaderColumn>p99</TableHeaderColumn>
<TableHeaderColumn>Max</TableHeaderColumn>
</TableRow>
</TableHeader>
<TableBody displayRowCheckbox={showCheckboxes}>
<TableRow key="DB">
<TableRowColumn>
<LinearProgress
mode="determinate"
min="0"
max={metrics.gauges['HikariPool-1.pool.TotalConnections'].value}
value={metrics.gauges['HikariPool-1.pool.ActiveConnections'].value}
/>
<span>{((metrics.gauges['HikariPool-1.pool.ActiveConnections'].value * 100) / metrics.gauges['HikariPool-1.pool.TotalConnections'].value) || 0}%</span>
</TableRowColumn>
<TableRowColumn>{metrics.histograms['HikariPool-1.pool.Usage'].count}</TableRowColumn>
<TableRowColumn>{metrics.histograms['HikariPool-1.pool.Usage'].mean * 1000 || 0}</TableRowColumn>
<TableRowColumn>{metrics.histograms['HikariPool-1.pool.Usage'].min * 1000 || 0}</TableRowColumn>
<TableRowColumn>{metrics.histograms['HikariPool-1.pool.Usage'].p50 * 1000 || 0}</TableRowColumn>
<TableRowColumn>{metrics.histograms['HikariPool-1.pool.Usage'].p75 * 1000 || 0}</TableRowColumn>
<TableRowColumn>{metrics.histograms['HikariPool-1.pool.Usage'].p95 * 1000 || 0}</TableRowColumn>
<TableRowColumn>{metrics.histograms['HikariPool-1.pool.Usage'].p99 * 1000 || 0}</TableRowColumn>
<TableRowColumn>{metrics.histograms['HikariPool-1.pool.Usage'].max * 1000 || 0}</TableRowColumn>
</TableRow>
</TableBody>
</Table>
</div>
</div>
: null }
</div>
</div>
</div>
</div>
);
}
}
export default connect(
({ administration }) => ({ metrics: administration.metrics, isFetching: administration.isFetching }),
{ systemMetrics, systemThreadDump }
)(MetricsPage);
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/administration/user-management/user-management.js
================================================
import React, { Component } from 'react';
import { connect } from 'react-redux';
import Translate from 'react-translate-component';
import { getUsers } from '../../../reducers/administration';
export class UserManagement extends Component {
constructor(props) {
super(props);
this.getUserList = this.getUserList.bind(this);
}
componentDidMount() {
this.props.getUsers();
}
getUserList() {
if (!this.props.isFetching) {
this.props.getUsers();
}
}
render() {
const { userManagement, isFetching } = this.props;
const users = (userManagement && userManagement.users) ? userManagement.users : [];
return (
<div className="well">
<div>
<h2 data-translate="gateway.title">Users</h2>
FIX ME datatable pagination, activate/deactivate, action buttons
<p>
<button type="button" onClick={() => this.getUserList()} className={isFetching ? 'btn btn-danger' : 'btn btn-primary'} disabled={isFetching}>
<span className="glyphicon glyphicon-refresh glyphicon-" />
<Translate component="span" content="gateway.refresh.button" />
</button>
</p>
</div>
<div className="table-responsive">
<table className="table table-striped">
<thead>
<tr jh-sort="vm.predicate" ascending="vm.reverse" callback="vm.transition()">
<th jh-sort-by="id"><span translate="global.field.id">ID</span><span className="glyphicon glyphicon-sort" /></th>
<th jh-sort-by="login"><span translate="userManagement.login">Login</span> <span className="glyphicon glyphicon-sort" /></th>
<th jh-sort-by="email"><span translate="userManagement.email">Email</span> <span className="glyphicon glyphicon-sort" /></th>
<th />
<th jh-sort-by="langKey"> <span translate="userManagement.langKey">Lang Key</span> <span className="glyphicon glyphicon-sort" /></th> <th><span translate="userManagement.profiles">Profiles</span></th> <th jh-sort-by="createdDate"><span translate="userManagement.createdDate">Created Date</span> <span className="glyphicon glyphicon-sort" /></th>
<th jh-sort-by="lastModifiedBy"><span translate="userManagement.lastModifiedBy">Last Modified By</span> <span className="glyphicon glyphicon-sort" /></th>
<th jh-sort-by="lastModifiedDate"><span translate="userManagement.lastModifiedDate">Last Modified Date</span> <span className="glyphicon glyphicon-sort" /></th>
<th />
</tr>
</thead>
<tbody>
{
users.map((user, i) => (
<tr key={`user-${i}`}>
<td><a>{user.id}</a></td>
<td>{user.login}</td>
<td>{user.email}</td>
<td>
{
user.activated ? (
<span
className="label label-success" ng-click="vm.setActive(user, false)" ng-show="user.activated"
translate="userManagement.activated" style={{ cursor: 'pointer' }}
>Activated</span>
) : (
<span
className="label label-danger" ng-click="vm.setActive(user, true)" ng-show="!user.activated"
translate="userManagement.deactivated" style={{ cursor: 'pointer' }}
>Deactivated</span>
)
}
</td>
<td>{user.langKey}</td>
<td>
{
users.authorities ? (
users.authorities.map((authority, i) => (
<div>
<span className="label label-info">{authority}</span>
</div>
))) : null
}
</td>
<td>{user.createdDate}</td>
<td>{user.lastModifiedBy}</td>
<td>{user.lastModifiedDate}</td>
<td className="text-right">
<div className="btn-group flex-btn-group-container">
<button
type="submit"
className="btn btn-info btn-sm"
>
<span className="glyphicon glyphicon-eye-open" />
<span className="hidden-xs hidden-sm" ><Translate content="entity.action.view" /></span>
</button>
<button
type="submit"
className="btn btn-primary btn-sm"
>
<span className="glyphicon glyphicon-pencil" />
<span className="hidden-xs hidden-sm"><Translate content="entity.action.edit" /></span>
</button>
<button
type="submit"
className="btn btn-danger btn-sm" disabled={this.props.account.login === user.login}
>
<span className="glyphicon glyphicon-remove-circle" />
<span className="hidden-xs hidden-sm"><Translate content="entity.action.delete" /></span>
</button>
</div>
</td>
</tr>
))
}
</tbody>
</table>
</div>
</div>
);
}
}
export default connect(
(state => ({ userManagement: state.administration.userManagement, isFetching: state.administration.isFetching, account: state.authentication.account })),
{ getUsers }
)(UserManagement);
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/home/home.js
================================================
import React, { Component } from 'react';
import { Link } from 'react-router';
import Translate from 'react-translate-component';
import { connect } from 'react-redux';
import { log } from '../../shared/util/log-util';
import { getSession } from '../../reducers/authentication';
import './home.scss';
export class Home extends Component {
static propTypes = {
account: React.PropTypes.object.isRequired,
getSession: React.PropTypes.func.isRequired
};
constructor(props) {
super(props);
this.state = {
currentUser: props.account
};
}
componentWillMount() {
this.props.getSession();
}
componentWillReceiveProps(nextProps) {
this.setState({
currentUser: nextProps.account
});
}
render() {
const { currentUser } = this.state;
return (
<div className="row">
<div className="col-md-9">
<h2><Translate content="home.title">Welcome, Java Hipster!</Translate></h2>
<p className="lead"><Translate content="home.subtitle">This is your homepage</Translate></p>
{
(currentUser && currentUser.login) ? (
<div>
<div className="alert alert-success">
<Translate content="home.logged.message">You are logged in as user </Translate> "{ currentUser.login }"
</div>
</div>
) : (
<div>
<div className="alert alert-warning">
<Translate content="global.messages.info.authenticated.prefix">If you want to </Translate>
<Link to="/login" className="alert-link"><Translate content="global.messages.info.authenticated.link">sign in</Translate></Link>
<Translate content="global.messages.info.authenticated.suffix">, you can try the default accounts:
<br />- Administrator (login="admin" and password="admin")
<br />- User (login="user" and password="user").</Translate>
</div>
<div className="alert alert-warning">
<Translate content="global.messages.info.register.noaccount">You do not have an account yet?</Translate>
<a className="alert-link"><Translate content="global.messages.info.register.link">Register a new account</Translate></a>
</div>
</div>
)
}
<p>
<Translate content="home.question">If you have any question on JHipster:</Translate>
</p>
<ul>
<li>
<a href="http://jhipster.github.io/" target="_blank" rel="noopener noreferrer">
<Translate content="home.link.homepage">JHipster homepage</Translate>
</a>
</li>
<li>
<a href="http://stackoverflow.com/tags/jhipster/info" target="_blank" rel="noopener noreferrer">
<Translate content="home.link.stackoverflow">JHipster on Stack Overflow</Translate>
</a>
</li>
<li>
<a href="https://github.com/jhipster/generator-jhipster/issues?state=open" target="_blank" rel="noopener noreferrer">
<Translate content="home.link.bugtracker">JHipster bug tracker</Translate>
</a>
</li>
<li>
<a href="https://gitter.im/jhipster/generator-jhipster" target="_blank" rel="noopener noreferrer">
<Translate content="home.link.chat">JHipster public chat room</Translate>
</a>
</li>
<li>
<a href="https://twitter.com/java_hipster" target="_blank" rel="noopener noreferrer">
<Translate content="home.link.follow">follow @java_hipster on Twitter</Translate>
</a>
</li>
</ul>
<p>
<span>If you like JHipster React, do not forget to give us a star on </span>
<a href="https://github.com/jhipster/generator-jhipster-react" target="_blank" rel="noopener noreferrer">Github</a>!
</p>
</div>
<div className="col-md-3 pad">
<span className="hipster img-fluid img-rounded" />
</div>
</div>
);
}
}
export default connect(
store => ({
account: store.authentication.account,
isAuthenticated: store.authentication.isAuthenticated
}),
{ getSession }
)(Home);
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/home/home.scss
================================================
/* ==========================================================================
Main page styles
========================================================================== */
.img-fluid {
max-width: 100%;
height: auto;
}
.hipster {
display: inline-block;
width: 347px;
height: 497px;
background: url("../../../static/images/logo-jhipster-react.svg") no-repeat center top;
background-size: contain;
}
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/home/index.js
================================================
export default {
/* Path not specified as this is the index route */
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('./home').default);
});
}
};
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/login/index.js
================================================
export const LoginRoute = {
path: 'login',
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('./login'));
});
}
};
export const LogoutRoute = {
path: 'logout',
onEnter(onLogout) {
onLogout();
},
getComponent(nextState, cb) {
require.ensure([], (require) => {
cb(null, require('./login'));
});
}
};
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/login/login-modal.js
================================================
import React, { Component, PropTypes } from 'react';
import Dialog from 'material-ui/Dialog';
import FlatButton from 'material-ui/FlatButton';
import TextField from 'material-ui/TextField';
import Translate from 'react-translate-component';
class LoginModal extends Component {
static propTypes = {
authenticationError: PropTypes.bool,
handleLogin: PropTypes.func.isRequired,
handleClose: PropTypes.func.isRequired,
handleForgottenPass: PropTypes.func.isRequired,
handleRegister: PropTypes.func.isRequired,
showModal: PropTypes.bool.isRequired
};
static defaultProps = {
authenticationError: false
};
constructor(props, context) {
super(props, context);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleUsernameChange = this.handleUsernameChange.bind(this);
this.handlePasswordChange = this.handlePasswordChange.bind(this);
this.state = {
username: null,
password: null
};
}
handleSubmit() {
const { handleLogin } = this.props;
const { username, password } = this.state;
handleLogin(username, password, false); // FIXME remember me value must be passed
}
handleUsernameChange(event) {
this.setState({ username: event.target.value });
}
handlePasswordChange(event) {
this.setState({ password: event.target.value });
}
render() {
const { authenticationError, handleClose } = this.props;
const actions = [
<FlatButton
label={<Translate content="entity.action.cancel" />}
onTouchTap={handleClose}
/>,
<FlatButton
label={<Translate content="login.form.button" />}
primary
keyboardFocused
onTouchTap={this.handleSubmit}
/>
];
return (
<Dialog
title={<h3><Translate content="login.title" /></h3>}
actions={actions}
modal autoScrollBodyContent
open={this.props.showModal}
onRequestClose={handleClose}
>
<div className="row">
<div className="col-md-12">
{ authenticationError ?
<div className="alert alert-danger">
<strong>Failed to sign in!</strong> <Translate content="login.messages.error.authentication" />
</div>
: null
}
</div>
<div className="col-md-12">
<TextField
id="username" name="username" fullWidth
hintText="Username"
floatingLabelText={<Translate content="global.form.username" />}
floatingLabelFixed
onChange={this.handleUsernameChange}
/><br />
<TextField
id="password" name="password" fullWidth type="password"
hintText="Password"
floatingLabelText={<Translate content="login.form.password" />}
floatingLabelFixed
onChange={this.handlePasswordChange}
/><br />
<p />
<div className="alert alert-warning">
<a className="alert-link" onClick={() => this.props.handleForgottenPass}><Translate content="login.password.forgot" /></a>
</div>
<div className="alert alert-warning">
You do not have an account yet?
<a className="alert-link" onClick={() => this.props.handleRegister}><Translate content="global.messages.info.register.link" /></a>
</div>
</div>
</div>
</Dialog>
);
}
}
export default LoginModal;
================================================
FILE: generators/client/templates/src/main/webapp/app/modules/login/login.js
================================================
import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { browserHistory } from 'react-router';
import LoginModal from './login-modal';
import { login } from '../../reducers/authentication';
export class Login extends Component {
static propTypes = {
login: PropTypes.func.isRequired,
isAuthenticated: PropTypes.bool.isRequired
};
constructor(props) {
super(props);
this.handleLogin = this.handleLogin.bind(this);
this.state = {
showModal: false
};
}
componentWillMount() {
this.setState({
showModal: !this.props.isAuthenticated
});
}
componentWillReceiveProps(nextProps) {
this.setState({
showModal: !nextProps.isAuthenticated
});
}
handleLogin(username, password, rememberMe = false) {
this.props.login(username, password, rememberMe);
}
handleClose = () => {
this.setState({ showModal: false });
};
render() {
return (
<LoginModal showModal={this.state.showModal} handleLogin={this.handleLogin} handleClose={this.handleClose} />
);
}
}
export default connect(
store => ({ account: store.authentication.account, isAuthenticated: store.authentication.isAuthenticated }),
{ login }
)(Login);
================================================
FILE: generators/client/templates/src/main/webapp/app/reducers/account.js
================================================
================================================
FILE: generators/client/templates/src/main/webapp/app/reducers/administration.js
================================================
const FETCH = 'administration/FETCH';
const FETCH_SUCCESS = 'administration/FETCH_SUCCESS';
const FETCH_FAIL = 'administration/FETCH_FAIL';
const FETCH_GATEWAY_ROUTE = 'administration/FETCH_GATEWAY_ROUTE';
const FETCH_LOGS = 'administration/FETCH_LOGS';
const FETCH_LOGS_CHANGE_LEVEL = 'administration/FETCH_LOGS_CHANGE_LEVEL';
const FETCH_HEALTH = 'administration/FETCH_HEALTH';
const FETCH_HEALTH_INFO = 'administration/FETCH_HEALTH_INFO';
const FETCH_METRICS = 'administration/FETCH_METRICS';
const FETCH_THREAD_DUMP = 'administration/FETCH_THREAD_DUMP';
const FETCH_USERS = 'administration/FETCH_USERS';
const FETCH_CONFIGURATIONS = 'administration/FETCH_CONFIGURATIONS';
const FETCH_ENV = 'administration/FETCH_ENV';
const FETCH_AUDITS = 'administration/FETCH_AUDITS';
const FETCH_API_DOCS = 'administration/FETCH_API_DOCS';
const initialState = {
loading: false,
gateway: {
routes: []
},
logs: {
loggers: []
},
health: {
},
metrics: {
},
userManagement: {
users: []
},
configuration: {
configProps: {},
env: {}
},
audits: [],
apiDocs: {
}
};
// Reducer
export default function reducer(state = initialState, action) {
switch (action.type) {
case FETCH:
return {
...state,
loading: true
};
case FETCH_SUCCESS:
return {
...state,
loading: false
};
case FETCH_GATEWAY_ROUTE:
return {
...state,
gateway: {
routes: action.result.data
},
loading: false
};
case FETCH_METRICS:
return {
...state,
metrics: action.result.data,
loading: false
};
case FETCH_THREAD_DUMP:
return {
...state,
threadDump: action.result.data,
loading: false
};
case FETCH_LOGS:
return {
...state,
logs: {
loggers: action.result.data
},
loading: false
};
case FETCH_USERS:
return {
...state,
userManagement: {
users: action.result.data
},
loading: false
};
case FETCH_CONFIGURATIONS:
return {
...state,
configuration: {
...state.configuration,
configProps: action.result.data
},
loading: false
};
case FETCH_ENV:
return {
...state,
configuration: {
...state.configuration,
env: action.result.data
},
loading: false
};
case FETCH_AUDITS:
return {
...state,
audits: action.result.data,
loading: false
};
case FETCH_HEALTH:
return {
...state,
health: action.result.data,
loading: false
};
case FETCH_HEALTH_INFO:
return {
...state,
health: action.result,
loading: false
};
case FETCH_API_DOCS:
return {
...state,
apiDocs: action.result.data,
loading: false
};
default:
return state;
}
}
// Actions
export function gatewayRoutes() {
return {
types: [FETCH, FETCH_GATEWAY_ROUTE, FETCH_FAIL],
promise: client => client.get('/api/gateway/routes')
};
}
export function getLoggers() {
return {
types: [FETCH, FETCH_LOGS, FETCH_FAIL],
promise: client => client.get('/management/logs')
};
}
export function systemHealth() {
return {
types: [FETCH, FETCH_HEALTH, FETCH_FAIL],
promise: client => client.get('/management/health')
};
}
export function systemHealthInfo(healthObj) {
return {
types: [FETCH, FETCH_HEALTH_INFO, FETCH_FAIL],
promise: () => Promise.resolve(healthObj)
};
}
export function systemMetrics() {
return {
types: [FETCH, FETCH_METRICS, FETCH_FAIL],
promise: client => client.get('/management/jhipster/metrics')
};
}
export function systemThreadDump() {
return {
types: [FETCH, FETCH_THREAD_DUMP, FETCH_FAIL],
promise: client => client.get('/management/dump')
};
}
export function changeLogLevel(name, level) {
const body = {
level,
name
};
return {
types: [FETCH, FETCH_LOGS_CHANGE_LEVEL, FETCH_FAIL],
promise: client => client.put('/management/jhipster/logs', body),
afterSuccess: dispatch => dispatch(getLoggers())
};
}
export function getUsers(page = 0, size = 10, sort = 'id, asc') {
return {
types: [FETCH, FETCH_USERS, FETCH_FAIL],
promise: client => client.get(`/api/users?cacheBuster=${new Date().getTime()}&page=${page}&size=${size}&sort=${sort}`)
};
}
export function getConfigurations() {
return {
types: [FETCH, FETCH_CONFIGURATIONS, FETCH_FAIL],
promise: client => client.get('/management/configprops')
};
}
export function getEnv() {
return {
types: [FETCH, FETCH_ENV, FETCH_FAIL],
promise: client => client.get('/management/env')
};
}
export function getAudits(fromDate, toDate, page = 0, size = 20) {
let requestUrl = `/management/jhipster/audits?page=${page}&size=${size}`;
if (toDate) {
requestUrl += `&toDate=${toDate}`;
}
if (fromDate) {
requestUrl += `&fromDate=${fromDate}`;
}
return {
types: [FETCH, FETCH_AUDITS, FETCH_FAIL],
promise: client => client.get(requestUrl)
};
}
export function getApiDocs() {
return {
types: [FETCH, FETCH_API_DOCS, FETCH_FAIL],
promise: client => client.get('/v2/api-docs')
};
}
================================================
FILE: generators/client/templates/src/main/webapp/app/reducers/authentication.js
================================================
import { hashHistory } from 'react-router';
const LOGIN = 'authentication/LOGIN';
const LOGIN_SUCCESS = 'authentication/LOGIN_SUCCESS';
const LOGIN_FAIL = 'authentication/LOGIN_FAIL';
const GET_SESSION = 'authentication/GET_SESSION';
const GET_SESSION_SUCCESS = 'authentication/GET_SESSION_SUCCESS';
const GET_SESSION_FAIL = 'authentication/GET_SESSION_FAIL';
const LOGOUT = 'authentication/LOGOUT';
const LOGOUT_SUCCESS = 'authentication/LOGOUT_SUCCESS';
const LOGOUT_FAIL = 'authentication/LOGOUT_FAIL';
const ERROR_MESSAGE = 'authentication/ERROR_MESSAGE';
const initialState = {
loading: false,
isAuthenticated: false,
account: {},
errorMessage: null, // Errors returned from server side
redirectMessage: null,
showModalLogin: false
};
// Reducer
export default function reducer(state = initialState, action) {
let isAuthenticated = false;
switch (action.type) {
case LOGIN:
return {
...initialState,
loading: true
};
case LOGIN_SUCCESS:
return {
...initialState,
isAuthenticated: true
};
case LOGIN_FAIL:
return {
...initialState,
errorMessage: action.error.data
};
case LOGOUT_SUCCESS:
return {
...initialState
};
case GET_SESSION:
return {
...state,
loading: true
};
case GET_SESSION_SUCCESS:
isAuthenticated = action.result.data ? action.result.data.activated : false;
return {
...initialState,
isAuthenticated,
account: action.result.data
};
case GET_SESSION_FAIL:
return {
...initialState,
errorMessage: action.error.data
};
case ERROR_MESSAGE:
return {
...initialState,
redirectMessage: action.message
};
default:
return state;
}
}
export function displayAuthError(message) {
return { type: ERROR_MESSAGE, message };
}
export function getSession() {
return {
types: [GET_SESSION, GET_SESSION_SUCCESS, GET_SESSION_FAIL],
promise: client => client.get('/api/account')
};
}
export function clearAuthToken() {
if (localStorage.getItem('jhi-authenticationToken')) {
localStorage.removeItem('jhi-authenticationToken');
}
if (sessionStorage.getItem('jhi-authenticationToken')) {
sessionStorage.removeItem('jhi-authenticationToken');
}
}
<%_ if (authenticationType === 'oauth2') { _%>
export function login(username, password, rememberMe = false) {
const data = `username=${encodeURIComponent(username)}&password=${
encodeURIComponent(password)}&grant_type=password&scope=read%20write&` +
'client_secret=my-secret-token-to-change-in-production&client_id=<%= baseName%>app';
const headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/json',
'Authorization': 'Basic ' + this.base64.encode('<%= baseName%>app' + ':' + 'my-secret-token-to-change-in-production')
};
return {
types: [LOGIN, LOGIN_SUCCESS, LOGIN_FAIL],
promise: client => client.post('oauth/token', data, { headers: headers }),
afterSuccess: (dispatch, getState, response) => {
const expiredAt = new Date();
expiredAt.setSeconds(expiredAt.getSeconds() + response.expires_in);
response.expires_at = expiredAt.getTime();
localStorage.setItem('jhi-authenticationToken', response);
const routingState = getState().routing.locationBeforeTransitions.state || {};
hashHistory.push(routingState.nextPathname || '/');
dispatch(getSession());
}
};
}
export function logout() {
return {
types: [LOGOUT, LOGOUT_SUCCESS, LOGOUT_FAIL],
promise: client => client.post('/api/logout', {}),
afterSuccess: () => {
clearAuthToken();
hashHistory.push('/');
}
};
}
<%_ } else if (authenticationType === 'jwt') { _%>
export function login(username, password, rememberMe = false) {
return {
types: [LOGIN, LOGIN_SUCCESS, LOGIN_FAIL],
promise: client => client.post('/api/authenticate', { username, password, rememberMe }),
afterSuccess: (dispatch, getState, response) => {
const bearerToken = response.headers.authorization;
if (bearerToken && bearerToken.slice(0, 7) === 'Bearer ') {
const jwt = bearerToken.slice(7, bearerToken.length);
if (rememberMe) {
localStorage.setItem('jhi-authenticationToken', jwt);
} else {
sessionStorage.setItem('jhi-authenticationToken', jwt);
}
}
const routingState = getState().routing.locationBeforeTransitions.state || {};
hashHistory.push(routingState.nextPathname || '/');
dispatch(getSession());
}
};
}
export function logout() {
return {
types: [LOGOUT, LOGOUT_SUCCESS, LOGOUT_FAIL],
promise: client => client.get('/api/account'),
afterSuccess: () => {
clearAuthToken();
hashHistory.push('/');
}
};
}
<%_ } else if (authenticationType === 'session') { _%>
export function login(username, password, rememberMe = false) {
const data = `j_username=${encodeURIComponent(username)
}&j_password=${encodeURIComponent(password)
}&remember-me=${rememberMe}&submit=Login`;
const headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
return {
types: [LOGIN, LOGIN_SUCCESS, LOGIN_FAIL],
promise: client => client.post('/api/authentication', data, { headers }),
afterSuccess: (dispatch, getState, response) => {
const routingState = getState().routing.locationBeforeTransitions.state || {};
hashHistory.push(routingState.nextPathname || '/');
dispatch(getSession());
}
};
}
export function logout() {
return {
types: [LOGOUT, LOGOUT_SUCCESS, LOGOUT_FAIL],
promise: client => client.post('/api/logout', {}),
afterSuccess: (dispatch, getState, response) => {
dispatch(getSession());
hashHistory.push('/');
}
};
}
<%_ } _%>
export function redirectToLoginWithMessage(messageKey) {
return (dispatch, getState) => {
dispatch(displayAuthError(messageKey));
let currentPath = getState().routing.locationBeforeTransitions.pathname;
if (currentPath === '/login') {
currentPath = getState().routing.locationBeforeTransitions.state.nextPathname || '/';
}
hashHistory.replace({
pathname: '/login',
state: { nextPathname: currentPath }
});
};
}
================================================
FILE: generators/client/templates/src/main/webapp/app/reducers/index.js
================================================
import { combineReducers } from 'redux';
import { routerReducer as routing } from 'react-router-redux';
import locale from './locale';
import authentication from './authentication';
import administration from './administration';
export default combineReducers({
authentication,
locale,
routing,
administration
});
================================================
FILE: generators/client/templates/src/main/webapp/app/reducers/locale.js
================================================
const SET_LOCALE = 'locale/SET_LOCALE';
export default function reducer(state = { locale: '<%= nativeLanguage %>' }, action) {
switch (action.type) {
case SET_LOCALE:
return {
currentLocale: action.locale
};
default:
return state;
}
}
export function setLocale(locale) {
return {
type: SET_LOCALE,
locale
};
}
================================================
FILE: generators/client/templates/src/main/webapp/app/routes.js
================================================
import React from 'react';
import { Route, IndexRoute } from 'react-router';
import AppComponent from './app';
import PrivateRoute from './shared/components/private-route/private-route';
if (typeof require.ensure !== 'function') {
require.ensure = function requireModule(deps, callback) {
callback(require);
};
}
if (process.env.NODE_ENV !== 'production') {
/* eslint-disable */
// Require async routes only in development for react-hot-reloader to work.
require('./modules/home/home');
require('./modules/login/login');
// require('./modules/account/settings');
// require('./modules/account/password');
// require('./modules/administration/gateway/gateway');
require('./modules/administration/logs/logs');
require('./modules/administration/health/health');
require('./modules/administration/metrics/metrics');
// require('./modules/administration/user-management/user-management');
require('./modules/administration/configuration/configuration');
require('./modules/administration/audits/audits');
require('./modules/administration/docs/docs');
/* eslint-enable */
}
// react-router setup with code-splitting
// More info: http://blog.mxstbr.com/2016/01/react-apps-with-pages/
export default (onLogout) => {
return (
<Route path="/" component={AppComponent}>
<IndexRoute
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, require('./modules/home/home').default);
});
}}
/>
<Route
path="/login"
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, require('./modules/login/login').default);
});
}}
/>
<Route
path="/logout"
onEnter={onLogout}
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, require('./modules/login/login').default);
});
}}
/>
{/*
<Route
path="/account/settings"
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, PrivateRoute(require('./modules/account/settings/settings').default));
});
}}
/>
<Route
path="/account/password"
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, PrivateRoute(require('./modules/account/password/password').default));
});
}}
/>
<Route
path="/admin/gateway"
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, PrivateRoute(require('./modules/administration/gateway/gateway').default));
});
}}
/>
<Route
path="/admin/user-management"
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, PrivateRoute(require('./modules/administration/user-management/user-management').default));
});
}}
/>
*/}
<Route
path="/admin/metrics"
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, PrivateRoute(require('./modules/administration/metrics/metrics').default));
});
}}
/>
<Route
path="/admin/metrics-detail"
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, require('./modules/administration/metrics/metrics-detail/metrics-detail').default);
});
}}
/>
<Route
path="/admin/health"
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, PrivateRoute(require('./modules/administration/health/health').default));
});
}}
/>
<Route
path="/admin/health-detail"
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, require('./modules/administration/health/health-detail/health-detail').default);
});
}}
/>
<Route
path="/admin/configuration"
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, PrivateRoute(require('./modules/administration/configuration/configuration').default));
});
}}
/>
<Route
path="/admin/audits"
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, PrivateRoute(require('./modules/administration/audits/audits').default));
});
}}
/>
<Route
path="/admin/logs"
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, PrivateRoute(require('./modules/administration/logs/logs').default));
});
}}
/>
<Route
path="/admin/docs"
getComponent={(nextState, cb) => {
require.ensure([], (require) => {
cb(null, PrivateRoute(require('./modules/administration/docs/docs').default));
});
}}
/>
</Route>
);
};
================================================
FILE: generators/client/templates/src/main/webapp/app/shared/components/footer/footer.js
================================================
import React, { Component } from 'react';
import Translate from 'react-translate-component';
export default class Footer extends Component {
render() {
return (
<div className="footer container">
<div className="row">
<p className="col-md-12"><Translate content="footer">My footer</Translate></p>
</div>
</div>
);
}
}
================================================
FILE: generators/client/templates/src/main/webapp/app/shared/components/header/header.js
================================================
import React, { Component, PropTypes } from 'react';
import Translate from 'react-translate-component';
import AppBar from 'material-ui/AppBar';
import Drawer from 'material-ui/Drawer';
import { List, ListItem } from 'material-ui/List';
import Subheader from 'material-ui/Subheader';
import MenuItem from 'material-ui/MenuItem';
import DropDownMenu from 'material-ui/DropDownMenu';
import {
ActionHome, ActionList, ActionVerifiedUser, DeviceAccessTime,
ActionSettings, ActionLock, ActionNoteAdd,
ActionExitToApp, CommunicationVpnKey,
SocialPersonAdd, SocialGroup, ActionAssessment,
ActionFavorite, ActionBuild, AlertAddAlert,
ActionAssignment, AvLibraryBooks
} from 'material-ui/svg-icons';
import { Link } from 'react-router';
import { locales } from '../../../config/translation';
import appConfig from '../../../config/constants';
import { HEADER_COLOR } from '../../util/global-style';
import './header.scss';
export default class Header extends Component {
static propTypes = {
isAuthenticated: PropTypes.bool.isRequired,
currentLocale: PropTypes.string.isRequired,
handleLogout: PropTypes.func.isRequired,
onLocaleChange: PropTypes.func.isRequired
};
constructor(props) {
super(props);
this.state = {
sidebarOpen: false
};
}
<%_ if (enableTranslation) { _%>
handleChange = (event, index, language) => {
this.props.onLocaleChange(language);
};
<%_ } _%>
toggleSideBar = () => {
this.setState({
sidebarOpen: !this.state.sidebarOpen
});
}
render() {
const { currentLocale, isAuthenticated, handleLogout } = this.props;
const menuListStyle = { marginLeft: 18 };
let menuItemAccountLogin = (
<Link to="/login">
<ListItem
key={2.1} innerDivStyle={menuListStyle}
primaryText={<Translate content="global.menu.account.login" />}
leftIcon={<ActionLock />}
/>
</Link>
);
let menuItemAccountRegister = (
<Link to="/register">
<ListItem
key={2.2} innerDivStyle={menuListStyle}
primaryText={<Translate content="global.menu.account.register" />}
leftIcon={<ActionNoteAdd />}
/>
</Link>
);
let menuItemEntities = null;
let menuItemAccountSettings = null;
let menuItemAccountPassword = null;
let menuItemAccountSignOut = null;
let menuItemAdministration = null;
if (isAuthenticated) {
menuItemEntities = (
<ListItem
primaryText={<Translate content="global.menu.entities.main" />}
leftIcon={<ActionList />}
initiallyOpen={false}
primaryTogglesNestedList
nestedItems={[
]}
/>
);
menuItemAccountLogin = null;
menuItemAccountRegister = null;
menuItemAccountSettings = (
<Link to="/account/settings">
<ListItem
key={2.3} innerDivStyle={menuListStyle}
primaryText={<Translate content="global.menu.account.settings" />}
leftIcon={<ActionSettings />}
/>
</Link>
);
menuItemAccountPassword = (
<Link to="/account/password">
<ListItem
key={2.4} innerDivStyle={menuListStyle}
primaryText={<Translate content="global.menu.account.password" />}
leftIcon={<CommunicationVpnKey />}
/>
</Link>
);
menuItemAccountSignOut = (
<ListItem
key={2.5} onClick={() => handleLogout()} innerDivStyle={menuListStyle}
primaryText={<Translate content="global.menu.account.logout" />}
leftIcon={<ActionExitToApp />}
/>
);
menuItemAdministration = (
<ListItem
key={4}
primaryText={<Translate content="global.menu.admin.main" />}
leftIcon={<SocialPersonAdd />}
initiallyOpen={false}
primaryTogglesNestedList
nestedItems={[
<%_ if (applicationType === 'gateway') { _%>
<Link to="/admin/gateway">
<ListItem
key={4.1} innerDivStyle={menuListStyle}
primaryText={<Translate content="global.menu.admin.gateway" />}
leftIcon={<ActionHome />}
/>
</Link>
<%_ } _%>
<Link to="/admin/user-management">
<ListItem
key={4.2} innerDivStyle={menuListStyle}
leftIcon={<SocialGroup />}
primaryText={<Translate content="global.menu.admin.userManagement" />}
/>
</Link>,
<Link to="/admin/metrics">
<ListItem
key={4.3} innerDivStyle={menuListStyle}
leftIcon={<ActionAssessment />}
primaryText={<Translate content="global.menu.admin.metrics" />}
/>
</Link>,
<Link to="/admin/health">
<ListItem
key={4.4} innerDivStyle={menuListStyle}
leftIcon={<ActionFavorite />}
primaryText={<Translate content="global.menu.admin.health" />}
/>
</Link>,
<%_ if (websocket == 'spring-websocket') { _%>
// TODO
<%_ } _%>
<Link to="/admin/configuration">
<ListItem
key={4.5} innerDivStyle={menuListStyle}
leftIcon={<ActionBuild />}
primaryText={<Translate content="global.menu.admin.configuration" />}
/>
</Link>,
<Link to="/admin/audits">
<ListItem
key={4.6} innerDivStyle={menuListStyle}
leftIcon={<AlertAddAlert />}
primaryText={<Translate content="global.menu.admin.audits" />}
/>
</Link>,
<Link to="/admin/logs">
<ListItem
key={4.7} innerDivStyle={menuListStyle}
leftIcon={<ActionAssignment />}
primaryText={<Translate content="global.menu.admin.logs" />}
/>
</Link>,
<Link to="/admin/docs">
<ListItem
key={4.8} innerDivStyle={menuListStyle}
leftIcon={<AvLibraryBooks />}
primaryText={<Translate content="global.menu.admin.apidocs" />}
/>
</Link><% if (devDatabaseType === 'h2Disk' || devDatabaseType === 'h2Memory') { %>,
<a href="/h2-console">
<ListItem
key={4.9} innerDivStyle={menuListStyle}
leftIcon={<AvLibraryBooks />}
primaryText={<Translate content="global.menu.admin.database" />}
/>
</a>
<%_ } _%>
]}
/>
);
}
return (
<div>
<div className="ribbon dev"><a href=""><Translate content="global.ribbon.dev" /></a></div>
<AppBar
title={
<div>
<Link to="/" className="brand-logo">
<span className="brand-title"><Translate content="global.title"><%= capitalizedBaseName %></Translate></span>
<span className="navbar-version">{appConfig.version}</span>
</Link>
</div>
}
onLeftIconButtonTouchTap={this.toggleSideBar}
<%_ if (enableTranslation) { _%>
iconElementRight={
<DropDownMenu value={currentLocale} onChange={this.handleChange} underlineStyle={{ borderTop: 'none' }} labelStyle={{ color: HEADER_COLOR }}>
{locales.map(lang => <MenuItem key={lang} value={lang} primaryText={lang.toUpperCase()} />)}
</DropDownMenu>
}
<%_ } _%>
/>
<Drawer open={this.state.sidebarOpen} docked={false} onRequestChange={sidebarOpen => this.setState({ sidebarOpen })}>
<List>
<Subheader>Application Menu</Subheader>
<Link to="/"><ListItem primaryText={<Translate content="global.menu.home" />} leftIcon={<ActionHome />} /></Link>
{menuItemEntities}
{menuItemAdministration}
<ListItem
primaryText={<Translate content="global.menu.account.main" />}
leftIcon={<ActionLock />}
initiallyOpen={false}
primaryTogglesNestedList key={2}
nestedItems={[
menuItemAccountLogin,
menuItemAccountRegister,
menuItemAccountSettings,
<%_ if (authenticationType == 'session') { _%>
// TODO
<%_ } _%>
menuItemAccountPassword,
menuItemAccountSignOut
]}
/>
</List>
</Drawer>
</div>
);
}
}
================================================
FILE: generators/client/templates/src/main/webapp/app/shared/components/header/header.scss
================================================
@import '../../variables';
/* ==========================================================================
Developement Ribbon
========================================================================== */
.ribbon {
background-color: rgba(170, 0, 0, 0.5);
left: -3.5em;
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
-o-transform: rotate(45deg);
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
overflow: hidden;
position: absolute;
bottom: 40px;
white-space: nowrap;
width: 15em;
z-index: 99999;
pointer-events: none;
opacity: 0.75;
a {
color: #fff;
display: block;
font-weight: 400;
margin: 1px 0;
padding: 10px 50px;
text-align: center;
text-decoration: none;
text-shadow: 0 0 5px #444;
pointer-events: none;
}
}
/* ==========================================================================
Navbar styles
========================================================================== */
.navbar-version {
font-size: 10px;
color: $header-color-secondary;
padding: 0 0 0 10px;
}
.brand-logo:hover {
text-decoration: none;
}
.brand-title {
color: $header-color;
&:hover {
color: $header-color-hover;
text-decoration: none;
}
}
.logo .logo-img {
height: 45px;
display: inline-block;
}
================================================
FILE: generators/client/templates/src/main/webapp/app/shared/components/private-route/private-route.js
================================================
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import { redirectToLoginWithMessage, getSession } from '../../../reducers/authentication';
const mapStoreToProps = store => ({
loading: store.authentication.loading,
isAuthenticated: store.authentication.isAuthenticated
});
const mapDispatchToProps = {
redirectToLoginWithMessage,
getSession
};
const privateRoute = Wrapped => connect(mapStoreToProps, mapDispatchToProps)(class extends React.Component {
static propTypes = {
getSession: PropTypes.func.isRequired,
redirectToLoginWithMessage: PropTypes.func.isRequired,
loading: PropTypes.bool.isRequired,
isAuthenticated: PropTypes.bool.isRequired
}
componentDidMount() {
this.props.getSession();
// this.redirectIfNotLogged(this.props);
}
componentWillReceiveProps(nextProps) {
// this.redirectIfNotLogged(nextProps);
}
// redirectIfNotLogged(props) {
// const { loading, isAuthenticated } = props;
// if (loading === false && !isAuthenticated) {
// // TODO fix issue with authentication redirect
// this.props.redirectToLoginWithMessage('login.messages.error.authentication');
// }
// }
render() {
const { loading, isAuthenticated } = this.props;
if (loading && !isAuthenticated) {
return (
<div className="center loader">
<div>Loading...</div>
<div>You are not authorized to view this page... <Link to="/login" className="alert-link">sign in</Link></div>
</div>
);
}
return <Wrapped {...this.props} />;
}
});
export default privateRoute;
================================================
FILE: generators/client/templates/src/main/webapp/app/shared/interceptors/axios.js
================================================
import axios from 'axios';
import { logError } from '../util/log-util';
const TIMEOUT = 10000;
const setupAxiosInterceptors = (onUnauthenticated, clearAuthToken) => {
const onRequestSuccess = (config) => {
<%_ if (authenticationType === 'oauth2') { _%>
const token = localStorage.getItem('jhi-authenticationToken') || sessionStorage.getItem('jhi-authenticationToken');
if (token && token.expires_at && token.expires_at > new Date().getTime()) {
config.headers.Authorization = `Bearer ${token.access_token}`;
}
<%_ } else if (authenticationType === 'jwt' || authenticationType === 'uaa') { _%>
const token = localStorage.getItem('jhi-authenticationToken') || sessionStorage.getItem('jhi-authenticationToken');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
<%_ } _%>
config.timeout = TIMEOUT;
return config;
};
const onResponseSuccess = response => response;
const onResponseError = (err) => {
logError(err);
const status = err.status || err.response.status;
if (status === 403 || status === 401) {
clearAuthToken();
onUnauthenticated();
}
return Promise.reject(err);
};
axios.interceptors.request.use(onRequestSuccess);
axios.interceptors.response.use(onResponseSuccess, onResponseError);
};
export default setupAxiosInterceptors;
================================================
FILE: generators/client/templates/src/main/webapp/app/shared/util/global-style.js
================================================
export const HEADER_COLOR = '#FFFFFF';
export const HEADER_COLOR_SECONDARY = '#CCCCCC';
================================================
FILE: generators/client/templates/src/main/webapp/app/shared/util/log-util.js
================================================
const enableLog = true;
export const log = (msg, data = '') => {
if (enableLog) console.info(msg, data);
};
export const logError = (msg, data = '') => {
if (enableLog) console.error(msg, data);
};
================================================
FILE: generators/client/templates/src/main/webapp/app/shared/variables.scss
================================================
$header-color: #fafafa;
$header-color-secondary: #635f5f;
$header-color-hover: lighten( $header-color, 100% );
$text-color: #333;
$side-dock-size: 65px;
================================================
FILE: generators/client/templates/src/main/webapp/index.html
================================================
<!doctype html>
<html class="no-js">
<head>
<base href="/" />
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title><%= baseName %></title>
<meta name="description" content=""><% if (enableTranslation) { %>
<meta name="google" value="notranslate"><% } %>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<!--[if lt IE 9]>
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<div id="root"></div>
<!-- Google Analytics: uncomment and change UA-XXXXX-X to be your site's ID.
<script>
(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
e.src='//www.google-analytics.com/analytics.js';
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
ga('create','UA-XXXXX-X');ga('send','pageview');
</script>-->
</body>
</html>
================================================
FILE: generators/client/templates/src/main/webapp/robots.txt
================================================
# robotstxt.org/
User-agent: *
Disallow: /api/account
Disallow: /api/account/change_password
Disallow: /api/account/sessions
Disallow: /api/audits/
Disallow: /api/logs/
Disallow: /api/users/
Disallow: /management/
Disallow: /v2/api-docs/
================================================
FILE: generators/client/templates/src/main/webapp/swagger-ui/_index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Swagger UI</title>
<link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32" />
<link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16" />
<link href='./dist/css/typography.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='./dist/css/reset.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='./dist/css/screen.css' media='screen' rel='stylesheet' type='text/css'/>
<link href='./dist/css/reset.css' media='print' rel='stylesheet' type='text/css'/>
<link href='./dist/css/print.css' media='print' rel='stylesheet' type='text/css'/>
<script src='./dist/lib/object-assign-pollyfill.js' type='text/javascript'></script>
<script src='./dist/lib/jquery-1.8.0.min.js' type='text/javascript'></script>
<script src='./dist/lib/jquery.slideto.min.js' type='text/javascript'></script>
<script src='./dist/lib/jquery.wiggle.min.js' type='text/javascript'></script>
<script src='./dist/lib/jquery.ba-bbq.min.js' type='text/javascript'></script>
<script src='./dist/lib/handlebars-4.0.5.js' type='text/javascript'></script>
<script src='./dist/lib/lodash.min.js' type='text/javascript'></script>
<script src='./dist/lib/backbone-min.js' type='text/javascript'></script>
<script src='./dist/swagger-ui.js' type='text/javascript'></script>
<script src='./dist/lib/highlight.9.1.0.pack.js' type='text/javascript'></script>
<script src='./dist/lib/highlight.9.1.0.pack.js' type='text/javascript'></script>
<script src='./dist/lib/jsoneditor.min.js' type='text/javascript'></script>
<script src='./dist/lib/marked.js' type='text/javascript'></script>
<script src='./dist/lib/swagger-oauth.js' type='text/javascript'></script>
<!-- Some basic translations -->
<!-- <script src='lang/translator.js' type='text/javascript'></script> -->
<!-- <script src='lang/ru.js' type='text/javascript'></script> -->
<!-- <script src='lang/en.js' type='text/javascript'></script> -->
<script type="text/javascript">
$(function() {
var springfox = {
"baseUrl": function() {
var urlMatches = /(.*)\/swagger-ui\/index.html.*/.exec(window.location.href);
return urlMatches[1];
},
"securityConfig": function(cb) {
$.getJSON(this.baseUrl() + "/swagger-resources/configuration/security", function(data) {
cb(data);
});
},
"uiConfig": function(cb) {
$.getJSON(this.baseUrl() + "/swagger-resources/configuration/ui", function(data) {
cb(data);
});
}
};
window.springfox = springfox;
window.oAuthRedirectUrl = springfox.baseUrl() + './dist/o2c.html'
window.springfox.uiConfig(function(data) {
window.swaggerUi = new SwaggerUi({
dom_id: "swagger-ui-container",
validatorUrl: data.validatorUrl,
supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'],
onComplete: function(swaggerApi, swaggerUi) {
initializeSpringfox();
if (window.SwaggerTranslator) {
window.SwaggerTranslator.translate();
}
$('pre code').each(function(i, e) {
hljs.highlightBlock(e)
});
},
onFailure: function(data) {
log("Unable to Load SwaggerUI");
},
docExpansion: "none",
apisSorter: "alpha",
showRequestHeaders: false
});
initializeBaseUrl();
$('#select_baseUrl').change(function() {
window.swaggerUi.headerView.trigger('update-swagger-ui', {
url: $('#select_baseUrl').val()
});
addApiKeyAuthorization();
});
function addApiKeyAuthorization() {
<%_ if (authenticationType === 'session') { _%>
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("X-XSRF-TOKEN", getCSRF(), "header");
window.swaggerUi.api.clientAuthorizations.add("key", apiKeyAuth);
<%_ } else if (authenticationType === 'oauth2') { _%>
var authToken = JSON.parse(localStorage.getItem("jhi-authenticationtoken")).access_token;
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("Authorization",
"Bearer " + authToken, "header");
window.swaggerUi.api.clientAuthorizations.add("key", apiKeyAuth);
<%_ } else if (authenticationType === 'jwt' || authenticationType === 'uaa') { _%>
var authToken = JSON.parse(localStorage.getItem("jhi-authenticationtoken") || sessionStorage.getItem("jhi-authenticationtoken"));
var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("Authorization", "Bearer " + authToken, "header");
window.swaggerUi.api.clientAuthorizations.add("bearer", apiKeyAuth);
<%_ } _%>
}
function getCSRF() {
var name = "XSRF-TOKEN=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1);
if (c.indexOf(name) != -1) return c.substring(name.length,c.length);
}
return "";
}
function log() {
if ('console' in window) {
console.log.apply(console, arguments);
}
}
function oAuthIsDefined(security) {
return security.clientId
&& security.clientSecret
&& security.appName
&& security.realm;
}
function initializeSpringfox() {
var security = {};
window.springfox.securityConfig(function(data) {
security = data;
if (typeof initOAuth == "function" && oAuthIsDefined(security)) {
initOAuth(security);
}
});
}
});
function maybePrefix(location, withRelativePath) {
var pat = /^https?:\/\//i;
if (pat.test(location)) {
return location;
}
return withRelativePath + location;
}
function initializeBaseUrl() {
var relativeLocation = springfox.baseUrl();
$('#input_baseUrl').hide();
$.getJSON(relativeLocation + "/swagger-resources", function(data) {
var $urlDropdown = $('#select_baseUrl');
$urlDropdown.empty();
$.each(data, function(i, resource) {
var option = $('<option></option>')
.attr("value", maybePrefix(resource.location, relativeLocation))
.text(resource.name + " (" + resource.location + ")");
$urlDropdown.append(option);
});
$urlDropdown.change();
});
}
});
</script>
</head>
<body class="swagger-section">
<div id='header'>
<div class="swagger-ui-wrap">
<a id="logo" href="http://swagger.io">swagger</a>
<form id='api_selector'>
<div class='input'>
<select id="select_baseUrl" name="select_baseUrl"></select>
</div>
<div class='input'><input placeholder="http://example.com/api" id="input_baseUrl" name="baseUrl" type="text"/>
</div>
</form>
</div>
</div>
<div id="message-bar" class="swagger-ui-wrap" data-sw-translate> </div>
<div id="swagger-ui-container" class="swagger-ui-wrap"></div>
</body>
</html>
================================================
FILE: generators/client/templates/webpack/webpack.common.js
================================================
/* eslint-disable */
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
/* eslint-enable */
module.exports = () => {
return {
entry: ['./src/main/webapp/app/index'],
resolve: {
extensions: [
'.js', '.jsx'
],
modules: ['node_modules']
},
module: {
rules: [
{
test: /\.json/,
loaders: ['json-loader']
}, {
test: /\.css$/,
loaders: ['style-loader', 'css-loader']
}, {
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader']
}, {
test: /\.(jpe?g|png|gif|svg|woff|woff2|ttf|eot)$/i,
loaders: [
'file-loader?hash=sha512&digest=hex&name=[hash].[ext]', {
loader: 'image-webpack-loader',
query: {
gifsicle: {
interlaced: false
},
optipng: {
optimizationLevel: 7
}
}
}
]
}
]
},
plugins: [
new CopyWebpackPlugin([
{
from: './node_modules/swagger-ui/dist',
to: 'swagger-ui/dist'
}, {
from: './src/main/webapp/swagger-ui/',
to: 'swagger-ui'
}, {
from: './src/main/webapp/static/',
to: 'static'
}, {
from: './src/main/webapp/favicon.ico',
to: 'favicon.ico'
}, {
from: './src/main/webapp/robots.txt',
to: 'robots.txt'
}
]),
new HtmlWebpackPlugin({
template: './src/main/webapp/index.html',
chunksSortMode: 'dependency',
inject: 'body'
}),
new ExtractTextPlugin('styles.css')
]
};
};
================================================
FILE: generators/client/templates/webpack/webpack.dev.js
================================================
/* eslint-disable */
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpackMerge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
/* eslint-enable */
module.exports = webpackMerge(commonConfig(), {
devtool: 'inline-source-map',
output: {
path: path.resolve('./<%= BUILD_DIR %>www'),
filename: '[name].bundle.js',
chunkFilename: '[id].chunk.js'
},
plugins: [
new webpack.NoEmitOnErrorsPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development')
}
})
],
module: {
rules: [
{
test: /\.js$/,
loaders: ['babel-loader?cacheDirectory'],
include: path.resolve('./src/main/webapp/app')
}
]
},
devServer: {
contentBase: './<%= BUILD_DIR %>www',
proxy: [
{
context: [
'/api', '/management', '/swagger-resources', '/v2/api-docs', '/h2-console'
],
target: 'http://127.0.0.1:8080',
secure: false
}, {
context: ['/websocket'],
target: 'ws://127.0.0.1:8080',
ws: true
}
]
}
});
================================================
FILE: generators/client/templates/webpack/webpack.prod.js
================================================
/* eslint-disable */
const path = require('path');
const webpack = require('webpack');
// const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpackMerge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
/* eslint-enable */
module.exports = webpackMerge(commonConfig(), {
devtool: 'source-map',
output: {
path: path.resolve('./<%= BUILD_DIR %>www'),
filename: '[name].js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendors',
minChunks(module) {
return (module.resource && module.resource.indexOf(path.resolve('node_modules')) === 0);
}
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production')
}
}),
// this conflicts with -p option
new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false
}
})
],
module: {
rules: [
{
enforce: 'pre',
test: /\.css$/,
loader: 'stripcomment-loader'
},
{
test: /\.js$/,
loaders: ['babel-loader'],
include: path.resolve('./src/main/webapp/app')
}
]
}
});
================================================
FILE: gulpfile.js
================================================
const gulp = require('gulp');
const bumper = require('gulp-bump');
const git = require('gulp-git');
const shell = require('gulp-shell');
const fs = require('fs');
const sequence = require('gulp-sequence');
const path = require('path');
const mocha = require('gulp-mocha');
const istanbul = require('gulp-istanbul');
const nsp = require('gulp-nsp');
const plumber = require('gulp-plumber');
gulp.task('nsp', (cb) => {
nsp({ package: path.resolve('package.json') }, cb);
});
gulp.task('pre-test', () => gulp.src('generators/app/index.js')
.pipe(istanbul({
includeUntested: true
}))
.pipe(istanbul.hookRequire()));
gulp.task('test', ['pre-test'], (cb) => {
let mochaErr;
gulp.src('test/*.js')
.pipe(plumber())
.pipe(mocha({ reporter: 'spec' }))
.on('error', (err) => {
mochaErr = err;
})
.pipe(istanbul.writeReports())
.on('end', () => {
cb(mochaErr);
});
});
gulp.task('bump-patch', bump('patch'));
gulp.task('bump-minor', bump('minor'));
gulp.task('bump-major', bump('major'));
gulp.task('git-commit', () => {
const v = `update to version ${version()}`;
gulp.src(['./generators/**/*', './README.md', './package.json', './gulpfile.js', './.travis.yml', './travis/**/*'])
.pipe(git.add())
.pipe(git.commit(v));
});
gulp.task('git-push', (cb) => {
const v = version();
git.push('origin', 'master', (err) => {
if (err) return cb(err);
git.tag(v, v, (err) => {
if (err) return cb(err);
git.push('origin', 'master', {
args: '--tags'
}, cb);
return true;
});
return true;
});
});
gulp.task('npm', shell.task([
'npm publish'
]));
function bump(level) {
return function () {
return gulp.src(['./package.json'])
.pipe(bumper({
type: level
}))
.pipe(gulp.dest('./'));
};
}
function version() {
return JSON.parse(fs.readFileSync('package.json', 'utf8')).version;
}
gulp.task('prepublish', ['nsp']);
gulp.task('default', ['static', 'test']);
gulp.task('deploy-patch', sequence('test', 'bump-patch', 'git-commit', 'git-push', 'npm'));
gulp.task('deploy-minor', sequence('test', 'bump-minor', 'git-commit', 'git-push', 'npm'));
gulp.task('deploy-major', sequence('test', 'bump-major', 'git-commit', 'git-push', 'npm'));
================================================
FILE: package.json
================================================
{
"name": "generator-jhipster-react",
"version": "0.0.0",
"description": "A Jhipster based generator to create react + spring boot application",
"homepage": "https://github.com/hipster-labs/generator-jhipster-react",
"author": {
"name": "Deepu KS",
"email": "d4udts@gmail.com",
"url": "https://deepu105.github.io"
},
"contributors": [
"Deepu KS <d4udts@gmail.com> (https://deepu105.github.io)",
"Sendil Kumar N <sendilkumarn@live.com> (https://sendilkumarn.js.org)",
"Yuri <yuri.kushch@gmail.com> (http://ykushch.net)",
"gdoslu (https://github.com/gdoslu)"
],
"files": [
"generators/app",
"generators/entity"
],
"main": "generators/app/index.js",
"keywords": [
"yeoman-generator",
"jhipster-module" ,
"Jhipster-react",
"JHipster",
"Java",
"Spring",
"Spring Security",
"JPA",
"Hibernate",
"ReactJS",
"Material UI",
"Material",
"Paper",
"React"
],
"dependencies": {
"chalk": "1.1.3",
"lodash": "4.17.4",
"mkdirp": "0.5.1",
"shelljs": "0.7.7",
"semver": "5.3.0",
"yeoman-generator": "1.1.1",
"generator-jhipster": "latest",
"underscore.string": "3.2.2"
},
"devDependencies": {
"gulp": "^3.6.0",
"gulp-bump": "^0.1.11",
"gulp-git": "^0.5.6",
"gulp-istanbul": "^0.9.0",
"gulp-mocha": "^2.0.0",
"gulp-nsp": "^2.1.0",
"gulp-plumber": "^1.0.0",
"gulp-rename": "^1.2.0",
"gulp-sequence": "^0.3.1",
"gulp-shell": "^0.2.11",
"eslint": "3.17.1",
"eslint-config-airbnb-base": "11.1.1",
"eslint-plugin-import": "2.2.0",
"fs-extra": "2.1.0",
"mocha": "3.2.0",
"yeoman-assert": "3.0.0",
"yeoman-test": "1.6.0"
},
"scripts": {
"pretest": "eslint .",
"lint": "eslint .",
"lint-fix": "eslint . --fix",
"test": "mocha --timeout 20000 --slow 0 --reporter spec"
},
"repository": {
"type": "git",
"url": "git+https://github.com/hipster-labs/generator-jhipster-react.git"
},
"engines": {
"node": ">=6.9.0",
"npm": ">=2.14.2"
},
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/hipster-labs/generator-jhipster-react/issues"
}
}
================================================
FILE: test/app.js
================================================
/* global describe, before, beforeEach, it*/
const path = require('path');
const assert = require('yeoman-assert');
const helpers = require('yeoman-generator').test;
describe('generator-jhipster-react:app', () => {
before((done) => {
helpers.run(path.join(__dirname, '../generators/app'))
.withOptions({ someOption: true })
.withPrompts({ someAnswer: true })
.on('end', done);
});
it('creates files', () => {
assert.file([
'dummyfile.txt'
]);
});
});
gitextract_jhdj0bxz/
├── .editorconfig
├── .eslintignore
├── .eslintrc.json
├── .gitattributes
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── generators/
│ ├── app/
│ │ ├── index.js
│ │ └── prompts.js
│ └── client/
│ ├── USAGE
│ ├── files.js
│ ├── index.js
│ ├── prompts.js
│ └── templates/
│ ├── _.babelrc
│ ├── _.editorconfig
│ ├── _.eslintrc.json
│ ├── _package.json
│ ├── _postcss.config.js
│ ├── src/
│ │ └── main/
│ │ └── webapp/
│ │ ├── 404.html
│ │ ├── app/
│ │ │ ├── app.js
│ │ │ ├── app.scss
│ │ │ ├── config/
│ │ │ │ ├── constants.js
│ │ │ │ ├── devtools.js
│ │ │ │ ├── promise-middleware.js
│ │ │ │ ├── store.js
│ │ │ │ ├── theme.js
│ │ │ │ └── translation.js
│ │ │ ├── index.js
│ │ │ ├── modules/
│ │ │ │ ├── account/
│ │ │ │ │ ├── password/
│ │ │ │ │ │ └── password.js
│ │ │ │ │ └── settings/
│ │ │ │ │ └── settings.js
│ │ │ │ ├── administration/
│ │ │ │ │ ├── audits/
│ │ │ │ │ │ └── audits.js
│ │ │ │ │ ├── configuration/
│ │ │ │ │ │ └── configuration.js
│ │ │ │ │ ├── docs/
│ │ │ │ │ │ └── docs.js
│ │ │ │ │ ├── gateway/
│ │ │ │ │ │ └── gateway.js
│ │ │ │ │ ├── health/
│ │ │ │ │ │ ├── health-detail/
│ │ │ │ │ │ │ ├── health-detail.js
│ │ │ │ │ │ │ ├── health-modal.js
│ │ │ │ │ │ │ └── index.js
│ │ │ │ │ │ └── health.js
│ │ │ │ │ ├── logs/
│ │ │ │ │ │ └── logs.js
│ │ │ │ │ ├── metrics/
│ │ │ │ │ │ ├── metrics-detail/
│ │ │ │ │ │ │ ├── index.js
│ │ │ │ │ │ │ ├── metrics-detail.js
│ │ │ │ │ │ │ └── metrics-modal.js
│ │ │ │ │ │ └── metrics.js
│ │ │ │ │ └── user-management/
│ │ │ │ │ └── user-management.js
│ │ │ │ ├── home/
│ │ │ │ │ ├── home.js
│ │ │ │ │ ├── home.scss
│ │ │ │ │ └── index.js
│ │ │ │ └── login/
│ │ │ │ ├── index.js
│ │ │ │ ├── login-modal.js
│ │ │ │ └── login.js
│ │ │ ├── reducers/
│ │ │ │ ├── account.js
│ │ │ │ ├── administration.js
│ │ │ │ ├── authentication.js
│ │ │ │ ├── index.js
│ │ │ │ └── locale.js
│ │ │ ├── routes.js
│ │ │ └── shared/
│ │ │ ├── components/
│ │ │ │ ├── footer/
│ │ │ │ │ └── footer.js
│ │ │ │ ├── header/
│ │ │ │ │ ├── header.js
│ │ │ │ │ └── header.scss
│ │ │ │ └── private-route/
│ │ │ │ └── private-route.js
│ │ │ ├── interceptors/
│ │ │ │ └── axios.js
│ │ │ ├── util/
│ │ │ │ ├── global-style.js
│ │ │ │ └── log-util.js
│ │ │ └── variables.scss
│ │ ├── index.html
│ │ ├── robots.txt
│ │ └── swagger-ui/
│ │ └── _index.html
│ └── webpack/
│ ├── webpack.common.js
│ ├── webpack.dev.js
│ └── webpack.prod.js
├── gulpfile.js
├── package.json
└── test/
└── app.js
SYMBOL INDEX (192 symbols across 36 files)
FILE: generators/app/index.js
method displayLogo (line 74) | displayLogo() {
method checkJava (line 78) | checkJava() {
method checkNode (line 82) | checkNode() {
method checkGit (line 86) | checkGit() {
method checkGitConnection (line 90) | checkGitConnection() {
method checkYarn (line 94) | checkYarn() {
method validate (line 98) | validate() {
method setupconsts (line 104) | setupconsts() {
method setup (line 145) | setup() {
method composeServer (line 175) | composeServer() {
method composeClient (line 185) | composeClient() {
method setSharedConfigOptions (line 202) | setSharedConfigOptions() {
method composeLanguages (line 221) | composeLanguages() {
method saveConfig (line 226) | saveConfig() {
method cleanup (line 246) | cleanup() {
FILE: generators/app/prompts.js
function askForInsightOptIn (line 11) | function askForInsightOptIn() {
function askForApplicationType (line 31) | function askForApplicationType() {
function askForModuleName (line 71) | function askForModuleName() {
function askFori18n (line 79) | function askFori18n() {
function askForTestOpts (line 86) | function askForTestOpts() {
FILE: generators/client/files.js
constant MAIN_SRC_DIR (line 5) | const MAIN_SRC_DIR = constants.CLIENT_MAIN_SRC_DIR;
constant REACT_DIR (line 7) | const REACT_DIR = constants.ANGULAR_DIR;
function writeFiles (line 388) | function writeFiles() {
FILE: generators/client/index.js
constant QUESTIONS (line 16) | const QUESTIONS = constants.CLIENT_QUESTIONS;
method displayLogo (line 133) | displayLogo() {
method setupClientconsts (line 139) | setupClientconsts() {
method setSharedConfigOptions (line 192) | setSharedConfigOptions() {
method insight (line 202) | insight() {
method configureGlobal (line 212) | configureGlobal() {
method saveConfig (line 226) | saveConfig() {
method getSharedConfigOptions (line 240) | getSharedConfigOptions() {
method composeLanguages (line 299) | composeLanguages() {
method writing (line 306) | writing() {
method install (line 310) | install() {
method end (line 335) | end() {
FILE: generators/client/prompts.js
function askForModuleName (line 8) | function askForModuleName() {
function askForClientSideOpts (line 14) | function askForClientSideOpts() {
function askFori18n (line 32) | function askFori18n() {
FILE: generators/client/templates/src/main/webapp/app/app.js
class App (line 15) | class App extends Component {
method constructor (line 30) | constructor(props) {
method componentDidMount (line 35) | componentDidMount() {
method handleLogout (line 39) | handleLogout() {
method render (line 43) | render() {
FILE: generators/client/templates/src/main/webapp/app/config/promise-middleware.js
function promiseMiddleware (line 4) | function promiseMiddleware({ dispatch, getState }) {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/audits/audits.js
class AuditsPage (line 9) | class AuditsPage extends Component {
method constructor (line 11) | constructor(props) {
method componentDidMount (line 16) | componentDidMount() {
method getAuditList (line 20) | getAuditList() {
method render (line 26) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/configuration/configuration.js
class ConfigurationPage (line 9) | class ConfigurationPage extends Component {
method constructor (line 11) | constructor(props) {
method componentDidMount (line 16) | componentDidMount() {
method getConfigurationList (line 21) | getConfigurationList() {
method render (line 28) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/docs/docs.js
class DocsPage (line 4) | class DocsPage extends Component {
method render (line 6) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/gateway/gateway.js
class GatewayPage (line 7) | class GatewayPage extends Component {
method constructor (line 9) | constructor(props) {
method componentDidMount (line 14) | componentDidMount() {
method getRoutes (line 18) | getRoutes() {
method render (line 24) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/health/health-detail/health-detail.js
class Health (line 7) | class Health extends Component {
method constructor (line 13) | constructor(props) {
method componentWillMount (line 20) | componentWillMount() {
method componentWillReceiveProps (line 26) | componentWillReceiveProps(nextProps) {
method render (line 37) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/health/health-detail/health-modal.js
class HealthModal (line 8) | class HealthModal extends Component {
method constructor (line 15) | constructor(props, context) {
method render (line 19) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/health/health-detail/index.js
method getComponent (line 3) | getComponent(nextState, cb) {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/health/health.js
class HealthPage (line 12) | class HealthPage extends Component {
method constructor (line 14) | constructor(props) {
method componentDidMount (line 21) | componentDidMount() {
method getSystemHealth (line 25) | getSystemHealth() {
method getSystemHealthInfo (line 31) | getSystemHealthInfo(healthObject) {
method getModuleName (line 36) | getModuleName(path, name) {
method addHealthObject (line 50) | addHealthObject(result, isLeaf, healthObject, name) {
method flattenHealthData (line 85) | flattenHealthData(result, path, data): any {
method transformHealthData (line 102) | transformHealthData(data) {
method getBaseName (line 108) | getBaseName(name) {
method getSubSystemName (line 116) | getSubSystemName() {
method hasSubSystem (line 126) | hasSubSystem(healthObject) {
method isHealthObject (line 139) | isHealthObject(healthObject) {
method render (line 151) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/logs/logs.js
class LogsPage (line 7) | class LogsPage extends Component {
method constructor (line 9) | constructor(props) {
method componentDidMount (line 15) | componentDidMount() {
method getLogs (line 19) | getLogs() {
method changeLevel (line 25) | changeLevel(loggerName, level) {
method render (line 29) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/metrics/metrics-detail/index.js
method getComponent (line 3) | getComponent(nextState, cb) {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/metrics/metrics-detail/metrics-detail.js
class Metrics (line 7) | class Metrics extends Component {
method constructor (line 13) | constructor(props) {
method componentWillMount (line 20) | componentWillMount() {
method componentWillReceiveProps (line 26) | componentWillReceiveProps(nextProps) {
method render (line 37) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/metrics/metrics-detail/metrics-modal.js
class MetricsModal (line 8) | class MetricsModal extends Component {
method constructor (line 15) | constructor(props, context) {
method render (line 19) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/metrics/metrics.js
class MetricsPage (line 12) | class MetricsPage extends Component {
method constructor (line 14) | constructor(props) {
method componentDidMount (line 21) | componentDidMount() {
method getMetrics (line 25) | getMetrics() {
method getThreadDump (line 31) | getThreadDump() {
method getStats (line 36) | getStats(metrics) {
method render (line 61) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/administration/user-management/user-management.js
class UserManagement (line 7) | class UserManagement extends Component {
method constructor (line 9) | constructor(props) {
method componentDidMount (line 14) | componentDidMount() {
method getUserList (line 18) | getUserList() {
method render (line 24) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/home/home.js
class Home (line 11) | class Home extends Component {
method constructor (line 17) | constructor(props) {
method componentWillMount (line 24) | componentWillMount() {
method componentWillReceiveProps (line 28) | componentWillReceiveProps(nextProps) {
method render (line 34) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/home/index.js
method getComponent (line 3) | getComponent(nextState, cb) {
FILE: generators/client/templates/src/main/webapp/app/modules/login/index.js
method getComponent (line 3) | getComponent(nextState, cb) {
method onEnter (line 12) | onEnter(onLogout) {
method getComponent (line 15) | getComponent(nextState, cb) {
FILE: generators/client/templates/src/main/webapp/app/modules/login/login-modal.js
class LoginModal (line 7) | class LoginModal extends Component {
method constructor (line 22) | constructor(props, context) {
method handleSubmit (line 33) | handleSubmit() {
method handleUsernameChange (line 39) | handleUsernameChange(event) {
method handlePasswordChange (line 43) | handlePasswordChange(event) {
method render (line 47) | render() {
FILE: generators/client/templates/src/main/webapp/app/modules/login/login.js
class Login (line 8) | class Login extends Component {
method constructor (line 15) | constructor(props) {
method componentWillMount (line 23) | componentWillMount() {
method componentWillReceiveProps (line 29) | componentWillReceiveProps(nextProps) {
method handleLogin (line 35) | handleLogin(username, password, rememberMe = false) {
method render (line 43) | render() {
FILE: generators/client/templates/src/main/webapp/app/reducers/administration.js
constant FETCH (line 1) | const FETCH = 'administration/FETCH';
constant FETCH_SUCCESS (line 2) | const FETCH_SUCCESS = 'administration/FETCH_SUCCESS';
constant FETCH_FAIL (line 3) | const FETCH_FAIL = 'administration/FETCH_FAIL';
constant FETCH_GATEWAY_ROUTE (line 4) | const FETCH_GATEWAY_ROUTE = 'administration/FETCH_GATEWAY_ROUTE';
constant FETCH_LOGS (line 5) | const FETCH_LOGS = 'administration/FETCH_LOGS';
constant FETCH_LOGS_CHANGE_LEVEL (line 6) | const FETCH_LOGS_CHANGE_LEVEL = 'administration/FETCH_LOGS_CHANGE_LEVEL';
constant FETCH_HEALTH (line 7) | const FETCH_HEALTH = 'administration/FETCH_HEALTH';
constant FETCH_HEALTH_INFO (line 8) | const FETCH_HEALTH_INFO = 'administration/FETCH_HEALTH_INFO';
constant FETCH_METRICS (line 9) | const FETCH_METRICS = 'administration/FETCH_METRICS';
constant FETCH_THREAD_DUMP (line 10) | const FETCH_THREAD_DUMP = 'administration/FETCH_THREAD_DUMP';
constant FETCH_USERS (line 11) | const FETCH_USERS = 'administration/FETCH_USERS';
constant FETCH_CONFIGURATIONS (line 12) | const FETCH_CONFIGURATIONS = 'administration/FETCH_CONFIGURATIONS';
constant FETCH_ENV (line 13) | const FETCH_ENV = 'administration/FETCH_ENV';
constant FETCH_AUDITS (line 14) | const FETCH_AUDITS = 'administration/FETCH_AUDITS';
constant FETCH_API_DOCS (line 15) | const FETCH_API_DOCS = 'administration/FETCH_API_DOCS';
function reducer (line 46) | function reducer(state = initialState, action) {
function gatewayRoutes (line 143) | function gatewayRoutes() {
function getLoggers (line 151) | function getLoggers() {
function systemHealth (line 158) | function systemHealth() {
function systemHealthInfo (line 165) | function systemHealthInfo(healthObj) {
function systemMetrics (line 172) | function systemMetrics() {
function systemThreadDump (line 179) | function systemThreadDump() {
function changeLogLevel (line 186) | function changeLogLevel(name, level) {
function getUsers (line 198) | function getUsers(page = 0, size = 10, sort = 'id, asc') {
function getConfigurations (line 205) | function getConfigurations() {
function getEnv (line 212) | function getEnv() {
function getAudits (line 219) | function getAudits(fromDate, toDate, page = 0, size = 20) {
function getApiDocs (line 233) | function getApiDocs() {
FILE: generators/client/templates/src/main/webapp/app/reducers/authentication.js
constant LOGIN (line 3) | const LOGIN = 'authentication/LOGIN';
constant LOGIN_SUCCESS (line 4) | const LOGIN_SUCCESS = 'authentication/LOGIN_SUCCESS';
constant LOGIN_FAIL (line 5) | const LOGIN_FAIL = 'authentication/LOGIN_FAIL';
constant GET_SESSION (line 7) | const GET_SESSION = 'authentication/GET_SESSION';
constant GET_SESSION_SUCCESS (line 8) | const GET_SESSION_SUCCESS = 'authentication/GET_SESSION_SUCCESS';
constant GET_SESSION_FAIL (line 9) | const GET_SESSION_FAIL = 'authentication/GET_SESSION_FAIL';
constant LOGOUT (line 11) | const LOGOUT = 'authentication/LOGOUT';
constant LOGOUT_SUCCESS (line 12) | const LOGOUT_SUCCESS = 'authentication/LOGOUT_SUCCESS';
constant LOGOUT_FAIL (line 13) | const LOGOUT_FAIL = 'authentication/LOGOUT_FAIL';
constant ERROR_MESSAGE (line 15) | const ERROR_MESSAGE = 'authentication/ERROR_MESSAGE';
function reducer (line 28) | function reducer(state = initialState, action) {
function displayAuthError (line 77) | function displayAuthError(message) {
function getSession (line 81) | function getSession() {
function clearAuthToken (line 88) | function clearAuthToken() {
function logout (line 123) | function logout() {
function logout (line 155) | function logout() {
function logout (line 184) | function logout() {
FILE: generators/client/templates/src/main/webapp/app/reducers/locale.js
constant SET_LOCALE (line 1) | const SET_LOCALE = 'locale/SET_LOCALE';
function reducer (line 3) | function reducer(state = { locale: '<%= nativeLanguage %>' }, action) {
function setLocale (line 14) | function setLocale(locale) {
FILE: generators/client/templates/src/main/webapp/app/shared/components/footer/footer.js
class Footer (line 4) | class Footer extends Component {
method render (line 5) | render() {
FILE: generators/client/templates/src/main/webapp/app/shared/components/header/header.js
method constructor (line 33) | constructor(props) {
FILE: generators/client/templates/src/main/webapp/app/shared/components/private-route/private-route.js
method componentDidMount (line 24) | componentDidMount() {
method componentWillReceiveProps (line 29) | componentWillReceiveProps(nextProps) {
method render (line 41) | render() {
FILE: generators/client/templates/src/main/webapp/app/shared/interceptors/axios.js
constant TIMEOUT (line 4) | const TIMEOUT = 10000;
FILE: generators/client/templates/src/main/webapp/app/shared/util/global-style.js
constant HEADER_COLOR (line 1) | const HEADER_COLOR = '#FFFFFF';
constant HEADER_COLOR_SECONDARY (line 2) | const HEADER_COLOR_SECONDARY = '#CCCCCC';
FILE: generators/client/templates/webpack/webpack.prod.js
method minChunks (line 18) | minChunks(module) {
FILE: gulpfile.js
function bump (line 68) | function bump(level) {
function version (line 78) | function version() {
Condensed preview — 74 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (191K chars).
[
{
"path": ".editorconfig",
"chars": 171,
"preview": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newli"
},
{
"path": ".eslintignore",
"chars": 31,
"preview": "generators/**/templates\ntravis\n"
},
{
"path": ".eslintrc.json",
"chars": 766,
"preview": "{\n \"env\": {\n \"node\": true,\n \"es6\": true\n },\n \"extends\": [\"airbnb-base\"],\n \"rules\": {\n \""
},
{
"path": ".gitattributes",
"chars": 12,
"preview": "* text=auto\n"
},
{
"path": ".gitignore",
"chars": 141,
"preview": "node_modules\ncoverage\n.DS_Store\n.vscode/\n.idea\n*.iml\n*.ipr\n*.iws\natlassian-ide-plugin.xml\n/.project\ntest/temp/\n*debug.lo"
},
{
"path": ".travis.yml",
"chars": 34,
"preview": "language: node_js\nnode_js:\n - v6\n"
},
{
"path": "LICENSE",
"chars": 640,
"preview": "Copyright 2016 Deepu KS <d4udts@gmail.com> (http://deepu105.github.io) <d4udts@gmail.com> (http://deepu105.github.io)\n\nL"
},
{
"path": "README.md",
"chars": 3117,
"preview": "# DEPRECATED\n\nThis module is now integrated into `generator-jhipster` repository as React support is now planned in the "
},
{
"path": "generators/app/index.js",
"chars": 9861,
"preview": "const util = require('util');\nconst generator = require('yeoman-generator');\nconst chalk = require('chalk');\nconst BaseG"
},
{
"path": "generators/app/prompts.js",
"chars": 3060,
"preview": "const chalk = require('chalk');\n\nmodule.exports = {\n askForInsightOptIn,\n askForApplicationType,\n askForModuleName,\n "
},
{
"path": "generators/client/USAGE",
"chars": 181,
"preview": "Description:\n Creates a new JHipster React client side application based on the selected options\n\nExample:\n yo jhi"
},
{
"path": "generators/client/files.js",
"chars": 13013,
"preview": "const mkdirp = require('mkdirp');\nconst constants = require('generator-jhipster/generators/generator-constants');\n\n/* Co"
},
{
"path": "generators/client/index.js",
"chars": 11972,
"preview": "const util = require('util');\nconst generator = require('yeoman-generator');\nconst chalk = require('chalk');\nconst _ = r"
},
{
"path": "generators/client/prompts.js",
"chars": 729,
"preview": "\nmodule.exports = {\n askForModuleName,\n askForClientSideOpts,\n askFori18n\n};\n\nfunction askForModuleName() {\n if (thi"
},
{
"path": "generators/client/templates/_.babelrc",
"chars": 244,
"preview": "{\n \"presets\": [\"react\", \"es2015\", \"stage-1\"],\n \"plugins\": [\n [\"babel-plugin-module-alias\", [\n { \"src\": \"./src/"
},
{
"path": "generators/client/templates/_.editorconfig",
"chars": 520,
"preview": "# EditorConfig helps developers define and maintain consistent\n# coding styles between different editors and IDEs\n# edit"
},
{
"path": "generators/client/templates/_.eslintrc.json",
"chars": 902,
"preview": "{\n \"extends\": [\n \"airbnb\",\n \"plugin:ava/recommended\"\n ],\n \"parser\": \"babel-eslint\",\n \"plugins\": [\n \"ava\"\n "
},
{
"path": "generators/client/templates/_package.json",
"chars": 3105,
"preview": "{\n \"name\": \"react-client\",\n \"version\": \"0.0.0\",\n \"description\": \"React client app\",\n \"private\": true,\n \"cacheDirect"
},
{
"path": "generators/client/templates/_postcss.config.js",
"chars": 36,
"preview": "module.exports = {\n plugins: []\n};\n"
},
{
"path": "generators/client/templates/src/main/webapp/404.html",
"chars": 1291,
"preview": "<!doctype html>\n<html lang=\"<%= nativeLanguage %>\">\n<head>\n <meta charset=\"utf-8\">\n <title>Page Not Found</title>\n"
},
{
"path": "generators/client/templates/src/main/webapp/app/app.js",
"chars": 1890,
"preview": "import 'flexboxgrid/dist/flexboxgrid.css';\nimport React, { Component, PropTypes } from 'react';\nimport { connect } from "
},
{
"path": "generators/client/templates/src/main/webapp/app/app.scss",
"chars": 4605,
"preview": "@import 'shared/variables';\n\nbody {\n background: #fafafa;\n font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif"
},
{
"path": "generators/client/templates/src/main/webapp/app/config/constants.js",
"chars": 72,
"preview": "const config = {\n version: '0.0.1-SNAPSHOT'\n};\n\nexport default config;\n"
},
{
"path": "generators/client/templates/src/main/webapp/app/config/devtools.js",
"chars": 490,
"preview": "import React from 'react';\n/* eslint-disable */\nimport { createDevTools } from 'redux-devtools';\nimport LogMonitor from "
},
{
"path": "generators/client/templates/src/main/webapp/app/config/promise-middleware.js",
"chars": 921,
"preview": "import axios from 'axios';\nimport { logError } from '../shared/util/log-util';\n\nexport default function promiseMiddlewar"
},
{
"path": "generators/client/templates/src/main/webapp/app/config/store.js",
"chars": 890,
"preview": "import { createStore, applyMiddleware, compose } from 'redux';\nimport reducer from '../reducers';\nimport DevTools from '"
},
{
"path": "generators/client/templates/src/main/webapp/app/config/theme.js",
"chars": 586,
"preview": "import {\n cyan500, cyan700,\n pinkA200,\n grey100, grey300, grey400, grey500,\n white, darkBlack, fullBlack\n} from 'mat"
},
{
"path": "generators/client/templates/src/main/webapp/app/config/translation.js",
"chars": 1173,
"preview": "import counterpart from 'counterpart';\nimport { setLocale } from '../reducers/locale';\n\nconst mergeTranslations = (requi"
},
{
"path": "generators/client/templates/src/main/webapp/app/index.js",
"chars": 1337,
"preview": "import React from 'react';\nimport { render } from 'react-dom';\nimport { Provider } from 'react-redux';\nimport { bindActi"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/account/password/password.js",
"chars": 0,
"preview": ""
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/account/settings/settings.js",
"chars": 0,
"preview": ""
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/audits/audits.js",
"chars": 2254,
"preview": "import React, { Component } from 'react';\nimport { connect } from 'react-redux';\nimport Translate from 'react-translate-"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/configuration/configuration.js",
"chars": 4365,
"preview": "import React, { Component } from 'react';\nimport { connect } from 'react-redux';\n\nimport { Table, TableBody, TableHeader"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/docs/docs.js",
"chars": 400,
"preview": "import React, { Component } from 'react';\nimport Translate from 'react-translate-component';\n\nexport class DocsPage exte"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/gateway/gateway.js",
"chars": 3316,
"preview": "import React, { Component } from 'react';\nimport { connect } from 'react-redux';\nimport Translate from 'react-translate-"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/health/health-detail/health-detail.js",
"chars": 985,
"preview": "import React, { Component, PropTypes } from 'react';\nimport { connect } from 'react-redux';\nimport { hashHistory } from "
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/health/health-detail/health-modal.js",
"chars": 1966,
"preview": "import React, { Component, PropTypes } from 'react';\nimport Dialog from 'material-ui/Dialog';\nimport FlatButton from 'ma"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/health/health-detail/index.js",
"chars": 189,
"preview": "export const HealthRoute = {\n path: 'admin/health-detail',\n getComponent(nextState, cb) {\n require.ensure([], (requ"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/health/health.js",
"chars": 6072,
"preview": "import React, { Component } from 'react';\nimport { connect } from 'react-redux';\nimport { Link, hashHistory } from 'reac"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/logs/logs.js",
"chars": 2879,
"preview": "import React, { Component } from 'react';\nimport { connect } from 'react-redux';\nimport Translate from 'react-translate-"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/metrics/metrics-detail/index.js",
"chars": 192,
"preview": "export const MetricsRoute = {\n path: 'admin/metrics-detail',\n getComponent(nextState, cb) {\n require.ensure([], (re"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/metrics/metrics-detail/metrics-detail.js",
"chars": 1007,
"preview": "import React, { Component, PropTypes } from 'react';\nimport { connect } from 'react-redux';\nimport { hashHistory } from "
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/metrics/metrics-detail/metrics-modal.js",
"chars": 3490,
"preview": "import React, { Component, PropTypes } from 'react';\nimport Dialog from 'material-ui/Dialog';\nimport FlatButton from 'ma"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/metrics/metrics.js",
"chars": 21023,
"preview": "import React, { Component } from 'react';\nimport { connect } from 'react-redux';\nimport { hashHistory } from 'react-rout"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/administration/user-management/user-management.js",
"chars": 5932,
"preview": "import React, { Component } from 'react';\nimport { connect } from 'react-redux';\n\nimport Translate from 'react-translate"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/home/home.js",
"chars": 4470,
"preview": "import React, { Component } from 'react';\nimport { Link } from 'react-router';\nimport Translate from 'react-translate-co"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/home/home.scss",
"chars": 428,
"preview": "\n/* ==========================================================================\nMain page styles\n========================"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/home/index.js",
"chars": 199,
"preview": "export default {\n /* Path not specified as this is the index route */\n getComponent(nextState, cb) {\n require.ensur"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/login/index.js",
"chars": 378,
"preview": "export const LoginRoute = {\n path: 'login',\n getComponent(nextState, cb) {\n require.ensure([], (require) => {\n "
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/login/login-modal.js",
"chars": 3522,
"preview": "import React, { Component, PropTypes } from 'react';\nimport Dialog from 'material-ui/Dialog';\nimport FlatButton from 'ma"
},
{
"path": "generators/client/templates/src/main/webapp/app/modules/login/login.js",
"chars": 1257,
"preview": "import React, { Component, PropTypes } from 'react';\nimport { connect } from 'react-redux';\nimport { browserHistory } fr"
},
{
"path": "generators/client/templates/src/main/webapp/app/reducers/account.js",
"chars": 0,
"preview": ""
},
{
"path": "generators/client/templates/src/main/webapp/app/reducers/administration.js",
"chars": 5389,
"preview": "const FETCH = 'administration/FETCH';\nconst FETCH_SUCCESS = 'administration/FETCH_SUCCESS';\nconst FETCH_FAIL = 'administ"
},
{
"path": "generators/client/templates/src/main/webapp/app/reducers/authentication.js",
"chars": 6390,
"preview": "import { hashHistory } from 'react-router';\n\nconst LOGIN = 'authentication/LOGIN';\nconst LOGIN_SUCCESS = 'authentication"
},
{
"path": "generators/client/templates/src/main/webapp/app/reducers/index.js",
"chars": 324,
"preview": "import { combineReducers } from 'redux';\nimport { routerReducer as routing } from 'react-router-redux';\n\nimport locale f"
},
{
"path": "generators/client/templates/src/main/webapp/app/reducers/locale.js",
"chars": 362,
"preview": "const SET_LOCALE = 'locale/SET_LOCALE';\n\nexport default function reducer(state = { locale: '<%= nativeLanguage %>' }, ac"
},
{
"path": "generators/client/templates/src/main/webapp/app/routes.js",
"chars": 5191,
"preview": "import React from 'react';\nimport { Route, IndexRoute } from 'react-router';\n\nimport AppComponent from './app';\nimport P"
},
{
"path": "generators/client/templates/src/main/webapp/app/shared/components/footer/footer.js",
"chars": 369,
"preview": "import React, { Component } from 'react';\nimport Translate from 'react-translate-component';\n\nexport default class Foote"
},
{
"path": "generators/client/templates/src/main/webapp/app/shared/components/header/header.js",
"chars": 8797,
"preview": "import React, { Component, PropTypes } from 'react';\nimport Translate from 'react-translate-component';\nimport AppBar fr"
},
{
"path": "generators/client/templates/src/main/webapp/app/shared/components/header/header.scss",
"chars": 1373,
"preview": "@import '../../variables';\n\n/* ==========================================================================\nDevelopement R"
},
{
"path": "generators/client/templates/src/main/webapp/app/shared/components/private-route/private-route.js",
"chars": 1662,
"preview": "import React, { PropTypes } from 'react';\nimport { connect } from 'react-redux';\nimport { Link } from 'react-router';\n\ni"
},
{
"path": "generators/client/templates/src/main/webapp/app/shared/interceptors/axios.js",
"chars": 1353,
"preview": "import axios from 'axios';\nimport { logError } from '../util/log-util';\n\nconst TIMEOUT = 10000;\nconst setupAxiosIntercep"
},
{
"path": "generators/client/templates/src/main/webapp/app/shared/util/global-style.js",
"chars": 88,
"preview": "export const HEADER_COLOR = '#FFFFFF';\nexport const HEADER_COLOR_SECONDARY = '#CCCCCC';\n"
},
{
"path": "generators/client/templates/src/main/webapp/app/shared/util/log-util.js",
"chars": 204,
"preview": "const enableLog = true;\n\nexport const log = (msg, data = '') => {\n if (enableLog) console.info(msg, data);\n};\n\nexport c"
},
{
"path": "generators/client/templates/src/main/webapp/app/shared/variables.scss",
"chars": 154,
"preview": "$header-color: #fafafa;\n$header-color-secondary: #635f5f;\n$header-color-hover: lighten( $header-color, 100% );\n$text-col"
},
{
"path": "generators/client/templates/src/main/webapp/index.html",
"chars": 1275,
"preview": "<!doctype html>\n<html class=\"no-js\">\n<head>\n <base href=\"/\" />\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-"
},
{
"path": "generators/client/templates/src/main/webapp/robots.txt",
"chars": 239,
"preview": "# robotstxt.org/\n\nUser-agent: *\nDisallow: /api/account\nDisallow: /api/account/change_password\nDisallow: /api/account/ses"
},
{
"path": "generators/client/templates/src/main/webapp/swagger-ui/_index.html",
"chars": 8572,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"UTF-8\">\n <title>Swagger UI</title>\n <link rel=\"icon\" type=\"image/"
},
{
"path": "generators/client/templates/webpack/webpack.common.js",
"chars": 1931,
"preview": "/* eslint-disable */\nconst CopyWebpackPlugin = require('copy-webpack-plugin');\nconst HtmlWebpackPlugin = require('html-w"
},
{
"path": "generators/client/templates/webpack/webpack.dev.js",
"chars": 1214,
"preview": "/* eslint-disable */\nconst path = require('path');\nconst webpack = require('webpack');\nconst HtmlWebpackPlugin = require"
},
{
"path": "generators/client/templates/webpack/webpack.prod.js",
"chars": 1190,
"preview": "/* eslint-disable */\nconst path = require('path');\nconst webpack = require('webpack');\n// const HtmlWebpackPlugin = requ"
},
{
"path": "gulpfile.js",
"chars": 2283,
"preview": "const gulp = require('gulp');\nconst bumper = require('gulp-bump');\nconst git = require('gulp-git');\nconst shell = requir"
},
{
"path": "package.json",
"chars": 2202,
"preview": "{\n \"name\": \"generator-jhipster-react\",\n \"version\": \"0.0.0\",\n \"description\": \"A Jhipster based generator to create rea"
},
{
"path": "test/app.js",
"chars": 497,
"preview": "/* global describe, before, beforeEach, it*/\nconst path = require('path');\nconst assert = require('yeoman-assert');\ncons"
}
]
About this extraction
This page contains the full source code of the hipster-labs/generator-jhipster-react GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 74 files (173.0 KB), approximately 43.3k tokens, and a symbol index with 192 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.