├── .deploy └── server_setup.sh ├── .editorconfig ├── .eslintrc ├── .gitignore ├── .storybook ├── .babelrc ├── config.js └── webpack.config.js ├── .travis.yml ├── .travis ├── build.sh ├── deploy.sh ├── install.sh ├── travis_cl_setup.txt └── travis_deploy.enc ├── CHANGELOG.md ├── LICENSE ├── README.md ├── config ├── env.js ├── jest │ ├── cssTransform.js │ └── fileTransform.js ├── paths.js ├── polyfills.js ├── webpack.config.dev.js ├── webpack.config.prod.js └── webpackDevServer.config.js ├── package.json ├── public ├── _redirects ├── favicon.ico └── index.html ├── scripts ├── build.js ├── start.js └── test.js ├── src ├── actions │ └── index.js ├── components │ ├── AboutPage │ │ ├── @AboutPage.scss │ │ ├── copy.md │ │ └── index.js │ ├── Catalog │ │ ├── @Catalog.scss │ │ └── index.js │ ├── ChartExperimental │ │ ├── @Chart.scss │ │ ├── @ChartExperimental.scss │ │ ├── @Histogram.scss │ │ ├── BlankChart.jsx │ │ ├── ChartExperimental.jsx │ │ ├── ChartExperimentalAreaStuff.jsx │ │ ├── ChartExperimentalBarStuff.jsx │ │ ├── ChartExperimentalCanvas.jsx │ │ ├── ChartExperimentalHistogramStuff.jsx │ │ ├── ChartExperimentalLineStuff.jsx │ │ ├── ChartExperimentalSideBar.jsx │ │ ├── ChartExperimentalSubTitle.jsx │ │ ├── ChartExperimentalTitle.jsx │ │ ├── CustomKeyAxisTick.jsx │ │ ├── CustomLegend.jsx │ │ ├── CustomXaxisLabel.jsx │ │ ├── CustomYaxisLabel.jsx │ │ └── HistogramTooltip.jsx │ ├── ChartTypePicker │ │ ├── @ChartTypePicker.scss │ │ └── index.js │ ├── ColumnFilter │ │ ├── @ColumnFilter.scss │ │ └── index.js │ ├── ColumnList │ │ └── index.js │ ├── ColumnSort │ │ ├── @ColumnSort.scss │ │ └── index.js │ ├── ConditionalOnSelect.js │ ├── CopySnippet │ │ ├── @CopySnippet.scss │ │ └── index.js │ ├── DatasetFrontMatter │ │ ├── @Dataset.scss │ │ └── index.js │ ├── DatasetNav │ │ ├── @DatasetNav.scss │ │ ├── DatasetDownloads.js │ │ └── index.js │ ├── DatasetOverview │ │ ├── @DatasetOverview.scss │ │ └── index.js │ ├── DateRangePicker │ │ ├── @DateRangePicker.scss │ │ └── index.js │ ├── DefaultListGroup │ │ ├── @DefaultListGroup.scss │ │ └── index.js │ ├── DefaultListGroupItem │ │ ├── @DefaultListGroupItem.scss │ │ └── index.js │ ├── FieldButton │ │ ├── @FieldButton.scss │ │ ├── FieldButton.spec.js │ │ └── index.js │ ├── FieldColumns │ │ ├── @FieldColumns.scss │ │ └── index.js │ ├── FieldProfile │ │ ├── @FieldProfile.scss │ │ └── index.js │ ├── FieldSelector │ │ ├── @FieldSelector.scss │ │ └── index.js │ ├── FieldTypeButton │ │ ├── @FieldTypeButton.scss │ │ └── index.js │ ├── FilterChartOptions │ │ ├── @FilterOptions.scss │ │ ├── @daterangepicker.scss │ │ ├── FilterBoolean.js │ │ ├── FilterCategory.js │ │ ├── FilterDateTime.js │ │ ├── FilterNumeric.js │ │ └── index.js │ ├── FilterListInput │ │ ├── @FilterListInput.scss │ │ └── index.js │ ├── Footer │ │ ├── @Footer.scss │ │ └── Footer.jsx │ ├── HideShowButton │ │ ├── @HideShowButton.scss │ │ └── index.js │ ├── HomePage │ │ ├── @HomePage.scss │ │ ├── find.gif │ │ ├── index.js │ │ ├── logo_big.png │ │ ├── model.js │ │ ├── understand.gif │ │ └── visualize.gif │ ├── Icon │ │ ├── @Icon.scss │ │ └── index.js │ ├── Loading │ │ ├── @Loading.scss │ │ ├── IconLoading.js │ │ └── index.js │ ├── Logo │ │ └── index.js │ ├── Messages │ │ ├── @Messages.scss │ │ └── index.js │ ├── MetadataCard │ │ ├── @MetadataCard.scss │ │ └── index.js │ ├── ModalShare │ │ └── index.js │ ├── Navigation │ │ ├── @Navigation.scss │ │ └── index.js │ ├── PanelHeader │ │ └── index.js │ ├── Query │ │ ├── @ChartTypeDisplay.scss │ │ ├── @Query.scss │ │ ├── ChartOptions.jsx │ │ ├── ColumnSelector.js │ │ ├── DateToggle.jsx │ │ ├── GroupOptions.js │ │ ├── OtherDataToggle.jsx │ │ ├── Panel.jsx │ │ └── SumOptions.js │ ├── ReadMore │ │ └── index.js │ ├── RelatedDatasetLink │ │ ├── @RelatedDatasetLink.scss │ │ └── index.js │ ├── RelatedDatasetTable │ │ ├── @RelatedDatasetTable.scss │ │ └── index.js │ ├── Table │ │ ├── @DataTable.scss │ │ └── index.js │ └── URLReader │ │ └── index.js ├── constants │ └── AppConstants.js ├── containers │ ├── @containers.scss │ ├── App.js │ ├── AutoSuggestSearch.js │ ├── Catalog.js │ ├── ChartFieldSelector.js │ ├── Charts.jsx │ ├── DataTable.js │ ├── Dataset.js │ ├── DatasetOverview.js │ ├── Embed.js │ ├── FieldDefFieldSelector.js │ ├── FieldDefinitions.js │ ├── ModalShare.js │ ├── Root.jsx │ └── VizContainer.js ├── helpers │ ├── dataTypeColors.js │ ├── fillArray.js │ ├── findCeiling.js │ ├── findMaxObjKeyValue.js │ ├── findMaxObjKeyValueGrpByStacked.js │ ├── findMaxObjKeyValueGrpByUnStacked.js │ ├── findMinObjKeyValue.js │ ├── getLocalTimeWithOffset.js │ ├── getMaxDomain.js │ ├── getMaxGrpBy.js │ ├── index.js │ ├── isColTypeTest.js │ ├── padDomainMax.js │ ├── replacePropertyNameValue.js │ ├── roundAxisZeros.js │ ├── roundNumberByPower.js │ ├── setClassNamesListItem.js │ ├── setDocumentTitle.js │ ├── sortObj.js │ ├── sumObj.js │ ├── toTitleCase.js │ └── transformOthers.js ├── index.js ├── middleware │ ├── airbrake.js │ ├── analytics.js │ ├── index.js │ ├── metadatasf.js │ └── socrata.js ├── reducers │ ├── chartReducer.js │ ├── columnsReducer.js │ ├── fieldsReducer.js │ ├── index.js │ ├── messagesReducer.js │ ├── metadataReducer.js │ ├── queryReducer.js │ ├── reducerUtilities.js │ ├── searchReducer.js │ ├── tableReducer.js │ └── uiReducer.js ├── routes.js ├── store │ └── index.js ├── stories │ ├── index.js │ └── stories.scss └── styles │ ├── _customizations.scss │ ├── _theme.scss │ ├── _variables.scss │ └── bootstrap-explorer.scss └── yarn.lock /.deploy/server_setup.sh: -------------------------------------------------------------------------------- 1 | #scripts to set up the server 2 | 3 | #update the system 4 | sudo apt-get update 5 | yes "y" | sudo apt-get install build-essential 6 | 7 | ####create swappable memory to the server to act like more ram### 8 | cd ~ 9 | sudo fallocate -l 2G /swapfile 10 | #checks to make sure its there 11 | ls -lh /swapfile 12 | 13 | #set perms 14 | sudo chmod 600 /swapfile 15 | sudo mkswap /swapfile 16 | sudo swapon /swapfile 17 | #check to make sure its working 18 | sudo swapon -s 19 | #enable swap each time we boot up our server 20 | fnLine="\n /swapfile none swap sw 0 0" 21 | echo $fnLine >> /etc/fstab 22 | 23 | ####install node v.6.+ #### 24 | curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - 25 | sudo apt-get install -y nodejs 26 | 27 | 28 | #####install git + nginx###### 29 | yes "y" | sudo apt-get install git 30 | yes "y" | sudo apt-get install nginx 31 | 32 | #configure nginx 33 | cd /var/wwww 34 | #get the github repo 35 | git clone https://github.com/DataSF/open-data-explorer.git 36 | 37 | cd /var/www/open-data-explorer 38 | #sudo npm install 39 | chown -R www-data:www-data /var/www/ 40 | #change the directory perms to use www-data 41 | #sudo npm run build 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.{js,json,jshintrc,html,jsx}] 12 | indent_style = space 13 | indent_size = 2 14 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "react-app", 3 | "rules": { 4 | "react/jsx-no-undef": ["error", { "allowGlobals": true }] 5 | }, 6 | "globals": { 7 | "Choose": true, 8 | "When": true, 9 | "Otherwise": true 10 | } 11 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /build 3 | *.log* 4 | .DS_Store 5 | *.orig 6 | /coverage 7 | 8 | # CSS is compiled by node-sass, don't commit 9 | *.css 10 | -------------------------------------------------------------------------------- /.storybook/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "react-app" 4 | ], 5 | "plugins": [ 6 | "jsx-control-statements" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.storybook/config.js: -------------------------------------------------------------------------------- 1 | import { configure } from '@kadira/storybook'; 2 | import '../src/styles/bootstrap-explorer.css' 3 | function loadStories() { 4 | require('../src/stories'); 5 | } 6 | 7 | configure(loadStories, module); 8 | -------------------------------------------------------------------------------- /.storybook/webpack.config.js: -------------------------------------------------------------------------------- 1 | // you can use this file to add your custom webpack plugins, loaders and anything you like. 2 | // This is just the basic way to add addional webpack configurations. 3 | // For more information refer the docs: https://getstorybook.io/docs/configurations/custom-webpack-config 4 | 5 | // IMPORTANT 6 | // When you add this file, we won't add the default configurations which is similar 7 | // to "React Create App". This only has babel loader to load JavaScript. 8 | var autoprefixer = require('autoprefixer'); 9 | 10 | module.exports = { 11 | plugins: [ 12 | // your custom plugins 13 | ], 14 | module: { 15 | loaders: [ 16 | { 17 | test: /\.css$/, 18 | loader: 'style!css?importLoaders=1!postcss' 19 | }, 20 | { 21 | test : /\.(ttf|eot|svg|woff(2)?)(\?[a-z0-9=&.]+)?$/, 22 | loader : 'file-loader' 23 | } 24 | ], 25 | }, 26 | postcss: function() { 27 | return [ 28 | autoprefixer({ 29 | browsers: [ 30 | '>1%', 31 | 'last 4 versions', 32 | 'Firefox ESR', 33 | 'not ie < 9', // React doesn't support IE8 anyway 34 | ] 35 | }), 36 | ]; 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '6' 4 | cache: 5 | yarn: true 6 | directories: 7 | - node_modules 8 | addons: 9 | ssh_known_hosts: datasfexplorer.tk 10 | before_install: 11 | - bash .travis/install.sh 12 | script: 13 | - bash .travis/build.sh 14 | after_success: 15 | - bash .travis/deploy.sh 16 | -------------------------------------------------------------------------------- /.travis/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #tests and builds project 3 | 4 | function error_exit 5 | { 6 | echo "$1" 1>&2 7 | exit 1 8 | } 9 | 10 | 11 | set -x 12 | if [ $TRAVIS_BRANCH == "master" ]; then 13 | if npm test; then 14 | if npm run build:production; then 15 | echo "******TESTS PASSED******" 16 | exit 0 17 | else 18 | error_exit "******BUILD FAILED! Aborting.*********" 19 | fi 20 | else 21 | error_exit "******TESTS FAILED! Aborting build.*********" 22 | fi 23 | elif [ $TRAVIS_BRANCH == "develop" ]; then 24 | if npm test; then 25 | if npm run build:staging; then 26 | echo "******TESTS PASSED******" 27 | exit 0 28 | else 29 | error_exit "******BUILD FAILED! Aborting.*********" 30 | fi 31 | else 32 | error_exit "******TESTS FAILED! Aborting build.*********" 33 | fi 34 | else 35 | if npm run test; then 36 | echo "*****TESTS PASSED****" 37 | else 38 | error_exit "******TESTS FAILED! Aborting build.*********" 39 | fi 40 | fi 41 | -------------------------------------------------------------------------------- /.travis/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # print outputs and exit on first failure/show output of commands 4 | set -xe 5 | echo $TRAVIS_BRANCH 6 | if [ $TRAVIS_BRANCH == "master" ] ; then 7 | echo "*******pushing build to production website!********" 8 | # setup ssh agent, git config and remote 9 | eval `ssh-agent -s` #start shh agent 10 | ssh-add ~/.ssh/id_rsa 11 | cd build 12 | # Initialize a new git repo in _site, and push it to our server. 13 | git init 14 | git remote add deploy "deploy@datasfexplorer.tk:/var/www/open-data-explorer/" 15 | git config user.name "Travis CI" 16 | git config user.email "travis@datasfexplorer.tk" 17 | 18 | # commit compressed files and push it to remote 19 | git add . 20 | git commit -m "Deploy compressed files" 21 | git push --force deploy master 22 | echo "****SUCCESS: Production build was deployed ********" 23 | 24 | elif [ $TRAVIS_BRANCH == "develop" ] ; then 25 | echo "******pushing build to staging website!*******" 26 | # setup ssh agent, git config and remote 27 | eval `ssh-agent -s` #start shh agent 28 | ssh-add ~/.ssh/id_rsa 29 | # Initialize a new git repo in _site, angd push it to our server. 30 | cd build 31 | git init 32 | git remote add deploy "deploy@datasfexplorer.tk:/var/www/staging-open-data-explorer/" 33 | git config user.name "Travis CI" 34 | git config user.email "travis@datasfexplorer.tk" 35 | # commit compressed files and push it to remote 36 | git add . 37 | git commit -m "Deploy compressed files" 38 | git branch 39 | git push --force deploy master 40 | echo "****SUCCESS: Staging build was deployed ********" 41 | else 42 | echo "No deploy script for branch '$TRAVIS_BRANCH'" 43 | 44 | fi 45 | -------------------------------------------------------------------------------- /.travis/install.sh: -------------------------------------------------------------------------------- 1 | 2 | #!/bin/bash 3 | set -x # Show the output of the following commands (useful for debugging) 4 | 5 | echo "Setting up ssh!" 6 | 7 | 8 | # Import the SSH deployment key 9 | 10 | 11 | openssl aes-256-cbc -K $encrypted_5c93ddfc62aa_key -iv $encrypted_5c93ddfc62aa_iv -in .travis/travis_deploy.enc -out travis_deploy -d 12 | rm travis_deploy.enc # Don't need it anymore 13 | chmod 600 travis_deploy 14 | mv travis_deploy ~/.ssh/id_rsa 15 | 16 | -------------------------------------------------------------------------------- /.travis/travis_cl_setup.txt: -------------------------------------------------------------------------------- 1 | #Set up travis CI 2 | 3 | #most helpful article: https://kjaer.io/travis/ 4 | 5 | #pre installation on local machine 6 | gem install travis 7 | #need to log onto travis ci website 8 | travis login 9 | 10 | 11 | #generate ssh keys in local repo: 12 | touch .travis.yml 13 | ssh-keygen 14 | 15 | #which will prompt something like this: 16 | #Generating public/private rsa key pair. 17 | #Enter file in which to save the key (/Users/Maxime Kjaer/.ssh/id_rsa): 18 | #enter in travis_deploy 19 | 20 | 21 | #You’ll need to copy your private key file (deploy-key) to your local repository. Then, we’ll install the Travis command line utility, log in, and encrypt the file: 22 | #This command encrypts a copy of your deployment key, travis_rsa.enc. It will also add a few lines to your .travis.yml 23 | 24 | travis encrypt-file travis_deploy --add 25 | 26 | #after the above runs successfully, delete the private key, you don't need it- and we don't want it getting in the git repo! 27 | rm travis_rsa 28 | #remember to keep the public key- you will need this in a little bit to add to the server. 29 | 30 | ##Setup Travis on the droplet 31 | 32 | #Create a passwordless travis user on the droplet, 33 | #setup the generated access key, and 34 | #give it access to the folder where the website is hosted: 35 | sudo adduser deploy 36 | sudo su deploy 37 | mkdir ~/.ssh 38 | chmod 700 .ssh 39 | chmod 600 .ssh/authorized_keys 40 | 41 | #switch back to you local machine and run the below- this is transfering the public key: 42 | cat travis_rsa.pub | ssh deploy@datasfexplorer.tk "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys" 43 | 44 | 45 | #Setting up a remote repo: 46 | #Remote is just a repository on our web server to which we can push. 47 | #We’ll want to push to a repository in /var/www/open-data-explorer/.git, and have the files available in /var/kjaermaxi.me/build. We’re placing the .git one level above public_html because we don’t want to serve it. 48 | #To do this, we’ll start out by creating an empty Git repo in /var/www/open-data-explorer/ 49 | 50 | #Set up for production 51 | sudo mkdir /var/www/open-data-explorer/: 52 | sudo chown -R deploy:deploy /var/www/open-data-explorer 53 | 54 | sudo su deploy 55 | mkdir /var/www/open-data-explorer/.git 56 | cd /var/www/open-data-explorer/.git/ 57 | git init --bare 58 | cd hooks 59 | 60 | vim post-receive 61 | #Then, you’ll need to coy following in : 62 | 63 | #!/bin/sh 64 | git --work-tree=/var/www/open-data-explorer/build/ --git-dir=/var/www/open-data-explorer/.git checkout -f 65 | 66 | #change the perms on the post-receive file 67 | chmod +x /var/www/open-data-explorer/.git/hooks/post-receive 68 | 69 | #repeat steps for staging: 70 | 71 | su superuser #aka user with sudo privs. 72 | sudo mkdir /var/www/staging-open-data-explorer/: 73 | sudo chown -R deploy:deploy /var/www/staging-open-data-explorer 74 | 75 | sudo su deploy 76 | mkdir /var/www/staging-open-data-explorer/.git 77 | cd /var/www/staging-open-data-explorer/.git/ 78 | git init --bare 79 | cd hooks 80 | 81 | vim post-receive 82 | #Then, you’ll need to coy following in : 83 | 84 | #!/bin/sh 85 | git --work-tree=/var/www/staging-open-data-explorer/build/ --git-dir=/var/www/staging-open-data-explorer/.git checkout -f 86 | 87 | #change the perms on the post-receive file 88 | chmod +x /var/www/staging-open-data-explorer/.git/hooks/post-receive 89 | 90 | #now create your .travis yaml file. See the actual yaml file and corresponding bash scripts for configuration. 91 | -------------------------------------------------------------------------------- /.travis/travis_deploy.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DataSF/open-data-explorer/3072e6f6cca68c87f4ed4b033082fce6b52523c8/.travis/travis_deploy.enc -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 City and County of San Francisco 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | open-data-explorer 2 | =================== 3 | 4 | The very quick getting started guide 5 | 6 | 1. `git clone git@github.com:DataSF/open-data-explorer.git` 7 | 2. `cd open-data-explorer` 8 | 3. `yarn install` 9 | 4. `yarn start` 10 | 11 | ## Libraries 12 | You can see all the libraries in use in package.json. Digging in, you should probably become familiar with the following: 13 | 14 | - [ReactJS](https://facebook.github.io/react/) 15 | - [ReduxJS](http://redux.js.org/) 16 | - [React-Router](https://github.com/reactjs/react-router) 17 | - [Webpack](https://webpack.github.io/) 18 | - [Babel](http://babeljs.io/) 19 | 20 | ## Code Structure 21 | 22 | The code structure reflects a [redux pattern for managing state in a javascript application](http://redux.js.org/). 23 | 24 | ### actions 25 | Actions are payloads of information that send data from your application to your store. They are the only source of information for the store. You send them to the store using store.dispatch() 26 | 27 | ### components 28 | components are similar to views in that they define the rendering of the app. These components are tied to root containers, which define the application logic. 29 | 30 | ### constants 31 | app constants as needed, things like API roots, etc. 32 | 33 | ### containers 34 | containers are a special kind of component. Some people call these smart components, skinny components, controller components. Whatever you call them, they basically define the application logic and pass actions and state down to the components. 35 | 36 | ### middleware 37 | this is where all of the specific functions related to external API calls (e.g. Socrata) live. 38 | 39 | ### reducers 40 | per the redux approach, reducers change the state based on actions. All state change logic lives in reducers. 41 | 42 | ### scss 43 | styles 44 | 45 | ### store 46 | the store holds the whole state tree of the application. A store is not a class; it's just an object with a few methods on it. 47 | 48 | ### app.jsx 49 | the entry point for the application 50 | 51 | ### routes.jsx 52 | the routes for the application, the routes point to containers, which then delegate props to their children 53 | 54 | 55 | ## Contributing 56 | 57 | ### Zenhub 58 | 59 | We use Zenhub to organize the work. Interested in following along or contributing, make sure to install [Zenhub](https://www.zenhub.io) so you can see our boards. 60 | 61 | ### Issue management 62 | 63 | We've adopted a similar [standardization of labels](https://github.com/datasf/data-portal-exploration/labels) as described here to make issues simpler to reason about: 64 | 65 | https://robinpowered.com/blog/best-practice-system-for-organizing-and-tagging-github-issues/ 66 | 67 | In addition we kept the `help wanted` label to indicate good places for others to dig in. There's also an `Epic` label which is generated by Zenhub to define Epics. [Learn what Epics are on the Zenhub blog](https://www.zenhub.io/blog/working-with-epics-in-github/). 68 | 69 | 70 | ### Branch naming format 71 | 72 | We use Git Flow for branch naming, which follows the format 73 | 74 | `/` 75 | 76 | The following are the **types** we use: 77 | 78 | - release/: For official releases 79 | - hotfix/: for making fixes off a previous release 80 | - bugfix/: for making fixes for a current bug 81 | - feature/: for adding features to the system 82 | - docs/: for making changes/updates to documentation 83 | 84 | 85 | ### Tests 86 | 87 | Coming soon 88 | -------------------------------------------------------------------------------- /config/env.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const paths = require('./paths'); 6 | 7 | // Make sure that including paths.js after env.js will read .env variables. 8 | delete require.cache[require.resolve('./paths')]; 9 | 10 | const NODE_ENV = process.env.NODE_ENV; 11 | if (!NODE_ENV) { 12 | throw new Error( 13 | 'The NODE_ENV environment variable is required but was not specified.' 14 | ); 15 | } 16 | 17 | // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use 18 | var dotenvFiles = [ 19 | `${paths.dotenv}.${NODE_ENV}.local`, 20 | `${paths.dotenv}.${NODE_ENV}`, 21 | // Don't include `.env.local` for `test` environment 22 | // since normally you expect tests to produce the same 23 | // results for everyone 24 | NODE_ENV !== 'test' && `${paths.dotenv}.local`, 25 | paths.dotenv, 26 | ].filter(Boolean); 27 | 28 | // Load environment variables from .env* files. Suppress warnings using silent 29 | // if this file is missing. dotenv will never modify any environment variables 30 | // that have already been set. 31 | // https://github.com/motdotla/dotenv 32 | dotenvFiles.forEach(dotenvFile => { 33 | if (fs.existsSync(dotenvFile)) { 34 | require('dotenv').config({ 35 | path: dotenvFile, 36 | }); 37 | } 38 | }); 39 | 40 | // We support resolving modules according to `NODE_PATH`. 41 | // This lets you use absolute paths in imports inside large monorepos: 42 | // https://github.com/facebookincubator/create-react-app/issues/253. 43 | // It works similar to `NODE_PATH` in Node itself: 44 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders 45 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored. 46 | // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims. 47 | // https://github.com/facebookincubator/create-react-app/issues/1023#issuecomment-265344421 48 | // We also resolve them to make sure all tools using them work consistently. 49 | const appDirectory = fs.realpathSync(process.cwd()); 50 | process.env.NODE_PATH = (process.env.NODE_PATH || '') 51 | .split(path.delimiter) 52 | .filter(folder => folder && !path.isAbsolute(folder)) 53 | .map(folder => path.resolve(appDirectory, folder)) 54 | .join(path.delimiter); 55 | 56 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be 57 | // injected into the application via DefinePlugin in Webpack configuration. 58 | const REACT_APP = /^REACT_APP_/i; 59 | 60 | function getClientEnvironment(publicUrl) { 61 | const raw = Object.keys(process.env) 62 | .filter(key => REACT_APP.test(key)) 63 | .reduce( 64 | (env, key) => { 65 | env[key] = process.env[key]; 66 | return env; 67 | }, 68 | { 69 | // Useful for determining whether we’re running in production mode. 70 | // Most importantly, it switches React into the correct mode. 71 | NODE_ENV: process.env.NODE_ENV || 'development', 72 | // Useful for resolving the correct path to static assets in `public`. 73 | // For example, . 74 | // This should only be used as an escape hatch. Normally you would put 75 | // images into the `src` and `import` them in code to get their paths. 76 | PUBLIC_URL: publicUrl, 77 | } 78 | ); 79 | // Stringify all values so we can feed into Webpack DefinePlugin 80 | const stringified = { 81 | 'process.env': Object.keys(raw).reduce( 82 | (env, key) => { 83 | env[key] = JSON.stringify(raw[key]); 84 | return env; 85 | }, 86 | {} 87 | ), 88 | }; 89 | 90 | return { raw, stringified }; 91 | } 92 | 93 | module.exports = getClientEnvironment; 94 | -------------------------------------------------------------------------------- /config/jest/cssTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This is a custom Jest transformer turning style imports into empty objects. 4 | // http://facebook.github.io/jest/docs/tutorial-webpack.html 5 | 6 | module.exports = { 7 | process() { 8 | return 'module.exports = {};'; 9 | }, 10 | getCacheKey() { 11 | // The output is always the same. 12 | return 'cssTransform'; 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /config/jest/fileTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | // This is a custom Jest transformer turning file imports into filenames. 6 | // http://facebook.github.io/jest/docs/tutorial-webpack.html 7 | 8 | module.exports = { 9 | process(src, filename) { 10 | return `module.exports = ${JSON.stringify(path.basename(filename))};`; 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /config/paths.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | const url = require('url'); 6 | 7 | // Make sure any symlinks in the project folder are resolved: 8 | // https://github.com/facebookincubator/create-react-app/issues/637 9 | const appDirectory = fs.realpathSync(process.cwd()); 10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath); 11 | 12 | const envPublicUrl = process.env.PUBLIC_URL; 13 | 14 | function ensureSlash(path, needsSlash) { 15 | const hasSlash = path.endsWith('/'); 16 | if (hasSlash && !needsSlash) { 17 | return path.substr(path, path.length - 1); 18 | } else if (!hasSlash && needsSlash) { 19 | return `${path}/`; 20 | } else { 21 | return path; 22 | } 23 | } 24 | 25 | const getPublicUrl = appPackageJson => 26 | envPublicUrl || require(appPackageJson).homepage; 27 | 28 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer 29 | // "public path" at which the app is served. 30 | // Webpack needs to know it to put the right