├── .babelrc
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── __tests__
└── reactTreeFunctions.test.js
├── generateContents
├── index-html.js
├── react-generate-App-css.js
├── react-generate-app-test.js
├── react-generate-content.js
├── react-generate-index-css.js
├── react-generate-index.js
├── react-generate-logo-svg.js
├── react-generate-registerServiceWorker.js
├── react-generate-stateless-component.js
├── redux-generate-action-creators.js
├── redux-generate-components.js
├── redux-generate-container.js
├── redux-generate-reducers.js
└── redux-index.js
├── index.html
├── index.js
├── main.js
├── node_modules
├── .bin
│ ├── acorn
│ ├── ansi-html
│ ├── atob
│ ├── babylon
│ ├── browserslist
│ ├── cssesc
│ ├── csso
│ ├── errno
│ ├── escodegen
│ ├── esgenerate
│ ├── esparse
│ ├── esvalidate
│ ├── handlebars
│ ├── he
│ ├── html-minifier
│ ├── import-local-fixture
│ ├── internal-ip
│ ├── is-ci
│ ├── jest
│ ├── jest-runtime
│ ├── js-yaml
│ ├── jsesc
│ ├── json5
│ ├── loose-envify
│ ├── miller-rabin
│ ├── mime
│ ├── mkdirp
│ ├── multicast-dns
│ ├── regjsparser
│ ├── rimraf
│ ├── sane
│ ├── semver
│ ├── sha.js
│ ├── sshpk-conv
│ ├── sshpk-sign
│ ├── sshpk-verify
│ ├── strip-indent
│ ├── svgo
│ ├── uglifyjs
│ ├── uuid
│ ├── watch
│ ├── webpack
│ ├── webpack-dev-server
│ └── which
└── react-sortable-tree
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── dist
│ └── main.js
│ ├── package.json
│ ├── style.css
│ └── style.css.map
├── package-lock.json
├── package.json
├── src
├── components
│ ├── App.js
│ ├── NotFound.js
│ ├── react-interface.js
│ ├── react-tree.js
│ ├── redux-interface.js
│ └── redux-tree.js
├── drawing.svg
├── gitHubIcon.png
├── reactLogo.png
├── reactVelocity.png
├── reactVelocity.svg
├── reactVelocity_black.svg
└── reduxLogo.png
├── styles
└── styles.css
├── test.js
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "env",
4 | "react"
5 | ],
6 | "plugins": [
7 | "transform-class-properties",
8 | "transform-object-rest-spread"
9 |
10 | ]
11 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_STORE
2 | Thumbs.db
3 | .Trashes
4 | node_modules
5 | package-lock.json
6 | build
7 | node_modules
8 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM godronus/ubuntu-csx
2 | WORKDIR /app
3 | COPY . .
4 | RUN npm install
5 | RUN npm run build
6 |
7 |
8 |
9 | #FROM mhart/alpine-node
10 | #RUN yarn global add serve
11 | #WORKDIR /app
12 | #COPY --from=0 /app/build .
13 | #CMD [“serve”, “-p 80”, “-s”, “.”]
14 | EXPOSE 8080
15 | EXPOSE 3000
16 | CMD ["npm", "start" ]
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 apjs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Velocity
2 |
3 | 
4 |
5 |
6 | React Velocity is an application that allows you to visualize your React project's component hierarchy before exporting the requisite boilerplate code. The two main features allow you to create React-based and React/Redux-based production level projects. This tool enables you to convert between stateless and stateful, class-based components. Your export will include a 'src' folder containing all of the same files that exist in the src folder of 'create-react-app'. Additionally, you will have a 'components' folder that contains your stateful and stateless components. Feel free to replace the 'src' folder in create-react-app with your newly exported 'src' folder from React Velocity.
7 |
8 | Within the Redux feature of the app, you can add action creators to your actions folder, reducers to your reducers folder, and containers and components to your containers and components folders, respectively. The simple design makes it user-friendly and intuitive to use for developers who work with React or it may be used by those who are just beginning their journey building Single Page Applications.
9 |
10 |
11 | ## Usage
12 |
13 | To get started, fork -> clone -> npm install -> npm start the project onto your machine and run it in localhost and select one of the two features that you wish to work in. You may also visit [reactvelocity.com](http://reactvelocity.com) but it is recommended to use this master repo for the most recent version as there can be delays in the website update. The cyan page allows you to begin adding components for a React-based application and the purple page allows you to add a layer of Redux functionality. In React mode, you can toggle between stateful and stateless components. Redux mode allows you to add much more including reducers, actions, and containers all while preserving the ability to add functional and presentational components.
14 |
15 |
16 | ## Contributing
17 |
18 | Please submit issues/pull requests if you have feedback or message the React Velocity team to be added as a contributor: apjs.react.velocity@gmail.com and CC Paul (pauldubovsky@gmail.com) to the email.
19 |
20 | ## Authors
21 |
22 | * Alex Clifton (https://github.com/AGCB)
23 | * Paul Dubovsky (https://github.com/menothe)
24 | * Justin Yip (https://github.com/jeyip12)
25 | * Scott Bengtson (https://github.com/sunsnba)
26 |
--------------------------------------------------------------------------------
/__tests__/reactTreeFunctions.test.js:
--------------------------------------------------------------------------------
1 | /*
2 | I am copying all functions defined inside react-tree.js into this file to test.
3 | For our future selves..... if you decide to change functionality on any of
4 | these methods, you will have to then copy the code into the function definition
5 | of this file.
6 | It's not an ideal workflow, but at least you won't have to rewrite any of the tests:)
7 |
8 | Only the formatName() function is clear to test for me at this point.
9 | All of the others use this.setState() and pieces of RST.
10 |
11 | Be aware that our formatName() is in react-tree.js AND redux-tree.js
12 | So, if changes need to be made, they need to be made in 3 places.
13 | 1- formatName() in react-tree.js
14 | 2- formatName() in redux-tree.js
15 | 3- formatName() in reactTreeFunctions.test.js
16 | */
17 |
18 | let formatName = (textField) => {
19 | let scrubbedResult = textField
20 | // Capitalize first letter of string.
21 | //| ^ = beginning of output | . = 1st char of str |
22 | .replace(/^./g, x => x.toUpperCase())
23 | // Capitalize first letter of each word and removes spaces.
24 | //| \ = matches | \w = any alphanumeric | \S = single char except white space
25 | //| * = preceeding expression 0 or more times | + = preceeding expression 1 or more times |
26 | .replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1);})
27 | .replace(/\ +/g, x => '')
28 | // Remove appending file extensions like .js or .json.
29 | //| \. = . in file extensions | $ = end of input |
30 | .replace(/\..+$/, '');
31 | return scrubbedResult;
32 | }
33 |
34 | test('formatName Function', () => {
35 | //must capitalize first string
36 | expect(formatName('barney')).toBe('Barney');
37 | //must remove spaces
38 | expect(formatName('Bar Bar')).toBe('BarBar');
39 | //must capitalize first letter of each word
40 | expect(formatName('barney barry')).toBe('BarneyBarry');
41 | //must remove file extensions like .js or .json
42 | expect(formatName('barney.js')).toBe('Barney');
43 | //last wild test.
44 | expect(formatName('barny.js')).toBe('Barny');
45 | });
46 |
47 |
48 |
49 |
50 | /*
51 | Now for a test on our Export Button's function...
52 |
53 | */
54 |
55 | function generateCode(data) {
56 | let filesToZip = {};
57 | let keys = Object.keys(data);
58 | let code = '';
59 | for (let i = 0; i < keys.length; i++) {
60 | code += "import React, { Component } from 'react';\n"
61 | if (data[keys[i]]) {
62 | for (let k=0; k < data[keys[i]].length; k++) {
63 | code += `import ${data[keys[i]][k]} from './${data[keys[i]][k]}';\n`;
64 | }
65 | }
66 | code += '\n';
67 | code += `class ${keys[i]} extends Component {\n`;
68 | code += ' render() {\n';
69 | code += ' return (\n';
70 | code += '
\n';
31 | code += ' );\n';
32 | code += ' };\n';
33 | code += '}\n\n';
34 | code += "function mapStateToProps(state = {}) {\n";
35 | code += ' return {prop: state.prop};\n';
36 | code += '}\n\n';
37 | code += 'function mapDispatchToProps(dispatch) {\n';
38 | code += ' return {actions: bindActionCreators(actionCreators, dispatch)};\n';
39 | code += '}\n\n';
40 | code += `export default connect(mapStateToProps, mapDispatchToProps)(${keys[i]});`;
41 | filesToZip[keys[i]] = code;
42 | code = '';
43 | }
44 | }
45 | return filesToZip;
46 | }
47 |
48 | export default generateContainer;
49 |
--------------------------------------------------------------------------------
/generateContents/redux-generate-reducers.js:
--------------------------------------------------------------------------------
1 | const generateReducers = (data) => {
2 | let code = '';
3 | for (let i = 0; i < data.length; i++) {
4 | if (data[i].node.componentType) {
5 | if (data[i].node.componentType === "Reducer") {
6 | code += `export function ${data[i].node.name}(state = {}, action) {\n`;
7 | code += ` switch (action.type) {\n`;
8 | if (data[i].node.case) {
9 | for (let j=0; j < data[i].node.case.length;j++) {
10 | code += ` case '${data[i].node.case[j]}':\n`;
11 | code += ` return Object.assign({}, state, {\n`;
12 | code += ` item: 'new item'\n`;
13 | code += ` });\n`;
14 | }
15 | }
16 | code += ` default:\n`;
17 | code += ` return state;\n`
18 | code += ` }\n`;
19 | code += `}\n\n`;
20 | }
21 | }
22 | }
23 | return code;
24 | }
25 |
26 | export default generateReducers;
27 |
--------------------------------------------------------------------------------
/generateContents/redux-index.js:
--------------------------------------------------------------------------------
1 | const generateReduxIndexJS = () => {
2 | let code = `import React from 'react';\n`;
3 | code += `import { render } from 'react-dom';\n`;
4 | code += `import { Provider } from 'react-redux';\n`;
5 | code += `import { createStore } from 'redux';\n`;
6 | code += `import * as rootReducer from './reducers/reducers';\n`;
7 | code += `import App from './components/App';\n\n`;
8 | code += `const store = createStore(rootReducer);\n\n`;
9 | code += `render(\n`;
10 | code += ` \n`;
11 | code += ` \n`;
12 | code += ` ,\n`;
13 | code += ` document.getElementById('app')\n`;
14 | code += `)`;
15 | return code;
16 | }
17 |
18 | export default generateReduxIndexJS;
19 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | React Velocity
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | /*
2 | This is the file that renders directly to the index.html inside the App id.
3 | MuiThemeProvider is our Material UI boilerplate.
4 | */
5 | import React from 'react';
6 | import ReactDOM from 'react-dom';
7 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
8 | import darkBaseTheme from 'material-ui/styles/baseThemes/darkBaseTheme';
9 | import getMuiTheme from 'material-ui/styles/getMuiTheme';
10 | import App from './src/components/App';
11 |
12 | ReactDOM.render(
13 |
14 |
15 | ,
16 | document.getElementById('app'));
17 |
--------------------------------------------------------------------------------
/node_modules/.bin/acorn:
--------------------------------------------------------------------------------
1 | ../acorn/bin/acorn
--------------------------------------------------------------------------------
/node_modules/.bin/ansi-html:
--------------------------------------------------------------------------------
1 | ../ansi-html/bin/ansi-html
--------------------------------------------------------------------------------
/node_modules/.bin/atob:
--------------------------------------------------------------------------------
1 | ../atob/bin/atob.js
--------------------------------------------------------------------------------
/node_modules/.bin/babylon:
--------------------------------------------------------------------------------
1 | ../babylon/bin/babylon.js
--------------------------------------------------------------------------------
/node_modules/.bin/browserslist:
--------------------------------------------------------------------------------
1 | ../browserslist/cli.js
--------------------------------------------------------------------------------
/node_modules/.bin/cssesc:
--------------------------------------------------------------------------------
1 | ../cssesc/bin/cssesc
--------------------------------------------------------------------------------
/node_modules/.bin/csso:
--------------------------------------------------------------------------------
1 | ../csso/bin/csso
--------------------------------------------------------------------------------
/node_modules/.bin/errno:
--------------------------------------------------------------------------------
1 | ../errno/cli.js
--------------------------------------------------------------------------------
/node_modules/.bin/escodegen:
--------------------------------------------------------------------------------
1 | ../escodegen/bin/escodegen.js
--------------------------------------------------------------------------------
/node_modules/.bin/esgenerate:
--------------------------------------------------------------------------------
1 | ../escodegen/bin/esgenerate.js
--------------------------------------------------------------------------------
/node_modules/.bin/esparse:
--------------------------------------------------------------------------------
1 | ../esprima/bin/esparse.js
--------------------------------------------------------------------------------
/node_modules/.bin/esvalidate:
--------------------------------------------------------------------------------
1 | ../esprima/bin/esvalidate.js
--------------------------------------------------------------------------------
/node_modules/.bin/handlebars:
--------------------------------------------------------------------------------
1 | ../handlebars/bin/handlebars
--------------------------------------------------------------------------------
/node_modules/.bin/he:
--------------------------------------------------------------------------------
1 | ../he/bin/he
--------------------------------------------------------------------------------
/node_modules/.bin/html-minifier:
--------------------------------------------------------------------------------
1 | ../html-minifier/cli.js
--------------------------------------------------------------------------------
/node_modules/.bin/import-local-fixture:
--------------------------------------------------------------------------------
1 | ../import-local/fixtures/cli.js
--------------------------------------------------------------------------------
/node_modules/.bin/internal-ip:
--------------------------------------------------------------------------------
1 | ../internal-ip/cli.js
--------------------------------------------------------------------------------
/node_modules/.bin/is-ci:
--------------------------------------------------------------------------------
1 | ../is-ci/bin.js
--------------------------------------------------------------------------------
/node_modules/.bin/jest:
--------------------------------------------------------------------------------
1 | ../jest/bin/jest.js
--------------------------------------------------------------------------------
/node_modules/.bin/jest-runtime:
--------------------------------------------------------------------------------
1 | ../jest-runtime/bin/jest-runtime.js
--------------------------------------------------------------------------------
/node_modules/.bin/js-yaml:
--------------------------------------------------------------------------------
1 | ../js-yaml/bin/js-yaml.js
--------------------------------------------------------------------------------
/node_modules/.bin/jsesc:
--------------------------------------------------------------------------------
1 | ../jsesc/bin/jsesc
--------------------------------------------------------------------------------
/node_modules/.bin/json5:
--------------------------------------------------------------------------------
1 | ../json5/lib/cli.js
--------------------------------------------------------------------------------
/node_modules/.bin/loose-envify:
--------------------------------------------------------------------------------
1 | ../loose-envify/cli.js
--------------------------------------------------------------------------------
/node_modules/.bin/miller-rabin:
--------------------------------------------------------------------------------
1 | ../miller-rabin/bin/miller-rabin
--------------------------------------------------------------------------------
/node_modules/.bin/mime:
--------------------------------------------------------------------------------
1 | ../mime/cli.js
--------------------------------------------------------------------------------
/node_modules/.bin/mkdirp:
--------------------------------------------------------------------------------
1 | ../mkdirp/bin/cmd.js
--------------------------------------------------------------------------------
/node_modules/.bin/multicast-dns:
--------------------------------------------------------------------------------
1 | ../multicast-dns/cli.js
--------------------------------------------------------------------------------
/node_modules/.bin/regjsparser:
--------------------------------------------------------------------------------
1 | ../regjsparser/bin/parser
--------------------------------------------------------------------------------
/node_modules/.bin/rimraf:
--------------------------------------------------------------------------------
1 | ../rimraf/bin.js
--------------------------------------------------------------------------------
/node_modules/.bin/sane:
--------------------------------------------------------------------------------
1 | ../sane/src/cli.js
--------------------------------------------------------------------------------
/node_modules/.bin/semver:
--------------------------------------------------------------------------------
1 | ../semver/bin/semver
--------------------------------------------------------------------------------
/node_modules/.bin/sha.js:
--------------------------------------------------------------------------------
1 | ../sha.js/bin.js
--------------------------------------------------------------------------------
/node_modules/.bin/sshpk-conv:
--------------------------------------------------------------------------------
1 | ../sshpk/bin/sshpk-conv
--------------------------------------------------------------------------------
/node_modules/.bin/sshpk-sign:
--------------------------------------------------------------------------------
1 | ../sshpk/bin/sshpk-sign
--------------------------------------------------------------------------------
/node_modules/.bin/sshpk-verify:
--------------------------------------------------------------------------------
1 | ../sshpk/bin/sshpk-verify
--------------------------------------------------------------------------------
/node_modules/.bin/strip-indent:
--------------------------------------------------------------------------------
1 | ../strip-indent/cli.js
--------------------------------------------------------------------------------
/node_modules/.bin/svgo:
--------------------------------------------------------------------------------
1 | ../svgo/bin/svgo
--------------------------------------------------------------------------------
/node_modules/.bin/uglifyjs:
--------------------------------------------------------------------------------
1 | ../uglify-js/bin/uglifyjs
--------------------------------------------------------------------------------
/node_modules/.bin/uuid:
--------------------------------------------------------------------------------
1 | ../uuid/bin/uuid
--------------------------------------------------------------------------------
/node_modules/.bin/watch:
--------------------------------------------------------------------------------
1 | ../watch/cli.js
--------------------------------------------------------------------------------
/node_modules/.bin/webpack:
--------------------------------------------------------------------------------
1 | ../webpack/bin/webpack.js
--------------------------------------------------------------------------------
/node_modules/.bin/webpack-dev-server:
--------------------------------------------------------------------------------
1 | ../webpack-dev-server/bin/webpack-dev-server.js
--------------------------------------------------------------------------------
/node_modules/.bin/which:
--------------------------------------------------------------------------------
1 | ../which/bin/which
--------------------------------------------------------------------------------
/node_modules/react-sortable-tree/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 |
6 | ## [2.0.1](https://github.com/fritz-c/react-sortable-tree/compare/v2.0.0...v2.0.1) (2018-02-10)
7 |
8 |
9 | ### Bug Fixes
10 |
11 | * restore highlight line appearance ([2c95205](https://github.com/fritz-c/react-sortable-tree/commit/2c95205))
12 |
13 |
14 |
15 |
16 | # [2.0.0](https://github.com/fritz-c/react-sortable-tree/compare/v1.8.1...v2.0.0) (2018-02-10)
17 |
18 |
19 | ### BREAKING CHANGES
20 |
21 | * from v2.0.0 on, you must import the css for the
22 | component yourself, using `import 'react-sortable-tree/style.css';`.
23 | You only need to do this once in your application.
24 |
25 |
26 |
27 |
28 | ## [1.8.1](https://github.com/fritz-c/react-sortable-tree/compare/v1.8.0...v1.8.1) (2018-01-21)
29 |
30 |
31 | ### Bug Fixes
32 |
33 | * rename parentNode callback param to nextParentNode ([24bf39d](https://github.com/fritz-c/react-sortable-tree/commit/24bf39d))
34 |
35 |
36 |
37 |
38 | # [1.8.0](https://github.com/fritz-c/react-sortable-tree/compare/v1.7.0...v1.8.0) (2018-01-21)
39 |
40 |
41 | ### Features
42 |
43 | * Parent node in onMoveNode callback ([537c6a4](https://github.com/fritz-c/react-sortable-tree/commit/537c6a4))
44 |
45 |
46 |
47 |
48 | # [1.7.0](https://github.com/fritz-c/react-sortable-tree/compare/v1.6.0...v1.7.0) (2018-01-16)
49 |
50 |
51 | ### Features
52 |
53 | * add onDragStateChanged callback ([2caa9d1](https://github.com/fritz-c/react-sortable-tree/commit/2caa9d1))
54 |
55 | onDragStateChanged is called when dragging begins and ends, so you can easily track the current state of dragging.
56 | Thanks to [@wuweiweiwu](https://github.com/wuweiweiwu) for the contribution!
57 |
58 |
59 |
60 |
61 | # [1.6.0](https://github.com/fritz-c/react-sortable-tree/compare/v1.5.5...v1.6.0) (2018-01-14)
62 |
63 |
64 | ### Features
65 |
66 | * add more parameters to rowHeight. Fixes [#199](https://github.com/fritz-c/react-sortable-tree/issues/199) ([8ff0ff2](https://github.com/fritz-c/react-sortable-tree/commit/8ff0ff2))
67 |
68 | Thanks to [@wuweiweiwu](https://github.com/wuweiweiwu) for the contribution!
69 |
70 |
71 |
72 |
73 | ## [1.5.5](https://github.com/fritz-c/react-sortable-tree/compare/v1.5.4...v1.5.5) (2018-01-13)
74 |
75 |
76 | ### Bug Fixes
77 |
78 | * expand tree for searches on initial mount. fixes [#223](https://github.com/fritz-c/react-sortable-tree/issues/223) ([64a984a](https://github.com/fritz-c/react-sortable-tree/commit/64a984a))
79 |
80 |
81 |
82 |
83 | ## [1.5.4](https://github.com/fritz-c/react-sortable-tree/compare/v1.5.3...v1.5.4) (2018-01-07)
84 |
85 | ### Bug Fixes
86 |
87 | * UglifyJS enabled to remove dead code, which had been causing issues with some builds. If the presence of UglifyJS causes issues in your production builds, please refer to https://github.com/fritz-c/react-sortable-tree#if-it-throws-typeerror-fn-is-not-a-function-errors-in-production
88 |
89 |
90 |
91 |
92 | ## [1.5.3](https://github.com/fritz-c/react-sortable-tree/compare/v1.5.2...v1.5.3) (2017-12-09)
93 |
94 |
95 | ### Bug Fixes
96 |
97 | * dragging past the bottom of the tree no longer slows down rendering ([3ce35f3](https://github.com/fritz-c/react-sortable-tree/commit/3ce35f3))
98 |
99 |
100 |
101 |
102 | ## [1.5.2](https://github.com/fritz-c/react-sortable-tree/compare/v1.5.1...v1.5.2) (2017-11-28)
103 |
104 |
105 | ### Bug Fixes
106 |
107 | * correct positioning of full-width draggable rows ([00396d1](https://github.com/fritz-c/react-sortable-tree/commit/00396d1))
108 |
109 |
110 |
111 |
112 | ## [1.5.1](https://github.com/fritz-c/react-sortable-tree/compare/v1.5.0...v1.5.1) (2017-11-28)
113 |
114 |
115 | ### Bug Fixes
116 |
117 | * prevent slowdown caused by invalid targetDepth when using maxDepth ([c21d4de](https://github.com/fritz-c/react-sortable-tree/commit/c21d4de)), closes [#194](https://github.com/fritz-c/react-sortable-tree/issues/194)
118 |
119 |
120 |
121 |
122 | # [1.5.0](https://github.com/fritz-c/react-sortable-tree/compare/v1.4.0...v1.5.0) (2017-10-29)
123 |
124 |
125 | ### Bug Fixes
126 |
127 | * Fix oblong collapse/expand button appearance on mobile safari ([62dfdec](https://github.com/fritz-c/react-sortable-tree/commit/62dfdec))
128 |
129 |
130 | ### Features
131 |
132 | * enable the use of themes for simplified appearance customization ([d07c6a7](https://github.com/fritz-c/react-sortable-tree/commit/d07c6a7))
133 |
134 |
135 |
136 |
137 | # [1.4.0](https://github.com/fritz-c/react-sortable-tree/compare/v1.3.1...v1.4.0) (2017-10-13)
138 |
139 |
140 | ### Features
141 |
142 | * Add path argument to onVisibilityToggle callback ([25cd134](https://github.com/fritz-c/react-sortable-tree/commit/25cd134))
143 |
144 |
145 |
146 |
147 | ## [1.3.1](https://github.com/fritz-c/react-sortable-tree/compare/v1.3.0...v1.3.1) (2017-10-03)
148 |
149 |
150 | ### Bug Fixes
151 |
152 | * Allow react[@16](https://github.com/16) ([9a31a03](https://github.com/fritz-c/react-sortable-tree/commit/9a31a03))
153 |
154 |
155 |
156 |
157 | # [1.3.0](https://github.com/fritz-c/react-sortable-tree/compare/v1.2.2...v1.3.0) (2017-09-20)
158 |
159 |
160 | ### Features
161 |
162 | * Provide more row parameters in rowHeight callback ([1b88b18](https://github.com/fritz-c/react-sortable-tree/commit/1b88b18))
163 |
164 |
165 |
166 |
167 | ## [1.2.2](https://github.com/fritz-c/react-sortable-tree/compare/v1.2.1...v1.2.2) (2017-09-12)
168 |
169 |
170 | ### Bug Fixes
171 |
172 | * Specify version of react-dnd-html5-backend to avoid invalid package installs ([a09b611](https://github.com/fritz-c/react-sortable-tree/commit/a09b611))
173 |
174 |
175 |
176 |
177 | ## [1.2.1](https://github.com/fritz-c/react-sortable-tree/compare/v1.2.0...v1.2.1) (2017-09-06)
178 |
179 |
180 | ### Bug Fixes
181 |
182 | * Allow children function in default renderer ([6f1dcac](https://github.com/fritz-c/react-sortable-tree/commit/6f1dcac))
183 |
184 |
185 |
186 |
187 | # [1.2.0](https://github.com/fritz-c/react-sortable-tree/compare/v1.1.1...v1.2.0) (2017-08-12)
188 |
189 |
190 | ### Features
191 |
192 | * Add `shouldCopyOnOutsideDrop` prop to enable copying of nodes that leave the tree ([d6a9be9](https://github.com/fritz-c/react-sortable-tree/commit/d6a9be9))
193 |
194 |
195 |
196 |
197 | ## [1.1.1](https://github.com/fritz-c/react-sortable-tree/compare/v1.1.0...v1.1.1) (2017-08-06)
198 |
199 |
200 | ### Bug Fixes
201 |
202 | * **tree-to-tree:** Fix node depth when dragging between trees ([323ccad](https://github.com/fritz-c/react-sortable-tree/commit/323ccad))
203 |
204 |
205 |
206 |
207 | # [1.1.0](https://github.com/fritz-c/react-sortable-tree/compare/v1.0.0...v1.1.0) (2017-08-05)
208 |
209 |
210 | ### Features
211 |
212 | * **node-renderer:** Make title and subtitle insertable via props ([fff72c6](https://github.com/fritz-c/react-sortable-tree/commit/fff72c6))
213 |
214 |
215 |
216 |
217 | # [1.0.0](https://github.com/fritz-c/react-sortable-tree/compare/v0.1.21...v1.0.0) (2017-08-05)
218 |
219 |
220 | ### Bug Fixes
221 |
222 | * External node offset was shifted ([d1ae0eb](https://github.com/fritz-c/react-sortable-tree/commit/d1ae0eb))
223 |
224 |
225 | ### Code Refactoring
226 |
227 | * get rid of `dndWrapExternalSource` api ([d103e9f](https://github.com/fritz-c/react-sortable-tree/commit/d103e9f))
228 |
229 |
230 | ### Features
231 |
232 | * **tree-to-tree:** Enable tree-to-tree drag-and-drop ([6986a23](https://github.com/fritz-c/react-sortable-tree/commit/6986a23))
233 | * Display droppable placeholder element when tree is empty ([2cd371c](https://github.com/fritz-c/react-sortable-tree/commit/2cd371c))
234 | * Add `prevPath` and `prevTreeIndex` to the `onMoveNode` callback ([6986a23](https://github.com/fritz-c/react-sortable-tree/commit/6986a23))
235 |
236 |
237 | ### BREAKING CHANGES
238 |
239 | * Trees that are empty now display a placeholder element
240 | in their place instead of being simply empty.
241 | * `dndWrapExternalSource` api no longer exists.
242 | You can achieve the same functionality and more with react-dnd
243 | APIs, as demonstrated in the storybook example.
244 |
245 |
246 |
247 |
248 | ## [0.1.21](https://github.com/fritz-c/react-sortable-tree/compare/v0.1.20...v0.1.21) (2017-07-15)
249 |
250 |
251 | ### Bug Fixes
252 |
253 | * Remove console.log left in after development ([da27c47](https://github.com/fritz-c/react-sortable-tree/commit/da27c47))
254 |
255 |
256 |
257 | See the GitHub [Releases](https://github.com/fritz-c/react-sortable-tree/releases) for information on updates.
258 |
--------------------------------------------------------------------------------
/node_modules/react-sortable-tree/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Chris Fritz
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/node_modules/react-sortable-tree/README.md:
--------------------------------------------------------------------------------
1 | # React Sortable Tree
2 |
3 | [](https://npmjs.org/package/react-sortable-tree)
4 |
5 | [](https://fritz-c.github.io/react-sortable-tree/)
6 |
7 | ### [Demo](https://fritz-c.github.io/react-sortable-tree/)
8 |
9 | [](https://fritz-c.github.io/react-sortable-tree/)
10 |
11 | ## Usage
12 |
13 | ```jsx
14 | import React, { Component } from 'react';
15 | import SortableTree from 'react-sortable-tree';
16 | import 'react-sortable-tree/style.css'; // This only needs to be imported once in your app
17 |
18 | export default class Tree extends Component {
19 | constructor(props) {
20 | super(props);
21 |
22 | this.state = {
23 | treeData: [{ title: 'Chicken', children: [{ title: 'Egg' }] }],
24 | };
25 | }
26 |
27 | render() {
28 | return (
29 |
30 | this.setState({ treeData })}
33 | />
34 |
35 | );
36 | }
37 | }
38 | ```
39 |
40 | Find more examples in the [Storybook](https://fritz-c.github.io/react-sortable-tree/storybook/)
41 |
42 | Play with the code on an [example on CodeSandbox](https://codesandbox.io/s/wkxvy3z15w)
43 |
44 | ## Options
45 |
46 | | Prop | Type |
Description
|
47 | | :----------------------------- | :------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
48 | | treeData _(required)_ | object[] | Tree data with the following keys:
`title` is the primary label for the node.
`subtitle` is a secondary label for the node.
`expanded` shows children of the node if true, or hides them if false. Defaults to false.
`children` is an array of child nodes belonging to the node.
**Example**: `[{title: 'main', subtitle: 'sub'}, { title: 'value2', expanded: true, children: [{ title: 'value3') }] }]` |
49 | | onChange _(required)_ | func | Called whenever tree data changed. Just like with React input elements, you have to update your own component's data to see the changes reflected.
`( treeData: object[] ): void`
|
50 | | getNodeKey _(recommended)_ | func | Specify the unique key used to identify each node and generate the `path` array passed in callbacks. With a setting of `getNodeKey={({ node }) => node.id}`, for example, in callbacks this will let you easily determine that the node with an `id` of `35` is (or has just become) a child of the node with an `id` of `12`, which is a child of ... and so on. It uses [`defaultGetNodeKey`](https://github.com/fritz-c/react-sortable-tree/blob/master/src/utils/default-handlers.js) by default, which returns the index in the tree (omitting hidden nodes).
`({ node: object, treeIndex: number }): string or number`
|
51 | | generateNodeProps | func | Generate an object with additional props to be passed to the node renderer. Use this for adding buttons via the `buttons` key, or additional `style` / `className` settings.
|
55 | | maxDepth | number | Maximum depth nodes can be inserted at. Defaults to infinite. |
56 | | canDrag | func or bool | Return false from callback to prevent node from dragging, by hiding the drag handle. Set prop to `false` to disable dragging on all nodes. Defaults to `true`.
|
57 | | canDrop | func | Return false to prevent node from dropping in the given location.
`({ node: object, prevPath: number[] or string[], prevParent: object, prevTreeIndex: number, nextPath: number[] or string[], nextParent: object, nextTreeIndex: number }): bool`
|
58 | | theme | object | Set an all-in-one packaged appearance for the tree. See the [Themes](#themes) section for more information. |
59 | | searchMethod | func | The method used to search nodes. Defaults to [`defaultSearchMethod`](https://github.com/fritz-c/react-sortable-tree/blob/master/src/utils/default-handlers.js), which uses the `searchQuery` string to search for nodes with matching `title` or `subtitle` values. NOTE: Changing `searchMethod` will not update the search, but changing the `searchQuery` will.
`({ node: object, path: number[] or string[], treeIndex: number, searchQuery: any }): bool`
|
60 | | searchQuery | string or any | Used by the `searchMethod` to highlight and scroll to matched nodes. Should be a string for the default `searchMethod`, but can be anything when using a custom search. Defaults to `null`. |
61 | | searchFocusOffset | number | Outline the <`searchFocusOffset`>th node and scroll to it. |
62 | | searchFinishCallback | func | Get the nodes that match the search criteria. Used for counting total matches, etc.
`(matches: { node: object, path: number[] or string[], treeIndex: number }[]): void`
|
63 | | dndType | string | String value used by [react-dnd](http://react-dnd.github.io/react-dnd/docs-overview.html) (see overview at the link) for dropTargets and dragSources types. If not set explicitly, a default value is applied by react-sortable-tree for you for its internal use. **NOTE:** Must be explicitly set and the same value used in order for correct functioning of external nodes |
64 | | shouldCopyOnOutsideDrop | func or bool | Return true, or a callback returning true, and dropping nodes to react-dnd drop targets outside of the tree will not remove them from the tree. Defaults to `false`.
8 | );
9 |
10 | export default NotFound;
11 |
--------------------------------------------------------------------------------
/src/components/react-interface.js:
--------------------------------------------------------------------------------
1 | import React, {Component} from 'react';
2 | import { Link } from "react-router-dom";
3 | import AppBar from 'material-ui/AppBar';
4 | import FlatButton from 'material-ui/FlatButton';
5 | import {Card, CardActions} from 'material-ui/Card';
6 | import Drawer from 'material-ui/Drawer';
7 | import RaisedButton from 'material-ui/RaisedButton';
8 | import TextField from 'material-ui/TextField';
9 | import IconButton from 'material-ui/IconButton';
10 | import Menu from 'material-ui/svg-icons/navigation/menu';
11 | import Avatar from 'material-ui/Avatar';
12 | import Chip from 'material-ui/Chip';
13 | import FileDownload from 'material-ui/svg-icons/file/file-download';
14 | import Settings from 'material-ui/svg-icons/action/settings';
15 | import Dialog from 'material-ui/Dialog';
16 | import {cyan200, cyan800, grey900, white} from 'material-ui/styles/colors';
17 |
18 | const styles = {
19 | chip: {
20 | margin: 4,
21 | },
22 | wrapper: {
23 | display: 'flex',
24 | flexWrap: 'wrap',
25 | },
26 | };
27 |
28 | const iconStyles = {
29 | marginRight: 24,
30 | };
31 |
32 | class ReactInterface extends Component {
33 | state = {
34 | drawerOpen: false,
35 | dialogOpen: false,
36 | };
37 |
38 | //Toggle = Drawer
39 | handleToggle = () => { this.setState({drawerOpen: !this.state.drawerOpen})};
40 | //Change = Select Field
41 | handleChange = (event, index, value) => {this.setState({value})};
42 | handleOpen = () => {this.setState({dialogOpen: true});};
43 | handleClose = () => {this.setState({dialogOpen: false});};
44 |
45 | render() {
46 | const actions = [
47 |
52 | ];
53 | const instructions = ['The component of ‘App’ is automatically generated, which may be used as the top-level parent component for your project.',
54 | 'In order to add children components to ‘App’, you can click on the ‘Add Child’ button to the far right of the ‘App’ component.',
55 | 'In case you delete the ‘App’ component, you can add another parent in the menu bar.',
56 | 'To delete a component, click on the ‘X’ that appears to the right of the ‘Add Child’ button. Deleting a parent node will also delete all of its children.',
57 | 'You may convert a stateless (or presentational) component to a stateful (or smart/class-based) component by toggling between the ‘stateless’ and ‘stateful’ buttons on the component.',
58 | 'Once you are satisfied with the structure of your project, click on the download button located at the top-right corner of the screen to export your components.',
59 | 'If you have any questions, please contact us at: apjs.react.velocity@gmail.com'
60 | ];
61 | return (
62 |
181 | );
182 | }
183 | }
184 | export default ReactInterface;
185 |
--------------------------------------------------------------------------------
/src/components/react-tree.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { render } from 'react-dom';
3 | import 'react-sortable-tree/style.css';
4 | import SortableTree, { addNodeUnderParent ,removeNodeAtPath, changeNodeAtPath, getFlatDataFromTree } from 'react-sortable-tree';
5 | import MenuItem from 'material-ui/MenuItem';
6 | import {cyan100, grey800, white} from 'material-ui/styles/colors';
7 | import ReactInterface from './react-interface';
8 | import IconButton from 'material-ui/IconButton';
9 | import generateCode from '../../generateContents/react-generate-content';
10 | import generatePresentationalComponent from '../../generateContents/react-generate-stateless-component';
11 | import generateAppCSS from '../../generateContents/react-generate-App-css';
12 | import generateAppTestJS from '../../generateContents/react-generate-app-test';
13 | import generateIndexCSS from '../../generateContents/react-generate-index-css';
14 | import generateReactIndexJS from '../../generateContents/react-generate-index';
15 | import generateLogoSVG from '../../generateContents/react-generate-logo-svg';
16 | import generateRegisterServiceWorker from '../../generateContents/react-generate-registerServiceWorker';
17 | import JSZip from 'jszip';
18 |
19 | const zip = new JSZip();
20 |
21 | class ReactTree extends Component {
22 | constructor(props) {
23 | super(props);
24 | /*
25 | treeData is boilerplate from react-sortable-tree that deals with the tree's
26 | organization. treeData is an array of deeply nested objects.
27 | */
28 | this.state = {
29 | treeData: [{
30 | name: 'App',
31 | //Parent is for canDrop and dictates that parents CANT be drag/dropped.
32 | parent: true,
33 | //isStateful defaults App component only to "stateful".
34 | isStateful: true,
35 | }],
36 | textFieldValue: '',
37 | /*
38 | flattenedArray takes the treeData and a helper function called
39 | getFlatDataFromTree and returns treeData as a flattened Array.
40 | */
41 | flattenedArray: [],
42 | /*
43 | The empty string for error is for all MaterialUI text fields so that
44 | they don't automatically return an error message.
45 | */
46 | error: '',
47 | /*
48 | Version2 is an object with key value pairs where the key is the name of
49 | the file we are zipping and the value is the code belonging to that file.
50 | */
51 | version2: {},
52 | };
53 | this.stateful = this.stateful.bind(this);
54 | this.formatName = this.formatName.bind(this);
55 | this.handleTextFieldChange = this.handleTextFieldChange.bind(this);
56 | this.concatNewComponent = this.concatNewComponent.bind(this);
57 | this.updateFlattenedData = this.updateFlattenedData.bind(this);
58 | this.onButtonPress = this.onButtonPress.bind(this);
59 | this.onKeyPress = this.onKeyPress.bind(this);
60 | this.createCodeForGenerateContent = this.createCodeForGenerateContent.bind(this);
61 | this.handleExport = this.handleExport.bind(this);
62 | this.exportZipFiles = this.exportZipFiles.bind(this);
63 | }
64 |
65 | /*
66 | stateful() generates an "isStateful" property on all components except App
67 | and defaults the stateful/stateless button to "stateless".
68 | */
69 | stateful(node,path,getNodeKey) {
70 | if (!('isStateful' in node)) {
71 | this.setState(state => ({
72 | treeData: changeNodeAtPath({
73 | treeData: state.treeData,
74 | path,
75 | getNodeKey,
76 | newNode: { ...node, isStateful:false }
77 | })
78 | }))
79 | }
80 | }
81 | /*
82 | formatName() is for sanitization of user input for naming react components
83 | using industry standard practice.
84 | */
85 | formatName(textField) {
86 | let scrubbedResult = textField
87 | // Capitalize first letter of string.
88 | //| ^ = beginning of output | . = 1st char of str |
89 | .replace(/^./g, x => x.toUpperCase())
90 | // Capitalize first letter of each word and removes spaces.
91 | //| \ = matches | \w = any alphanumeric | \S = single char except white space
92 | //| * = preceeding expression 0 or more times | + = preceeding expression 1 or more times |
93 | .replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1);})
94 | .replace(/\ +/g, x => '')
95 | // Remove appending file extensions like .js or .json.
96 | //| \. = . in file extensions | $ = end of input |
97 | .replace(/\..+$/, '');
98 | return scrubbedResult;
99 | }
100 |
101 | handleTextFieldChange(e){
102 | this.setState({
103 | textFieldValue: e.target.value,
104 | });
105 | }
106 |
107 | /*
108 | concatNewComponent() is run when a user clicks "add child" or hits "Enter" when
109 | inside the textfield. It adds a new node to treeData with the name of the
110 | value of the textfield. If there is nothing written in the textfield, it
111 | returns an error message.
112 | */
113 | concatNewComponent() {
114 | if(this.state.textFieldValue !== '') {
115 | this.setState(state => ({
116 | treeData: state.treeData.concat({
117 | name: this.formatName(this.state.textFieldValue),
118 | }),
119 | error: "",
120 | }))
121 | } else {(this.setState(state => ({
122 | error: "This field is required"
123 | })
124 | ))}
125 | }
126 |
127 | /*
128 | Code Generation is not based off of treeData, it is based off of a flattenedArray.
129 | updateFlattenedData() makes sure that flattenedArray is up to date with treeData.
130 | textFieldValue is set to an empty string to reset the textField after you hit
131 | "Enter" or "Add Child".
132 | */
133 | updateFlattenedData() {
134 | const getNodeKey = ({ treeIndex }) => treeIndex;
135 | const flatteningNestedArray = getFlatDataFromTree({treeData: this.state.treeData, getNodeKey});
136 | this.setState(state => ({
137 | flattenedArray: flatteningNestedArray,
138 | textFieldValue: '',
139 | }))
140 | }
141 |
142 | /* onButtonPress() adds a new node to the treeData. concatNewComponent has to
143 | finish before updateFlattenedData() to ensure that updateFlattenedData knows
144 | about the new node. To ensure this, we put updateFlattenedData on a short
145 | time-out. Refer to onButtonPress for onKeyPress.
146 | */
147 | onButtonPress(){
148 | this.concatNewComponent();
149 | /* using setTimeout breaks binding, so use a variable to store this to give
150 | to the function when it runs
151 | */
152 | const that = this;
153 | setTimeout(function(){that.updateFlattenedData()},100);
154 | };
155 |
156 | onKeyPress(e) {
157 | if(e.key == 'Enter') {
158 | this.concatNewComponent();
159 | const that = this;
160 | setTimeout(function(){that.updateFlattenedData()},100);
161 | }
162 | }
163 | /*
164 | For exporting zipped js files, we need an array of subArrays
165 | flattenedVar comes from react-sortable-tree.
166 | */
167 | createCodeForGenerateContent() {
168 | const getNodeKey = ({ treeIndex }) => treeIndex;
169 | const flatteningNestedArray = getFlatDataFromTree({treeData: this.state.treeData, getNodeKey});
170 | let flattenedVar = flatteningNestedArray;
171 | /*
172 | version1 is an array of sub-arrays. Within each array, the last element
173 | is the parent of all previous elements.
174 | */
175 | let version1 = [];
176 | /* For version2, the key is the parent. Value is all of the children
177 | stored as elements in an array.
178 | */
179 | let version2 = {};
180 |
181 | for(let i = 0; i {that.handleExport()}, 100);
261 | }
262 |
263 | render() {
264 |
265 | const getNodeKey = ({ treeIndex }) => treeIndex;
266 | const flattenedArray = getFlatDataFromTree({treeData: this.state.treeData, getNodeKey});
267 | let isStateful = true;
268 | const canDrop = ({ node, nextParent, prevPath, nextPath }) => {
269 | if (node.parent) {
270 | return false;
271 | }
272 | return true;
273 | };
274 |
275 | return (
276 |