mirror of
https://github.com/Haiti-Distributed-Healthcare-System/hdhs.git
synced 2026-10-26 17:35:23 +00:00
Merge branch 'dev' into feature/fmp_to_postgresql_t17
This commit is contained in:
commit
5de0b8641f
36 files changed
+15779
-6086
No files matched your search
@@ -17,6 +17,7 @@ jobs:
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- run: docker-compose -f dev-docker-compose.yml up --detach
|
||||
- run: docker exec haiti_pwa npm run lint
|
||||
- run: docker exec haiti_pwa npm run test:cov
|
||||
- run: docker exec haiti_pwa npm run cy:run
|
||||
- run: docker exec haiti_pwa npm run build
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
module.exports = {
|
||||
parser: "@typescript-eslint/parser", // Specifies the ESLint parser
|
||||
extends: [
|
||||
"plugin:react/recommended", // Uses the recommended rules from @eslint-plugin-react
|
||||
"plugin:@typescript-eslint/recommended", // Uses the recommended rules from the @typescript-eslint/eslint-plugin
|
||||
"prettier/@typescript-eslint", // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
|
||||
"plugin:prettier/recommended", // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
|
||||
sourceType: "module", // Allows for the use of imports
|
||||
ecmaFeatures: {
|
||||
jsx: true, // Allows for the parsing of JSX
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
"@typescript-eslint/no-empty-interface": "off",
|
||||
"@typescript-eslint/ban-ts-ignore": "off",
|
||||
},
|
||||
settings: {
|
||||
react: {
|
||||
version: "detect", // Tells eslint-plugin-react to automatically detect the version of React to use
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
semi: false,
|
||||
trailingComma: 'all',
|
||||
singleQuote: true,
|
||||
printWidth: 80,
|
||||
tabWidth: 4,
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
|
||||
}
|
||||
Vendored
+31
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"eslint.autoFixOnSave": true,
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
{
|
||||
"language": "typescript",
|
||||
"autoFix": true
|
||||
},
|
||||
{
|
||||
"language": "typescriptreact",
|
||||
"autoFix": true
|
||||
}
|
||||
],
|
||||
"editor.formatOnSave": true,
|
||||
"[javascript]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[javascriptreact]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.formatOnSave": true
|
||||
},
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,10 @@
|
||||
/// <reference types="cypress" />
|
||||
|
||||
describe('Homepage', () => {
|
||||
it('shows login button', function () {
|
||||
cy.visit('http://localhost:3000')
|
||||
cy.get('.am-button').contains('Login')
|
||||
})
|
||||
it('shows login button', function () {
|
||||
cy.visit('http://localhost:3000')
|
||||
cy.get('.am-button').contains('Login')
|
||||
})
|
||||
})
|
||||
|
||||
export {};
|
||||
export {}
|
||||
Generated
+443
-140
@@ -1158,6 +1158,34 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@cypress/request": {
|
||||
"version": "2.88.5",
|
||||
"resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.5.tgz",
|
||||
"integrity": "sha512-TzEC1XMi1hJkywWpRfD2clreTa/Z+lOrXDCxxBTBPEcY5azdPi56A6Xw+O4tWJnaJH3iIE7G5aDXZC6JgRZLcA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.3",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.5.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"@cypress/webpack-preprocessor": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@cypress/webpack-preprocessor/-/webpack-preprocessor-4.1.3.tgz",
|
||||
@@ -1211,9 +1239,9 @@
|
||||
"integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA=="
|
||||
},
|
||||
"@hapi/hoek": {
|
||||
"version": "8.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.0.tgz",
|
||||
"integrity": "sha512-7XYT10CZfPsH7j9F1Jmg1+d0ezOux2oM2GfArAzLwWe4mE2Dr3hVjsAL6+TFY49RRJlCdJDMw3nJsLFroTc8Kw=="
|
||||
"version": "8.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz",
|
||||
"integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow=="
|
||||
},
|
||||
"@hapi/joi": {
|
||||
"version": "15.1.1",
|
||||
@@ -1653,6 +1681,34 @@
|
||||
"@babel/types": "^7.3.0"
|
||||
}
|
||||
},
|
||||
"@types/blob-util": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/blob-util/-/blob-util-1.3.3.tgz",
|
||||
"integrity": "sha512-4ahcL/QDnpjWA2Qs16ZMQif7HjGP2cw3AGjHabybjw7Vm1EKu+cfQN1D78BaZbS1WJNa1opSMF5HNMztx7lR0w==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/bluebird": {
|
||||
"version": "3.5.29",
|
||||
"resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.29.tgz",
|
||||
"integrity": "sha512-kmVtnxTuUuhCET669irqQmPAez4KFnFVKvpleVRyfC3g+SHD1hIkFZcWLim9BVcwUBLO59o8VZE4yGCmTif8Yw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/chai": {
|
||||
"version": "4.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.7.tgz",
|
||||
"integrity": "sha512-luq8meHGYwvky0O7u0eQZdA7B4Wd9owUCqvbw2m3XCrCU8mplYOujMBbvyS547AxJkC+pGnd0Cm15eNxEUNU8g==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/chai-jquery": {
|
||||
"version": "1.1.40",
|
||||
"resolved": "https://registry.npmjs.org/@types/chai-jquery/-/chai-jquery-1.1.40.tgz",
|
||||
"integrity": "sha512-mCNEZ3GKP7T7kftKeIs7QmfZZQM7hslGSpYzKbOlR2a2HCFf9ph4nlMRA9UnuOETeOQYJVhJQK7MwGqNZVyUtQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/chai": "*",
|
||||
"@types/jquery": "*"
|
||||
}
|
||||
},
|
||||
"@types/color-name": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
|
||||
@@ -1678,6 +1734,11 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/history": {
|
||||
"version": "4.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.5.tgz",
|
||||
"integrity": "sha512-wLD/Aq2VggCJXSjxEwrMafIP51Z+13H78nXIX0ABEuIGhmB5sNGbR113MOKo+yfw+RDo1ZU3DM6yfnnRF/+ouw=="
|
||||
},
|
||||
"@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz",
|
||||
@@ -1708,16 +1769,37 @@
|
||||
"jest-diff": "^24.3.0"
|
||||
}
|
||||
},
|
||||
"@types/jquery": {
|
||||
"version": "3.3.31",
|
||||
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.31.tgz",
|
||||
"integrity": "sha512-Lz4BAJihoFw5nRzKvg4nawXPzutkv7wmfQ5121avptaSIXlDNJCUuxZxX/G+9EVidZGuO0UBlk+YjKbwRKJigg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/sizzle": "*"
|
||||
}
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz",
|
||||
"integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA=="
|
||||
},
|
||||
"@types/lodash": {
|
||||
"version": "4.14.149",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz",
|
||||
"integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/minimatch": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
|
||||
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
|
||||
},
|
||||
"@types/mocha": {
|
||||
"version": "5.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz",
|
||||
"integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "12.12.26",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.26.tgz",
|
||||
@@ -1755,6 +1837,25 @@
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-router": {
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.5.tgz",
|
||||
"integrity": "sha512-RZPdCtZympi6X7EkGyaU7ISiAujDYTWgqMF9owE3P6efITw27IWQykcti0BvA5h4Mu1LLl5rxrpO3r8kHyUZ/Q==",
|
||||
"requires": {
|
||||
"@types/history": "*",
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-router-dom": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.4.tgz",
|
||||
"integrity": "sha512-LO0z5qqSfWdYtCNsRm8/OMnnkv52hwADJKrAfpKIyfHclORllcgAMGypEA7ajHm38+jOonKLx8nPygNAAZGxtg==",
|
||||
"requires": {
|
||||
"@types/history": "*",
|
||||
"@types/react": "*",
|
||||
"@types/react-router": "*"
|
||||
}
|
||||
},
|
||||
"@types/react-test-renderer": {
|
||||
"version": "16.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-16.9.2.tgz",
|
||||
@@ -1764,6 +1865,22 @@
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/sinon": {
|
||||
"version": "7.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.5.1.tgz",
|
||||
"integrity": "sha512-EZQUP3hSZQyTQRfiLqelC9NMWd1kqLcmQE0dMiklxBkgi84T+cHOhnKpgk4NnOWpGX863yE6+IaGnOXUNFqDnQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/sinon-chai": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.3.tgz",
|
||||
"integrity": "sha512-TOUFS6vqS0PVL1I8NGVSNcFaNJtFoyZPXZ5zur+qlhDfOmQECZZM4H4kKgca6O8L+QceX/ymODZASfUfn+y4yQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/chai": "*",
|
||||
"@types/sinon": "*"
|
||||
}
|
||||
},
|
||||
"@types/sizzle": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz",
|
||||
@@ -1816,42 +1933,42 @@
|
||||
"integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw=="
|
||||
},
|
||||
"@typescript-eslint/eslint-plugin": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.19.0.tgz",
|
||||
"integrity": "sha512-u7IcQ9qwsB6U806LupZmINRnQjC+RJyv36sV/ugaFWMHTbFm/hlLTRx3gGYJgHisxcGSTnf+I/fPDieRMhPSQQ==",
|
||||
"version": "2.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.28.0.tgz",
|
||||
"integrity": "sha512-w0Ugcq2iatloEabQP56BRWJowliXUP5Wv6f9fKzjJmDW81hOTBxRoJ4LoEOxRpz9gcY51Libytd2ba3yLmSOfg==",
|
||||
"requires": {
|
||||
"@typescript-eslint/experimental-utils": "2.19.0",
|
||||
"eslint-utils": "^1.4.3",
|
||||
"@typescript-eslint/experimental-utils": "2.28.0",
|
||||
"functional-red-black-tree": "^1.0.1",
|
||||
"regexpp": "^3.0.0",
|
||||
"tsutils": "^3.17.1"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/experimental-utils": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.19.0.tgz",
|
||||
"integrity": "sha512-zwpg6zEOPbhB3+GaQfufzlMUOO6GXCNZq6skk+b2ZkZAIoBhVoanWK255BS1g5x9bMwHpLhX0Rpn5Fc3NdCZdg==",
|
||||
"version": "2.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.28.0.tgz",
|
||||
"integrity": "sha512-4SL9OWjvFbHumM/Zh/ZeEjUFxrYKtdCi7At4GyKTbQlrj1HcphIDXlje4Uu4cY+qzszR5NdVin4CCm6AXCjd6w==",
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.3",
|
||||
"@typescript-eslint/typescript-estree": "2.19.0",
|
||||
"eslint-scope": "^5.0.0"
|
||||
"@typescript-eslint/typescript-estree": "2.28.0",
|
||||
"eslint-scope": "^5.0.0",
|
||||
"eslint-utils": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/parser": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.19.0.tgz",
|
||||
"integrity": "sha512-s0jZoxAWjHnuidbbN7aA+BFVXn4TCcxEVGPV8lWMxZglSs3NRnFFAlL+aIENNmzB2/1jUJuySi6GiM6uACPmpg==",
|
||||
"version": "2.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.28.0.tgz",
|
||||
"integrity": "sha512-RqPybRDquui9d+K86lL7iPqH6Dfp9461oyqvlXMNtap+PyqYbkY5dB7LawQjDzot99fqzvS0ZLZdfe+1Bt3Jgw==",
|
||||
"requires": {
|
||||
"@types/eslint-visitor-keys": "^1.0.0",
|
||||
"@typescript-eslint/experimental-utils": "2.19.0",
|
||||
"@typescript-eslint/typescript-estree": "2.19.0",
|
||||
"@typescript-eslint/experimental-utils": "2.28.0",
|
||||
"@typescript-eslint/typescript-estree": "2.28.0",
|
||||
"eslint-visitor-keys": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.19.0.tgz",
|
||||
"integrity": "sha512-n6/Xa37k0jQdwpUszffi19AlNbVCR0sdvCs3DmSKMD7wBttKY31lhD2fug5kMD91B2qW4mQldaTEc1PEzvGu8w==",
|
||||
"version": "2.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.28.0.tgz",
|
||||
"integrity": "sha512-HDr8MP9wfwkiuqzRVkuM3BeDrOC4cKbO5a6BymZBHUt5y/2pL0BXD6I/C/ceq2IZoHWhcASk+5/zo+dwgu9V8Q==",
|
||||
"requires": {
|
||||
"debug": "^4.1.1",
|
||||
"eslint-visitor-keys": "^1.1.0",
|
||||
@@ -2067,9 +2184,9 @@
|
||||
}
|
||||
},
|
||||
"acorn": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
|
||||
"integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ=="
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
|
||||
"integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg=="
|
||||
},
|
||||
"acorn-globals": {
|
||||
"version": "4.3.4",
|
||||
@@ -2088,9 +2205,9 @@
|
||||
}
|
||||
},
|
||||
"acorn-jsx": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz",
|
||||
"integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw=="
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz",
|
||||
"integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ=="
|
||||
},
|
||||
"acorn-walk": {
|
||||
"version": "6.2.0",
|
||||
@@ -4374,13 +4491,24 @@
|
||||
"integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk="
|
||||
},
|
||||
"cypress": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-4.2.0.tgz",
|
||||
"integrity": "sha512-8LdreL91S/QiTCLYLNbIjLL8Ht4fJmu/4HGLxUI20Tc7JSfqEfCmXELrRfuPT0kjosJwJJZacdSji9XSRkPKUw==",
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cypress/-/cypress-4.4.0.tgz",
|
||||
"integrity": "sha512-ZpsV3pVemANGi4Cxu0UIqFv23uHdDJZYlKY+8P/eixujCpI1TQ5RSPBp2grfV3ZvlGYrOXPJY44j9iEh1xoQug==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@cypress/listr-verbose-renderer": "0.4.1",
|
||||
"@cypress/request": "2.88.5",
|
||||
"@cypress/xvfb": "1.2.4",
|
||||
"@types/blob-util": "1.3.3",
|
||||
"@types/bluebird": "3.5.29",
|
||||
"@types/chai": "4.2.7",
|
||||
"@types/chai-jquery": "1.1.40",
|
||||
"@types/jquery": "3.3.31",
|
||||
"@types/lodash": "4.14.149",
|
||||
"@types/minimatch": "3.0.3",
|
||||
"@types/mocha": "5.2.7",
|
||||
"@types/sinon": "7.5.1",
|
||||
"@types/sinon-chai": "3.2.3",
|
||||
"@types/sizzle": "2.3.2",
|
||||
"arch": "2.1.1",
|
||||
"bluebird": "3.7.2",
|
||||
@@ -4394,7 +4522,7 @@
|
||||
"eventemitter2": "4.1.2",
|
||||
"execa": "1.0.0",
|
||||
"executable": "4.1.1",
|
||||
"extract-zip": "1.6.7",
|
||||
"extract-zip": "1.7.0",
|
||||
"fs-extra": "8.1.0",
|
||||
"getos": "3.1.4",
|
||||
"is-ci": "2.0.0",
|
||||
@@ -4403,12 +4531,11 @@
|
||||
"listr": "0.14.3",
|
||||
"lodash": "4.17.15",
|
||||
"log-symbols": "3.0.0",
|
||||
"minimist": "1.2.2",
|
||||
"minimist": "1.2.5",
|
||||
"moment": "2.24.0",
|
||||
"ospath": "1.2.2",
|
||||
"pretty-bytes": "5.3.0",
|
||||
"ramda": "0.26.1",
|
||||
"request": "github:cypress-io/request#b5af0d1fa47eec97ba980cde90a13e69a2afcd16",
|
||||
"request-progress": "3.0.0",
|
||||
"supports-color": "7.1.0",
|
||||
"tmp": "0.1.0",
|
||||
@@ -4429,39 +4556,6 @@
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.2.tgz",
|
||||
"integrity": "sha512-rIqbOrKb8GJmx/5bc2M0QchhUouMXSpd1RTclXsB41JdL+VtnojfaJR+h7F9k18/4kHUsBFgk80Uk+q569vjPA==",
|
||||
"dev": true
|
||||
},
|
||||
"request": {
|
||||
"version": "github:cypress-io/request#b5af0d1fa47eec97ba980cde90a13e69a2afcd16",
|
||||
"from": "github:cypress-io/request#b5af0d1fa47eec97ba980cde90a13e69a2afcd16",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.3",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.5.0",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
|
||||
@@ -4532,6 +4626,11 @@
|
||||
"integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
|
||||
"dev": true
|
||||
},
|
||||
"debounce": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz",
|
||||
"integrity": "sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg=="
|
||||
},
|
||||
"debug": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||
@@ -4911,6 +5010,37 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"easy-peasy": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/easy-peasy/-/easy-peasy-3.3.0.tgz",
|
||||
"integrity": "sha512-wkTDAG+nRy+4g8Z3/k1vuTyrhxet19oY5MCmuRgOObm8dtZ2m+g5Mk/sdf3UWPuyx/sKIYH5Fy/HXab8iNKjTQ==",
|
||||
"requires": {
|
||||
"debounce": "^1.2.0",
|
||||
"immer-peasy": "3.1.3",
|
||||
"is-plain-object": "^3.0.0",
|
||||
"memoizerific": "^1.11.3",
|
||||
"prop-types": "^15.6.2",
|
||||
"redux": "^4.0.5",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"symbol-observable": "^1.2.0",
|
||||
"ts-toolbelt": "^6.1.6"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-plain-object": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz",
|
||||
"integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==",
|
||||
"requires": {
|
||||
"isobject": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"isobject": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz",
|
||||
"integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
@@ -5176,10 +5306,18 @@
|
||||
"v8-compile-cache": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint-utils": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
|
||||
"integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
|
||||
"requires": {
|
||||
"eslint-visitor-keys": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"globals": {
|
||||
"version": "12.3.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz",
|
||||
"integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==",
|
||||
"version": "12.4.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
|
||||
"integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
|
||||
"requires": {
|
||||
"type-fest": "^0.8.1"
|
||||
}
|
||||
@@ -5205,6 +5343,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"eslint-config-prettier": {
|
||||
"version": "6.10.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.10.1.tgz",
|
||||
"integrity": "sha512-svTy6zh1ecQojvpbJSgH3aei/Rt7C6i090l5f2WQ4aB05lYHeZIR1qL4wZyyILTbtmnbHP5Yn8MrsOJMGa8RkQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"get-stdin": "^6.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"get-stdin": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
|
||||
"integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"eslint-config-react-app": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-5.2.0.tgz",
|
||||
@@ -5482,6 +5637,15 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"eslint-plugin-prettier": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.3.tgz",
|
||||
"integrity": "sha512-+HG5jmu/dN3ZV3T6eCD7a4BlAySdN7mLIbJYo0z1cFQuI+r2DiTJEFeF68ots93PsnrMxbzIZ2S/ieX+mkrBeQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"prettier-linter-helpers": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"eslint-plugin-react": {
|
||||
"version": "7.18.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.18.0.tgz",
|
||||
@@ -5523,9 +5687,9 @@
|
||||
}
|
||||
},
|
||||
"eslint-utils": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
|
||||
"integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz",
|
||||
"integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==",
|
||||
"requires": {
|
||||
"eslint-visitor-keys": "^1.1.0"
|
||||
}
|
||||
@@ -5536,12 +5700,12 @@
|
||||
"integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A=="
|
||||
},
|
||||
"espree": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz",
|
||||
"integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==",
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz",
|
||||
"integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==",
|
||||
"requires": {
|
||||
"acorn": "^7.1.0",
|
||||
"acorn-jsx": "^5.1.0",
|
||||
"acorn": "^7.1.1",
|
||||
"acorn-jsx": "^5.2.0",
|
||||
"eslint-visitor-keys": "^1.1.0"
|
||||
}
|
||||
},
|
||||
@@ -5551,11 +5715,18 @@
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
|
||||
},
|
||||
"esquery": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
|
||||
"integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
|
||||
"integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
|
||||
"requires": {
|
||||
"estraverse": "^4.0.0"
|
||||
"estraverse": "^5.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"estraverse": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz",
|
||||
"integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"esrecurse": {
|
||||
@@ -5900,15 +6071,15 @@
|
||||
}
|
||||
},
|
||||
"extract-zip": {
|
||||
"version": "1.6.7",
|
||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
|
||||
"integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz",
|
||||
"integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"concat-stream": "1.6.2",
|
||||
"debug": "2.6.9",
|
||||
"mkdirp": "0.5.1",
|
||||
"yauzl": "2.4.1"
|
||||
"concat-stream": "^1.6.2",
|
||||
"debug": "^2.6.9",
|
||||
"mkdirp": "^0.5.4",
|
||||
"yauzl": "^2.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
@@ -5925,15 +6096,6 @@
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"dev": true
|
||||
},
|
||||
"yauzl": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
|
||||
"integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fd-slicer": "~1.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -5947,6 +6109,12 @@
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
|
||||
"integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
|
||||
},
|
||||
"fast-diff": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
|
||||
"integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
|
||||
"dev": true
|
||||
},
|
||||
"fast-glob": {
|
||||
"version": "2.2.7",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz",
|
||||
@@ -6037,9 +6205,9 @@
|
||||
}
|
||||
},
|
||||
"fd-slicer": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
|
||||
"integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
"integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pend": "~1.2.0"
|
||||
@@ -6165,9 +6333,9 @@
|
||||
}
|
||||
},
|
||||
"flatted": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
|
||||
"integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg=="
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
|
||||
"integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA=="
|
||||
},
|
||||
"flatten": {
|
||||
"version": "1.0.3",
|
||||
@@ -6636,6 +6804,11 @@
|
||||
"resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz",
|
||||
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE="
|
||||
},
|
||||
"gud": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
|
||||
"integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
|
||||
},
|
||||
"gzip-size": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz",
|
||||
@@ -6771,6 +6944,19 @@
|
||||
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
|
||||
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ=="
|
||||
},
|
||||
"history": {
|
||||
"version": "4.10.1",
|
||||
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
|
||||
"integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"loose-envify": "^1.2.0",
|
||||
"resolve-pathname": "^3.0.0",
|
||||
"tiny-invariant": "^1.0.2",
|
||||
"tiny-warning": "^1.0.0",
|
||||
"value-equal": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"hmac-drbg": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
|
||||
@@ -6781,6 +6967,14 @@
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"hoist-non-react-statics": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||
"requires": {
|
||||
"react-is": "^16.7.0"
|
||||
}
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.5",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz",
|
||||
@@ -7028,6 +7222,11 @@
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-1.10.0.tgz",
|
||||
"integrity": "sha512-O3sR1/opvCDGLEVcvrGTMtLac8GJ5IwZC4puPrLuRj3l7ICKvkmA0vGuU9OW8mV9WIBRnaxp5GJh9IEAaNOoYg=="
|
||||
},
|
||||
"immer-peasy": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/immer-peasy/-/immer-peasy-3.1.3.tgz",
|
||||
"integrity": "sha512-WzoZ96A93jOmcDOLNChMWAqy+ZU8vEYQx2DcKjgo7P5SToiJs+GL+5yQbWzH8X02Lhvv6xrGgVNa1xbki66Eow=="
|
||||
},
|
||||
"import-cwd": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
|
||||
@@ -8959,12 +9158,12 @@
|
||||
}
|
||||
},
|
||||
"loader-fs-cache": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.2.tgz",
|
||||
"integrity": "sha512-70IzT/0/L+M20jUlEqZhZyArTU6VKLRTYRDAYN26g4jfzpJqjipLL3/hgYpySqI9PwsVRHHFja0LfEmsx9X2Cw==",
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz",
|
||||
"integrity": "sha512-ldcgZpjNJj71n+2Mf6yetz+c9bM4xpKtNds4LbqXzU/PTdeAX0g3ytnU1AJMEcTk2Lex4Smpe3Q/eCTsvUBxbA==",
|
||||
"requires": {
|
||||
"find-cache-dir": "^0.1.1",
|
||||
"mkdirp": "0.5.1"
|
||||
"mkdirp": "^0.5.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"find-cache-dir": {
|
||||
@@ -9293,6 +9492,11 @@
|
||||
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
|
||||
"integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0="
|
||||
},
|
||||
"map-or-similar": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/map-or-similar/-/map-or-similar-1.5.0.tgz",
|
||||
"integrity": "sha1-beJlMXSt+12e3DPGnT6Sobdvrwg="
|
||||
},
|
||||
"map-visit": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
|
||||
@@ -9331,6 +9535,14 @@
|
||||
"p-is-promise": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"memoizerific": {
|
||||
"version": "1.11.3",
|
||||
"resolved": "https://registry.npmjs.org/memoizerific/-/memoizerific-1.11.3.tgz",
|
||||
"integrity": "sha1-fIekZGREwy11Q4VwkF8tvRsagFo=",
|
||||
"requires": {
|
||||
"map-or-similar": "^1.5.0"
|
||||
}
|
||||
},
|
||||
"memory-fs": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz",
|
||||
@@ -9586,6 +9798,16 @@
|
||||
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz",
|
||||
"integrity": "sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY="
|
||||
},
|
||||
"mini-create-react-context": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.3.2.tgz",
|
||||
"integrity": "sha512-2v+OeetEyliMt5VHMXsBhABoJ0/M4RCe7fatd/fBy6SMiKazUSEt3gxxypfnk2SHMkdBYvorHRoQxuGoiwbzAw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.4.0",
|
||||
"gud": "^1.0.0",
|
||||
"tiny-warning": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"mini-css-extract-plugin": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz",
|
||||
@@ -9628,9 +9850,9 @@
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
|
||||
},
|
||||
"minipass": {
|
||||
"version": "3.1.1",
|
||||
@@ -9717,18 +9939,11 @@
|
||||
}
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
|
||||
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
},
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
}
|
||||
"minimist": "^1.2.5"
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
@@ -11693,6 +11908,21 @@
|
||||
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
|
||||
"integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.4.tgz",
|
||||
"integrity": "sha512-SVJIQ51spzFDvh4fIbCLvciiDMCrRhlN3mbZvv/+ycjvmF5E73bKdGfU8QDLNmjYJf+lsGnDBC4UUnvTe5OO0w==",
|
||||
"dev": true
|
||||
},
|
||||
"prettier-linter-helpers": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
|
||||
"integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-diff": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"pretty-bytes": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz",
|
||||
@@ -12269,6 +12499,52 @@
|
||||
"react-tween-state": "^0.1.5"
|
||||
}
|
||||
},
|
||||
"react-router": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.1.2.tgz",
|
||||
"integrity": "sha512-yjEuMFy1ONK246B+rsa0cUam5OeAQ8pyclRDgpxuSCrAlJ1qN9uZ5IgyKC7gQg0w8OM50NXHEegPh/ks9YuR2A==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"history": "^4.9.0",
|
||||
"hoist-non-react-statics": "^3.1.0",
|
||||
"loose-envify": "^1.3.1",
|
||||
"mini-create-react-context": "^0.3.0",
|
||||
"path-to-regexp": "^1.7.0",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-is": "^16.6.0",
|
||||
"tiny-invariant": "^1.0.2",
|
||||
"tiny-warning": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
|
||||
"integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
|
||||
"requires": {
|
||||
"isarray": "0.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-router-dom": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.1.2.tgz",
|
||||
"integrity": "sha512-7BPHAaIwWpZS074UKaw1FjVdZBSVWEk8IuDXdB+OkLb8vd/WRQIpA4ag9WQk61aEfQs47wHyjWUoUGGZxpQXew==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.1.2",
|
||||
"history": "^4.9.0",
|
||||
"loose-envify": "^1.3.1",
|
||||
"prop-types": "^15.6.2",
|
||||
"react-router": "5.1.2",
|
||||
"tiny-invariant": "^1.0.2",
|
||||
"tiny-warning": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"react-scripts": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.3.1.tgz",
|
||||
@@ -12707,6 +12983,20 @@
|
||||
"strip-indent": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"redux": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/redux/-/redux-4.0.5.tgz",
|
||||
"integrity": "sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w==",
|
||||
"requires": {
|
||||
"loose-envify": "^1.4.0",
|
||||
"symbol-observable": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"redux-thunk": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz",
|
||||
"integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw=="
|
||||
},
|
||||
"regenerate": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
|
||||
@@ -12757,9 +13047,9 @@
|
||||
}
|
||||
},
|
||||
"regexpp": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz",
|
||||
"integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g=="
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz",
|
||||
"integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q=="
|
||||
},
|
||||
"regexpu-core": {
|
||||
"version": "4.6.0",
|
||||
@@ -12980,6 +13270,11 @@
|
||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
|
||||
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
|
||||
},
|
||||
"resolve-pathname": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
|
||||
"integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
|
||||
},
|
||||
"resolve-url": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
|
||||
@@ -14487,9 +14782,9 @@
|
||||
}
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
|
||||
"integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw=="
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz",
|
||||
"integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w=="
|
||||
},
|
||||
"style-loader": {
|
||||
"version": "1.1.3",
|
||||
@@ -14634,8 +14929,7 @@
|
||||
"symbol-observable": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
|
||||
"integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==",
|
||||
"dev": true
|
||||
"integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
|
||||
},
|
||||
"symbol-tree": {
|
||||
"version": "3.2.4",
|
||||
@@ -14891,6 +15185,16 @@
|
||||
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
|
||||
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
|
||||
},
|
||||
"tiny-invariant": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
|
||||
"integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw=="
|
||||
},
|
||||
"tiny-warning": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
||||
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
|
||||
},
|
||||
"tinycolor2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
|
||||
@@ -15045,6 +15349,11 @@
|
||||
"resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.1.5.tgz",
|
||||
"integrity": "sha512-ti7OGMOUOzo66wLF3liskw6YQIaSsBgc4GOAlWRnIEj8htCxJUxskanMUoJOD6MDCRAXo36goXJZch+nOS0VMA=="
|
||||
},
|
||||
"ts-toolbelt": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-6.5.1.tgz",
|
||||
"integrity": "sha512-zjnZ/vy1eUA0li3H0JXecl0R3jiP42snpLimsrppt9V3LLbM4NM4jMgjXQ4S67hvehq+r9CxpX4Wj6RnFRzReA=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
|
||||
@@ -15364,6 +15673,11 @@
|
||||
"spdx-expression-parse": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"value-equal": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
|
||||
"integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
@@ -17427,17 +17741,6 @@
|
||||
"requires": {
|
||||
"buffer-crc32": "~0.2.3",
|
||||
"fd-slicer": "~1.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"fd-slicer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
"integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"pend": "~1.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"zscroller": {
|
||||
|
||||
+73
-64
@@ -1,67 +1,76 @@
|
||||
{
|
||||
"name": "hdhs",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.0.5",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.4.0",
|
||||
"@testing-library/user-event": "^7.2.1",
|
||||
"@types/jest": "^24.9.1",
|
||||
"@types/node": "^12.12.26",
|
||||
"@types/react": "^16.9.19",
|
||||
"@types/react-dom": "^16.9.5",
|
||||
"antd-mobile": "^2.3.1",
|
||||
"node-sass": "^4.13.1",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-scripts": "3.3.1",
|
||||
"typescript": "^3.7.5"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"cy:open": "cypress open",
|
||||
"cy:run": "cypress run",
|
||||
"test:cov": "react-scripts test --coverage --watchAll=false",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"jest": {
|
||||
"coverageThreshold": {
|
||||
"global": {
|
||||
"statements": 90
|
||||
}
|
||||
"name": "hdhs",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.0.5",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.4.0",
|
||||
"@testing-library/user-event": "^7.2.1",
|
||||
"@types/jest": "^24.9.1",
|
||||
"@types/node": "^12.12.26",
|
||||
"@types/react": "^16.9.19",
|
||||
"@types/react-dom": "^16.9.5",
|
||||
"@types/react-router-dom": "^5.1.4",
|
||||
"antd-mobile": "^2.3.1",
|
||||
"easy-peasy": "^3.3.0",
|
||||
"node-sass": "^4.13.1",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-router-dom": "^5.1.2",
|
||||
"react-scripts": "3.3.1",
|
||||
"typescript": "^3.7.5"
|
||||
},
|
||||
"coverageReporters": [
|
||||
"lcov"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cypress/webpack-preprocessor": "^4.1.3",
|
||||
"@testing-library/react-hooks": "^3.2.1",
|
||||
"awesome-typescript-loader": "^5.2.1",
|
||||
"babel-loader": "^8.1.0",
|
||||
"babel-plugin-import": "^1.13.0",
|
||||
"cypress": "^4.2.0",
|
||||
"react-test-renderer": "^16.13.1",
|
||||
"svg-url-loader": "^5.0.0",
|
||||
"ts-loader": "^6.2.2",
|
||||
"webpack": "^4.42.1"
|
||||
}
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"cy:open": "cypress open",
|
||||
"cy:run": "cypress run",
|
||||
"lint": "tsc --noEmit && eslint 'src/*.{js,ts,tsx}' --fix",
|
||||
"test:cov": "react-scripts test --coverage --watchAll=false"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"jest": {
|
||||
"coverageThreshold": {
|
||||
"global": {
|
||||
"statements": 90
|
||||
}
|
||||
},
|
||||
"coverageReporters": [
|
||||
"lcov"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cypress/webpack-preprocessor": "^4.1.3",
|
||||
"@testing-library/react-hooks": "^3.2.1",
|
||||
"@typescript-eslint/eslint-plugin": "^2.28.0",
|
||||
"@typescript-eslint/parser": "^2.28.0",
|
||||
"awesome-typescript-loader": "^5.2.1",
|
||||
"babel-loader": "^8.1.0",
|
||||
"babel-plugin-import": "^1.13.0",
|
||||
"cypress": "^4.2.0",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.10.1",
|
||||
"eslint-plugin-prettier": "^3.1.3",
|
||||
"prettier": "^2.0.4",
|
||||
"react-test-renderer": "^16.13.1",
|
||||
"svg-url-loader": "^5.0.0",
|
||||
"ts-loader": "^6.2.2",
|
||||
"webpack": "^4.42.1"
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import App from './App';
|
||||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import App from './App'
|
||||
|
||||
test('renders learn react link', () => {
|
||||
const { getByText } = render(<App />);
|
||||
const linkElement = getByText(/Login/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
||||
const { getByText } = render(<App />)
|
||||
const linkElement = getByText(/Login/i)
|
||||
expect(linkElement).toBeInTheDocument()
|
||||
})
|
||||
+45
-12
@@ -1,15 +1,48 @@
|
||||
import React from "react";
|
||||
import "./scss/App.scss";
|
||||
import "./antd-mobile.css";
|
||||
import React from 'react'
|
||||
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom'
|
||||
|
||||
import Login from "./components/Login";
|
||||
import { StoreProvider } from 'easy-peasy'
|
||||
import store from './state/store'
|
||||
|
||||
const App = () => {
|
||||
return (
|
||||
<>
|
||||
<Login />
|
||||
</>
|
||||
);
|
||||
};
|
||||
import Login from './components/Login'
|
||||
import LandingPage from './components/LandingPage'
|
||||
import Wrapper from './Wrapper'
|
||||
import PatientInfoForm from './components/PatientInfoForm'
|
||||
|
||||
export default App;
|
||||
import './scss/App.scss'
|
||||
import './antd-mobile.css'
|
||||
import DebugShowEasyPeasy from './components/DebugShowEasyPeasy'
|
||||
|
||||
const App: React.FunctionComponent = () => {
|
||||
return (
|
||||
<StoreProvider store={store}>
|
||||
<Router>
|
||||
<Switch>
|
||||
<Route path="/login">
|
||||
<Login />
|
||||
</Route>
|
||||
<Route path="/landing">
|
||||
<LandingPage />
|
||||
</Route>
|
||||
<Route path="/patientinfo">
|
||||
<Wrapper
|
||||
navTitle="Patient Information"
|
||||
leftArrowText="Home"
|
||||
leftArrowRoute="/"
|
||||
>
|
||||
<PatientInfoForm />
|
||||
</Wrapper>
|
||||
</Route>
|
||||
<Route path="/easy-peasy">
|
||||
<DebugShowEasyPeasy />
|
||||
</Route>
|
||||
<Route path="/">
|
||||
<Login />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</StoreProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
@@ -0,0 +1,75 @@
|
||||
import React from 'react'
|
||||
import { render, queryByAttribute, fireEvent } from '@testing-library/react'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import Wrapper from './Wrapper'
|
||||
|
||||
const mockHistoryPush = jest.fn()
|
||||
jest.mock('react-router-dom', () => ({
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
||||
useHistory: () => ({
|
||||
push: mockHistoryPush,
|
||||
}),
|
||||
}))
|
||||
|
||||
test("renders it's inner contents", () => {
|
||||
const dom = render(
|
||||
<Wrapper leftArrowText="back">
|
||||
<div>Hello!</div>
|
||||
</Wrapper>,
|
||||
)
|
||||
|
||||
const textContents = dom.getByText('Hello!')
|
||||
|
||||
expect(textContents).toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('renders navBar when given navTitle', () => {
|
||||
const dom = render(
|
||||
<Wrapper navTitle="CHI">
|
||||
<div>Hello!</div>
|
||||
</Wrapper>,
|
||||
)
|
||||
|
||||
const getById = queryByAttribute.bind(null, 'id')
|
||||
const renderedNavBar = getById(dom.container, 'nav-bar')
|
||||
const navTitle = dom.getByText('CHI')
|
||||
|
||||
expect(renderedNavBar).toBeTruthy()
|
||||
expect(navTitle).toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('renders no navBar when not given props', () => {
|
||||
const dom = render(
|
||||
<Wrapper>
|
||||
<div>Hello!</div>
|
||||
</Wrapper>,
|
||||
)
|
||||
const getById = queryByAttribute.bind(null, 'id')
|
||||
const renderedNavBar = getById(dom.container, 'nav-bar')
|
||||
expect(renderedNavBar).toBeFalsy()
|
||||
})
|
||||
|
||||
test('renders leftArrowText', () => {
|
||||
const dom = render(
|
||||
<Wrapper leftArrowText="back">
|
||||
<div>Hello!</div>
|
||||
</Wrapper>,
|
||||
)
|
||||
|
||||
const leftArrowText = dom.getByText('back')
|
||||
|
||||
expect(leftArrowText).toBeInTheDocument()
|
||||
})
|
||||
|
||||
test('redirects on left arrow click ', () => {
|
||||
const dom = render(
|
||||
<Wrapper leftArrowText="back" leftArrowRoute="/">
|
||||
<div>Hello!</div>
|
||||
</Wrapper>,
|
||||
)
|
||||
|
||||
const leftArrowText = dom.getByText('back')
|
||||
fireEvent.click(leftArrowText)
|
||||
|
||||
expect(useHistory().push).toBeCalledWith('/')
|
||||
})
|
||||
@@ -0,0 +1,44 @@
|
||||
import React from 'react'
|
||||
import { NavBar, Icon } from 'antd-mobile'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
|
||||
import './scss/Wrapper.scss'
|
||||
|
||||
type WrapperProps = {
|
||||
navTitle?: string
|
||||
leftArrowText?: string
|
||||
leftArrowRoute?: string
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const Wrapper: React.FunctionComponent<WrapperProps> = (
|
||||
props: WrapperProps,
|
||||
) => {
|
||||
const { navTitle, leftArrowText, leftArrowRoute } = props
|
||||
const hist = useHistory()
|
||||
const needNavBar = navTitle || leftArrowText || leftArrowRoute
|
||||
const leftContentArr = leftArrowText
|
||||
? [<Icon key={1} type="left" />, `${leftArrowText}`]
|
||||
: []
|
||||
const leftRoute = leftArrowRoute ? `${leftArrowRoute}` : '/'
|
||||
|
||||
return (
|
||||
<div id="primary-wrapper">
|
||||
<div id="wrapper-contents">
|
||||
{needNavBar && (
|
||||
<NavBar
|
||||
id="nav-bar"
|
||||
mode="light"
|
||||
onLeftClick={(): void => hist.push(leftRoute)}
|
||||
leftContent={leftContentArr}
|
||||
>
|
||||
{`${navTitle}`}
|
||||
</NavBar>
|
||||
)}
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Wrapper
|
||||
+5949
-5380
File diff suppressed because it is too large.
Load diff
Vendored
+7875
-2
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,16 @@
|
||||
/* istanbul ignore file */
|
||||
// This component is a debug utility to show
|
||||
// all contents of easy-peasy when rendered
|
||||
|
||||
import React, { ReactElement } from 'react'
|
||||
import { useStoreState } from '../state/storeIndex'
|
||||
|
||||
export default function DebugShowEasyPeasy(): ReactElement {
|
||||
const patientInfoFormData = useStoreState(
|
||||
(state) => state.patientInfoFormModel.fields,
|
||||
)
|
||||
|
||||
console.log(patientInfoFormData)
|
||||
|
||||
return <div>patientInfoFormData: {JSON.stringify(patientInfoFormData)}</div>
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from "react";
|
||||
import { render } from "@testing-library/react";
|
||||
import LandingPage from "./LandingPage";
|
||||
import React from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import LandingPage from './LandingPage'
|
||||
|
||||
test("renders learn react link", () => {
|
||||
const { getByText } = render(<LandingPage />);
|
||||
const lookupButtonElement = getByText(/Patient Lookup/i);
|
||||
const newPatientButtonElement = getByText(/New Patient/i);
|
||||
expect(lookupButtonElement).toBeInTheDocument();
|
||||
expect(newPatientButtonElement).toBeInTheDocument();
|
||||
});
|
||||
test('renders learn react link', () => {
|
||||
const { getByText } = render(<LandingPage />)
|
||||
const lookupButtonElement = getByText(/Patient Lookup/i)
|
||||
const newPatientButtonElement = getByText(/New Patient/i)
|
||||
expect(lookupButtonElement).toBeInTheDocument()
|
||||
expect(newPatientButtonElement).toBeInTheDocument()
|
||||
})
|
||||
@@ -1,34 +1,35 @@
|
||||
import React, { ReactElement } from "react";
|
||||
import { WhiteSpace, Button } from "antd-mobile";
|
||||
import Icon, { UserAddOutlined } from "@ant-design/icons";
|
||||
import React, { ReactElement } from 'react'
|
||||
import { WhiteSpace, Button } from 'antd-mobile'
|
||||
import { UserAddOutlined } from '@ant-design/icons'
|
||||
|
||||
import "../scss/LandingPage.scss";
|
||||
import '../scss/LandingPage.scss'
|
||||
|
||||
export default function LandingPage(): ReactElement {
|
||||
/* istanbul ignore next */
|
||||
const patientLookup = () => {
|
||||
console.log("Clicked Patient Lookup");
|
||||
};
|
||||
/* istanbul ignore next */
|
||||
// TODO: these onClick functions could be mocked in a unit test
|
||||
const patientLookup = () => {
|
||||
console.log('Clicked Patient Lookup')
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
const newPatient = () => {
|
||||
console.log("Clicked New Patient");
|
||||
};
|
||||
return (
|
||||
<div id="landing-wrapper">
|
||||
<div className="button-flex">
|
||||
<Button onClick={patientLookup} icon="search">
|
||||
Patient Lookup
|
||||
</Button>
|
||||
<WhiteSpace />
|
||||
</div>
|
||||
<br />
|
||||
<div className="button-flex">
|
||||
<Button icon={<UserAddOutlined />} onClick={newPatient}>
|
||||
New Patient
|
||||
</Button>
|
||||
<WhiteSpace />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
/* istanbul ignore next */
|
||||
const newPatient = () => {
|
||||
console.log('Clicked New Patient')
|
||||
}
|
||||
return (
|
||||
<div id="landing-wrapper">
|
||||
<div className="button-flex">
|
||||
<Button onClick={patientLookup} icon="search">
|
||||
Patient Lookup
|
||||
</Button>
|
||||
<WhiteSpace />
|
||||
</div>
|
||||
<br />
|
||||
<div className="button-flex">
|
||||
<Button icon={<UserAddOutlined />} onClick={newPatient}>
|
||||
New Patient
|
||||
</Button>
|
||||
<WhiteSpace />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -1,31 +1,29 @@
|
||||
import React, { ReactElement } from 'react'
|
||||
import useApi from '../hooks/useApi'
|
||||
import {InputItem, Button} from 'antd-mobile'
|
||||
import { InputItem, Button } from 'antd-mobile'
|
||||
import '../scss/Login.scss'
|
||||
|
||||
export default function Login(): ReactElement {
|
||||
const {response, error, isLoading} = useApi("")
|
||||
const { response, isLoading } = useApi('')
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id="loginWrapper">
|
||||
<div id="loginGrid">
|
||||
<div id="iconCard">
|
||||
<div id="imgWrap">
|
||||
<img src="/logoIcon512.jpg" alt="CHI Logo"></img>
|
||||
</div>
|
||||
return (
|
||||
<>
|
||||
<div id="loginWrapper">
|
||||
<div id="loginGrid">
|
||||
<div id="iconCard">
|
||||
<div id="imgWrap">
|
||||
<img src="/logoIcon512.jpg" alt="CHI Logo"></img>
|
||||
</div>
|
||||
</div>
|
||||
<InputItem placeholder="username" />
|
||||
<InputItem placeholder="password" type="password" />
|
||||
<div id="buttonFlex">
|
||||
<Button>Login</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<InputItem placeholder="username"/>
|
||||
<InputItem placeholder="password" type="password"/>
|
||||
<div id="buttonFlex">
|
||||
<Button>Login</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p>Loading API Fetch: {isLoading.toString()}</p>
|
||||
{response &&
|
||||
<p>API Fetch Result: {JSON.stringify(response)}</p>
|
||||
}
|
||||
</>
|
||||
)
|
||||
<p>Loading API Fetch: {isLoading.toString()}</p>
|
||||
{response && <p>API Fetch Result: {JSON.stringify(response)}</p>}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
import React from 'react'
|
||||
import { render, fireEvent, prettyDOM } from '@testing-library/react'
|
||||
import PatientInfoForm from './PatientInfoForm'
|
||||
import { StoreProvider } from 'easy-peasy'
|
||||
import store from '../state/store'
|
||||
|
||||
test('female-only div is only displayed if the sex is selected as female', async () => {
|
||||
const femaleOnlyFormFields = ['Pregnant?', 'LMP', 'Wants Planning?']
|
||||
|
||||
const dom = render(
|
||||
<StoreProvider store={store}>
|
||||
<PatientInfoForm />
|
||||
</StoreProvider>,
|
||||
)
|
||||
|
||||
// ensure the female-only div is not displayed
|
||||
femaleOnlyFormFields.forEach((fieldText) => {
|
||||
expect(dom.queryByText(fieldText)).toBeNull()
|
||||
})
|
||||
|
||||
// click the radio button for 'female'
|
||||
const femaleButton = dom.getByTestId('female-button')
|
||||
fireEvent.click(femaleButton)
|
||||
|
||||
femaleOnlyFormFields.forEach((fieldText) => {
|
||||
expect(dom.queryByText(fieldText)).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
test('sets visit input', () => {
|
||||
const dom = render(
|
||||
<StoreProvider store={store}>
|
||||
<PatientInfoForm />
|
||||
</StoreProvider>,
|
||||
)
|
||||
const firstVisitYesInput = dom.queryByTestId('first-visit-Yes')
|
||||
const checkBox = firstVisitYesInput.getElementsByTagName('span')[0]
|
||||
|
||||
expect(checkBox).not.toHaveClass('am-radio-checked')
|
||||
fireEvent.click(firstVisitYesInput)
|
||||
expect(checkBox).toHaveClass('am-radio-checked')
|
||||
})
|
||||
|
||||
test('sets pregnant input', () => {
|
||||
const dom = render(
|
||||
<StoreProvider store={store}>
|
||||
<PatientInfoForm />
|
||||
</StoreProvider>,
|
||||
)
|
||||
const femaleButton = dom.getByTestId('female-button')
|
||||
fireEvent.click(femaleButton)
|
||||
|
||||
const pregnantYesInput = dom.queryByTestId('pregnant-Yes')
|
||||
const checkBox = pregnantYesInput.getElementsByTagName('span')[0]
|
||||
|
||||
expect(checkBox).not.toHaveClass('am-radio-checked')
|
||||
fireEvent.click(pregnantYesInput)
|
||||
expect(checkBox).toHaveClass('am-radio-checked')
|
||||
})
|
||||
|
||||
test('sets planning input', () => {
|
||||
const dom = render(
|
||||
<StoreProvider store={store}>
|
||||
<PatientInfoForm />
|
||||
</StoreProvider>,
|
||||
)
|
||||
const femaleButton = dom.getByTestId('female-button')
|
||||
fireEvent.click(femaleButton)
|
||||
|
||||
const planningYesInput = dom.queryByTestId('planning-Yes')
|
||||
const checkBox = planningYesInput.getElementsByTagName('span')[0]
|
||||
|
||||
expect(checkBox).not.toHaveClass('am-radio-checked')
|
||||
fireEvent.click(planningYesInput)
|
||||
expect(checkBox).toHaveClass('am-radio-checked')
|
||||
})
|
||||
|
||||
test('validates blood pressure input', () => {
|
||||
const dom = render(
|
||||
<StoreProvider store={store}>
|
||||
<PatientInfoForm />
|
||||
</StoreProvider>,
|
||||
)
|
||||
|
||||
const bpInput = dom.getByPlaceholderText(
|
||||
'Blood Pressure',
|
||||
) as HTMLInputElement
|
||||
fireEvent.change(bpInput, { target: { value: '130/85' } })
|
||||
expect(bpInput.value).toBe('130/85')
|
||||
fireEvent.change(bpInput, { target: { value: '' } })
|
||||
fireEvent.change(bpInput, { target: { value: 'abcd' } })
|
||||
expect(bpInput.value).toBe('') // Empty String
|
||||
})
|
||||
|
||||
test('sets albendazole input', () => {
|
||||
const dom = render(
|
||||
<StoreProvider store={store}>
|
||||
<PatientInfoForm />
|
||||
</StoreProvider>,
|
||||
)
|
||||
|
||||
const albendazoleYesInput = dom.queryByTestId('albendazole-Yes')
|
||||
const checkBox = albendazoleYesInput.getElementsByTagName('span')[0]
|
||||
|
||||
expect(checkBox).not.toHaveClass('am-radio-checked')
|
||||
fireEvent.click(albendazoleYesInput)
|
||||
expect(checkBox).toHaveClass('am-radio-checked')
|
||||
})
|
||||
|
||||
test('renders the Patient Info Form fields', () => {
|
||||
const formFields = [
|
||||
'First Name',
|
||||
'First Name',
|
||||
'Last Name',
|
||||
'Last Name',
|
||||
'Sex',
|
||||
'Birth',
|
||||
'Age',
|
||||
'Phone',
|
||||
'Town',
|
||||
'Visit',
|
||||
'Nickname',
|
||||
'BP',
|
||||
'Temp',
|
||||
'Pulse',
|
||||
'Weight',
|
||||
'Height',
|
||||
'Z-Score',
|
||||
'Albendazole',
|
||||
'Allergies',
|
||||
'Medicines',
|
||||
'Chief Complaint',
|
||||
'History',
|
||||
'Exam',
|
||||
]
|
||||
|
||||
const { getByText } = render(
|
||||
<StoreProvider store={store}>
|
||||
<PatientInfoForm />
|
||||
</StoreProvider>,
|
||||
)
|
||||
|
||||
formFields.forEach((fieldText) => {
|
||||
const re = new RegExp(fieldText, 'gi')
|
||||
expect(getByText(re)).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,388 @@
|
||||
import React, { ReactElement, useState } from 'react'
|
||||
import { useStoreActions } from '../state/storeIndex'
|
||||
import { SEX } from '../state/enums'
|
||||
import {
|
||||
InputItem,
|
||||
List,
|
||||
TextareaItem,
|
||||
Button,
|
||||
Radio,
|
||||
WhiteSpace,
|
||||
} from 'antd-mobile'
|
||||
import '../scss/PatientInfoForm.scss'
|
||||
|
||||
const RadioItem = Radio.RadioItem
|
||||
|
||||
export default function Form(): ReactElement {
|
||||
// State Hooks for Radio Buttons
|
||||
// useState returns a value, and a function to set that value
|
||||
const [sex, setSex] = useState(null as number) // Default: null
|
||||
const [albendazole, setAlbendazole] = useState(0) // Default: No
|
||||
const [firstVisit, setFirstVisit] = useState(0) // Default: No
|
||||
const [pregnant, setPregnant] = useState(0) // Default: No
|
||||
const [planning, setPlanning] = useState(0) // Default: No
|
||||
const [bloodPressureValue, setBloodPressureValue] = useState('')
|
||||
const updateCentralState = useStoreActions(
|
||||
(actions) => actions.patientInfoFormModel.updateFields,
|
||||
)
|
||||
|
||||
// Data for Radio Buttons
|
||||
const sexValues = [
|
||||
{ value: 0, label: 'Male' },
|
||||
{ value: 1, label: 'Female' },
|
||||
]
|
||||
|
||||
const radioYesNo = [
|
||||
{ value: 0, label: 'No' },
|
||||
{ value: 1, label: 'Yes' },
|
||||
]
|
||||
|
||||
/* istanbul ignore next */
|
||||
const onSubmit = () => {
|
||||
const firstNameField: HTMLInputElement = document.getElementById(
|
||||
'firstname',
|
||||
) as HTMLInputElement
|
||||
const lastNameField: HTMLInputElement = document.getElementById(
|
||||
'lastname',
|
||||
) as HTMLInputElement
|
||||
const nicknameField: HTMLInputElement = document.getElementById(
|
||||
'nickname',
|
||||
) as HTMLInputElement
|
||||
const birthdateField: HTMLInputElement = document.getElementById(
|
||||
'birthdate',
|
||||
) as HTMLInputElement
|
||||
const age: HTMLInputElement = document.getElementById(
|
||||
'age',
|
||||
) as HTMLInputElement
|
||||
const phone: HTMLInputElement = document.getElementById(
|
||||
'phone',
|
||||
) as HTMLInputElement
|
||||
const town: HTMLInputElement = document.getElementById(
|
||||
'town',
|
||||
) as HTMLInputElement
|
||||
const gravida: HTMLInputElement = document.getElementById(
|
||||
'gravida',
|
||||
) as HTMLInputElement
|
||||
const para: HTMLInputElement = document.getElementById(
|
||||
'para',
|
||||
) as HTMLInputElement
|
||||
const abortus: HTMLInputElement = document.getElementById(
|
||||
'abortus',
|
||||
) as HTMLInputElement
|
||||
const lmp: HTMLInputElement = document.getElementById(
|
||||
'lmp',
|
||||
) as HTMLInputElement
|
||||
const weight: HTMLInputElement = document.getElementById(
|
||||
'weight',
|
||||
) as HTMLInputElement
|
||||
const height: HTMLInputElement = document.getElementById(
|
||||
'height',
|
||||
) as HTMLInputElement
|
||||
const temp: HTMLInputElement = document.getElementById(
|
||||
'temp',
|
||||
) as HTMLInputElement
|
||||
const pulse: HTMLInputElement = document.getElementById(
|
||||
'pulse',
|
||||
) as HTMLInputElement
|
||||
const zScore: HTMLInputElement = document.getElementById(
|
||||
'z-score',
|
||||
) as HTMLInputElement
|
||||
const allergies: HTMLInputElement = document.getElementById(
|
||||
'allergies',
|
||||
) as HTMLInputElement
|
||||
const medicines: HTMLInputElement = document.getElementById(
|
||||
'medicines',
|
||||
) as HTMLInputElement
|
||||
const complaintField1: HTMLInputElement = document.getElementById(
|
||||
'complaint1',
|
||||
) as HTMLInputElement
|
||||
const complaintField2: HTMLInputElement = document.getElementById(
|
||||
'complaint2',
|
||||
) as HTMLInputElement
|
||||
const complaintField3: HTMLInputElement = document.getElementById(
|
||||
'complaint3',
|
||||
) as HTMLInputElement
|
||||
const history: HTMLInputElement = document.getElementById(
|
||||
'history',
|
||||
) as HTMLInputElement
|
||||
const exam: HTMLInputElement = document.getElementById(
|
||||
'exam',
|
||||
) as HTMLInputElement
|
||||
updateCentralState({
|
||||
firstName: firstNameField.value,
|
||||
lastName: lastNameField.value,
|
||||
nickname: nicknameField.value,
|
||||
sex: sex ? SEX.female : SEX.male,
|
||||
birthDate: new Date(birthdateField.value),
|
||||
age: parseInt(age.value),
|
||||
phone: phone.value,
|
||||
town: town.value,
|
||||
firstVisit: firstVisit,
|
||||
pregnant: pregnant,
|
||||
G: sex ? parseInt(gravida.value) : null,
|
||||
P: sex ? parseInt(para.value) : null,
|
||||
A: sex ? parseInt(abortus.value) : null,
|
||||
LMP: sex ? new Date(lmp.value) : null,
|
||||
wantsPlanning: planning,
|
||||
weight: parseFloat(weight.value),
|
||||
height: parseFloat(height.value),
|
||||
bloodPressure: bloodPressureValue,
|
||||
temperature: parseFloat(temp.value),
|
||||
pulse: parseFloat(pulse.value),
|
||||
zScore: parseFloat(zScore.value),
|
||||
albendazole: albendazole,
|
||||
allergies: allergies.value,
|
||||
medicines: medicines.value,
|
||||
chiefComplaint: [
|
||||
complaintField1.value,
|
||||
complaintField2.value,
|
||||
complaintField3.value,
|
||||
],
|
||||
history: history.value,
|
||||
exam: exam.value,
|
||||
})
|
||||
}
|
||||
|
||||
const validateAndSetBloodPressure = (value: string) => {
|
||||
const newChar = value.slice(-1)
|
||||
if (newChar.match(/[0-9]|\/|^$/) && value.length < 8) {
|
||||
setBloodPressureValue(value)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div id="patient-info-wrapper">
|
||||
<TextareaItem
|
||||
title="First Name"
|
||||
placeholder="First Name"
|
||||
autoHeight
|
||||
id="firstname"
|
||||
/>
|
||||
|
||||
<TextareaItem
|
||||
title="Last Name"
|
||||
placeholder="Last Name"
|
||||
id="lastname"
|
||||
autoHeight
|
||||
/>
|
||||
|
||||
<TextareaItem
|
||||
title="Nickname"
|
||||
placeholder="Nickname"
|
||||
id="nickname"
|
||||
autoHeight
|
||||
/>
|
||||
|
||||
<List renderHeader={() => 'Sex'}>
|
||||
{sexValues.map((i) => (
|
||||
<RadioItem
|
||||
data-testid={`${i.label.toLowerCase()}-button`}
|
||||
id={`${i.label.toLowerCase()}-button`}
|
||||
key={i.value}
|
||||
name="sex"
|
||||
checked={sex === i.value}
|
||||
onClick={() => setSex(i.value)}
|
||||
>
|
||||
{i.label}
|
||||
</RadioItem>
|
||||
))}
|
||||
</List>
|
||||
|
||||
<WhiteSpace />
|
||||
|
||||
<InputItem placeholder="YYYY-MM-DD" id="birthdate" maxLength={10}>
|
||||
Birth Date
|
||||
</InputItem>
|
||||
|
||||
<InputItem type="number" placeholder="Age" id="age" maxLength={3}>
|
||||
Age{' '}
|
||||
</InputItem>
|
||||
|
||||
<InputItem type="number" placeholder="Phone" id="phone">
|
||||
Phone
|
||||
</InputItem>
|
||||
|
||||
<TextareaItem
|
||||
title="Town"
|
||||
placeholder="Town"
|
||||
id="town"
|
||||
autoHeight
|
||||
/>
|
||||
|
||||
<List renderHeader={() => 'First Visit?'}>
|
||||
{radioYesNo.map((i) => (
|
||||
<RadioItem
|
||||
key={i.value}
|
||||
data-testid={`first-visit-${i.label}`}
|
||||
name="visit"
|
||||
checked={firstVisit === i.value}
|
||||
onClick={() => setFirstVisit(i.value)}
|
||||
>
|
||||
{i.label}
|
||||
</RadioItem>
|
||||
))}
|
||||
</List>
|
||||
|
||||
{/* Only display the 'female-only' div if the patient is female */}
|
||||
{sex ? (
|
||||
<div id="female-only">
|
||||
<WhiteSpace />
|
||||
<List renderHeader={() => 'Pregnant?'}>
|
||||
{radioYesNo.map((i) => (
|
||||
<RadioItem
|
||||
data-testid={`pregnant-${i.label}`}
|
||||
key={i.value}
|
||||
name="pregnant"
|
||||
checked={pregnant === i.value}
|
||||
onClick={() => setPregnant(i.value)}
|
||||
>
|
||||
{i.label}
|
||||
</RadioItem>
|
||||
))}
|
||||
</List>
|
||||
|
||||
<InputItem
|
||||
title="G"
|
||||
type="number"
|
||||
id="gravida"
|
||||
placeholder="0"
|
||||
>
|
||||
G
|
||||
</InputItem>
|
||||
|
||||
<InputItem
|
||||
title="P"
|
||||
type="number"
|
||||
id="para"
|
||||
placeholder="0"
|
||||
>
|
||||
P
|
||||
</InputItem>
|
||||
|
||||
<InputItem
|
||||
title="A"
|
||||
type="number"
|
||||
id="abortus"
|
||||
placeholder="0"
|
||||
>
|
||||
A
|
||||
</InputItem>
|
||||
|
||||
<InputItem placeholder="YYYY-MM-DD" id="lmp" maxLength={10}>
|
||||
LMP
|
||||
</InputItem>
|
||||
|
||||
<List renderHeader={() => 'Wants Planning?'}>
|
||||
{radioYesNo.map((i) => (
|
||||
<RadioItem
|
||||
data-testid={`planning-${i.label}`}
|
||||
key={i.value}
|
||||
name="planning"
|
||||
checked={planning === i.value}
|
||||
onClick={() => setPlanning(i.value)}
|
||||
>
|
||||
{i.label}
|
||||
</RadioItem>
|
||||
))}
|
||||
</List>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<WhiteSpace />
|
||||
|
||||
<InputItem
|
||||
type="number"
|
||||
placeholder="Weight"
|
||||
id="weight"
|
||||
maxLength={3}
|
||||
>
|
||||
Weight (kg)
|
||||
</InputItem>
|
||||
|
||||
<InputItem
|
||||
type="number"
|
||||
placeholder="Height"
|
||||
id="height"
|
||||
maxLength={3}
|
||||
>
|
||||
Height (cm)
|
||||
</InputItem>
|
||||
|
||||
<InputItem
|
||||
placeholder="Blood Pressure"
|
||||
id="bp"
|
||||
value={bloodPressureValue}
|
||||
onChange={validateAndSetBloodPressure}
|
||||
>
|
||||
BP
|
||||
</InputItem>
|
||||
|
||||
<InputItem type="number" placeholder="Temp" id="temp" maxLength={3}>
|
||||
Temp (F)
|
||||
</InputItem>
|
||||
|
||||
<InputItem
|
||||
type="number"
|
||||
placeholder="Pulse"
|
||||
id="pulse"
|
||||
maxLength={3}
|
||||
>
|
||||
Pulse
|
||||
</InputItem>
|
||||
|
||||
<InputItem type="number" placeholder="Z-Score" id="z-score">
|
||||
Z-Score
|
||||
</InputItem>
|
||||
|
||||
<List renderHeader={() => 'Albendazole?'}>
|
||||
{radioYesNo.map((i) => (
|
||||
<RadioItem
|
||||
data-testid={`albendazole-${i.label}`}
|
||||
key={i.value}
|
||||
checked={albendazole === i.value}
|
||||
onClick={() => setAlbendazole(i.value)}
|
||||
>
|
||||
{i.label}
|
||||
</RadioItem>
|
||||
))}
|
||||
</List>
|
||||
|
||||
<List renderHeader={() => 'Allergies'}>
|
||||
<TextareaItem autoHeight id="allergies" />
|
||||
</List>
|
||||
|
||||
<List renderHeader={() => 'Medicines'}>
|
||||
<TextareaItem autoHeight id="medicines" />
|
||||
</List>
|
||||
|
||||
<List renderHeader={() => 'Chief Complaint'}>
|
||||
<TextareaItem
|
||||
placeholder="1."
|
||||
// autoHeight
|
||||
autoHeight
|
||||
id="complaint1"
|
||||
/>
|
||||
<TextareaItem placeholder="2." autoHeight id="complaint2" />
|
||||
<TextareaItem placeholder="3." autoHeight id="complaint3" />
|
||||
</List>
|
||||
|
||||
<List renderHeader={() => 'History'}>
|
||||
<TextareaItem autoHeight id="history" />
|
||||
</List>
|
||||
|
||||
<List renderHeader={() => 'Exam'}>
|
||||
<TextareaItem autoHeight id="exam" />
|
||||
</List>
|
||||
|
||||
<WhiteSpace />
|
||||
|
||||
<div className="submit-button">
|
||||
<List>
|
||||
<Button data-testid="submit-button" onClick={onSubmit}>
|
||||
Submit
|
||||
</Button>
|
||||
</List>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -2,8 +2,8 @@ import { renderHook } from '@testing-library/react-hooks'
|
||||
import useApi from './useApi'
|
||||
|
||||
test('should return loading and then a response', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(() => useApi(""))
|
||||
|
||||
const { result, waitForNextUpdate } = renderHook(() => useApi(''))
|
||||
|
||||
expect(result.current.response).toBeNull()
|
||||
expect(result.current.error).toBeNull()
|
||||
expect(result.current.isLoading).toBeTruthy()
|
||||
@@ -13,4 +13,16 @@ test('should return loading and then a response', async () => {
|
||||
expect(result.current.response).toBeTruthy()
|
||||
expect(result.current.error).toBeNull()
|
||||
expect(result.current.isLoading).toBeFalsy()
|
||||
})
|
||||
})
|
||||
|
||||
test('should return an error on a non existent route', async () => {
|
||||
const { result, waitForNextUpdate } = renderHook(() => useApi('/404'))
|
||||
|
||||
expect(result.current.response).toBeNull()
|
||||
expect(result.current.error).toBeNull()
|
||||
|
||||
await waitForNextUpdate()
|
||||
|
||||
expect(result.current.response).toBeFalsy()
|
||||
expect(result.current.error).toBeTruthy()
|
||||
})
|
||||
+30
-30
@@ -1,35 +1,35 @@
|
||||
import React from 'react'
|
||||
|
||||
const useApi = (route: string) => {
|
||||
const [response, setResponse] = React.useState(null);
|
||||
const [error, setError] = React.useState(null);
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
|
||||
/* istanbul ignore next */
|
||||
const getUrl = () => {
|
||||
if (process.env.environment === "docker"){
|
||||
return "http://api:4000/"
|
||||
}
|
||||
else {
|
||||
return "http://localhost:4000/"
|
||||
}
|
||||
}
|
||||
const [response, setResponse] = React.useState(null)
|
||||
const [error, setError] = React.useState(null)
|
||||
const [isLoading, setIsLoading] = React.useState(false)
|
||||
|
||||
React.useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const res = await fetch(getUrl() + route);
|
||||
const json = await res.json();
|
||||
setResponse(json);
|
||||
setIsLoading(false)
|
||||
} catch (error) {
|
||||
setError(error);
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
}, []);
|
||||
return { response, error, isLoading };
|
||||
};
|
||||
/* istanbul ignore next */
|
||||
const getUrl = () => {
|
||||
if (process.env.environment === 'docker') {
|
||||
return 'http://api:4000/'
|
||||
} else {
|
||||
return 'http://localhost:4000/'
|
||||
}
|
||||
}
|
||||
|
||||
export default useApi
|
||||
React.useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
setIsLoading(true)
|
||||
try {
|
||||
const res = await fetch(getUrl() + route)
|
||||
const json = await res.json()
|
||||
setResponse(json)
|
||||
setIsLoading(false)
|
||||
} catch (error) {
|
||||
setError(error)
|
||||
}
|
||||
}
|
||||
fetchData()
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
return { response, error, isLoading }
|
||||
}
|
||||
|
||||
export default useApi
|
||||
+7
-7
@@ -1,13 +1,13 @@
|
||||
/* istanbul ignore file */
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import './scss/index.scss';
|
||||
import App from './App';
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import './scss/index.scss'
|
||||
import App from './App'
|
||||
import * as serviceWorker from './serviceWorker'
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('root'));
|
||||
ReactDOM.render(<App />, 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: https://bit.ly/CRA-PWA
|
||||
serviceWorker.register();
|
||||
serviceWorker.register()
|
||||
+10
-2
@@ -1,7 +1,15 @@
|
||||
.am-button:hover {
|
||||
cursor: pointer;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#root {
|
||||
height: 100vh;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.am-input-label {
|
||||
padding-right: 0.5em !important;
|
||||
}
|
||||
|
||||
.am-textarea-label {
|
||||
padding-right: 0.5em !important;
|
||||
}
|
||||
@@ -1,21 +1,19 @@
|
||||
.button-flex {
|
||||
animation-name: fade-in;
|
||||
animation-duration: 2s;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 2em 0;
|
||||
.am-button {
|
||||
background-color: #9bd7ff;
|
||||
width: 40%;
|
||||
&.am-button-active {
|
||||
background-color: #ccebff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 2em 0;
|
||||
.am-button {
|
||||
background-color: #9bd7ff;
|
||||
width: 40%;
|
||||
&.am-button-active {
|
||||
background-color: #ccebff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#landing-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
+69
-61
@@ -2,70 +2,78 @@
|
||||
// @include media("<desktop") {
|
||||
|
||||
#loginWrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
height: 100%;
|
||||
padding: 0 2rem;
|
||||
#loginGrid {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 45%;
|
||||
#iconCard {
|
||||
animation-name: fade-in-from-up;
|
||||
animation-duration: 1.5s;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
#imgWrap {
|
||||
width: 28%;
|
||||
margin: auto;
|
||||
padding: .2rem;
|
||||
background-color: #eee;
|
||||
border-radius: 5px;
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 512px;
|
||||
height: auto;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
height: 100%;
|
||||
padding: 0 2rem;
|
||||
#loginGrid {
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 45%;
|
||||
#iconCard {
|
||||
animation-name: fade-in-from-up;
|
||||
animation-duration: 1.5s;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
#imgWrap {
|
||||
width: 28%;
|
||||
margin: auto;
|
||||
padding: 0.2rem;
|
||||
background-color: #eee;
|
||||
border-radius: 5px;
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 512px;
|
||||
height: auto;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
input {
|
||||
animation-name: fade-in;
|
||||
animation-duration: 2s;
|
||||
}
|
||||
#buttonFlex{
|
||||
animation-name: fade-in;
|
||||
animation-duration: 2s;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
.am-button {
|
||||
background-color: #9BD7FF;
|
||||
width: 40%;
|
||||
&.am-button-active {
|
||||
background-color: #ccebff;
|
||||
input {
|
||||
animation-name: fade-in;
|
||||
animation-duration: 2s;
|
||||
}
|
||||
#buttonFlex {
|
||||
animation-name: fade-in;
|
||||
animation-duration: 2s;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
.am-button {
|
||||
background-color: #9bd7ff;
|
||||
width: 40%;
|
||||
&.am-button-active {
|
||||
background-color: #ccebff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$animationDelay: 1;
|
||||
@for $i from 1 through 15 {
|
||||
.loginGrid :nth-child(#{$i}) {
|
||||
animation-delay: #{0.3+ ($i)/30}s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$animationDelay: 1;
|
||||
@for $i from 1 through 15 {
|
||||
.loginGrid :nth-child(#{$i}) {
|
||||
animation-delay: #{0.3+($i)/30}s;
|
||||
}
|
||||
}
|
||||
@keyframes fade-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
0% { opacity: 0; }
|
||||
100% { opacity: 1; }
|
||||
@keyframes fade-in-from-up {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(-100px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in-from-up {
|
||||
0% { opacity: 0; transform: translateY(-100px)}
|
||||
100% { opacity: 1; }
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#patient-info-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
.submit-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 2em 0;
|
||||
width: 100%;
|
||||
.am-list {
|
||||
min-width: 8em;
|
||||
width: 40%;
|
||||
max-width: 20em;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#primary-wrapper {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
#wrapper-contents {
|
||||
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2),
|
||||
0 6px 20px 0 rgba(0, 0, 0, 0.19);
|
||||
width: 55em;
|
||||
overflow: scroll;
|
||||
}
|
||||
}
|
||||
+200
-170
@@ -22,7 +22,6 @@
|
||||
/// @access public
|
||||
////
|
||||
|
||||
|
||||
///
|
||||
/// Creates a list of global breakpoints
|
||||
///
|
||||
@@ -30,12 +29,11 @@
|
||||
/// $breakpoints: ('phone': 320px);
|
||||
///
|
||||
$breakpoints: (
|
||||
'phone': 320px,
|
||||
'tablet': 768px,
|
||||
'desktop': 1024px
|
||||
'phone': 320px,
|
||||
'tablet': 768px,
|
||||
'desktop': 1024px,
|
||||
) !default;
|
||||
|
||||
|
||||
///
|
||||
/// Creates a list of static expressions or media types
|
||||
///
|
||||
@@ -48,16 +46,17 @@ $breakpoints: (
|
||||
/// );
|
||||
///
|
||||
$media-expressions: (
|
||||
'screen': 'screen',
|
||||
'print': 'print',
|
||||
'handheld': 'handheld',
|
||||
'landscape': '(orientation: landscape)',
|
||||
'portrait': '(orientation: portrait)',
|
||||
'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 2dppx)',
|
||||
'retina3x': '(-webkit-min-device-pixel-ratio: 3), (min-resolution: 350dpi), (min-resolution: 3dppx)'
|
||||
'screen': 'screen',
|
||||
'print': 'print',
|
||||
'handheld': 'handheld',
|
||||
'landscape': '(orientation: landscape)',
|
||||
'portrait': '(orientation: portrait)',
|
||||
'retina2x':
|
||||
'(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 2dppx)',
|
||||
'retina3x':
|
||||
'(-webkit-min-device-pixel-ratio: 3), (min-resolution: 350dpi), (min-resolution: 3dppx)',
|
||||
) !default;
|
||||
|
||||
|
||||
///
|
||||
/// Defines a number to be added or subtracted from each unit when declaring breakpoints with exclusive intervals
|
||||
///
|
||||
@@ -80,10 +79,10 @@ $media-expressions: (
|
||||
/// @media (min-width: 2.1rem) {}
|
||||
///
|
||||
$unit-intervals: (
|
||||
'px': 1,
|
||||
'em': 0.01,
|
||||
'rem': 0.1,
|
||||
'': 0
|
||||
'px': 1,
|
||||
'em': 0.01,
|
||||
'rem': 0.1,
|
||||
'': 0,
|
||||
) !default;
|
||||
|
||||
///
|
||||
@@ -175,7 +174,6 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @access private
|
||||
////
|
||||
|
||||
|
||||
///
|
||||
/// Log a message either with `@error` if supported
|
||||
/// else with `@warn`, using `feature-exists('at-error')`
|
||||
@@ -184,17 +182,16 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @param {String} $message - Message to log
|
||||
///
|
||||
@function im-log($message) {
|
||||
@if feature-exists('at-error') {
|
||||
@error $message;
|
||||
} @else {
|
||||
@warn $message;
|
||||
$_: noop();
|
||||
}
|
||||
@if feature-exists('at-error') {
|
||||
@error $message;
|
||||
} @else {
|
||||
@warn $message;
|
||||
$_: noop();
|
||||
}
|
||||
|
||||
@return $message;
|
||||
@return $message;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Wrapper mixin for the log function so it can be used with a more friendly
|
||||
/// API than `@if im-log('..') {}` or `$_: im-log('..')`. Basically, use the function
|
||||
@@ -204,15 +201,16 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @param {String} $message - Message to log
|
||||
///
|
||||
@mixin log($message) {
|
||||
@if im-log($message) {}
|
||||
@if im-log($message) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Function with no `@return` called next to `@warn` in Sass 3.3
|
||||
/// to trigger a compiling error and stop the process.
|
||||
///
|
||||
@function noop() {}
|
||||
@function noop() {
|
||||
}
|
||||
|
||||
///
|
||||
/// Determines whether a list of conditions is intercepted by the static breakpoint.
|
||||
@@ -222,28 +220,30 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @return {Boolean} - Returns true if the conditions are intercepted by the static breakpoint
|
||||
///
|
||||
@function im-intercepts-static-breakpoint($conditions...) {
|
||||
$no-media-breakpoint-value: map-get($breakpoints, $im-no-media-breakpoint);
|
||||
$no-media-breakpoint-value: map-get($breakpoints, $im-no-media-breakpoint);
|
||||
|
||||
@if not $no-media-breakpoint-value {
|
||||
@if im-log('`#{$im-no-media-breakpoint}` is not a valid breakpoint.') {}
|
||||
}
|
||||
|
||||
@each $condition in $conditions {
|
||||
@if not map-has-key($media-expressions, $condition) {
|
||||
$operator: get-expression-operator($condition);
|
||||
$prefix: get-expression-prefix($operator);
|
||||
$value: get-expression-value($condition, $operator);
|
||||
|
||||
@if ($prefix == 'max' and $value <= $no-media-breakpoint-value) or
|
||||
($prefix == 'min' and $value > $no-media-breakpoint-value) {
|
||||
@return false;
|
||||
}
|
||||
} @else if not index($im-no-media-expressions, $condition) {
|
||||
@return false;
|
||||
@if not $no-media-breakpoint-value {
|
||||
@if im-log('`#{$im-no-media-breakpoint}` is not a valid breakpoint.') {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@return true;
|
||||
@each $condition in $conditions {
|
||||
@if not map-has-key($media-expressions, $condition) {
|
||||
$operator: get-expression-operator($condition);
|
||||
$prefix: get-expression-prefix($operator);
|
||||
$value: get-expression-value($condition, $operator);
|
||||
|
||||
@if ($prefix == 'max' and $value <= $no-media-breakpoint-value) or
|
||||
($prefix == 'min' and $value > $no-media-breakpoint-value)
|
||||
{
|
||||
@return false;
|
||||
}
|
||||
} @else if not index($im-no-media-expressions, $condition) {
|
||||
@return false;
|
||||
}
|
||||
}
|
||||
|
||||
@return true;
|
||||
}
|
||||
|
||||
////
|
||||
@@ -252,7 +252,6 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @access private
|
||||
////
|
||||
|
||||
|
||||
///
|
||||
/// Get operator of an expression
|
||||
///
|
||||
@@ -261,21 +260,20 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @return {String} - Any of `>=`, `>`, `<=`, `<`, `≥`, `≤`
|
||||
///
|
||||
@function get-expression-operator($expression) {
|
||||
@each $operator in ('>=', '>', '<=', '<', '≥', '≤') {
|
||||
@if str-index($expression, $operator) {
|
||||
@return $operator;
|
||||
@each $operator in ('>=', '>', '<=', '<', '≥', '≤') {
|
||||
@if str-index($expression, $operator) {
|
||||
@return $operator;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// It is not possible to include a mixin inside a function, so we have to
|
||||
// rely on the `im-log(..)` function rather than the `log(..)` mixin. Because
|
||||
// functions cannot be called anywhere in Sass, we need to hack the call in
|
||||
// a dummy variable, such as `$_`. If anybody ever raise a scoping issue with
|
||||
// Sass 3.3, change this line in `@if im-log(..) {}` instead.
|
||||
$_: im-log('No operator found in `#{$expression}`.');
|
||||
// It is not possible to include a mixin inside a function, so we have to
|
||||
// rely on the `im-log(..)` function rather than the `log(..)` mixin. Because
|
||||
// functions cannot be called anywhere in Sass, we need to hack the call in
|
||||
// a dummy variable, such as `$_`. If anybody ever raise a scoping issue with
|
||||
// Sass 3.3, change this line in `@if im-log(..) {}` instead.
|
||||
$_: im-log('No operator found in `#{$expression}`.');
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Get dimension of an expression, based on a found operator
|
||||
///
|
||||
@@ -285,18 +283,17 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @return {String} - `width` or `height` (or potentially anything else)
|
||||
///
|
||||
@function get-expression-dimension($expression, $operator) {
|
||||
$operator-index: str-index($expression, $operator);
|
||||
$parsed-dimension: str-slice($expression, 0, $operator-index - 1);
|
||||
$dimension: 'width';
|
||||
$operator-index: str-index($expression, $operator);
|
||||
$parsed-dimension: str-slice($expression, 0, $operator-index - 1);
|
||||
$dimension: 'width';
|
||||
|
||||
@if str-length($parsed-dimension) > 0 {
|
||||
$dimension: $parsed-dimension;
|
||||
}
|
||||
@if str-length($parsed-dimension) > 0 {
|
||||
$dimension: $parsed-dimension;
|
||||
}
|
||||
|
||||
@return $dimension;
|
||||
@return $dimension;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Get dimension prefix based on an operator
|
||||
///
|
||||
@@ -305,10 +302,9 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @return {String} - `min` or `max`
|
||||
///
|
||||
@function get-expression-prefix($operator) {
|
||||
@return if(index(('<', '<=', '≤'), $operator), 'max', 'min');
|
||||
@return if(index(('<', '<=', '≤'), $operator), 'max', 'min');
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Get value of an expression, based on a found operator
|
||||
///
|
||||
@@ -318,36 +314,35 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @return {Number} - A numeric value
|
||||
///
|
||||
@function get-expression-value($expression, $operator) {
|
||||
$operator-index: str-index($expression, $operator);
|
||||
$value: str-slice($expression, $operator-index + str-length($operator));
|
||||
$operator-index: str-index($expression, $operator);
|
||||
$value: str-slice($expression, $operator-index + str-length($operator));
|
||||
|
||||
@if map-has-key($breakpoints, $value) {
|
||||
$value: map-get($breakpoints, $value);
|
||||
} @else {
|
||||
$value: to-number($value);
|
||||
}
|
||||
@if map-has-key($breakpoints, $value) {
|
||||
$value: map-get($breakpoints, $value);
|
||||
} @else {
|
||||
$value: to-number($value);
|
||||
}
|
||||
|
||||
$interval: map-get($unit-intervals, unit($value));
|
||||
$interval: map-get($unit-intervals, unit($value));
|
||||
|
||||
@if not $interval {
|
||||
// It is not possible to include a mixin inside a function, so we have to
|
||||
// rely on the `im-log(..)` function rather than the `log(..)` mixin. Because
|
||||
// functions cannot be called anywhere in Sass, we need to hack the call in
|
||||
// a dummy variable, such as `$_`. If anybody ever raise a scoping issue with
|
||||
// Sass 3.3, change this line in `@if im-log(..) {}` instead.
|
||||
$_: im-log('Unknown unit `#{unit($value)}`.');
|
||||
}
|
||||
@if not $interval {
|
||||
// It is not possible to include a mixin inside a function, so we have to
|
||||
// rely on the `im-log(..)` function rather than the `log(..)` mixin. Because
|
||||
// functions cannot be called anywhere in Sass, we need to hack the call in
|
||||
// a dummy variable, such as `$_`. If anybody ever raise a scoping issue with
|
||||
// Sass 3.3, change this line in `@if im-log(..) {}` instead.
|
||||
$_: im-log('Unknown unit `#{unit($value)}`.');
|
||||
}
|
||||
|
||||
@if $operator == '>' {
|
||||
$value: $value + $interval;
|
||||
} @else if $operator == '<' {
|
||||
$value: $value - $interval;
|
||||
}
|
||||
@if $operator == '>' {
|
||||
$value: $value + $interval;
|
||||
} @else if $operator == '<' {
|
||||
$value: $value - $interval;
|
||||
}
|
||||
|
||||
@return $value;
|
||||
@return $value;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Parse an expression to return a valid media-query expression
|
||||
///
|
||||
@@ -356,18 +351,18 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @return {String} - Valid media query
|
||||
///
|
||||
@function parse-expression($expression) {
|
||||
// If it is part of $media-expressions, it has no operator
|
||||
// then there is no need to go any further, just return the value
|
||||
@if map-has-key($media-expressions, $expression) {
|
||||
@return map-get($media-expressions, $expression);
|
||||
}
|
||||
// If it is part of $media-expressions, it has no operator
|
||||
// then there is no need to go any further, just return the value
|
||||
@if map-has-key($media-expressions, $expression) {
|
||||
@return map-get($media-expressions, $expression);
|
||||
}
|
||||
|
||||
$operator: get-expression-operator($expression);
|
||||
$dimension: get-expression-dimension($expression, $operator);
|
||||
$prefix: get-expression-prefix($operator);
|
||||
$value: get-expression-value($expression, $operator);
|
||||
$operator: get-expression-operator($expression);
|
||||
$dimension: get-expression-dimension($expression, $operator);
|
||||
$prefix: get-expression-prefix($operator);
|
||||
$value: get-expression-value($expression, $operator);
|
||||
|
||||
@return '(#{$prefix}-#{$dimension}: #{$value})';
|
||||
@return '(#{$prefix}-#{$dimension}: #{$value})';
|
||||
}
|
||||
|
||||
///
|
||||
@@ -382,17 +377,17 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @return {List} Sliced list
|
||||
///
|
||||
@function slice($list, $start: 1, $end: length($list)) {
|
||||
@if length($list) < 1 or $start > $end {
|
||||
@return ();
|
||||
}
|
||||
@if length($list) < 1 or $start > $end {
|
||||
@return ();
|
||||
}
|
||||
|
||||
$result: ();
|
||||
$result: ();
|
||||
|
||||
@for $i from $start through $end {
|
||||
$result: append($result, nth($list, $i));
|
||||
}
|
||||
@for $i from $start through $end {
|
||||
$result: append($result, nth($list, $i));
|
||||
}
|
||||
|
||||
@return $result;
|
||||
@return $result;
|
||||
}
|
||||
|
||||
////
|
||||
@@ -401,7 +396,6 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @access private
|
||||
////
|
||||
|
||||
|
||||
///
|
||||
/// Casts a string into a number
|
||||
///
|
||||
@@ -410,44 +404,57 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @return {Number}
|
||||
///
|
||||
@function to-number($value) {
|
||||
@if type-of($value) == 'number' {
|
||||
@return $value;
|
||||
} @else if type-of($value) != 'string' {
|
||||
$_: im-log('Value for `to-number` should be a number or a string.');
|
||||
}
|
||||
|
||||
$first-character: str-slice($value, 1, 1);
|
||||
$result: 0;
|
||||
$digits: 0;
|
||||
$minus: ($first-character == '-');
|
||||
$numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9);
|
||||
|
||||
// Remove +/- sign if present at first character
|
||||
@if ($first-character == '+' or $first-character == '-') {
|
||||
$value: str-slice($value, 2);
|
||||
}
|
||||
|
||||
@for $i from 1 through str-length($value) {
|
||||
$character: str-slice($value, $i, $i);
|
||||
|
||||
@if not (index(map-keys($numbers), $character) or $character == '.') {
|
||||
@return to-length(if($minus, -$result, $result), str-slice($value, $i))
|
||||
@if type-of($value) == 'number' {
|
||||
@return $value;
|
||||
} @else if type-of($value) != 'string' {
|
||||
$_: im-log('Value for `to-number` should be a number or a string.');
|
||||
}
|
||||
|
||||
@if $character == '.' {
|
||||
$digits: 1;
|
||||
} @else if $digits == 0 {
|
||||
$result: $result * 10 + map-get($numbers, $character);
|
||||
} @else {
|
||||
$digits: $digits * 10;
|
||||
$result: $result + map-get($numbers, $character) / $digits;
|
||||
}
|
||||
}
|
||||
$first-character: str-slice($value, 1, 1);
|
||||
$result: 0;
|
||||
$digits: 0;
|
||||
$minus: ($first-character == '-');
|
||||
$numbers: (
|
||||
'0': 0,
|
||||
'1': 1,
|
||||
'2': 2,
|
||||
'3': 3,
|
||||
'4': 4,
|
||||
'5': 5,
|
||||
'6': 6,
|
||||
'7': 7,
|
||||
'8': 8,
|
||||
'9': 9,
|
||||
);
|
||||
|
||||
@return if($minus, -$result, $result);
|
||||
// Remove +/- sign if present at first character
|
||||
@if ($first-character == '+' or $first-character == '-') {
|
||||
$value: str-slice($value, 2);
|
||||
}
|
||||
|
||||
@for $i from 1 through str-length($value) {
|
||||
$character: str-slice($value, $i, $i);
|
||||
|
||||
@if not(index(map-keys($numbers), $character) or $character == '.') {
|
||||
@return to-length(
|
||||
if($minus, -$result, $result),
|
||||
str-slice($value, $i)
|
||||
);
|
||||
}
|
||||
|
||||
@if $character == '.' {
|
||||
$digits: 1;
|
||||
} @else if $digits == 0 {
|
||||
$result: $result * 10 + map-get($numbers, $character);
|
||||
} @else {
|
||||
$digits: $digits * 10;
|
||||
$result: $result + map-get($numbers, $character) / $digits;
|
||||
}
|
||||
}
|
||||
|
||||
@return if($minus, -$result, $result);
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Add `$unit` to `$value`
|
||||
///
|
||||
@@ -457,13 +464,29 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @return {Number} - `$value` expressed in `$unit`
|
||||
///
|
||||
@function to-length($value, $unit) {
|
||||
$units: ('px': 1px, 'cm': 1cm, 'mm': 1mm, '%': 1%, 'ch': 1ch, 'pc': 1pc, 'in': 1in, 'em': 1em, 'rem': 1rem, 'pt': 1pt, 'ex': 1ex, 'vw': 1vw, 'vh': 1vh, 'vmin': 1vmin, 'vmax': 1vmax);
|
||||
$units: (
|
||||
'px': 1px,
|
||||
'cm': 1cm,
|
||||
'mm': 1mm,
|
||||
'%': 1%,
|
||||
'ch': 1ch,
|
||||
'pc': 1pc,
|
||||
'in': 1in,
|
||||
'em': 1em,
|
||||
'rem': 1rem,
|
||||
'pt': 1pt,
|
||||
'ex': 1ex,
|
||||
'vw': 1vw,
|
||||
'vh': 1vh,
|
||||
'vmin': 1vmin,
|
||||
'vmax': 1vmax,
|
||||
);
|
||||
|
||||
@if not index(map-keys($units), $unit) {
|
||||
$_: im-log('Invalid unit `#{$unit}`.');
|
||||
}
|
||||
@if not index(map-keys($units), $unit) {
|
||||
$_: im-log('Invalid unit `#{$unit}`.');
|
||||
}
|
||||
|
||||
@return $value * map-get($units, $unit);
|
||||
@return $value * map-get($units, $unit);
|
||||
}
|
||||
|
||||
///
|
||||
@@ -505,19 +528,22 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// }
|
||||
///
|
||||
@mixin media-context($tweakpoints: (), $tweak-media-expressions: ()) {
|
||||
// Save global configuration
|
||||
$global-breakpoints: $breakpoints;
|
||||
$global-media-expressions: $media-expressions;
|
||||
// Save global configuration
|
||||
$global-breakpoints: $breakpoints;
|
||||
$global-media-expressions: $media-expressions;
|
||||
|
||||
// Update global configuration
|
||||
$breakpoints: map-merge($breakpoints, $tweakpoints) !global;
|
||||
$media-expressions: map-merge($media-expressions, $tweak-media-expressions) !global;
|
||||
// Update global configuration
|
||||
$breakpoints: map-merge($breakpoints, $tweakpoints) !global;
|
||||
$media-expressions: map-merge(
|
||||
$media-expressions,
|
||||
$tweak-media-expressions
|
||||
) !global;
|
||||
|
||||
@content;
|
||||
@content;
|
||||
|
||||
// Restore global configuration
|
||||
$breakpoints: $global-breakpoints !global;
|
||||
$media-expressions: $global-media-expressions !global;
|
||||
// Restore global configuration
|
||||
$breakpoints: $global-breakpoints !global;
|
||||
$media-expressions: $global-media-expressions !global;
|
||||
}
|
||||
|
||||
////
|
||||
@@ -526,7 +552,6 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @access public
|
||||
////
|
||||
|
||||
|
||||
///
|
||||
/// Generates a media query based on a list of conditions
|
||||
///
|
||||
@@ -551,15 +576,20 @@ $im-no-media-expressions: ('screen', 'portrait', 'landscape') !default;
|
||||
/// @include media('>=350px', '<tablet', 'retina3x') { }
|
||||
///
|
||||
@mixin media($conditions...) {
|
||||
@if ($im-media-support and length($conditions) == 0) or
|
||||
(not $im-media-support and im-intercepts-static-breakpoint($conditions...)) {
|
||||
@content;
|
||||
} @else if ($im-media-support and length($conditions) > 0) {
|
||||
@media #{unquote(parse-expression(nth($conditions, 1)))} {
|
||||
// Recursive call
|
||||
@include media(slice($conditions, 2)...) {
|
||||
@if ($im-media-support and length($conditions) == 0) or
|
||||
(
|
||||
not
|
||||
$im-media-support and
|
||||
im-intercepts-static-breakpoint($conditions...)
|
||||
)
|
||||
{
|
||||
@content;
|
||||
}
|
||||
} @else if ($im-media-support and length($conditions) > 0) {
|
||||
@media #{unquote(parse-expression(nth($conditions, 1)))} {
|
||||
// Recursive call
|
||||
@include media(slice($conditions, 2) ...) {
|
||||
@content;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-12
@@ -1,16 +1,16 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
background-color: #e8ffd9;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto',
|
||||
'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans',
|
||||
'Helvetica Neue', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
background-color: #e8ffd9;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
+112
-113
@@ -1,4 +1,5 @@
|
||||
/* istanbul ignore file */
|
||||
/* eslint-disable */
|
||||
// This optional code is used to register a service worker.
|
||||
// register() is not called by default.
|
||||
|
||||
@@ -12,135 +13,133 @@
|
||||
// opt-in, read https://bit.ly/CRA-PWA
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.0/8 are considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.0/8 are considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/,
|
||||
),
|
||||
)
|
||||
|
||||
type Config = {
|
||||
onSuccess?: (registration: ServiceWorkerRegistration) => void;
|
||||
onUpdate?: (registration: ServiceWorkerRegistration) => void;
|
||||
};
|
||||
onSuccess?: (registration: ServiceWorkerRegistration) => void
|
||||
onUpdate?: (registration: ServiceWorkerRegistration) => void
|
||||
}
|
||||
|
||||
export function register(config?: 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;
|
||||
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 https://bit.ly/CRA-PWA',
|
||||
)
|
||||
})
|
||||
} else {
|
||||
// Is not localhost. Just register service worker
|
||||
registerValidSW(swUrl, config)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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 https://bit.ly/CRA-PWA'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// Is not localhost. Just register service worker
|
||||
registerValidSW(swUrl, config);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerValidSW(swUrl: string, config?: 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 https://bit.ly/CRA-PWA.'
|
||||
);
|
||||
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 https://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.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);
|
||||
}
|
||||
// Execute callback
|
||||
if (config && config.onSuccess) {
|
||||
config.onSuccess(registration)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Error during service worker registration:', error)
|
||||
})
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl: string, config?: Config) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl, {
|
||||
headers: { 'Service-Worker': 'script' }
|
||||
})
|
||||
.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);
|
||||
}
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl, {
|
||||
headers: { 'Service-Worker': 'script' },
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
);
|
||||
});
|
||||
.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();
|
||||
});
|
||||
}
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then((registration) => {
|
||||
registration.unregister()
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -2,4 +2,4 @@
|
||||
// allows you to do things like:
|
||||
// expect(element).toHaveTextContent(/react/i)
|
||||
// learn more: https://github.com/testing-library/jest-dom
|
||||
import '@testing-library/jest-dom/extend-expect';
|
||||
import '@testing-library/jest-dom/extend-expect'
|
||||
@@ -0,0 +1,13 @@
|
||||
/* istanbul ignore file */
|
||||
|
||||
export enum SEX {
|
||||
male = 'male',
|
||||
female = 'female',
|
||||
}
|
||||
|
||||
export enum YN {
|
||||
YES = 1,
|
||||
NO = 0,
|
||||
}
|
||||
|
||||
export default {}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { Action, action } from 'easy-peasy'
|
||||
import { SEX, YN } from '../enums'
|
||||
|
||||
interface PatientInfoFormFields {
|
||||
firstName?: string
|
||||
lastName?: string
|
||||
nickname?: string
|
||||
sex?: SEX
|
||||
birthDate?: Date
|
||||
age?: number
|
||||
phone?: string
|
||||
town?: string
|
||||
firstVisit?: YN
|
||||
pregnant?: YN
|
||||
G?: number
|
||||
P?: number
|
||||
A?: number
|
||||
LMP?: Date
|
||||
wantsPlanning?: YN
|
||||
weight?: number
|
||||
height?: number
|
||||
bloodPressure?: string
|
||||
temperature?: number
|
||||
pulse?: number
|
||||
zScore?: number
|
||||
albendazole?: YN
|
||||
allergies?: string
|
||||
medicines?: string
|
||||
chiefComplaint?: string[]
|
||||
history?: string
|
||||
exam?: string
|
||||
}
|
||||
|
||||
export interface PatientInfoFormModel {
|
||||
fields: PatientInfoFormFields
|
||||
updateFields: Action<PatientInfoFormModel, PatientInfoFormFields>
|
||||
}
|
||||
|
||||
/* istanbul ignore next */
|
||||
// Form submission requests validated in integration test
|
||||
const patientInfoFormModel: PatientInfoFormModel = {
|
||||
fields: {},
|
||||
updateFields: action((state, formObject) => {
|
||||
state.fields = formObject
|
||||
}),
|
||||
}
|
||||
|
||||
export default patientInfoFormModel
|
||||
@@ -0,0 +1,8 @@
|
||||
/* istanbul ignore file */
|
||||
|
||||
import { createStore, persist } from 'easy-peasy'
|
||||
import storeIndex from './storeIndex'
|
||||
|
||||
const store = createStore(persist(storeIndex))
|
||||
|
||||
export default store
|
||||
@@ -0,0 +1,17 @@
|
||||
/* istanbul ignore file */
|
||||
import { createTypedHooks } from 'easy-peasy'
|
||||
|
||||
import patientInfoFormModel from './models/patientInfoForm.model'
|
||||
|
||||
export const storeModels = {
|
||||
patientInfoFormModel,
|
||||
}
|
||||
|
||||
export const {
|
||||
useStore,
|
||||
useStoreState,
|
||||
useStoreActions,
|
||||
useStoreDispatch,
|
||||
} = createTypedHooks<typeof storeModels>()
|
||||
|
||||
export default storeModels
|
||||
Reference in new issue
Block a user