diff --git a/.gitignore b/.gitignore index d210845a..4accc6ef 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ package-lock.json npm-debug.log* yarn-debug.log* yarn-error.log* + +docker-compose.override.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..e5689640 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,19 @@ +language: node_js + +node_js: + - "stable" + +cache: + yarn: true + directories: + - node_modules + +install: + - yarn install + +script: + # - yarn inspect + - yarn test + - yarn build # Make sure the app can be built without errors + +sudo: false diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..6ff46d10 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,12 @@ +FROM node:10.4.1-alpine +MAINTAINER Alejandro Celaya + +# Install yarn +RUN apk add --no-cache --virtual yarn + +# Make home dir writable by anyone +RUN chmod 777 /home + +CMD cd /home/shlink/www && \ + yarn install && \ + yarn start diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..0993fbf0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 shlinkio + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 301ff129..a23d1eea 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # shlink-web-client -[![Build Status](https://travis-ci.org/shlinkio/shlink-web-client.svg?branch=develop)](https://travis-ci.org/shlinkio/shlink-web-client) +[![Build Status](https://travis-ci.org/shlinkio/shlink-web-client.svg?branch=master)](https://travis-ci.org/shlinkio/shlink-web-client) A React-based client application for [Shlink](https://shlink.io) diff --git a/config/setupEnzyme.js b/config/setupEnzyme.js new file mode 100644 index 00000000..fc7b0dce --- /dev/null +++ b/config/setupEnzyme.js @@ -0,0 +1,4 @@ +import Enzyme from 'enzyme'; +import Adapter from 'enzyme-adapter-react-16'; + +Enzyme.configure({ adapter: new Adapter() }); diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js index 326546d9..9cccca44 100644 --- a/config/webpack.config.dev.js +++ b/config/webpack.config.dev.js @@ -23,6 +23,27 @@ const publicUrl = ''; // Get environment variables to inject into our app. const env = getClientEnvironment(publicUrl); +const postCssLoader = { + loader: require.resolve('postcss-loader'), + options: { + // Necessary for external CSS imports to work + // https://github.com/facebookincubator/create-react-app/issues/2677 + ident: 'postcss', + plugins: () => [ + require('postcss-flexbugs-fixes'), + autoprefixer({ + browsers: [ + '>1%', + 'last 4 versions', + 'Firefox ESR', + 'not ie < 9', // React doesn't support IE8 anyway + ], + flexbox: 'no-2009', + }), + ], + }, +}; + // This is the development configuration. // It is focused on developer experience and fast rebuilds. // The production configuration is different and lives in a separate file. @@ -167,33 +188,14 @@ module.exports = { importLoaders: 1, }, }, - { - loader: require.resolve('postcss-loader'), - options: { - // Necessary for external CSS imports to work - // https://github.com/facebookincubator/create-react-app/issues/2677 - ident: 'postcss', - plugins: () => [ - require('postcss-flexbugs-fixes'), - autoprefixer({ - browsers: [ - '>1%', - 'last 4 versions', - 'Firefox ESR', - 'not ie < 9', // React doesn't support IE8 anyway - ], - flexbox: 'no-2009', - }), - ], - }, - }, + postCssLoader, ], }, { test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', - use: ['css-loader', 'sass-loader'] + use: ['css-loader', 'sass-loader', postCssLoader] }) }, // "file" loader makes sure those assets get served by WebpackDevServer. @@ -251,7 +253,7 @@ module.exports = { // https://github.com/jmblog/how-to-optimize-momentjs-with-webpack // You can remove this if you don't use Moment.js: new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), - new ExtractTextPlugin('main.[hash:8].css'), + new ExtractTextPlugin('main.css'), ], // Some libraries import Node modules but don't use them in the browser. // Tell Webpack to provide empty mocks for them so importing them works. diff --git a/dist/.gitignore b/dist/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/dist/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/docker-compose.override.yml.dist b/docker-compose.override.yml.dist new file mode 100644 index 00000000..f9ad2f8f --- /dev/null +++ b/docker-compose.override.yml.dist @@ -0,0 +1,8 @@ +version: '3' + +services: + shlink_web_client_node: + user: 1000:1000 + volumes: + - /etc/passwd:/etc/passwd:ro + - /etc/group:/etc/group:ro diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..5ecdd13d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3' + +services: + shlink_web_client_node: + container_name: shlink_web_client_node + build: + context: . + dockerfile: ./Dockerfile + volumes: + - ./:/home/shlink/www + ports: + - "3000:3000" + - "56745:56745" diff --git a/indocker b/indocker new file mode 100755 index 00000000..ede86328 --- /dev/null +++ b/indocker @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +docker exec -it shlink_web_client_node /bin/sh -c "cd /home/shlink/www && $*" diff --git a/package.json b/package.json index 6ea9136b..b89f28c7 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,41 @@ { "name": "shlink-web-client-react", + "description": "A React-based web client for shlink", "version": "0.1.0", - "private": true, + "private": false, + "scripts": { + "start": "node scripts/start.js", + "build": "node scripts/build.js", + "test": "node scripts/test.js --env=jsdom" + }, "dependencies": { + "@fortawesome/fontawesome": "^1.1.8", + "@fortawesome/fontawesome-free-regular": "^5.0.13", + "@fortawesome/fontawesome-free-solid": "^5.0.13", + "@fortawesome/react-fontawesome": "0.0.19", + "axios": "^0.18.0", + "bootstrap": "^4.1.1", + "chart.js": "^2.7.2", + "moment": "^2.22.2", + "promise": "8.0.1", + "qs": "^6.5.2", + "ramda": "^0.25.0", + "react": "^16.3.2", + "react-chartjs-2": "^2.7.4", + "react-copy-to-clipboard": "^5.0.1", + "react-datepicker": "^1.5.0", + "react-dom": "^16.3.2", + "react-moment": "^0.7.6", + "react-redux": "^5.0.7", + "react-router-dom": "^4.2.2", + "react-tag-autocomplete": "^5.5.1", + "reactstrap": "^6.0.1", + "redux": "^4.0.0", + "redux-thunk": "^2.3.0", + "uuid": "^3.3.2" + }, + "devDependencies": { + "adm-zip": "^0.4.11", "autoprefixer": "7.1.6", "babel-core": "6.26.0", "babel-eslint": "7.2.3", @@ -15,6 +48,8 @@ "css-loader": "0.28.7", "dotenv": "4.0.0", "dotenv-expand": "4.2.0", + "enzyme": "^3.3.0", + "enzyme-adapter-react-16": "^1.1.1", "eslint": "4.10.0", "eslint-config-react-app": "^2.1.0", "eslint-loader": "1.9.0", @@ -22,19 +57,19 @@ "eslint-plugin-import": "2.8.0", "eslint-plugin-jsx-a11y": "5.1.1", "eslint-plugin-react": "7.4.0", + "extract-text-webpack-plugin": "^3.0.2", "file-loader": "1.1.5", "fs-extra": "3.0.1", "html-webpack-plugin": "2.29.0", "jest": "20.0.4", + "node-sass": "^4.9.0", "object-assign": "4.1.1", "postcss-flexbugs-fixes": "3.2.0", "postcss-loader": "2.0.8", - "promise": "8.0.1", "raf": "3.4.0", - "react": "^16.3.2", "react-dev-utils": "^5.0.1", - "react-dom": "^16.3.2", "resolve": "1.6.0", + "sass-loader": "^7.0.1", "style-loader": "0.19.0", "sw-precache-webpack-plugin": "0.11.4", "url-loader": "0.6.2", @@ -43,26 +78,16 @@ "webpack-manifest-plugin": "1.3.2", "whatwg-fetch": "2.0.3" }, - "scripts": { - "start": "node scripts/start.js", - "build": "node scripts/build.js", - "test": "node scripts/test.js --env=jsdom" - }, - "devDependencies": { - "extract-text-webpack-plugin": "^3.0.2", - "node-sass": "^4.9.0", - "sass-loader": "^7.0.1" - }, "jest": { "collectCoverageFrom": [ "src/**/*.{js,jsx,mjs}" ], "setupFiles": [ - "/config/polyfills.js" + "/config/polyfills.js", + "/config/setupEnzyme.js" ], "testMatch": [ - "/src/**/__tests__/**/*.{js,jsx,mjs}", - "/src/**/?(*.)(spec|test).{js,jsx,mjs}" + "/test/**/*.test.{js,jsx,mjs}" ], "testEnvironment": "node", "testURL": "http://localhost", diff --git a/public/favicon.ico b/public/favicon.ico index a11777cc..8157d0e0 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/icons/shlink-128.png b/public/icons/shlink-128.png new file mode 100644 index 00000000..1d82aa73 Binary files /dev/null and b/public/icons/shlink-128.png differ diff --git a/public/icons/shlink-16.png b/public/icons/shlink-16.png new file mode 100644 index 00000000..ded45981 Binary files /dev/null and b/public/icons/shlink-16.png differ diff --git a/public/icons/shlink-24.png b/public/icons/shlink-24.png new file mode 100644 index 00000000..ea9251f0 Binary files /dev/null and b/public/icons/shlink-24.png differ diff --git a/public/icons/shlink-32.png b/public/icons/shlink-32.png new file mode 100644 index 00000000..813c1b0b Binary files /dev/null and b/public/icons/shlink-32.png differ diff --git a/public/icons/shlink-64.png b/public/icons/shlink-64.png new file mode 100644 index 00000000..0dcd6f22 Binary files /dev/null and b/public/icons/shlink-64.png differ diff --git a/public/index.html b/public/index.html index ed0ebafa..00c6003c 100644 --- a/public/index.html +++ b/public/index.html @@ -2,12 +2,17 @@ - - + + + + + + + - React App + Shlink — The URL shortener