From 80b808d922ef1bc7b812debc3969331afe00820b Mon Sep 17 00:00:00 2001 From: Hendrik de Graaf Date: Wed, 16 Jun 2021 22:20:30 +0200 Subject: [PATCH] feat: general configuration, application layout and directory structure (#1) * feat: general configuration, application layout and directory structure * fix: file capitalization * refactor: remove providers and replace cached-resources by current-user * refactor: rename auth-wall dir to auth because it contains a hook too * refactor: export directly Co-authored-by: Jan-Gerke Salomon Co-authored-by: Jan-Gerke Salomon --- .editorconfig | 16 + .github/dependabot.yml | 8 + .github/semantic.yml | 4 + .github/workflows/dhis2-verify-app.yml | 145 ++++++ .ls-lint.yml | 19 + .prettierrc.js | 13 + .tx/config | 10 + d2.config.js | 5 +- i18n/en.pot | 19 + jest.config.js | 8 + package.json | 17 +- src/App.js | 31 -- src/App.module.css | 9 - src/App.test.js | 9 - src/action-bar/action-bar.js | 5 + src/action-bar/index.js | 1 + src/app/app.js | 32 ++ src/app/app.test.js | 9 + src/app/index.js | 3 + src/app/layout.js | 28 ++ src/app/layout.module.css | 26 + src/auth/auth-wall.js | 30 ++ src/auth/auth-wall.module.css | 4 + src/auth/auth-wall.test.js | 30 ++ src/auth/index.js | 1 + src/auth/use-is-authorized.js | 8 + src/auth/use-is-authorized.test.js | 54 ++ src/context-selector/context-selector.js | 5 + src/context-selector/index.js | 1 + src/current-user/current-user-context.js | 5 + src/current-user/current-user-provider.js | 57 +++ .../current-user-provider.test.js | 55 ++ src/current-user/index.js | 3 + src/current-user/use-current-user.js | 4 + src/current-user/use-current-user.test.js | 22 + src/data-workspace/data-workspace.js | 5 + src/data-workspace/index.js | 1 + src/test-utils/expect-render-error.js | 56 +++ src/test-utils/setup-tests.js | 4 + yarn.lock | 473 +++++++++++++++++- 40 files changed, 1157 insertions(+), 78 deletions(-) create mode 100755 .editorconfig create mode 100755 .github/dependabot.yml create mode 100755 .github/semantic.yml create mode 100644 .github/workflows/dhis2-verify-app.yml create mode 100644 .ls-lint.yml create mode 100644 .tx/config create mode 100644 i18n/en.pot create mode 100644 jest.config.js delete mode 100644 src/App.js delete mode 100644 src/App.module.css delete mode 100644 src/App.test.js create mode 100644 src/action-bar/action-bar.js create mode 100644 src/action-bar/index.js create mode 100644 src/app/app.js create mode 100644 src/app/app.test.js create mode 100644 src/app/index.js create mode 100644 src/app/layout.js create mode 100644 src/app/layout.module.css create mode 100644 src/auth/auth-wall.js create mode 100644 src/auth/auth-wall.module.css create mode 100644 src/auth/auth-wall.test.js create mode 100644 src/auth/index.js create mode 100644 src/auth/use-is-authorized.js create mode 100644 src/auth/use-is-authorized.test.js create mode 100644 src/context-selector/context-selector.js create mode 100644 src/context-selector/index.js create mode 100644 src/current-user/current-user-context.js create mode 100644 src/current-user/current-user-provider.js create mode 100644 src/current-user/current-user-provider.test.js create mode 100644 src/current-user/index.js create mode 100644 src/current-user/use-current-user.js create mode 100644 src/current-user/use-current-user.test.js create mode 100644 src/data-workspace/data-workspace.js create mode 100644 src/data-workspace/index.js create mode 100644 src/test-utils/expect-render-error.js create mode 100644 src/test-utils/setup-tests.js diff --git a/.editorconfig b/.editorconfig new file mode 100755 index 00000000..57becb87 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# For more information about the properties used in +# this file, please see the EditorConfig documentation: +# https://editorconfig.org/ + +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100755 index 00000000..8ddd72b6 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,8 @@ +version: 2 +updates: + - package-ecosystem: 'npm' + directory: '/' + schedule: + interval: 'weekly' + open-pull-requests-limit: 5 + versioning-strategy: 'increase' diff --git a/.github/semantic.yml b/.github/semantic.yml new file mode 100755 index 00000000..16651452 --- /dev/null +++ b/.github/semantic.yml @@ -0,0 +1,4 @@ +titleOnly: false +commitsOnly: false +titleAndCommits: true +allowMergeCommits: true diff --git a/.github/workflows/dhis2-verify-app.yml b/.github/workflows/dhis2-verify-app.yml new file mode 100644 index 00000000..8a31f3c2 --- /dev/null +++ b/.github/workflows/dhis2-verify-app.yml @@ -0,0 +1,145 @@ +name: 'dhis2: verify (app)' + +on: push + +concurrency: + group: ${{ github.workflow}}-${{ github.ref }} + cancel-in-progress: true + +env: + GIT_AUTHOR_NAME: '@dhis2-bot' + GIT_AUTHOR_EMAIL: 'apps@dhis2.org' + GIT_COMMITTER_NAME: '@dhis2-bot' + GIT_COMMITTER_EMAIL: 'apps@dhis2.org' + GH_TOKEN: ${{secrets.DHIS2_BOT_GITHUB_TOKEN}} + CI: true + D2_VERBOSE: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 12.x + + - uses: c-hive/gha-yarn-cache@v1 + - run: yarn install --frozen-lockfile + + - name: Build + run: yarn build + + - uses: actions/upload-artifact@v2 + with: + name: app-build + path: | + **/build + !**/node_modules + retention-days: 1 + + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 12.x + + - uses: c-hive/gha-yarn-cache@v1 + - run: yarn install --frozen-lockfile + + - name: Lint + run: yarn lint + + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-node@v1 + with: + node-version: 12.x + + - uses: c-hive/gha-yarn-cache@v1 + - run: yarn install --frozen-lockfile + + # Can be removed if translations aren't required for tests, or if not using the App Platform + - name: Generate translations + run: yarn d2-app-scripts i18n generate + + - name: Test + run: yarn test + + #e2e: + # runs-on: ubuntu-latest + # if: "!github.event.push.repository.fork && github.actor != 'dependabot[bot]'" + # + # strategy: + # fail-fast: false + # matrix: + # containers: [1, 2, 3, 4] + # + # steps: + # - name: Checkout + # uses: actions/checkout@v2 + # + # - uses: actions/setup-node@v1 + # with: + # node-version: 12.x + # + # - name: End-to-End tests + # uses: cypress-io/github-action@v2 + # with: + # # This should be a command that serves the app. + # start: yarn d2-app-scripts start + # wait-on: 'http://localhost:3000' + # wait-on-timeout: 300 + # record: true + # parallel: true + # env: + # BROWSER: none + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} + # CYPRESS_dhis2BaseUrl: https://debug.dhis2.org/dev + # CYPRESS_dhis2ApiVersion: 37 + # CYPRESS_networkMode: stub + + publish: + runs-on: ubuntu-latest + needs: [build, lint, test] # add e2e if you use it + if: "!github.event.push.repository.fork && github.actor != 'dependabot[bot]'" + steps: + - uses: actions/checkout@v2 + with: + token: ${{env.GH_TOKEN}} + + - uses: actions/setup-node@v1 + with: + node-version: 12.x + + - uses: actions/download-artifact@v2 + with: + name: app-build + + - uses: dhis2/deploy-build@master + with: + # uncomment following line for monorepo apps: + #cwd: ./packages/app + build-dir: build/app + github-token: ${{ env.GH_TOKEN }} + + release: + runs-on: ubuntu-latest + needs: [publish] + if: "!github.event.push.repository.fork && github.actor != 'dependabot[bot]'" + steps: + - uses: actions/checkout@v2 + with: + token: ${{env.GH_TOKEN}} + + - uses: actions/setup-node@v1 + with: + node-version: 12.x + + - name: Publish release to GitHub + run: npx @dhis2/cli-utils release diff --git a/.ls-lint.yml b/.ls-lint.yml new file mode 100644 index 00000000..9308e0e9 --- /dev/null +++ b/.ls-lint.yml @@ -0,0 +1,19 @@ +ls: + ./**/{src,cypress,lib}: + .css: kebab-case + .module.css: kebab-case + .feature: kebab-case + .js: kebab-case + .stories.js: kebab-case + .stories.e2e.js: kebab-case + .styles.js: kebab-case + .test.js: kebab-case + .jsx: kebab-case + .ts: kebab-case + .tsx: kebab-case + .d.ts: kebab-case + +ignore: + - node_modules + - .d2 + - build diff --git a/.prettierrc.js b/.prettierrc.js index def7934e..0fde60d9 100755 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -1,5 +1,18 @@ +/* + * The code snippet below was generated by @dhis2/cli-style. + * There is nothing wrong with it, but somehow the VSCode + * prettier plugin can't work with it. As a temporary hack + * we use the theoretically equivalent code below, that doesn't + * break the plugin. + const { config } = require('@dhis2/cli-style') module.exports = { ...require(config.prettier), } + +*/ + +const prettierConfig = require('@dhis2/cli-style/config/prettier.config.js') + +module.exports = { ...prettierConfig } diff --git a/.tx/config b/.tx/config new file mode 100644 index 00000000..f6e8dc64 --- /dev/null +++ b/.tx/config @@ -0,0 +1,10 @@ +[main] +host = https://www.transifex.com +lang_map = fa_AF: prs, uz@Cyrl: uz, uz@Latn: uz_Latn + +[app-approval-app.en-pot] +file_filter = i18n/.po +minimum_perc = 0 +source_file = i18n/en.pot +source_lang = en +type = PO diff --git a/d2.config.js b/d2.config.js index 9908e499..874ec9bd 100644 --- a/d2.config.js +++ b/d2.config.js @@ -1,7 +1,8 @@ module.exports = { type: 'app', - + title: 'Data Approval App', + coreApp: true, entryPoints: { - app: './src/App.js', + app: './src/app/index.js', }, } diff --git a/i18n/en.pot b/i18n/en.pot new file mode 100644 index 00000000..765c6c38 --- /dev/null +++ b/i18n/en.pot @@ -0,0 +1,19 @@ +msgid "" +msgstr "" +"Project-Id-Version: i18next-conv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"POT-Creation-Date: 2021-06-15T13:56:19.937Z\n" +"PO-Revision-Date: 2021-06-15T13:56:19.937Z\n" + +msgid "Not authorized" +msgstr "Not authorized" + +msgid "" +"You don't have access to the Data Approval App. Contact a system " +"administrator to request access." +msgstr "" +"You don't have access to the Data Approval App. Contact a system " +"administrator to request access." diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 00000000..efe36917 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,8 @@ +module.exports = { + setupFilesAfterEnv: ['/src/test-utils/setup-tests.js'], + collectCoverageFrom: ['src/**/*.{js,jsx}', '!src/{setupTests.js}'], + coveragePathIgnorePatterns: ['/node_modules/', '/src/locales/'], + moduleNameMapper: { + '\\.css$': 'identity-obj-proxy', + }, +} diff --git a/package.json b/package.json index d40348f9..d977f838 100644 --- a/package.json +++ b/package.json @@ -6,15 +6,24 @@ "private": true, "scripts": { "build": "d2-app-scripts build", + "deploy": "d2-app-scripts deploy", + "format": "d2-style apply", + "lint": "d2-style check", "start": "d2-app-scripts start", - "test": "d2-app-scripts test", - "deploy": "d2-app-scripts deploy" + "test": "d2-app-scripts test" }, "devDependencies": { "@dhis2/cli-app-scripts": "^6.2.0", - "@dhis2/cli-style": "^8.3.0" + "@dhis2/cli-style": "^8.4.1", + "@testing-library/react-hooks": "^7.0.0", + "enzyme": "^3.11.0", + "enzyme-adapter-react-16": "^1.15.6", + "identity-obj-proxy": "^3.0.0" }, "dependencies": { - "@dhis2/app-runtime": "^2.8.0" + "@dhis2/app-runtime": "^2.8.0", + "prop-types": "^15.7.2", + "query-string": "^7.0.0", + "use-query-params": "^1.2.2" } } diff --git a/src/App.js b/src/App.js deleted file mode 100644 index 38aedc55..00000000 --- a/src/App.js +++ /dev/null @@ -1,31 +0,0 @@ -import { DataQuery } from '@dhis2/app-runtime' -import i18n from '@dhis2/d2-i18n' -import React from 'react' -import classes from './App.module.css' - -const query = { - me: { - resource: 'me', - }, -} - -const MyApp = () => ( -
- - {({ error, loading, data }) => { - if (error) return ERROR - if (loading) return ... - return ( - <> -

- {i18n.t('Hello {{name}}', { name: data.me.name })} -

-

{i18n.t('Welcome to DHIS2!')}

- - ) - }} -
-
-) - -export default MyApp diff --git a/src/App.module.css b/src/App.module.css deleted file mode 100644 index a824cffd..00000000 --- a/src/App.module.css +++ /dev/null @@ -1,9 +0,0 @@ -.container { - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: 1rem; -} diff --git a/src/App.test.js b/src/App.test.js deleted file mode 100644 index fe9b6717..00000000 --- a/src/App.test.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react' -import ReactDOM from 'react-dom' -import App from './App' - -it('renders without crashing', () => { - const div = document.createElement('div') - ReactDOM.render(, div) - ReactDOM.unmountComponentAtNode(div) -}) diff --git a/src/action-bar/action-bar.js b/src/action-bar/action-bar.js new file mode 100644 index 00000000..b338222e --- /dev/null +++ b/src/action-bar/action-bar.js @@ -0,0 +1,5 @@ +import React from 'react' + +const ActionBar = () =>
ActionBar placeholder
+ +export { ActionBar } diff --git a/src/action-bar/index.js b/src/action-bar/index.js new file mode 100644 index 00000000..e10703bd --- /dev/null +++ b/src/action-bar/index.js @@ -0,0 +1 @@ +export { ActionBar } from './action-bar.js' diff --git a/src/app/app.js b/src/app/app.js new file mode 100644 index 00000000..7b3ca8a9 --- /dev/null +++ b/src/app/app.js @@ -0,0 +1,32 @@ +import { CssVariables } from '@dhis2/ui' +import React from 'react' +import { QueryParamProvider } from 'use-query-params' +import { ActionBar } from '../action-bar' +import { AuthWall } from '../auth' +import { ContextSelector } from '../context-selector' +import { CurrentUserProvider } from '../current-user' +import { DataWorkspace } from '../data-workspace' +import { Layout } from './layout.js' + +const App = () => ( + + + + + + + + + + + + + + + + + + +) + +export { App } diff --git a/src/app/app.test.js b/src/app/app.test.js new file mode 100644 index 00000000..4841aee8 --- /dev/null +++ b/src/app/app.test.js @@ -0,0 +1,9 @@ +import { shallow } from 'enzyme' +import React from 'react' +import { App } from './app' + +describe('', () => { + it('renders without errors', () => { + shallow() + }) +}) diff --git a/src/app/index.js b/src/app/index.js new file mode 100644 index 00000000..bcfa909d --- /dev/null +++ b/src/app/index.js @@ -0,0 +1,3 @@ +import { App } from './app.js' + +export default App diff --git a/src/app/layout.js b/src/app/layout.js new file mode 100644 index 00000000..48b3b460 --- /dev/null +++ b/src/app/layout.js @@ -0,0 +1,28 @@ +import PropTypes from 'prop-types' +import React from 'react' +import classes from './layout.module.css' + +const LayoutSection = ({ children, className }) => ( +
{children}
+) + +LayoutSection.propTypes = { + children: PropTypes.node, + className: PropTypes.string, +} + +const Container = props => ( + +) +const Top = props => +const Content = props => ( + +) +const Bottom = props => + +export const Layout = { + Container, + Top, + Content, + Bottom, +} diff --git a/src/app/layout.module.css b/src/app/layout.module.css new file mode 100644 index 00000000..08ec82b0 --- /dev/null +++ b/src/app/layout.module.css @@ -0,0 +1,26 @@ +:global(html) { + background-color: var(--colors-grey100); +} +.container { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; +} +.top { + padding: 0 8px 0 0; + border-bottom: 2px solid var(--colors-grey300); + background-color: var(--colors-white); +} +.content { + flex-grow: 1; + overflow: auto; + padding: 12px 8px; + background-color: var(--colors-grey100); +} +.bottom { + padding: 8px 12px; + box-shadow: 0 -2px 4px 0 rgba(0, 0, 0, 0.12); + border-top: 1px solid var(--colors-grey300); + background-color: var(--colors-white); +} diff --git a/src/auth/auth-wall.js b/src/auth/auth-wall.js new file mode 100644 index 00000000..1e30ac58 --- /dev/null +++ b/src/auth/auth-wall.js @@ -0,0 +1,30 @@ +import i18n from '@dhis2/d2-i18n' +import { NoticeBox } from '@dhis2/ui' +import PropTypes from 'prop-types' +import React from 'react' +import classes from './auth-wall.module.css' +import { useIsAuthorized } from './use-is-authorized.js' + +const AuthWall = ({ children }) => { + const isAuthorized = useIsAuthorized() + + if (!isAuthorized) { + return ( +
+ + {i18n.t( + "You don't have access to the Data Approval App. Contact a system administrator to request access." + )} + +
+ ) + } + + return children +} + +AuthWall.propTypes = { + children: PropTypes.node.isRequired, +} + +export { AuthWall } diff --git a/src/auth/auth-wall.module.css b/src/auth/auth-wall.module.css new file mode 100644 index 00000000..5ed0a48d --- /dev/null +++ b/src/auth/auth-wall.module.css @@ -0,0 +1,4 @@ +.wrapper { + max-width: 800px; + margin: var(--spacers-dp24) auto 0; +} diff --git a/src/auth/auth-wall.test.js b/src/auth/auth-wall.test.js new file mode 100644 index 00000000..56a695ad --- /dev/null +++ b/src/auth/auth-wall.test.js @@ -0,0 +1,30 @@ +import { shallow } from 'enzyme' +import React from 'react' +import { AuthWall } from './auth-wall.js' +import { useIsAuthorized } from './use-is-authorized' + +jest.mock('./use-is-authorized', () => ({ + useIsAuthorized: jest.fn(), +})) + +afterEach(() => { + jest.resetAllMocks() +}) + +describe('', () => { + it('shows a noticebox for unauthorized users', () => { + useIsAuthorized.mockImplementation(() => false) + + const wrapper = shallow(Child) + + expect(wrapper.find('NoticeBox')).toHaveLength(1) + }) + + it('renders the children for authorised users', () => { + useIsAuthorized.mockImplementation(() => true) + + const wrapper = shallow(Child) + + expect(wrapper.text()).toEqual(expect.stringContaining('Child')) + }) +}) diff --git a/src/auth/index.js b/src/auth/index.js new file mode 100644 index 00000000..f20b68e8 --- /dev/null +++ b/src/auth/index.js @@ -0,0 +1 @@ +export { AuthWall } from './auth-wall.js' diff --git a/src/auth/use-is-authorized.js b/src/auth/use-is-authorized.js new file mode 100644 index 00000000..c7da950e --- /dev/null +++ b/src/auth/use-is-authorized.js @@ -0,0 +1,8 @@ +import { useCurrentUser } from '../current-user' + +export const useIsAuthorized = () => { + const { authorities } = useCurrentUser() + return authorities.some( + authority => authority === 'ALL' || authority === 'M_dhis-web-approval' + ) +} diff --git a/src/auth/use-is-authorized.test.js b/src/auth/use-is-authorized.test.js new file mode 100644 index 00000000..8ab37e20 --- /dev/null +++ b/src/auth/use-is-authorized.test.js @@ -0,0 +1,54 @@ +import { renderHook } from '@testing-library/react-hooks' +import React from 'react' +import { CurrentUserContext } from '../current-user' +import { useIsAuthorized } from './use-is-authorized.js' + +describe('useIsAuthorized', () => { + it('returns false for unauthorised users', () => { + const value = { + authorities: ['dummy'], + } + + const wrapper = ({ children }) => ( + + {children} + + ) + + const { result } = renderHook(() => useIsAuthorized(), { wrapper }) + + expect(result.current).toEqual(false) + }) + + it('returns true for authorised users', () => { + const value = { + authorities: ['M_dhis-web-approval'], + } + + const wrapper = ({ children }) => ( + + {children} + + ) + + const { result } = renderHook(() => useIsAuthorized(), { wrapper }) + + expect(result.current).toEqual(true) + }) + + it('returns true for superusers', () => { + const value = { + authorities: ['ALL'], + } + + const wrapper = ({ children }) => ( + + {children} + + ) + + const { result } = renderHook(() => useIsAuthorized(), { wrapper }) + + expect(result.current).toEqual(true) + }) +}) diff --git a/src/context-selector/context-selector.js b/src/context-selector/context-selector.js new file mode 100644 index 00000000..f96d6455 --- /dev/null +++ b/src/context-selector/context-selector.js @@ -0,0 +1,5 @@ +import React from 'react' + +const ContextSelector = () =>
ContextSelector placeholder
+ +export { ContextSelector } diff --git a/src/context-selector/index.js b/src/context-selector/index.js new file mode 100644 index 00000000..b2064cd7 --- /dev/null +++ b/src/context-selector/index.js @@ -0,0 +1 @@ +export { ContextSelector } from './context-selector' diff --git a/src/current-user/current-user-context.js b/src/current-user/current-user-context.js new file mode 100644 index 00000000..36518bd5 --- /dev/null +++ b/src/current-user/current-user-context.js @@ -0,0 +1,5 @@ +import { createContext } from 'react' + +const CurrentUserContext = createContext({}) + +export { CurrentUserContext } diff --git a/src/current-user/current-user-provider.js b/src/current-user/current-user-provider.js new file mode 100644 index 00000000..80f9c780 --- /dev/null +++ b/src/current-user/current-user-provider.js @@ -0,0 +1,57 @@ +import { useDataQuery } from '@dhis2/app-runtime' +import { PropTypes } from '@dhis2/prop-types' +import { CircularLoader, Layer, CenteredContent } from '@dhis2/ui' +import React from 'react' +import { CurrentUserContext } from './current-user-context' + +const query = { + me: { + resource: 'me', + params: { + fields: [ + // TODO: adjust fields according to actual requirements + 'authorities', + 'programs', + 'dataSets', + 'userGroups', + 'organisationUnits', + 'dataViewOrganisationUnits', + ], + }, + }, +} + +const CurrentUserProvider = ({ children }) => { + const { data, loading, error } = useDataQuery(query) + + if (loading) { + return ( + + + + + + ) + } + + if (error) { + /** + * The app can't continue if this fails, because it doesn't + * have any data, so throw the error and let it be caught by + * the error boundary in the app-shell + */ + throw error + } + + return ( + + {children} + + ) +} + +CurrentUserProvider.propTypes = { + children: PropTypes.node.isRequired, +} + +export { CurrentUserProvider } diff --git a/src/current-user/current-user-provider.test.js b/src/current-user/current-user-provider.test.js new file mode 100644 index 00000000..d3ef006f --- /dev/null +++ b/src/current-user/current-user-provider.test.js @@ -0,0 +1,55 @@ +import { useDataQuery } from '@dhis2/app-runtime' +import { shallow, mount } from 'enzyme' +import React from 'react' +import { expectRenderError } from '../test-utils/expect-render-error.js' +import { CurrentUserProvider } from './current-user-provider.js' + +jest.mock('@dhis2/app-runtime', () => ({ + useDataQuery: jest.fn(), +})) + +afterEach(() => { + jest.resetAllMocks() +}) + +describe('', () => { + it('shows a spinner when loading', () => { + useDataQuery.mockImplementation(() => ({ loading: true })) + + const wrapper = mount(Child) + const loadingIndicator = wrapper.find({ + 'data-test': 'dhis2-uicore-circularloader', + }) + + expect(loadingIndicator).toHaveLength(1) + }) + + it('throws fetching errors if they occur', () => { + const props = { children: 'Child' } + const message = 'Something went wrong' + const error = new Error(message) + + useDataQuery.mockImplementation(() => ({ + loading: false, + error, + })) + + expectRenderError(, message) + }) + + it('renders the children once data has been received', () => { + useDataQuery.mockImplementation(() => ({ + loading: false, + error: undefined, + data: { + me: {}, + }, + })) + + const wrapper = shallow( + Child + ) + + expect(wrapper.text()).toEqual(expect.stringContaining('Child')) + }) +}) diff --git a/src/current-user/index.js b/src/current-user/index.js new file mode 100644 index 00000000..f95b2bcb --- /dev/null +++ b/src/current-user/index.js @@ -0,0 +1,3 @@ +export { CurrentUserContext } from './current-user-context.js' +export { CurrentUserProvider } from './current-user-provider.js' +export { useCurrentUser } from './use-current-user.js' diff --git a/src/current-user/use-current-user.js b/src/current-user/use-current-user.js new file mode 100644 index 00000000..77b30f57 --- /dev/null +++ b/src/current-user/use-current-user.js @@ -0,0 +1,4 @@ +import { useContext } from 'react' +import { CurrentUserContext } from './current-user-context' + +export const useCurrentUser = () => useContext(CurrentUserContext) diff --git a/src/current-user/use-current-user.test.js b/src/current-user/use-current-user.test.js new file mode 100644 index 00000000..4ce17343 --- /dev/null +++ b/src/current-user/use-current-user.test.js @@ -0,0 +1,22 @@ +import { renderHook } from '@testing-library/react-hooks' +import React from 'react' +import { CurrentUserContext } from './current-user-context' +import { useCurrentUser } from './use-current-user' + +describe('useCurrentUser', () => { + const value = { + authorities: ['dummy'], + } + + const wrapper = ({ children }) => ( + + {children} + + ) + + it('returns an object with current user properties', () => { + const { result } = renderHook(() => useCurrentUser(), { wrapper }) + + expect(result.current).toEqual(value) + }) +}) diff --git a/src/data-workspace/data-workspace.js b/src/data-workspace/data-workspace.js new file mode 100644 index 00000000..5ce5f287 --- /dev/null +++ b/src/data-workspace/data-workspace.js @@ -0,0 +1,5 @@ +import React from 'react' + +const DataWorkspace = () =>
DataWorkspace placeholder
+ +export { DataWorkspace } diff --git a/src/data-workspace/index.js b/src/data-workspace/index.js new file mode 100644 index 00000000..da06e370 --- /dev/null +++ b/src/data-workspace/index.js @@ -0,0 +1 @@ +export { DataWorkspace } from './data-workspace.js' diff --git a/src/test-utils/expect-render-error.js b/src/test-utils/expect-render-error.js new file mode 100644 index 00000000..eed2f513 --- /dev/null +++ b/src/test-utils/expect-render-error.js @@ -0,0 +1,56 @@ +import { PropTypes } from 'prop-types' +import React from 'react' +import ReactDOM from 'react-dom' + +/** + * Taken from the gist referenced here: https://github.com/facebook/react/issues/11098#issuecomment-412682721 + * This module allows asserting component render errors, and prevents them from + * showing up in the console. + */ + +// Noop error boundary for testing. +class TestBoundary extends React.Component { + constructor(props) { + super(props) + this.state = { didError: false } + } + + componentDidCatch() { + this.setState({ didError: true }) + } + + render() { + return this.state.didError ? null : this.props.children + } +} + +TestBoundary.propTypes = { + children: PropTypes.node.isRequired, +} + +// Assertion +const expectRenderError = (element, expectedError) => { + // Record all errors. + const topLevelErrors = [] + + function handleTopLevelError(event) { + topLevelErrors.push(event.error) + + // Prevent logging + event.preventDefault() + } + + const div = document.createElement('div') + window.addEventListener('error', handleTopLevelError) + + try { + ReactDOM.render({element}, div) + } finally { + window.removeEventListener('error', handleTopLevelError) + } + + expect(topLevelErrors.length).toBe(1) + expect(topLevelErrors[0].message).toContain(expectedError) +} + +export { expectRenderError } diff --git a/src/test-utils/setup-tests.js b/src/test-utils/setup-tests.js new file mode 100644 index 00000000..3d6cd1d5 --- /dev/null +++ b/src/test-utils/setup-tests.js @@ -0,0 +1,4 @@ +import { configure } from 'enzyme' +import Adapter from 'enzyme-adapter-react-16' + +configure({ adapter: new Adapter() }) diff --git a/yarn.lock b/yarn.lock index 6e614180..d57e460c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1181,6 +1181,13 @@ dependencies: regenerator-runtime "^0.13.4" +"@babel/runtime@^7.12.5": + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" + integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/template@^7.10.4", "@babel/template@^7.12.13", "@babel/template@^7.3.3", "@babel/template@^7.4.0": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" @@ -1466,7 +1473,7 @@ parse-gitignore "^1.0.1" styled-jsx "<3.3.3" -"@dhis2/cli-helpers-engine@^2.1.1", "@dhis2/cli-helpers-engine@^2.2.0": +"@dhis2/cli-helpers-engine@^2.1.1": version "2.3.0" resolved "https://registry.yarnpkg.com/@dhis2/cli-helpers-engine/-/cli-helpers-engine-2.3.0.tgz#040cb9b2352fa618d9648a06226347f07ad9d15b" integrity sha512-i46Q5mC+vNPdImut7GcfpNf2VSg3EWlL7CFTYTfJtjGrIj77mvNkR9lTSz51ZKCQgdSgTMhpcraI0TjW7RZvWw== @@ -1481,14 +1488,29 @@ update-notifier "^3.0.0" yargs "^13.1.0" -"@dhis2/cli-style@^8.3.0": - version "8.3.0" - resolved "https://registry.yarnpkg.com/@dhis2/cli-style/-/cli-style-8.3.0.tgz#b54c9716935023478fede65537dd86061c4c3637" - integrity sha512-h404QBbFPe5L/BgGgSFAGZAo9B1Q5zilcBWwyhkkGrDYxOyEV6JnxpnUDKQzVEuvO2FAe1wxwZvWgjTbB0xuBw== +"@dhis2/cli-helpers-engine@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@dhis2/cli-helpers-engine/-/cli-helpers-engine-2.4.0.tgz#1609d358088f0616fb400aa9f90fc8bb57d4b196" + integrity sha512-SRcN3s/sQTkd5VUbWAs2+UeYtJ0zLdj4F/RkrL8x2/RX/79vIxvryqBom4FFw/meY0c2GDpXgrpKNQcST/OHBQ== + dependencies: + chalk "^3.0.0" + cross-spawn "^7.0.3" + find-up "^5.0.0" + fs-extra "^8.0.1" + inquirer "^7.3.3" + request "^2.88.0" + tar "^4.4.8" + update-notifier "^3.0.0" + yargs "^13.1.0" + +"@dhis2/cli-style@^8.4.1": + version "8.4.1" + resolved "https://registry.yarnpkg.com/@dhis2/cli-style/-/cli-style-8.4.1.tgz#6246df4e2b5879af92239c3c15e9f54129799a84" + integrity sha512-4jNRCh/WO5jhzeGkDJ9+2Dx16muy67xTNuniQdJdb7eq7Dm9DN8X9h1QlKxEQuyc4O8jJ08Sk1j3YDL1ApS+ZA== dependencies: "@commitlint/cli" "^11.0.0" "@commitlint/config-conventional" "^11.0.0" - "@dhis2/cli-helpers-engine" "^2.2.0" + "@dhis2/cli-helpers-engine" "^2.4.0" "@ls-lint/ls-lint" "^1.9.2" babel-eslint "^10.1.0" eslint "^7.18.0" @@ -2172,6 +2194,17 @@ dependencies: defer-to-connect "^1.0.1" +"@testing-library/react-hooks@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-7.0.0.tgz#dd6d37a7e018f147a3b9153137f10e013be8472b" + integrity sha512-WFBGH8DWdIGGBHt6PBtQPe2v4Kbj9vQ1sQ9qLBTmwn1PNggngint4MTE/IiWCYhPbyTW3oc/7X62DObMn/AjQQ== + dependencies: + "@babel/runtime" "^7.12.5" + "@types/react" ">=16.9.0" + "@types/react-dom" ">=16.9.0" + "@types/react-test-renderer" ">=16.9.0" + react-error-boundary "^3.1.0" + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -2315,11 +2348,39 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.2.3.tgz#ef65165aea2924c9359205bf748865b8881753c0" integrity sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA== +"@types/prop-types@*": + version "15.7.3" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" + integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== + "@types/q@^1.5.1": version "1.5.4" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== +"@types/react-dom@>=16.9.0": + version "17.0.7" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.7.tgz#b8ee15ead9e5d6c2c858b44949fdf2ebe5212232" + integrity sha512-Wd5xvZRlccOrCTej8jZkoFZuZRKHzanDDv1xglI33oBNFMWrqOSzrvWFw7ngSiZjrpJAzPKFtX7JvuXpkNmQHA== + dependencies: + "@types/react" "*" + +"@types/react-test-renderer@>=16.9.0": + version "17.0.1" + resolved "https://registry.yarnpkg.com/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz#3120f7d1c157fba9df0118dae20cb0297ee0e06b" + integrity sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@>=16.9.0": + version "17.0.11" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.11.tgz#67fcd0ddbf5a0b083a0f94e926c7d63f3b836451" + integrity sha512-yFRQbD+whVonItSk7ZzP/L+gPTJVBkL/7shLEF+i9GC/1cV3JmUxEQz6+9ylhUpWSDuqo1N9qEvqS6vTj4USUA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + "@types/resolve@0.0.8": version "0.0.8" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" @@ -2327,6 +2388,11 @@ dependencies: "@types/node" "*" +"@types/scheduler@*": + version "0.16.1" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275" + integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA== + "@types/source-list-map@*": version "0.1.2" resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" @@ -2827,6 +2893,21 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" +airbnb-prop-types@^2.16.0: + version "2.16.0" + resolved "https://registry.yarnpkg.com/airbnb-prop-types/-/airbnb-prop-types-2.16.0.tgz#b96274cefa1abb14f623f804173ee97c13971dc2" + integrity sha512-7WHOFolP/6cS96PhKNrslCLMYAI8yB1Pp6u6XmxozQOiZbsI5ycglZr5cHhBFfuRcQQjzCMith5ZPZdYiJCxUg== + dependencies: + array.prototype.find "^2.1.1" + function.prototype.name "^1.1.2" + is-regex "^1.1.0" + object-is "^1.1.2" + object.assign "^4.1.0" + object.entries "^1.1.2" + prop-types "^15.7.2" + prop-types-exact "^1.2.0" + react-is "^16.13.1" + ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" @@ -3075,7 +3156,26 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -array.prototype.flat@^1.2.4: +array.prototype.filter@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array.prototype.filter/-/array.prototype.filter-1.0.0.tgz#24d63e38983cdc6bf023a3c574b2f2a3f384c301" + integrity sha512-TfO1gz+tLm+Bswq0FBOXPqAchtCr2Rn48T8dLJoRFl8NoEosjZmzptmuo1X8aZBzZcqsR1W8U761tjACJtngTQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.5" + +array.prototype.find@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.1.1.tgz#3baca26108ca7affb08db06bf0be6cb3115a969c" + integrity sha512-mi+MYNJYLTx2eNYy+Yh6raoQacCsNeeMUaspFPh9Y141lFSsWxxB8V9mM2ye+eqiRs917J6/pJ4M9ZPzenWckA== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.4" + +array.prototype.flat@^1.2.3, array.prototype.flat@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== @@ -4030,6 +4130,30 @@ check-types@^11.1.1: resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.1.2.tgz#86a7c12bf5539f6324eb0e70ca8896c0e38f3e2f" integrity sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ== +cheerio-select@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-1.5.0.tgz#faf3daeb31b17c5e1a9dabcee288aaf8aafa5823" + integrity sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg== + dependencies: + css-select "^4.1.3" + css-what "^5.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + domutils "^2.7.0" + +cheerio@^1.0.0-rc.3: + version "1.0.0-rc.10" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.10.tgz#2ba3dcdfcc26e7956fc1f440e61d51c643379f3e" + integrity sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw== + dependencies: + cheerio-select "^1.5.0" + dom-serializer "^1.3.2" + domhandler "^4.2.0" + htmlparser2 "^6.1.0" + parse5 "^6.0.1" + parse5-htmlparser2-tree-adapter "^6.0.1" + tslib "^2.2.0" + chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" @@ -4715,6 +4839,17 @@ css-select@^2.0.0, css-select@^2.0.2: domutils "^1.7.0" nth-check "^1.0.2" +css-select@^4.1.3: + version "4.1.3" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067" + integrity sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA== + dependencies: + boolbase "^1.0.0" + css-what "^5.0.0" + domhandler "^4.2.0" + domutils "^2.6.0" + nth-check "^2.0.0" + css-tree@1.0.0-alpha.37: version "1.0.0-alpha.37" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.37.tgz#98bebd62c4c1d9f960ec340cf9f7522e30709a22" @@ -4736,6 +4871,11 @@ css-what@^3.2.1: resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== +css-what@^5.0.0, css-what@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.0.1.tgz#3efa820131f4669a8ac2408f9c32e7c7de9f4cad" + integrity sha512-FYDTSHb/7KXsWICVsxdmiExPjCfRC4qRFBdVwv7Ax9hMnvMmEjP9RfxTEZ3qPZGmADDn2vAKSo9UcN1jKVYscg== + css@^2.0.0: version "2.2.4" resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" @@ -4860,6 +5000,11 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" +csstype@^3.0.2: + version "3.0.8" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340" + integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw== + cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -5126,6 +5271,11 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" +discontinuous-range@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" + integrity sha1-44Mx8IRLukm5qctxx3FYWqsbxlo= + dns-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" @@ -5175,6 +5325,15 @@ dom-serializer@0: domelementtype "^2.0.1" entities "^2.0.0" +dom-serializer@^1.0.1, dom-serializer@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91" + integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" @@ -5185,7 +5344,7 @@ domelementtype@1, domelementtype@^1.3.1: resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== -domelementtype@^2.0.1: +domelementtype@^2.0.1, domelementtype@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== @@ -5211,6 +5370,13 @@ domhandler@^2.3.0: dependencies: domelementtype "1" +domhandler@^4.0.0, domhandler@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059" + integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA== + dependencies: + domelementtype "^2.2.0" + domutils@^1.5.1, domutils@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" @@ -5219,6 +5385,15 @@ domutils@^1.5.1, domutils@^1.7.0: dom-serializer "0" domelementtype "1" +domutils@^2.5.2, domutils@^2.6.0, domutils@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.7.0.tgz#8ebaf0c41ebafcf55b0b72ec31c56323712c5442" + integrity sha512-8eaHa17IwJUPAiB+SoTYBo5mCdeMgdcAoXJ59m6DT1vw+5iLS3gNoqYaRowaBKtGVrOF1Jz4yDTgYKLK2kvfJg== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + dot-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" @@ -5407,6 +5582,70 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== +enzyme-adapter-react-16@^1.15.6: + version "1.15.6" + resolved "https://registry.yarnpkg.com/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.6.tgz#fd677a658d62661ac5afd7f7f541f141f8085901" + integrity sha512-yFlVJCXh8T+mcQo8M6my9sPgeGzj85HSHi6Apgf1Cvq/7EL/J9+1JoJmJsRxZgyTvPMAqOEpRSu/Ii/ZpyOk0g== + dependencies: + enzyme-adapter-utils "^1.14.0" + enzyme-shallow-equal "^1.0.4" + has "^1.0.3" + object.assign "^4.1.2" + object.values "^1.1.2" + prop-types "^15.7.2" + react-is "^16.13.1" + react-test-renderer "^16.0.0-0" + semver "^5.7.0" + +enzyme-adapter-utils@^1.14.0: + version "1.14.0" + resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.14.0.tgz#afbb0485e8033aa50c744efb5f5711e64fbf1ad0" + integrity sha512-F/z/7SeLt+reKFcb7597IThpDp0bmzcH1E9Oabqv+o01cID2/YInlqHbFl7HzWBl4h3OdZYedtwNDOmSKkk0bg== + dependencies: + airbnb-prop-types "^2.16.0" + function.prototype.name "^1.1.3" + has "^1.0.3" + object.assign "^4.1.2" + object.fromentries "^2.0.3" + prop-types "^15.7.2" + semver "^5.7.1" + +enzyme-shallow-equal@^1.0.1, enzyme-shallow-equal@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.4.tgz#b9256cb25a5f430f9bfe073a84808c1d74fced2e" + integrity sha512-MttIwB8kKxypwHvRynuC3ahyNc+cFbR8mjVIltnmzQ0uKGqmsfO4bfBuLxb0beLNPhjblUEYvEbsg+VSygvF1Q== + dependencies: + has "^1.0.3" + object-is "^1.1.2" + +enzyme@^3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.11.0.tgz#71d680c580fe9349f6f5ac6c775bc3e6b7a79c28" + integrity sha512-Dw8/Gs4vRjxY6/6i9wU0V+utmQO9kvh9XLnz3LIudviOnVYDEe2ec+0k+NQoMamn1VrjKgCUOWj5jG/5M5M0Qw== + dependencies: + array.prototype.flat "^1.2.3" + cheerio "^1.0.0-rc.3" + enzyme-shallow-equal "^1.0.1" + function.prototype.name "^1.1.2" + has "^1.0.3" + html-element-map "^1.2.0" + is-boolean-object "^1.0.1" + is-callable "^1.1.5" + is-number-object "^1.0.4" + is-regex "^1.0.5" + is-string "^1.0.5" + is-subset "^0.1.1" + lodash.escape "^4.0.1" + lodash.isequal "^4.5.0" + object-inspect "^1.7.0" + object-is "^1.0.2" + object.assign "^4.1.0" + object.entries "^1.1.1" + object.values "^1.1.1" + raf "^3.4.1" + rst-selector-parser "^2.2.3" + string.prototype.trim "^1.2.1" + eol@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/eol/-/eol-0.9.1.tgz#f701912f504074be35c6117a5c4ade49cd547acd" @@ -5438,7 +5677,7 @@ error-stack-parser@^2.0.6: dependencies: stackframe "^1.1.1" -es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2: +es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.18.0, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2: version "1.18.3" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.3.tgz#25c4c3380a27aa203c44b2b685bba94da31b63e0" integrity sha512-nQIr12dxV7SSxE6r6f1l3DtAeEYdsGpps13dR0TwJg1S8gyp4ZPgy3FZcHBgbiQqnoqSTb+oC+kO4UQ0C/J8vw== @@ -5460,6 +5699,11 @@ es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es- string.prototype.trimstart "^1.0.4" unbox-primitive "^1.0.1" +es-array-method-boxes-properly@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" + integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + es-to-primitive@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" @@ -6128,6 +6372,11 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +filter-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" + integrity sha1-mzERErxsYSehbgFsbF1/GeCAXFs= + final-form@^4.20.2: version "4.20.2" resolved "https://registry.yarnpkg.com/final-form/-/final-form-4.20.2.tgz#c820b37d7ebb73d71169480256a36c7e6e6c9155" @@ -6388,11 +6637,26 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function.prototype.name@^1.1.2, function.prototype.name@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.4.tgz#e4ea839b9d3672ae99d0efd9f38d9191c5eaac83" + integrity sha512-iqy1pIotY/RmhdFZygSSlW0wko2yxkSCKqsuv4pr8QESohpYyG/Z7B/XXvPRKTJS//960rgguE5mSRUsDdaJrQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + functions-have-names "^1.2.2" + functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +functions-have-names@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.2.tgz#98d93991c39da9361f8e50b337c4f6e41f120e21" + integrity sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA== + gaze@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" @@ -6839,6 +7103,14 @@ hsla-regex@^1.0.0: resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38" integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg= +html-element-map@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/html-element-map/-/html-element-map-1.3.1.tgz#44b2cbcfa7be7aa4ff59779e47e51012e1c73c08" + integrity sha512-6XMlxrAFX4UEEGxctfFnmrFaaZFNf9i5fNuV5wZ3WWQ4FVaNP1aX1LkX9j2mfEx1NpjeE/rL3nmgEn23GdFmrg== + dependencies: + array.prototype.filter "^1.0.0" + call-bind "^1.0.2" + html-encoding-sniffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" @@ -6903,6 +7175,16 @@ htmlparser2@^3.10.1: inherits "^2.0.1" readable-stream "^3.1.1" +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + http-cache-semantics@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" @@ -7081,7 +7363,7 @@ icss-utils@^4.0.0, icss-utils@^4.1.1: dependencies: postcss "^7.0.14" -identity-obj-proxy@3.0.0: +identity-obj-proxy@3.0.0, identity-obj-proxy@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz#94d2bda96084453ef36fbc5aaec37e0f79f1fc14" integrity sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ= @@ -7338,7 +7620,7 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" -is-boolean-object@^1.1.0: +is-boolean-object@^1.0.1, is-boolean-object@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.1.tgz#3c0878f035cb821228d350d2e1e36719716a3de8" integrity sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng== @@ -7350,7 +7632,7 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.3: +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.1.5, is-callable@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== @@ -7572,7 +7854,7 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== -is-regex@^1.0.4, is-regex@^1.1.3: +is-regex@^1.0.4, is-regex@^1.0.5, is-regex@^1.1.0, is-regex@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f" integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ== @@ -7617,6 +7899,11 @@ is-string@^1.0.5, is-string@^1.0.6: resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f" integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w== +is-subset@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" + integrity sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY= + is-symbol@^1.0.2, is-symbol@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" @@ -8972,16 +9259,31 @@ lodash.difference@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" integrity sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw= +lodash.escape@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98" + integrity sha1-yQRGkMIeBClL6qUXcS/e0fqI3pg= + lodash.flatten@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= + lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" @@ -9438,6 +9740,11 @@ moment@^2.24.0, moment@^2.29.1: resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== +moo@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.1.tgz#7aae7f384b9b09f620b6abf6f74ebbcd1b65dbc4" + integrity sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w== + move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -9527,6 +9834,16 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +nearley@^2.7.10: + version "2.20.1" + resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.20.1.tgz#246cd33eff0d012faf197ff6774d7ac78acdd474" + integrity sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ== + dependencies: + commander "^2.19.0" + moo "^0.5.0" + railroad-diagrams "^1.0.0" + randexp "0.4.6" + negotiator@0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" @@ -9719,6 +10036,13 @@ nth-check@^1.0.2: dependencies: boolbase "~1.0.0" +nth-check@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125" + integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q== + dependencies: + boolbase "^1.0.0" + num2fraction@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" @@ -9748,12 +10072,12 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.10.3, object-inspect@^1.9.0: +object-inspect@^1.10.3, object-inspect@^1.7.0, object-inspect@^1.9.0: version "1.10.3" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369" integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw== -object-is@^1.0.1: +object-is@^1.0.1, object-is@^1.0.2, object-is@^1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== @@ -9783,7 +10107,7 @@ object.assign@^4.0.4, object.assign@^4.1.0, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" -object.entries@^1.1.0, object.entries@^1.1.4: +object.entries@^1.1.0, object.entries@^1.1.1, object.entries@^1.1.2, object.entries@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.4.tgz#43ccf9a50bc5fd5b649d45ab1a579f24e088cafd" integrity sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA== @@ -9792,7 +10116,7 @@ object.entries@^1.1.0, object.entries@^1.1.4: define-properties "^1.1.3" es-abstract "^1.18.2" -object.fromentries@^2.0.4: +object.fromentries@^2.0.3, object.fromentries@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.4.tgz#26e1ba5c4571c5c6f0890cef4473066456a120b8" integrity sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ== @@ -9818,7 +10142,7 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -object.values@^1.1.0, object.values@^1.1.3, object.values@^1.1.4: +object.values@^1.1.0, object.values@^1.1.1, object.values@^1.1.2, object.values@^1.1.3, object.values@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.4.tgz#0d273762833e816b693a637d30073e7051535b30" integrity sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg== @@ -10114,12 +10438,19 @@ parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse5-htmlparser2-tree-adapter@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== + dependencies: + parse5 "^6.0.1" + parse5@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== -parse5@6.0.1: +parse5@6.0.1, parse5@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== @@ -11098,6 +11429,15 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" +prop-types-exact@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/prop-types-exact/-/prop-types-exact-1.2.0.tgz#825d6be46094663848237e3925a98c6e944e9869" + integrity sha512-K+Tk3Kd9V0odiXFP9fwDHUYRyvK3Nun3GVyPapSIs5OBkITAm15W0CPFD/YKTkMUAbc0b9CUwRQp2ybiBIq+eA== + dependencies: + has "^1.0.3" + object.assign "^4.1.0" + reflect.ownkeys "^0.2.0" + prop-types@^15, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" @@ -11205,6 +11545,16 @@ query-string@^4.1.0: object-assign "^4.1.0" strict-uri-encode "^1.0.0" +query-string@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.0.0.tgz#aaad2c8d5c6a6d0c6afada877fecbd56af79e609" + integrity sha512-Iy7moLybliR5ZgrK/1R3vjrXq03S13Vz4Rbm5Jg3EFq1LUmQppto0qtXz4vqZ386MSRjZgnTSZ9QC+NZOSd/XA== + dependencies: + decode-uri-component "^0.2.0" + filter-obj "^1.1.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -11242,6 +11592,19 @@ raf@^3.4.1: dependencies: performance-now "^2.1.0" +railroad-diagrams@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz#eb7e6267548ddedfb899c1b90e57374559cddb7e" + integrity sha1-635iZ1SN3t+4mcG5Dlc3RVnN234= + +randexp@0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/randexp/-/randexp-0.4.6.tgz#e986ad5e5e31dae13ddd6f7b3019aa7c87f60ca3" + integrity sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ== + dependencies: + discontinuous-range "1.0.0" + ret "~0.1.10" + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -11334,6 +11697,13 @@ react-dom@^16.8.6: prop-types "^15.6.2" scheduler "^0.19.1" +react-error-boundary@^3.1.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.3.tgz#276bfa05de8ac17b863587c9e0647522c25e2a0b" + integrity sha512-A+F9HHy9fvt9t8SNDlonq01prnU8AmkjvGKV4kk8seB9kU3xMEO8J/PQlLVmoOIDODl5U2kufSBs4vrWIqhsAA== + dependencies: + "@babel/runtime" "^7.12.5" + react-error-overlay@^6.0.9: version "6.0.9" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" @@ -11351,7 +11721,7 @@ react-final-form@^6.5.3: dependencies: "@babel/runtime" "^7.12.1" -react-is@^16.8.1, react-is@^16.8.4: +react-is@^16.13.1, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== @@ -11440,6 +11810,16 @@ react-scripts@^4.0.0: optionalDependencies: fsevents "^2.1.3" +react-test-renderer@^16.0.0-0: + version "16.14.0" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.14.0.tgz#e98360087348e260c56d4fe2315e970480c228ae" + integrity sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg== + dependencies: + object-assign "^4.1.1" + prop-types "^15.6.2" + react-is "^16.8.6" + scheduler "^0.19.1" + react@^16.8.6: version "16.14.0" resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" @@ -11553,6 +11933,11 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +reflect.ownkeys@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460" + integrity sha1-dJrO7H8/34tj+SegSAnpDFwLNGA= + regenerate-unicode-properties@^8.2.0: version "8.2.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" @@ -11976,6 +12361,14 @@ rollup@^1.31.1: "@types/node" "*" acorn "^7.1.0" +rst-selector-parser@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91" + integrity sha1-gbIw6i/MYGbInjRy3nlChdmwPZE= + dependencies: + lodash.flattendeep "^4.4.0" + nearley "^2.7.10" + rsvp@^4.8.4: version "4.8.5" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" @@ -12126,7 +12519,7 @@ semver-diff@^2.0.0: dependencies: semver "^5.0.3" -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -12186,6 +12579,11 @@ serialize-javascript@^5.0.1: dependencies: randombytes "^2.1.0" +serialize-query-params@^1.3.3: + version "1.3.4" + resolved "https://registry.yarnpkg.com/serialize-query-params/-/serialize-query-params-1.3.4.tgz#21a6a1c6110ac46aa23a269a0e1517e4de3204ed" + integrity sha512-hSVbcw7DLktsgdbfcFrwIFDxM1m/EBvba/YJe/uYeN58FMHrhza9VgM5S4EruJnDlB2YShynfTgnYpVkN23rxA== + serve-index@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" @@ -12519,6 +12917,11 @@ spdy@^4.0.2: select-hose "^2.0.0" spdy-transport "^3.0.0" +split-on-first@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -12646,6 +13049,11 @@ strict-uri-encode@^1.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= +strict-uri-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= + string-hash@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" @@ -12712,6 +13120,15 @@ string.prototype.matchall@^4.0.5: regexp.prototype.flags "^1.3.1" side-channel "^1.0.4" +string.prototype.trim@^1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.4.tgz#6014689baf5efaf106ad031a5fa45157666ed1bd" + integrity sha512-hWCk/iqf7lp0/AgTF7/ddO1IWtSNPASjlzCicV5irAVdE1grjsneK26YG6xACMBEdCvO8fUST0UzDMh/2Qy+9Q== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.18.0-next.2" + string.prototype.trimend@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" @@ -13318,6 +13735,11 @@ tslib@^2.0.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== +tslib@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== + tsutils@^3.17.1, tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -13618,6 +14040,13 @@ url@^0.11.0: punycode "1.3.2" querystring "0.2.0" +use-query-params@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/use-query-params/-/use-query-params-1.2.2.tgz#4c4b274133d699605301510b5aa01047f92b5ce0" + integrity sha512-Uyfe+/TECsNNzCSkgUM1MM24OEGxGE4aeWvZEf0a14iQFp/m43wiqI1HZ9oTlrRSZwD5yABeLc9rN+wtiB5B3Q== + dependencies: + serialize-query-params "^1.3.3" + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -13830,10 +14259,8 @@ watchpack@^1.7.4: resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== dependencies: - chokidar "^3.4.1" graceful-fs "^4.1.2" neo-async "^2.5.0" - watchpack-chokidar2 "^2.0.1" optionalDependencies: chokidar "^3.4.1" watchpack-chokidar2 "^2.0.1"