1
0
Fork 0
mirror of https://github.com/plankanban/planka.git synced 2025-07-18 04:39:44 +02:00

Docker, update readme, update dependencies

This commit is contained in:
Maksim Eltyshev 2019-10-01 04:18:33 +05:00
parent 2398199740
commit adbcb67f03
30 changed files with 1202 additions and 1744 deletions

10
.dockerignore Normal file
View file

@ -0,0 +1,10 @@
*/node_modules
*/.gitignore
*/README.md
**/.DS_Store
**/.gitkeep
server/public/*
server/views/*
client/build

43
Dockerfile Normal file
View file

@ -0,0 +1,43 @@
FROM node:alpine AS server-builder
WORKDIR /app
RUN apk add vips-dev fftw-dev build-base python --no-cache \
--repository https://alpine.global.ssl.fastly.net/alpine/edge/community/ \
--repository https://alpine.global.ssl.fastly.net/alpine/edge/main/
COPY server/package.json server/package-lock.json ./
RUN npm i --prod --silent
FROM node:alpine AS client-builder
WORKDIR /app
COPY client/package.json client/package-lock.json ./
RUN npm i --silent
COPY client .
RUN npm run build
FROM node:alpine
RUN apk add bash vips --no-cache \
--repository https://alpine.global.ssl.fastly.net/alpine/edge/community/
WORKDIR /app
COPY --from=server-builder /app/node_modules node_modules
COPY server .
COPY --from=client-builder /app/build public
COPY --from=client-builder /app/build/index.html views
ENV BASE_URL DATABASE_URL
VOLUME /app/public/uploads
EXPOSE 1337
CMD ["npm", "start"]

View file

@ -2,11 +2,11 @@
A Trello-like application built with React and Redux.
![](https://github.com/meltyshev/planka/blob/master/demo.gif?raw=true)
![](https://raw.githubusercontent.com/meltyshev/planka/master/demo.gif)
[Client demo](https://meltyshev.github.io/planka) (with some restrictions).
[**Client demo**](https://meltyshev.github.io/planka) (with some limitations).
### Features
## Features
- Create projects, boards, lists, cards, labels and tasks
- Add card members, track time, set a deadline, write comments
@ -15,40 +15,52 @@ A Trello-like application built with React and Redux.
- User notifications
- Internationalization
### Tech stack
## Deploy
- React, Redux, Redux-Saga, Redux-ORM, Semantic UI React, react-beautiful-dnd
- Sails.js, Knex.js
- PostgreSQL
### Docker Compose
### Run in development
[![](https://d207aa93qlcgug.cloudfront.net/1.95.5.qa/img/nav/docker-logo-loggedout.png)](https://hub.docker.com/r/meltyshev/planka)
```bash
- Make sure you have Docker and Docker Compose installed and operational.
- Create docker-compose.yml based on the example. This is the ONLY file you will need. You can create this file on your own machine by copy and pasting the content.
- Edit BASE_URL to match your domain name or IP address.
Download the docker-compose.yaml:
```
curl -L https://raw.githubusercontent.com/meltyshev/planka/master/docker-compose.yml -o docker-compose.yml
```
Pull images and start services:
```
docker-compose up -d
```
Demo user: demo@demo.demo demo
## Development
```
git clone https://github.com/meltyshev/planka.git
```
Server:
Server folder:
```bash
cd server
npm install
```
npm install
Create a database and edit DATABASE_URL in .env file.
# Create a database and edit DATABASE_URL in .env file
```bash
npm run db:migrate
npm run db:seed
npm run start:dev
```
Client (second terminal window):
```bash
cd client
Client folder:
```
npm install
npm start
@ -56,11 +68,13 @@ npm start
Demo user: demo@demo.demo demo
## Run in production
## Tech stack
In progress..
- React, Redux, Redux-Saga, Redux-ORM, Semantic UI React, react-beautiful-dnd
- Sails.js, Knex.js
- PostgreSQL
## Todo
## Roadmap
In progress..

587
client/package-lock.json generated
View file

@ -11,17 +11,17 @@
}
},
"@babel/core": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.0.tgz",
"integrity": "sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw==",
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.5.tgz",
"integrity": "sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg==",
"requires": {
"@babel/code-frame": "^7.5.5",
"@babel/generator": "^7.6.0",
"@babel/helpers": "^7.6.0",
"@babel/parser": "^7.6.0",
"@babel/template": "^7.6.0",
"@babel/traverse": "^7.6.0",
"@babel/types": "^7.6.0",
"@babel/generator": "^7.5.5",
"@babel/helpers": "^7.5.5",
"@babel/parser": "^7.5.5",
"@babel/template": "^7.4.4",
"@babel/traverse": "^7.5.5",
"@babel/types": "^7.5.5",
"convert-source-map": "^1.1.0",
"debug": "^4.1.0",
"json5": "^2.1.0",
@ -971,9 +971,9 @@
"integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA=="
},
"@hapi/hoek": {
"version": "8.2.4",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.2.4.tgz",
"integrity": "sha512-Ze5SDNt325yZvNO7s5C4fXDscjJ6dcqLFXJQ/M7dZRQCewuDj2iDUuBi6jLQt+APbW9RjjVEvLr35FXuOEqjow=="
"version": "8.2.5",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.2.5.tgz",
"integrity": "sha512-rmGFzok1zR3xZKd5m3ihWdqafXFxvPHoQ/78+AG5URKbEbJiwBBfRgzbu+07W5f3+07JRshw6QqGbVmCp8ntig=="
},
"@hapi/joi": {
"version": "15.1.1",
@ -1037,6 +1037,20 @@
"rimraf": "^2.5.4",
"slash": "^2.0.0",
"strip-ansi": "^5.0.0"
},
"dependencies": {
"jest-resolve": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz",
"integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==",
"requires": {
"@jest/types": "^24.9.0",
"browser-resolve": "^1.11.3",
"chalk": "^2.0.1",
"jest-pnp-resolver": "^1.2.1",
"realpath-native": "^1.1.0"
}
}
}
},
"@jest/environment": {
@ -1088,6 +1102,18 @@
"string-length": "^2.0.0"
},
"dependencies": {
"jest-resolve": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz",
"integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==",
"requires": {
"@jest/types": "^24.9.0",
"browser-resolve": "^1.11.3",
"chalk": "^2.0.1",
"jest-pnp-resolver": "^1.2.1",
"realpath-native": "^1.1.0"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@ -1456,9 +1482,9 @@
"integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw=="
},
"@types/yargs": {
"version": "13.0.2",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.2.tgz",
"integrity": "sha512-lwwgizwk/bIIU+3ELORkyuOgDjCh7zuWDFqRtPPhhVgq9N1F7CvLNKg1TX4f2duwtKQ0p044Au9r1PLIXHrIzQ==",
"version": "13.0.3",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.3.tgz",
"integrity": "sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ==",
"requires": {
"@types/yargs-parser": "*"
}
@ -1469,47 +1495,52 @@
"integrity": "sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg=="
},
"@typescript-eslint/eslint-plugin": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.3.1.tgz",
"integrity": "sha512-VqVNEsvemviajlaWm03kVMabc6S3xCHGYuY0fReTrIIOZg+3WzB+wfw6fD3KYKerw5lYxmzogmHOZ0i7YKnuwA==",
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.13.0.tgz",
"integrity": "sha512-WQHCozMnuNADiqMtsNzp96FNox5sOVpU8Xt4meaT4em8lOG1SrOv92/mUbEHQVh90sldKSfcOc/I0FOb/14G1g==",
"requires": {
"@typescript-eslint/experimental-utils": "2.3.1",
"eslint-utils": "^1.4.2",
"@typescript-eslint/experimental-utils": "1.13.0",
"eslint-utils": "^1.3.1",
"functional-red-black-tree": "^1.0.1",
"regexpp": "^2.0.1",
"tsutils": "^3.17.1"
"tsutils": "^3.7.0"
}
},
"@typescript-eslint/experimental-utils": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.3.1.tgz",
"integrity": "sha512-FaZEj73o4h6Wd0Lg+R4pZiJGdR0ZYbJr+O2+RbQ1aZjX8bZcfkVDtD+qm74Dv77rfSKkDKE64UTziLBo9UYHQA==",
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz",
"integrity": "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==",
"requires": {
"@types/json-schema": "^7.0.3",
"@typescript-eslint/typescript-estree": "2.3.1",
"eslint-scope": "^5.0.0"
"@typescript-eslint/typescript-estree": "1.13.0",
"eslint-scope": "^4.0.0"
}
},
"@typescript-eslint/parser": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.3.1.tgz",
"integrity": "sha512-ZlWdzhCJ2iZnSp/VBAJ/sowFbyHycIux8t0UEH0JsKgQvfSf7949hLYFMwTXdCMeEnpP1zRTHimrR+YHzs8LIw==",
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.13.0.tgz",
"integrity": "sha512-ITMBs52PCPgLb2nGPoeT4iU3HdQZHcPaZVw+7CsFagRJHUhyeTgorEwHXhFf3e7Evzi8oujKNpHc8TONth8AdQ==",
"requires": {
"@types/eslint-visitor-keys": "^1.0.0",
"@typescript-eslint/experimental-utils": "2.3.1",
"@typescript-eslint/typescript-estree": "2.3.1",
"eslint-visitor-keys": "^1.1.0"
"@typescript-eslint/experimental-utils": "1.13.0",
"@typescript-eslint/typescript-estree": "1.13.0",
"eslint-visitor-keys": "^1.0.0"
}
},
"@typescript-eslint/typescript-estree": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.3.1.tgz",
"integrity": "sha512-9SFhUgFuePJBB6jlLkOPPhMkZNiDCr+S8Ft7yAkkP2c5x5bxPhG3pe/exMiQaF8IGyVMDW6Ul0q4/cZ+uF3uog==",
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz",
"integrity": "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==",
"requires": {
"glob": "^7.1.4",
"is-glob": "^4.0.1",
"lodash.unescape": "4.0.1",
"semver": "^6.3.0"
"semver": "5.5.0"
},
"dependencies": {
"semver": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
}
}
},
"@webassemblyjs/ast": {
@ -1681,9 +1712,9 @@
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ=="
},
"abab": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.1.tgz",
"integrity": "sha512-1zSbbCuoIjafKZ3mblY5ikvAb0ODUbqBnFuUb7f6uLeQhhGJ0vEV4ntmtxKLT2WgXCO94E07BjunsIw1jOMPZw=="
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.2.tgz",
"integrity": "sha512-2scffjvioEmNz0OyDSLGWDfKCVwaKc6l9Pm9kOIREU13ClXZvHpg/nRL5xyjSSSLhOnXqft2HpsAzNEEA8cFFg=="
},
"accepts": {
"version": "1.3.7",
@ -2083,16 +2114,27 @@
}
},
"babel-eslint": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.3.tgz",
"integrity": "sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA==",
"version": "10.0.2",
"resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.2.tgz",
"integrity": "sha512-UdsurWPtgiPgpJ06ryUnuaSXC2s0WoSZnQmEpbAH65XZSdwowgN5MvyP7e88nW07FYXv72erVtpBkxyDVKhH1Q==",
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/parser": "^7.0.0",
"@babel/traverse": "^7.0.0",
"@babel/types": "^7.0.0",
"eslint-visitor-keys": "^1.0.0",
"resolve": "^1.12.0"
"eslint-scope": "3.7.1",
"eslint-visitor-keys": "^1.0.0"
},
"dependencies": {
"eslint-scope": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
"integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
}
}
},
"babel-extract-comments": {
@ -2228,6 +2270,27 @@
"babel-plugin-transform-react-remove-prop-types": "0.4.24"
},
"dependencies": {
"@babel/core": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.0.tgz",
"integrity": "sha512-FuRhDRtsd6IptKpHXAa+4WPZYY2ZzgowkbLBecEDDSje1X/apG7jQM33or3NdOmjXBKWGOg4JmSiRfUfuTtHXw==",
"requires": {
"@babel/code-frame": "^7.5.5",
"@babel/generator": "^7.6.0",
"@babel/helpers": "^7.6.0",
"@babel/parser": "^7.6.0",
"@babel/template": "^7.6.0",
"@babel/traverse": "^7.6.0",
"@babel/types": "^7.6.0",
"convert-source-map": "^1.1.0",
"debug": "^4.1.0",
"json5": "^2.1.0",
"lodash": "^4.17.13",
"resolve": "^1.3.2",
"semver": "^5.4.1",
"source-map": "^0.5.0"
}
},
"@babel/plugin-proposal-object-rest-spread": {
"version": "7.5.5",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz",
@ -2302,6 +2365,19 @@
"regenerator-runtime": "^0.13.2"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"requires": {
"ms": "^2.1.1"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
@ -3351,9 +3427,9 @@
}
},
"chownr": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz",
"integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A=="
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz",
"integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw=="
},
"chrome-trace-event": {
"version": "1.0.2",
@ -3534,9 +3610,9 @@
}
},
"commander": {
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ=="
"version": "2.20.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.1.tgz",
"integrity": "sha512-cCuLsMhJeWQ/ZpsFTbE765kvVfoeSddc4nU3up4fV+fDBcfUXnbITJ+JzhkdjzOqhURjZgujxaioam4RM9yGUg=="
},
"common-tags": {
"version": "1.8.0",
@ -4155,9 +4231,9 @@
}
},
"date-fns": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.3.0.tgz",
"integrity": "sha512-A8o+iXBVqQayl9Z39BHgb7m/zLOfhF7LK82t+n9Fq1adds1vaUn8ByVoADqWLe4OTc6BZYc/FdbdTwufNYqkJw=="
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.4.1.tgz",
"integrity": "sha512-2RhmH/sjDSCYW2F3ZQxOUx/I7PvzXpi89aQL2d3OAxSTwLx6NilATeUbe0menFE3Lu5lFkOFci36ivimwYHHxw=="
},
"date-now": {
"version": "0.1.4",
@ -4483,9 +4559,9 @@
"integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w=="
},
"dotenv-expand": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz",
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA=="
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-4.2.0.tgz",
"integrity": "sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU="
},
"duplexer": {
"version": "0.1.1",
@ -4547,9 +4623,9 @@
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"electron-to-chromium": {
"version": "1.3.265",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.265.tgz",
"integrity": "sha512-ypHt5Nv1Abr27QvJqk3VC4YDNqsrrWYMCmpmR7BNfCpcgYEwmCDoi3uJpp6kvj/MIjpScQoZMCQzLqfMQGmOsg=="
"version": "1.3.269",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.269.tgz",
"integrity": "sha512-t2ZTfo07HxkxTOUbIwMmqHBSnJsC9heqJUm7LwQu2iSk0wNhG4H5cMREtb8XxeCrQABDZ6IqQKY3yZq+NfAqwg=="
},
"elliptic": {
"version": "6.5.1",
@ -4581,9 +4657,9 @@
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
},
"end-of-stream": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.3.tgz",
"integrity": "sha512-cbNhPFS6MlYlWTGncSiDYbdqKhwWFy7kNeb1YSOG6K65i/wPTkLVCJQj0hXA4j0m5Da+hBWnqopEnu1FFelisQ==",
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"requires": {
"once": "^1.4.0"
}
@ -4820,6 +4896,15 @@
"ms": "^2.1.1"
}
},
"eslint-scope": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
"integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
},
"import-fresh": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz",
@ -4891,25 +4976,15 @@
}
},
"eslint-loader": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-3.0.0.tgz",
"integrity": "sha512-rdxyQ0i9VlhwVlR6oEzrIft8WNKYSD2/cOAJ1YVH/F76gAta7Zv1Dr5xJOUyx0fAsHB5cKNz9hwlUVLMFsQlPA==",
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/eslint-loader/-/eslint-loader-2.2.1.tgz",
"integrity": "sha512-RLgV9hoCVsMLvOxCuNjdqOrUqIj9oJg8hF44vzJaYqsAHuY9G2YAeN3joQ9nxP0p5Th9iFSIpKo+SD8KISxXRg==",
"requires": {
"loader-fs-cache": "^1.0.2",
"loader-utils": "^1.2.3",
"object-hash": "^1.3.1",
"schema-utils": "^2.1.0"
},
"dependencies": {
"schema-utils": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.2.0.tgz",
"integrity": "sha512-5EwsCNhfFTZvUreQhx/4vVQpJ/lnCAkgoIHLhSpp4ZirE+4hzFvdJi0FMub6hxbFVBJYSpeVVmon+2e7uEGRrA==",
"requires": {
"ajv": "^6.10.2",
"ajv-keywords": "^3.4.1"
}
}
"loader-fs-cache": "^1.0.0",
"loader-utils": "^1.0.2",
"object-assign": "^4.0.1",
"object-hash": "^1.1.4",
"rimraf": "^2.6.1"
}
},
"eslint-module-utils": {
@ -5159,15 +5234,14 @@
}
},
"eslint-plugin-react-hooks": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-2.0.1.tgz",
"integrity": "sha512-xir+3KHKo86AasxlCV8AHRtIZPHljqCRRUYgASkbatmt0fad4+5GgC7zkT7o/06hdKM6MIwp8giHVXqBPaarHQ==",
"dev": true
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz",
"integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA=="
},
"eslint-scope": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
"integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
"integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
@ -6062,9 +6136,9 @@
"integrity": "sha512-d4sze1JNC454Wdo2fkuyzCr6aHcbL6PGGuFAz0Li/NcOm1tCHGnWDRmJP85dh9IhQErTc2svWFEX5xHIOo//kQ=="
},
"handlebars": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.3.0.tgz",
"integrity": "sha512-7XlnO8yBXOdi7AzowjZssQr47Ctidqm7GbgARapOaqSN9HQhlClnOkR9HieGauIT3A8MBC6u9wPCXs97PCYpWg==",
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.0.tgz",
"integrity": "sha512-xkRtOt3/3DzTKMOt3xahj2M/EqNhY988T+imYSlMgs5fVhLN2fmKVVj0LtEGmb+3UUYV5Qmm1052Mm3dIQxOvw==",
"requires": {
"neo-async": "^2.6.0",
"optimist": "^0.6.1",
@ -6814,11 +6888,6 @@
"path-is-inside": "^1.0.1"
}
},
"is-plain-obj": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
},
"is-plain-object": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
@ -6991,12 +7060,12 @@
}
},
"jest": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz",
"integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==",
"version": "24.8.0",
"resolved": "https://registry.npmjs.org/jest/-/jest-24.8.0.tgz",
"integrity": "sha512-o0HM90RKFRNWmAWvlyV8i5jGZ97pFwkeVoGvPW1EtLTgJc2+jcuqcbbqcSZLE/3f2S5pt0y2ZBETuhpWNl1Reg==",
"requires": {
"import-local": "^2.0.0",
"jest-cli": "^24.9.0"
"jest-cli": "^24.8.0"
},
"dependencies": {
"jest-cli": {
@ -7053,6 +7122,20 @@
"micromatch": "^3.1.10",
"pretty-format": "^24.9.0",
"realpath-native": "^1.1.0"
},
"dependencies": {
"jest-resolve": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz",
"integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==",
"requires": {
"@jest/types": "^24.9.0",
"browser-resolve": "^1.11.3",
"chalk": "^2.0.1",
"jest-pnp-resolver": "^1.2.1",
"realpath-native": "^1.1.0"
}
}
}
},
"jest-diff": {
@ -7768,11 +7851,11 @@
"integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA=="
},
"jest-resolve": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz",
"integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==",
"version": "24.8.0",
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz",
"integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==",
"requires": {
"@jest/types": "^24.9.0",
"@jest/types": "^24.8.0",
"browser-resolve": "^1.11.3",
"chalk": "^2.0.1",
"jest-pnp-resolver": "^1.2.1",
@ -7813,6 +7896,20 @@
"jest-worker": "^24.6.0",
"source-map-support": "^0.5.6",
"throat": "^4.0.0"
},
"dependencies": {
"jest-resolve": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz",
"integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==",
"requires": {
"@jest/types": "^24.9.0",
"browser-resolve": "^1.11.3",
"chalk": "^2.0.1",
"jest-pnp-resolver": "^1.2.1",
"realpath-native": "^1.1.0"
}
}
}
},
"jest-runtime": {
@ -7843,6 +7940,20 @@
"slash": "^2.0.0",
"strip-bom": "^3.0.0",
"yargs": "^13.3.0"
},
"dependencies": {
"jest-resolve": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz",
"integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==",
"requires": {
"@jest/types": "^24.9.0",
"browser-resolve": "^1.11.3",
"chalk": "^2.0.1",
"jest-pnp-resolver": "^1.2.1",
"realpath-native": "^1.1.0"
}
}
}
},
"jest-serializer": {
@ -7868,6 +7979,20 @@
"natural-compare": "^1.4.0",
"pretty-format": "^24.9.0",
"semver": "^6.2.0"
},
"dependencies": {
"jest-resolve": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz",
"integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==",
"requires": {
"@jest/types": "^24.9.0",
"browser-resolve": "^1.11.3",
"chalk": "^2.0.1",
"jest-pnp-resolver": "^1.2.1",
"realpath-native": "^1.1.0"
}
}
}
},
"jest-util": {
@ -7915,40 +8040,16 @@
}
},
"jest-watch-typeahead": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.4.0.tgz",
"integrity": "sha512-bJR/HPNgOQnkmttg1OkBIrYFAYuxFxExtgQh67N2qPvaWGVC8TCkedRNPKBfmZfVXFD3u2sCH+9OuS5ApBfCgA==",
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/jest-watch-typeahead/-/jest-watch-typeahead-0.3.1.tgz",
"integrity": "sha512-cDIko96c4Yqg/7mfye1eEYZ6Pvugo9mnOOhGQod3Es7/KptNv1b+9gFVaotzdqNqTlwbkA80BnWHtzV4dc+trA==",
"requires": {
"ansi-escapes": "^4.2.1",
"ansi-escapes": "^3.0.0",
"chalk": "^2.4.1",
"jest-watcher": "^24.3.0",
"slash": "^3.0.0",
"string-length": "^3.1.0",
"slash": "^2.0.0",
"string-length": "^2.0.0",
"strip-ansi": "^5.0.0"
},
"dependencies": {
"ansi-escapes": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz",
"integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==",
"requires": {
"type-fest": "^0.5.2"
}
},
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
},
"string-length": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz",
"integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==",
"requires": {
"astral-regex": "^1.0.0",
"strip-ansi": "^5.2.0"
}
}
}
},
"jest-watcher": {
@ -8607,12 +8708,11 @@
}
},
"mini-css-extract-plugin": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.8.0.tgz",
"integrity": "sha512-MNpRGbNA52q6U92i0qbVpQNsgk7LExy41MdAlG84FeytfDOtRIf/mCHdEgG8rpTKOaNKiqUnZdlptF469hxqOw==",
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz",
"integrity": "sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw==",
"requires": {
"loader-utils": "^1.1.0",
"normalize-url": "1.9.1",
"schema-utils": "^1.0.0",
"webpack-sources": "^1.1.0"
}
@ -8924,9 +9024,9 @@
}
},
"node-releases": {
"version": "1.1.32",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.32.tgz",
"integrity": "sha512-VhVknkitq8dqtWoluagsGPn3dxTvN9fwgR59fV3D7sLBHe0JfDramsMI8n8mY//ccq/Kkrf8ZRHRpsyVZ3qw1A==",
"version": "1.1.33",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.33.tgz",
"integrity": "sha512-I0V30bWQEoHb+10W8oedVoUrdjW5wIkYm0w7vvcrPO95pZY738m1k77GF5sO0vKg5eXYg9oGtrMAETbgZGm11A==",
"requires": {
"semver": "^5.3.0"
},
@ -8970,15 +9070,9 @@
"integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI="
},
"normalize-url": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz",
"integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
"requires": {
"object-assign": "^4.0.1",
"prepend-http": "^1.0.0",
"query-string": "^4.1.0",
"sort-keys": "^1.0.0"
}
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
"integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg=="
},
"npm-run-path": {
"version": "2.0.2",
@ -10232,13 +10326,6 @@
"normalize-url": "^3.0.0",
"postcss": "^7.0.0",
"postcss-value-parser": "^3.0.0"
},
"dependencies": {
"normalize-url": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
"integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg=="
}
}
},
"postcss-normalize-whitespace": {
@ -10462,11 +10549,6 @@
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
"prepend-http": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
},
"pretty-bytes": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz",
@ -10628,15 +10710,6 @@
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
},
"query-string": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
"integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
"requires": {
"object-assign": "^4.1.0",
"strict-uri-encode": "^1.0.0"
}
},
"querystring": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
@ -10716,9 +10789,9 @@
"integrity": "sha512-JsecfN+JlckncVXTWFWjn0Vk6uInl8GSf4eEd9tTk5qXHlgqkPdILpnYpgZcISXNYAzvfvsCZviaDk8AxyS5sg=="
},
"react": {
"version": "16.9.0",
"resolved": "https://registry.npmjs.org/react/-/react-16.9.0.tgz",
"integrity": "sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w==",
"version": "16.10.1",
"resolved": "https://registry.npmjs.org/react/-/react-16.10.1.tgz",
"integrity": "sha512-2bisHwMhxQ3XQz4LiJJwG3360pY965pTl/MRrZYxIBKVj4fOHoDs5aZAkYXGxDRO1Li+SyjTAilQEbOmtQJHzA==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
@ -10827,14 +10900,14 @@
}
},
"react-dom": {
"version": "16.9.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.9.0.tgz",
"integrity": "sha512-YFT2rxO9hM70ewk9jq0y6sQk8cL02xm4+IzYBz75CQGlClQQ1Bxq0nhHF6OtSbit+AIahujJgb/CPRibFkMNJQ==",
"version": "16.10.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.10.1.tgz",
"integrity": "sha512-SmM4ZW0uug0rn95U8uqr52I7UdNf6wdGLeXDmNLfg3y5q5H9eAbdjF5ubQc3bjDyRrvdAB2IKG7X0GzSpnn5Mg==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.15.0"
"scheduler": "^0.16.1"
}
},
"react-error-overlay": {
@ -10843,9 +10916,9 @@
"integrity": "sha512-DHRuRk3K4Lg9obI6J4Y+nKvtwjasYRU9CFL3ud42x9YJG1HbQjSNublapC/WBJOA726gNUbqbj0U2df9+uzspQ=="
},
"react-i18next": {
"version": "10.13.0",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-10.13.0.tgz",
"integrity": "sha512-6BeRvNPlEw7MEmdE63A+VCl+HoVlTi/g0BWvhFWSaKlPFozUn5GGMf91UkpUZd4ItueR18Xvw8yKtji9RSOAOw==",
"version": "10.13.1",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-10.13.1.tgz",
"integrity": "sha512-MReJUMoYooaKZONvoewFuAwf31bQU60Xt25P5wBIPTMphY4LjDJE27rwhEKjNLL24nSIHa3Jh+z9bPwSKISAoA==",
"requires": {
"@babel/runtime": "^7.3.1",
"html-parse-stringify2": "2.0.1"
@ -10861,9 +10934,9 @@
}
},
"react-is": {
"version": "16.9.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz",
"integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw=="
"version": "16.10.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.10.1.tgz",
"integrity": "sha512-BXUMf9sIOPXXZWqr7+c5SeOKJykyVr2u0UDzEf4LNGc6taGkQe1A9DFD07umCIXz45RLr9oAAwZbAJ0Pkknfaw=="
},
"react-onclickoutside": {
"version": "6.9.0",
@ -10897,9 +10970,9 @@
}
},
"react-router": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.1.0.tgz",
"integrity": "sha512-n9HXxaL/6yRlig9XPfGyagI8+bUNdqcu7FUAx0/Z+Us22Z8iHsbkyJ21Inebn9HOxI5Nxlfc8GNabkNSeXfhqw==",
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.1.1.tgz",
"integrity": "sha512-ozTXqxKZsn4GfZqpG5rVFHSSxlNuDoMNxgyjM+mFJVhqlnPwwkRsAPkDm1PcNjBdYxMzqAhtz48HkQB6fSYaAQ==",
"requires": {
"@babel/runtime": "^7.1.2",
"history": "^4.9.0",
@ -10914,41 +10987,41 @@
}
},
"react-router-dom": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.1.0.tgz",
"integrity": "sha512-OkxKbMKjO7IkYqnoaZNX19MnwgjhxwZE871cPUTq0YU2wpIw7QwGxSnSoNRMOa7wO1TwvJJMFpgiEB4C/gVhTw==",
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.1.1.tgz",
"integrity": "sha512-r8R8H0Vt2ISqpk02rR6VZBLk+JZdR6pZV+h9K1y0ISh3/G4GGByNevYBS69x6czcOcWVRcZmXjwY8l9UBCKV+w==",
"requires": {
"@babel/runtime": "^7.1.2",
"history": "^4.9.0",
"loose-envify": "^1.3.1",
"prop-types": "^15.6.2",
"react-router": "5.1.0",
"react-router": "5.1.1",
"tiny-invariant": "^1.0.2",
"tiny-warning": "^1.0.0"
}
},
"react-scripts": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.1.2.tgz",
"integrity": "sha512-aN9E1jn+Qii45/uLUzS7Hjfd/DXbcaAiRkoMwnJXAXShbpJiP2xwmr7yuVF0kR0cnvt0SI+IPZjsOH8MziSYQQ==",
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.1.1.tgz",
"integrity": "sha512-dbjTG9vJC61OI62hIswQYg5xHvwlxDTH6QXz6ICEuA5AqkFQWk1LKl76sk8fVL2WsyumbBc4FErALwKcEV2vNA==",
"requires": {
"@babel/core": "7.6.0",
"@babel/core": "7.5.5",
"@svgr/webpack": "4.3.2",
"@typescript-eslint/eslint-plugin": "^2.2.0",
"@typescript-eslint/parser": "^2.2.0",
"babel-eslint": "10.0.3",
"babel-jest": "^24.9.0",
"@typescript-eslint/eslint-plugin": "1.13.0",
"@typescript-eslint/parser": "1.13.0",
"babel-eslint": "10.0.2",
"babel-jest": "^24.8.0",
"babel-loader": "8.0.6",
"babel-plugin-named-asset-import": "^0.3.4",
"babel-preset-react-app": "^9.0.2",
"babel-plugin-named-asset-import": "^0.3.3",
"babel-preset-react-app": "^9.0.1",
"camelcase": "^5.2.0",
"case-sensitive-paths-webpack-plugin": "2.2.0",
"css-loader": "2.1.1",
"dotenv": "6.2.0",
"dotenv-expand": "5.1.0",
"dotenv-expand": "4.2.0",
"eslint": "^6.1.0",
"eslint-config-react-app": "^5.0.2",
"eslint-loader": "3.0.0",
"eslint-config-react-app": "^5.0.1",
"eslint-loader": "2.2.1",
"eslint-plugin-flowtype": "3.13.0",
"eslint-plugin-import": "2.18.2",
"eslint-plugin-jsx-a11y": "6.2.3",
@ -10960,11 +11033,11 @@
"html-webpack-plugin": "4.0.0-beta.5",
"identity-obj-proxy": "3.0.0",
"is-wsl": "^1.1.0",
"jest": "24.9.0",
"jest": "24.8.0",
"jest-environment-jsdom-fourteen": "0.1.0",
"jest-resolve": "24.9.0",
"jest-watch-typeahead": "0.4.0",
"mini-css-extract-plugin": "0.8.0",
"jest-resolve": "24.8.0",
"jest-watch-typeahead": "0.3.1",
"mini-css-extract-plugin": "0.5.0",
"optimize-css-assets-webpack-plugin": "5.0.3",
"pnp-webpack-plugin": "1.5.0",
"postcss-flexbugs-fixes": "4.1.0",
@ -10972,27 +11045,20 @@
"postcss-normalize": "7.0.1",
"postcss-preset-env": "6.7.0",
"postcss-safe-parser": "4.0.1",
"react-app-polyfill": "^1.0.3",
"react-dev-utils": "^9.0.4",
"react-app-polyfill": "^1.0.2",
"react-dev-utils": "^9.0.3",
"resolve": "1.12.0",
"resolve-url-loader": "3.1.0",
"sass-loader": "7.2.0",
"semver": "6.3.0",
"style-loader": "1.0.0",
"terser-webpack-plugin": "1.4.1",
"ts-pnp": "1.1.4",
"ts-pnp": "1.1.2",
"url-loader": "2.1.0",
"webpack": "4.40.2",
"webpack": "4.39.1",
"webpack-dev-server": "3.2.1",
"webpack-manifest-plugin": "2.0.4",
"workbox-webpack-plugin": "4.3.1"
},
"dependencies": {
"eslint-plugin-react-hooks": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz",
"integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA=="
}
}
},
"react-textarea-autosize": {
@ -11106,9 +11172,9 @@
}
},
"redux-orm": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/redux-orm/-/redux-orm-0.14.0.tgz",
"integrity": "sha512-ivB1GoZkp3qW5fCPq6C68k7QsMEScfzKI7FzmXdIGwWmqeZ0zwWJTv+JlckBzSosjAUCwA+ZsREIY5yZ6L2hYA==",
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/redux-orm/-/redux-orm-0.14.1.tgz",
"integrity": "sha512-0bh1nFxEmdV1SvYfYRmXx9KKhOURCR+Gl8GSGl+Hc7ePjF3v8mCVDIhQlANgdbs/8fXte7ZpOoVb0Syl+0i8pw==",
"requires": {
"@babel/runtime": "^7.6.0",
"immutable-ops": "^0.7.0",
@ -11635,9 +11701,9 @@
}
},
"scheduler": {
"version": "0.15.0",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.15.0.tgz",
"integrity": "sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg==",
"version": "0.16.1",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.16.1.tgz",
"integrity": "sha512-MIuie7SgsqMYOdCXVFZa8SKoNorJZUWHW8dPgto7uEHn1lX3fg2Gu0TzgK8USj76uxV7vB5eRMnZs/cdEHg+cg==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
@ -12156,14 +12222,6 @@
}
}
},
"sort-keys": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
"integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=",
"requires": {
"is-plain-obj": "^1.0.0"
}
},
"source-list-map": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@ -12459,11 +12517,6 @@
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI="
},
"strict-uri-encode": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
},
"string-length": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz",
@ -12594,9 +12647,9 @@
},
"dependencies": {
"schema-utils": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.2.0.tgz",
"integrity": "sha512-5EwsCNhfFTZvUreQhx/4vVQpJ/lnCAkgoIHLhSpp4ZirE+4hzFvdJi0FMub6hxbFVBJYSpeVVmon+2e7uEGRrA==",
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.4.1.tgz",
"integrity": "sha512-RqYLpkPZX5Oc3fw/kHHHyP56fg5Y+XBpIpV8nCg0znIALfq3OH+Ea9Hfeac9BAMwG5IICltiZ0vxFvJQONfA5w==",
"requires": {
"ajv": "^6.10.2",
"ajv-keywords": "^3.4.1"
@ -12698,9 +12751,9 @@
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA=="
},
"terser": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.3.2.tgz",
"integrity": "sha512-obxk4x19Zlzj9zY4QeXj9iPCb5W8YGn4v3pn4/fHj0Nw8+R7N02Kvwvz9VpOItCZZD8RC+vnYCDL0gP6FAJ7Xg==",
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/terser/-/terser-4.3.4.tgz",
"integrity": "sha512-Kcrn3RiW8NtHBP0ssOAzwa2MsIRQ8lJWiBG/K7JgqPlomA3mtb2DEmp4/hrUA+Jujx+WZ02zqd7GYD+QRBB/2Q==",
"requires": {
"commander": "^2.20.0",
"source-map": "~0.6.1",
@ -12908,9 +12961,9 @@
}
},
"ts-pnp": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.1.4.tgz",
"integrity": "sha512-1J/vefLC+BWSo+qe8OnJQfWTYRS6ingxjwqmHMqaMxXMj7kFtKLgAaYW3JeX3mktjgUL+etlU8/B4VUAUI9QGw=="
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.1.2.tgz",
"integrity": "sha512-f5Knjh7XCyRIzoC/z1Su1yLLRrPrFCgtUAh/9fCSP6NKbATwpOL1+idQVXQokK9GRFURn/jYPGPfegIctwunoA=="
},
"tslib": {
"version": "1.10.0",
@ -12956,11 +13009,6 @@
"prelude-ls": "~1.1.2"
}
},
"type-fest": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz",
"integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw=="
},
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@ -13189,9 +13237,9 @@
},
"dependencies": {
"schema-utils": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.2.0.tgz",
"integrity": "sha512-5EwsCNhfFTZvUreQhx/4vVQpJ/lnCAkgoIHLhSpp4ZirE+4hzFvdJi0FMub6hxbFVBJYSpeVVmon+2e7uEGRrA==",
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.4.1.tgz",
"integrity": "sha512-RqYLpkPZX5Oc3fw/kHHHyP56fg5Y+XBpIpV8nCg0znIALfq3OH+Ea9Hfeac9BAMwG5IICltiZ0vxFvJQONfA5w==",
"requires": {
"ajv": "^6.10.2",
"ajv-keywords": "^3.4.1"
@ -13374,9 +13422,9 @@
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
},
"webpack": {
"version": "4.40.2",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.40.2.tgz",
"integrity": "sha512-5nIvteTDCUws2DVvP9Qe+JPla7kWPPIDFZv55To7IycHWZ+Z5qBdaBYPyuXWdhggTufZkQwfIK+5rKQTVovm2A==",
"version": "4.39.1",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.39.1.tgz",
"integrity": "sha512-/LAb2TJ2z+eVwisldp3dqTEoNhzp/TLCZlmZm3GGGAlnfIWDgOEE758j/9atklNLfRyhKbZTCOIoPqLJXeBLbQ==",
"requires": {
"@webassemblyjs/ast": "1.8.5",
"@webassemblyjs/helper-module-context": "1.8.5",
@ -13407,22 +13455,13 @@
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz",
"integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA=="
},
"eslint-scope": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
"integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
"requires": {
"esrecurse": "^4.1.0",
"estraverse": "^4.1.1"
}
}
}
},
"webpack-dev-middleware": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.1.tgz",
"integrity": "sha512-5MWu9SH1z3hY7oHOV6Kbkz5x7hXbxK56mGHNqHTe6d+ewxOwKUxoUJBs7QIaJb33lPjl9bJZ3X0vCoooUzC36A==",
"version": "3.7.2",
"resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz",
"integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==",
"requires": {
"memory-fs": "^0.4.1",
"mime": "^2.4.4",
@ -13993,9 +14032,9 @@
"integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w=="
},
"yallist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A=="
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.0.tgz",
"integrity": "sha512-6gpP93MR+VOOehKbCPchro3wFZNSNmek8A2kbkOAZLIZAYx1KP/zAqwO0sOHi3xJEb+UBz8NaYt/17UNit1Q9w=="
},
"yargs": {
"version": "13.3.0",

View file

@ -23,14 +23,11 @@
],
"parser": "babel-eslint"
},
"eslintIgnore": [
"src/service-worker.js"
],
"dependencies": {
"axios": "^0.19.0",
"classnames": "^2.2.6",
"connected-react-router": "^6.5.2",
"date-fns": "^2.3.0",
"date-fns": "^2.4.1",
"dequal": "^1.0.0",
"history": "^4.10.1",
"i18next": "^17.0.16",
@ -38,19 +35,19 @@
"initials": "^3.0.1",
"lodash": "^4.17.15",
"prop-types": "^15.7.2",
"react": "^16.9.0",
"react": "^16.10.1",
"react-beautiful-dnd": "^11.0.5",
"react-datepicker": "^2.9.6",
"react-dom": "^16.9.0",
"react-i18next": "^10.13.0",
"react-dom": "^16.10.1",
"react-i18next": "^10.13.1",
"react-input-mask": "^2.0.4",
"react-redux": "^7.1.1",
"react-router-dom": "^5.1.0",
"react-scripts": "3.1.2",
"react-router-dom": "^5.1.1",
"react-scripts": "3.1.1",
"react-textarea-autosize": "^7.1.0",
"redux": "^4.0.4",
"redux-logger": "^3.0.6",
"redux-orm": "^0.14.0",
"redux-orm": "^0.14.1",
"redux-saga": "^1.1.1",
"reselect": "^4.0.0",
"sails.io.js": "^1.2.1",
@ -60,11 +57,7 @@
"whatwg-fetch": "^3.0.0"
},
"devDependencies": {
"eslint": "^6.4.0",
"eslint-config-airbnb": "^18.0.1",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-react": "^7.14.3",
"eslint-plugin-react-hooks": "^2.0.1"
"eslint": "6.4.0",
"eslint-config-airbnb": "^18.0.1"
}
}

View file

@ -13,7 +13,7 @@ const http = {};
return result;
}, new FormData());
return fetch(`${Config.API_URL}${Config.API_PATH}${url}`, {
return fetch(`${Config.SERVER_BASE_URL}/api${url}`, {
method,
headers,
body: formData,

View file

@ -5,7 +5,7 @@ import Config from '../constants/Config';
const io = sailsIOClient(socketIOClient);
io.sails.url = Config.API_URL;
io.sails.url = Config.SERVER_BASE_URL;
io.sails.autoConnect = false;
io.sails.reconnection = true;
io.sails.useCORSRouteToGetCookie = false;
@ -22,7 +22,7 @@ socket.connect = socket._connect; // eslint-disable-line no-underscore-dangle
method,
data,
headers,
url: `${Config.API_PATH}${url}`,
url: `/api${url}`,
},
(_, { body, error }) => {
if (error) {

View file

@ -1,13 +1,12 @@
const API_URL = 'http://localhost:1337';
const API_PATH = '';
const SERVER_BASE_URL = process.env.REACT_APP_SERVER_BASE_URL
|| (process.env.NODE_ENV === 'production' ? '' : 'http://localhost:1337');
const POSITION_GAP = 65535;
const ACTIONS_LIMIT = 10;
export default {
API_URL,
API_PATH,
SERVER_BASE_URL,
POSITION_GAP,
ACTIONS_LIMIT,
};

View file

@ -3,14 +3,8 @@ import ReactDOM from 'react-dom';
import store from './store';
import history from './history';
import * as serviceWorker from './service-worker';
import Root from './components/Root';
import './i18n';
ReactDOM.render(React.createElement(Root, { store, history }), document.getElementById('root'));
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.register();

View file

@ -15,8 +15,7 @@ export default {
addUser_title: 'Add User',
administrator: 'Administrator',
all: 'All',
allChangesWillBeAutomaticallySavedAfterConnectionRestored:
'All changes will be automatically saved<br />after connection restored',
allChangesWillBeAutomaticallySavedAfterConnectionRestored: 'All changes will be automatically saved<br />after connection restored',
areYouSureYouWantToDeleteThisBoard: 'Are you sure you want to delete this board?',
areYouSureYouWantToDeleteThisCard: 'Are you sure you want to delete this card?',
areYouSureYouWantToDeleteThisComment: 'Are you sure you want to delete this comment?',
@ -25,8 +24,7 @@ export default {
areYouSureYouWantToDeleteThisProject: 'Are you sure you want to delete this project?',
areYouSureYouWantToDeleteThisTask: 'Are you sure you want to delete this task?',
areYouSureYouWantToDeleteThisUser: 'Are you sure you want to delete this user?',
areYouSureYouWantToRemoveThisMemberFromProject:
'Are you sure you want to remove this member from project?',
areYouSureYouWantToRemoveThisMemberFromProject: 'Are you sure you want to remove this member from project?',
boardNotFound_title: 'Board Not Found',
cardActions_title: 'Card Actions',
cardNotFound_title: 'Card Not Found',
@ -72,10 +70,8 @@ export default {
notifications: 'Notifications',
noUnreadNotifications: 'No unread notifications',
openBoard_title: 'Open Board',
pageNotFound_title: 'Page Not Found',
projectNotFound_title: 'Project Not Found',
refreshPageToLoadLastDataAndReceiveUpdates:
'<0>Refresh the page</0> to load last data<br />and receive updates',
refreshPageToLoadLastDataAndReceiveUpdates: '<0>Refresh the page</0> to load last data<br />and receive updates',
removeMember_title: 'Remove Member',
seconds: 'Seconds',
taskActions_title: 'Task Actions',
@ -87,8 +83,7 @@ export default {
userIsAlreadyExist: 'User is already exist',
userLeftNewCommentToCard: '{{user}} left a new comment «{{comment}}» to <2>{{card}}</2>',
userMovedCardFromListToList: '{{user}} moved <2>{{card}}</2> from {{fromList}} to {{toList}}',
userMovedThisCardFromListToList:
'<0>{{user}}</0><1> moved this card from {{fromList}} to {{toList}}</1>',
userMovedThisCardFromListToList: '<0>{{user}}</0><1> moved this card from {{fromList}} to {{toList}}</1> 12342134123412412412412412412',
users: 'Users',
writeComment: 'Write a comment...',
},

View file

@ -6,6 +6,7 @@ export default {
invalidPassword: 'Invalid password',
logInToPlanka: 'Log in to Planka',
noInternetConnection: 'No internet connection',
pageNotFound_title: 'Page Not Found',
password: 'Password',
projectManagment: 'Project managment',
serverConnectionFailed: 'Server connection failed',

View file

@ -19,8 +19,7 @@ export default {
addUser: 'Добавление пользователя',
administrator: 'Администратор',
all: 'Все',
allChangesWillBeAutomaticallySavedAfterConnectionRestored:
'Все изменения сохранятся автоматически,<br />как только подключение восстановится',
allChangesWillBeAutomaticallySavedAfterConnectionRestored: 'Все изменения сохранятся автоматически,<br />как только подключение восстановится',
areYouSureYouWantToDeleteThisBoard: 'Вы уверены, что хотите удалить эту доску?',
areYouSureYouWantToDeleteThisCard: 'Вы уверены, что хотите удалить эту карточку?',
areYouSureYouWantToDeleteThisComment: 'Вы уверены, что хотите удалить этот комментарий?',
@ -29,8 +28,7 @@ export default {
areYouSureYouWantToDeleteThisProject: 'Вы уверены, что хотите удалить этот проект?',
areYouSureYouWantToDeleteThisTask: 'Вы уверены, что хотите удалить эту задачу?',
areYouSureYouWantToDeleteThisUser: 'Вы уверены, что хотите удалить этого пользователя?',
areYouSureYouWantToRemoveThisMemberFromProject:
'Вы уверены, что хотите удалить этого участника из проекта?',
areYouSureYouWantToRemoveThisMemberFromProject: 'Вы уверены, что хотите удалить этого участника из проекта?',
boardNotFound: 'Доска не найдена',
cardActions: 'Действия с карточкой',
cardNotFound: 'Карточка не найдена',
@ -76,10 +74,8 @@ export default {
notifications: 'Уведомления',
noUnreadNotifications: 'Уведомлений нет',
openBoard: 'Откройте доску',
pageNotFound: 'Страница не найдена',
projectNotFound: 'Доска не найдена',
refreshPageToLoadLastDataAndReceiveUpdates:
'<0>Обновите страницу</0>, чтобы загрузить<br />актуальные данные и получать обновления',
refreshPageToLoadLastDataAndReceiveUpdates: '<0>Обновите страницу</0>, чтобы загрузить<br />актуальные данные и получать обновления',
removeMember: 'Удаление участника',
seconds: 'Секунды',
taskActions: 'Действия с задачей',
@ -90,10 +86,8 @@ export default {
userAddedThisCardToList: '<0>{{user}}</0><1> добавил(а) эту карточку в {{list}}</1>',
userIsAlreadyExist: 'Пользователь уже существует',
userLeftNewCommentToCard: '{{user}} оставил(а) комментарий «{{comment}}» к <2>{{card}}</2>',
userMovedCardFromListToList:
'{{user}} переместил(а) <2>{{card}}</2> из {{fromList}} в {{toList}}',
userMovedThisCardFromListToList:
'<0>{{user}}</0><1> переместил(а) эту карточку из {{fromList}} в {{toList}}</1>',
userMovedCardFromListToList: '{{user}} переместил(а) <2>{{card}}</2> из {{fromList}} в {{toList}}',
userMovedThisCardFromListToList: '<0>{{user}}</0><1> переместил(а) эту карточку из {{fromList}} в {{toList}}</1>',
users: 'Пользователи',
writeComment: 'Напишите комментарий...',
},

View file

@ -6,6 +6,7 @@ export default {
invalidPassword: 'Неверный пароль',
logInToPlanka: 'Вход в Planka',
noInternetConnection: 'Нет соединения',
pageNotFound: 'Страница не найдена',
password: 'Пароль',
projectManagment: 'Управление проектами',
serverConnectionFailed: 'Не могу подключиться к серверу',

View file

@ -1,135 +0,0 @@
// This optional code is used to register a service worker.
// register() is not called by default.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on subsequent visits to a page, after all the
// existing tabs open on the page have been closed, since previously cached
// resources are updated in the background.
// To learn more about the benefits of this model and instructions on how to
// opt-in, read http://bit.ly/CRA-PWA
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.1/8 is considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export function register(config) {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Let's check if a service worker still exists or not.
checkValidServiceWorker(swUrl, config);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit http://bit.ly/CRA-PWA'
);
});
} else {
// Is not localhost. Just register service worker
registerValidSW(swUrl, config);
}
});
}
}
function registerValidSW(swUrl, config) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker == null) {
return;
}
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the updated precached content has been fetched,
// but the previous service worker will still serve the older
// content until all client tabs are closed.
console.log(
'New content is available and will be used when all ' +
'tabs for this page are closed. See http://bit.ly/CRA-PWA.'
);
// Execute callback
if (config && config.onUpdate) {
config.onUpdate(registration);
}
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
// Execute callback
if (config && config.onSuccess) {
config.onSuccess(registration);
}
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl, config) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl)
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
const contentType = response.headers.get('content-type');
if (
response.status === 404 ||
(contentType != null && contentType.indexOf('javascript') === -1)
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl, config);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready.then(registration => {
registration.unregister();
});
}
}

BIN
demo.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 792 KiB

After

Width:  |  Height:  |  Size: 1.1 MiB

Before After
Before After

35
docker-compose.yml Normal file
View file

@ -0,0 +1,35 @@
version: '3'
services:
planka:
image: meltyshev/planka:latest
command: >
bash -c
"for i in `seq 1 30`; do
npm start &&
s=$$? && break || s=$$?;
echo \"Tried $$i times. Waiting 5 seconds...\";
sleep 5;
done; (exit $$s)"
restart: unless-stopped
volumes:
- uploads:/app/public/uploads
ports:
- 3000:1337
environment:
- BASE_URL=http://localhost:3000
- DATABASE_URL=postgresql://postgres@postgres/planka
depends_on:
- postgres
postgres:
image: postgres:alpine
restart: unless-stopped
volumes:
- db-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=planka
volumes:
uploads:
db-data:

View file

@ -1,3 +1,3 @@
TZ=UTC
DATABASE_URL=postgresql://localhost/planka
BASE_URL=http://localhost:1337
DATABASE_URL=postgresql://localhost/planka

16
server/.gitignore vendored
View file

@ -46,9 +46,6 @@
config/local.js
.env.local
.env.*.local
################################################
# Dependencies
#
@ -103,10 +100,7 @@ node_modules
# Temporary files generated by Sails/Waterline.
################################################
.tmp/*
!.tmp/public
.tmp/public/uploads/*
!.tmp/public/uploads/.gitkeep
.tmp
################################################
# Miscellaneous
@ -130,3 +124,11 @@ lib-cov
*.log
*.out
*.pid
public/*
!public/uploads
public/uploads/*
!public/uploads/.gitkeep
views/*
!views/.gitkeep

View file

@ -2,15 +2,17 @@
"generators": {
"modules": {}
},
"_generatedWith": {
"sails": "1.1.0",
"sails-generate": "1.16.4"
},
"hooks": {
"blueprints": false,
"grunt": false,
"i18n": false,
"session": false,
"views": false
"session": false
},
"paths": {
"public": "public"
},
"_generatedWith": {
"sails": "1.1.0",
"sails-generate": "1.16.4"
}
}

View file

@ -20,6 +20,6 @@ module.exports.custom = {
baseUrl: process.env.BASE_URL,
uploadsPath: path.join(sails.config.paths.tmp, 'public', 'uploads'),
uploadsPath: path.join(sails.config.paths.public, 'uploads'),
uploadsUrl: `${process.env.BASE_URL}/uploads`,
};

View file

@ -19,6 +19,7 @@
* https://sailsjs.com/docs/concepts/deployment
*/
const url = require('url');
const path = require('path');
const sails = require('sails');
@ -246,7 +247,7 @@ module.exports = {
***************************************************************************/
onlyAllowOrigins: [
process.env.BASE_URL,
new url.URL(process.env.BASE_URL).origin,
],
/***************************************************************************
@ -360,7 +361,7 @@ module.exports = {
custom: {
baseUrl: process.env.BASE_URL,
uploadsPath: path.join(sails.config.paths.tmp, 'public', 'uploads'),
uploadsPath: path.join(sails.config.paths.public, 'uploads'),
uploadsUrl: `${process.env.BASE_URL}/uploads`,
// mailgunDomain: 'mg.example.com',

View file

@ -9,55 +9,60 @@
*/
module.exports.routes = {
'POST /access-tokens': 'access-tokens/create',
'POST /api/access-tokens': 'access-tokens/create',
'GET /users': 'users/index',
'POST /users': 'users/create',
'GET /users/me': 'users/show',
'PATCH /users/:id': 'users/update',
'POST /users/:id/upload-avatar': 'users/upload-avatar',
'DELETE /users/:id': 'users/delete',
'GET /api/users': 'users/index',
'POST /api/users': 'users/create',
'GET /api/users/me': 'users/show',
'PATCH /api/users/:id': 'users/update',
'POST /api/users/:id/upload-avatar': 'users/upload-avatar',
'DELETE /api/users/:id': 'users/delete',
'GET /projects': 'projects/index',
'POST /projects': 'projects/create',
'PATCH /projects/:id': 'projects/update',
'DELETE /projects/:id': 'projects/delete',
'GET /api/projects': 'projects/index',
'POST /api/projects': 'projects/create',
'PATCH /api/projects/:id': 'projects/update',
'DELETE /api/projects/:id': 'projects/delete',
'POST /projects/:projectId/memberships': 'project-memberships/create',
'DELETE /project-memberships/:id': 'project-memberships/delete',
'POST /api/projects/:projectId/memberships': 'project-memberships/create',
'DELETE /api/project-memberships/:id': 'project-memberships/delete',
'POST /projects/:projectId/boards': 'boards/create',
'GET /boards/:id': 'boards/show',
'PATCH /boards/:id': 'boards/update',
'DELETE /boards/:id': 'boards/delete',
'POST /api/projects/:projectId/boards': 'boards/create',
'GET /api/boards/:id': 'boards/show',
'PATCH /api/boards/:id': 'boards/update',
'DELETE /api/boards/:id': 'boards/delete',
'POST /boards/:boardId/lists': 'lists/create',
'PATCH /lists/:id': 'lists/update',
'DELETE /lists/:id': 'lists/delete',
'POST /api/boards/:boardId/lists': 'lists/create',
'PATCH /api/lists/:id': 'lists/update',
'DELETE /api/lists/:id': 'lists/delete',
'POST /boards/:boardId/labels': 'labels/create',
'PATCH /labels/:id': 'labels/update',
'DELETE /labels/:id': 'labels/delete',
'POST /api/boards/:boardId/labels': 'labels/create',
'PATCH /api/labels/:id': 'labels/update',
'DELETE /api/labels/:id': 'labels/delete',
'POST /lists/:listId/cards': 'cards/create',
'GET /cards/:id': 'cards/show',
'PATCH /cards/:id': 'cards/update',
'DELETE /cards/:id': 'cards/delete',
'POST /cards/:cardId/memberships': 'card-memberships/create',
'DELETE /cards/:cardId/memberships': 'card-memberships/delete',
'POST /cards/:cardId/labels': 'card-labels/create',
'DELETE /cards/:cardId/labels/:labelId': 'card-labels/delete',
'POST /api/lists/:listId/cards': 'cards/create',
'GET /api/cards/:id': 'cards/show',
'PATCH /api/cards/:id': 'cards/update',
'DELETE /api/cards/:id': 'cards/delete',
'POST /api/cards/:cardId/memberships': 'card-memberships/create',
'DELETE /api/cards/:cardId/memberships': 'card-memberships/delete',
'POST /api/cards/:cardId/labels': 'card-labels/create',
'DELETE /api/cards/:cardId/labels/:labelId': 'card-labels/delete',
'POST /cards/:cardId/tasks': 'tasks/create',
'PATCH /tasks/:id': 'tasks/update',
'DELETE /tasks/:id': 'tasks/delete',
'POST /api/cards/:cardId/tasks': 'tasks/create',
'PATCH /api/tasks/:id': 'tasks/update',
'DELETE /api/tasks/:id': 'tasks/delete',
'GET /cards/:cardId/actions': 'actions/index',
'GET /api/cards/:cardId/actions': 'actions/index',
'POST /cards/:cardId/comment-actions': 'comment-actions/create',
'PATCH /comment-actions/:id': 'comment-actions/update',
'DELETE /comment-actions/:id': 'comment-actions/delete',
'POST /api/cards/:cardId/comment-actions': 'comment-actions/create',
'PATCH /api/comment-actions/:id': 'comment-actions/update',
'DELETE /api/comment-actions/:id': 'comment-actions/delete',
'GET /notifications': 'notifications/index',
'PATCH /notifications/:ids': 'notifications/update'
'GET /api/notifications': 'notifications/index',
'PATCH /api/notifications/:ids': 'notifications/update',
'GET /*': {
view: 'index',
skipAssets: true,
},
};

View file

@ -24,7 +24,7 @@ module.exports.views = {
* *
***************************************************************************/
// extension: 'ejs',
extension: 'html',
/***************************************************************************
* *
@ -35,5 +35,5 @@ module.exports.views = {
* *
***************************************************************************/
layout: 'layouts/layout',
layout: false,
};

19
server/db/init.js Normal file
View file

@ -0,0 +1,19 @@
const config = require('./knexfile');
const knex = require('knex')(config);
(async function () {
try {
const exists = await knex.schema.hasTable(config.migrations.tableName);
if (!exists) {
await knex.migrate.latest();
await knex.seed.run();
}
} catch (error) {
process.exitCode = 1;
throw error;
} finally {
knex.destroy();
}
})();

View file

@ -1,15 +1,15 @@
const path = require('path');
const _ = require('lodash');
require('dotenv').config({
path: path.resolve(__dirname, '../.env')
});
// Update with your config settings.
module.exports = {
client: 'pg',
connection: process.env.DATABASE_URL,
migrations: {
tableName: 'migration'
}
},
wrapIdentifier: (value, origImpl) => origImpl(_.snakeCase(value))
};

View file

@ -4,13 +4,11 @@ exports.seed = function(knex) {
const date = new Date().toUTCString();
return knex('user').insert({
/* eslint-disable camelcase */
email: 'demo@demo.demo',
password: bcrypt.hashSync('demo', 10),
is_admin: true,
isAdmin: true,
name: 'Demo Demo',
created_at: date,
updated_at: date
/* eslint-enable camelcase */
createdAt: date,
updatedAt: date
});
};

1833
server/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -4,10 +4,11 @@
"scripts": {
"console": "dotenv sails console",
"custom-tests": "echo \"(No other custom tests yet.)\" && echo",
"db:init": "cd db && node init.js",
"db:migrate": "knex migrate:latest --cwd db",
"db:seed": "knex seed:run --cwd db",
"lint": "node_modules/@sailshq/eslint/bin/eslint.js . --max-warnings=0 --report-unused-disable-directives && echo '✔ Your .js files look good.'",
"start": "NODE_ENV=production node app.js",
"start": "npm run db:init && NODE_ENV=production node app.js",
"start:dev": "nodemon",
"test": "npm run lint && npm run custom-tests && echo 'Done.'"
},
@ -23,13 +24,13 @@
"sails-hook-orm": "^2.1.1",
"sails-hook-sockets": "^2.0.0",
"sails-postgresql": "^1.0.1",
"sharp": "^0.23.0"
"sharp": "^0.23.1"
},
"devDependencies": {
"@sailshq/eslint": "^4.19.3",
"js-yaml": ">=3.13.1",
"mixin-deep": ">=1.3.2",
"nodemon": "^1.19.2",
"nodemon": "^1.19.3",
"set-value": ">=2.0.1"
},
"engines": {

0
server/views/.gitkeep Normal file
View file