From a0348a47acf33e1dc32c0a1d2d081fb78a53e875 Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Wed, 25 Mar 2020 19:13:46 +0100 Subject: [PATCH 01/80] [SIG-2394] Category history request --- src/components/History/index.test.js | 28 +------- .../Detail/__tests__/Detail.test.js | 66 +++++++++++++------ .../settings/categories/Detail/index.js | 18 +++-- src/utils/__tests__/fixtures/history.json | 38 +++++++++++ 4 files changed, 98 insertions(+), 52 deletions(-) create mode 100644 src/utils/__tests__/fixtures/history.json diff --git a/src/components/History/index.test.js b/src/components/History/index.test.js index 8a30e991f5..b542c8c799 100644 --- a/src/components/History/index.test.js +++ b/src/components/History/index.test.js @@ -2,6 +2,7 @@ import React from 'react'; import { render, cleanup } from '@testing-library/react'; import { withAppContext } from 'test/utils'; +import historyJSON from 'utils/__tests__/fixtures/history.json'; import History from '.'; @@ -10,32 +11,7 @@ describe('', () => { beforeEach(() => { props = { - list: [ - { - identifier: 'UPDATE_STATUS_6686', - when: '2019-07-31T15:10:28.696413+02:00', - what: 'UPDATE_STATUS', - action: 'Update status naar: Gesplitst', - description: 'Deze melding is opgesplitst.', - who: 'steve@apple.com', - }, - { - identifier: 'UPDATE_PRIORITY_3790', - when: '2019-07-26T11:51:50.275505+02:00', - what: 'UPDATE_PRIORITY', - action: 'Prioriteit update naar: Normal', - description: null, - who: 'SIA systeem', - }, - { - identifier: 'UPDATE_CATEGORY_ASSIGNMENT_3996', - when: '2019-07-26T11:51:50.273841+02:00', - what: 'UPDATE_CATEGORY_ASSIGNMENT', - action: 'Categorie gewijzigd naar: Geluidsoverlast installaties', - description: null, - who: 'Foo bar baz', - }, - ], + list: historyJSON, }; }); diff --git a/src/signals/settings/categories/Detail/__tests__/Detail.test.js b/src/signals/settings/categories/Detail/__tests__/Detail.test.js index 25313b5419..e7e1109e7e 100644 --- a/src/signals/settings/categories/Detail/__tests__/Detail.test.js +++ b/src/signals/settings/categories/Detail/__tests__/Detail.test.js @@ -5,9 +5,11 @@ import * as reactRedux from 'react-redux'; import { withAppContext } from 'test/utils'; import routes from 'signals/settings/routes'; import categoryJSON from 'utils/__tests__/fixtures/category.json'; +import historyJSON from 'utils/__tests__/fixtures/history.json'; import configuration from 'shared/services/configuration/configuration'; import { fetchCategories } from 'models/categories/actions'; import { showGlobalNotification } from 'containers/App/actions'; +import * as appSelectors from 'containers/App/selectors'; import useConfirmedCancel from '../../../hooks/useConfirmedCancel'; import CategoryDetailContainer from '..'; @@ -29,8 +31,10 @@ jest.mock('models/categories/actions', () => ({ jest.mock('../../../hooks/useConfirmedCancel'); -const userCan = jest.fn(() => true); -jest.spyOn(reactRedux, 'useSelector').mockImplementation(() => userCan); +const userCan = jest.fn(() => () => true); +jest + .spyOn(appSelectors, 'makeSelectUserCan') + .mockImplementation(userCan); const dispatch = jest.fn(); jest.spyOn(reactRedux, 'useDispatch').mockImplementation(() => dispatch); @@ -45,14 +49,19 @@ useConfirmedCancel.mockImplementation(() => confirmedCancel); describe('signals/settings/categories/Detail', () => { beforeEach(() => { - fetch.resetMocks(); - fetch.mockResponse(JSON.stringify(categoryJSON)); + fetch + .once(JSON.stringify(categoryJSON)) + .once(JSON.stringify(historyJSON)); dispatch.mockReset(); push.mockReset(); confirmedCancel.mockReset(); }); + afterEach(() => { + fetch.resetMocks(); + }); + it('should render a backlink', async () => { const { container } = render(withAppContext()); @@ -117,10 +126,9 @@ describe('signals/settings/categories/Detail', () => { categoryId: 123, })); - const { getByTestId } = render(withAppContext()); + const { findByTestId } = render(withAppContext()); - await wait(() => getByTestId('detailCategoryForm')); - expect(getByTestId('detailCategoryForm')).toBeInTheDocument(); + await findByTestId('detailCategoryForm'); expect(document.querySelector('#name').value).toEqual(categoryJSON.name); expect(document.querySelector('#description').value).toEqual( @@ -133,12 +141,11 @@ describe('signals/settings/categories/Detail', () => { categoryId: 456, })); - const { container, getByTestId } = render( + const { container, getByTestId, findByTestId } = render( withAppContext() ); - await wait(() => getByTestId('detailCategoryForm')); - expect(getByTestId('detailCategoryForm')).toBeInTheDocument(); + await findByTestId('detailCategoryForm'); const nameField = container.querySelector('#name'); const cancelButton = getByTestId('cancelBtn'); @@ -176,16 +183,22 @@ describe('signals/settings/categories/Detail', () => { expect(confirmedCancel).toHaveBeenLastCalledWith(false); }); - it('should call confirmedCancel when data has NULL values', async () => { + it.only('should call confirmedCancel when data has NULL values', async () => { const dataWithNullValue = { ...categoryJSON, description: null }; - fetch.mockResponse(JSON.stringify(dataWithNullValue)); + fetch + .once(JSON.stringify(dataWithNullValue)) + .once(JSON.stringify(historyJSON)); + + const categoryId = 10101; + jest.spyOn(reactRouterDom, 'useParams').mockImplementation(() => ({ + categoryId, + })); - const { container, getByTestId } = render( + const { container, getByTestId, findByTestId } = render( withAppContext() ); - await wait(() => getByTestId('detailCategoryForm')); - expect(getByTestId('detailCategoryForm')).toBeInTheDocument(); + await findByTestId('detailCategoryForm'); const descriptionField = container.querySelector('#description'); const cancelButton = getByTestId('cancelBtn'); @@ -203,6 +216,8 @@ describe('signals/settings/categories/Detail', () => { fireEvent.change(descriptionField, { target: { value: '' } }); }); + await findByTestId('detailCategoryForm'); + act(() => { fireEvent.click(cancelButton); }); @@ -215,6 +230,8 @@ describe('signals/settings/categories/Detail', () => { fireEvent.change(descriptionField, { target: { value: 'Here be a description' } }); }); + await findByTestId('detailCategoryForm'); + act(() => { fireEvent.click(cancelButton); }); @@ -224,17 +241,21 @@ describe('signals/settings/categories/Detail', () => { }); it('should call patch on submit', async () => { + fetch + .once(JSON.stringify(categoryJSON)) // GET response (category) + .once(JSON.stringify(historyJSON)) // GET response (history) + .once(JSON.stringify(categoryJSON)); // PATCH response (category) + const categoryId = 789; jest.spyOn(reactRouterDom, 'useParams').mockImplementation(() => ({ categoryId, })); - const { getByTestId } = render(withAppContext()); + const { getByTestId, findByTestId } = render(withAppContext()); - await wait(() => getByTestId('detailCategoryForm')); - expect(getByTestId('detailCategoryForm')).toBeInTheDocument(); + await findByTestId('detailCategoryForm'); - expect(fetch).toHaveBeenCalledTimes(1); + expect(fetch).toHaveBeenCalledTimes(2); const submitBtn = getByTestId('submitBtn'); @@ -244,7 +265,7 @@ describe('signals/settings/categories/Detail', () => { expect(dispatch).not.toHaveBeenCalled(); - expect(fetch).toHaveBeenCalledTimes(2); + expect(fetch).toHaveBeenCalledTimes(3); expect(fetch).toHaveBeenLastCalledWith( `${configuration.CATEGORIES_PRIVATE_ENDPOINT}${categoryId}`, expect.objectContaining({ method: 'PATCH' }) @@ -257,6 +278,11 @@ describe('signals/settings/categories/Detail', () => { }); it('should redirect on patch success', async () => { + fetch + .once(JSON.stringify(categoryJSON)) // GET response (category) + .once(JSON.stringify(historyJSON)) // GET response (history) + .once(JSON.stringify(categoryJSON)); // PATCH response (category) + const categoryId = 789; jest.spyOn(reactRouterDom, 'useParams').mockImplementation(() => ({ categoryId, diff --git a/src/signals/settings/categories/Detail/index.js b/src/signals/settings/categories/Detail/index.js index 0e2726bd79..0a7f13fd7e 100644 --- a/src/signals/settings/categories/Detail/index.js +++ b/src/signals/settings/categories/Detail/index.js @@ -62,6 +62,7 @@ const CategoryDetail = () => { const isExistingCategory = categoryId !== undefined; const { isLoading, isSuccess, error, data, get, patch } = useFetch(); + const historyFetch = useFetch(); const confirmedCancel = useConfirmedCancel(redirectURL); @@ -78,6 +79,11 @@ const CategoryDetail = () => { (isExistingCategory && userCan('change_category')) || (!isExistingCategory && userCan('add_category')); + // console.log('isExistingCategory', isExistingCategory); + // console.log('data', data); + // console.log('shouldRenderForm', shouldRenderForm); + // console.log('userCanSubmitForm', userCanSubmitForm); + useFetchResponseNotification({ entityName, error, @@ -87,10 +93,6 @@ const CategoryDetail = () => { redirectURL, }); - const refetchCategories = useCallback(() => { - dispatch(fetchCategories()); - }, [dispatch]); - const title = `${entityName} ${ isExistingCategory ? 'wijzigen' : 'toevoegen' }`; @@ -131,6 +133,8 @@ const CategoryDetail = () => { const combinedData = { ...initialData, ...formData }; const isPristine = isEqual(initialData, combinedData); + console.log('initialData', initialData); + console.log('combinedData', combinedData); confirmedCancel(isPristine); }, [confirmedCancel, data, getFormData] @@ -149,13 +153,14 @@ const CategoryDetail = () => { useEffect(() => { if (isSuccess) { - refetchCategories(); + dispatch(fetchCategories()); } - }, [isSuccess, refetchCategories]); + }, [isSuccess, dispatch]); useEffect(() => { if (isExistingCategory) { get(categoryURL); + historyFetch.get(`${categoryURL}/history`); } // Disabling linter; only need to execute on mount; defining the dependencies @@ -176,6 +181,7 @@ const CategoryDetail = () => { {shouldRenderForm && ( Date: Wed, 25 Mar 2020 19:38:20 +0100 Subject: [PATCH 02/80] Fixes category detail tests --- .../Detail/__tests__/Detail.test.js | 31 ++++++++++++++----- .../settings/categories/Detail/index.js | 7 ----- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/signals/settings/categories/Detail/__tests__/Detail.test.js b/src/signals/settings/categories/Detail/__tests__/Detail.test.js index e7e1109e7e..f34b0db34b 100644 --- a/src/signals/settings/categories/Detail/__tests__/Detail.test.js +++ b/src/signals/settings/categories/Detail/__tests__/Detail.test.js @@ -49,9 +49,16 @@ useConfirmedCancel.mockImplementation(() => confirmedCancel); describe('signals/settings/categories/Detail', () => { beforeEach(() => { - fetch - .once(JSON.stringify(categoryJSON)) - .once(JSON.stringify(historyJSON)); + fetch.mockResponses( + [ + JSON.stringify(categoryJSON), + { status: 200 }, + ], + [ + JSON.stringify(historyJSON), + { status: 200 }, + ], + ); dispatch.mockReset(); push.mockReset(); @@ -183,11 +190,21 @@ describe('signals/settings/categories/Detail', () => { expect(confirmedCancel).toHaveBeenLastCalledWith(false); }); - it.only('should call confirmedCancel when data has NULL values', async () => { + it('should call confirmedCancel when data has NULL values', async () => { const dataWithNullValue = { ...categoryJSON, description: null }; - fetch - .once(JSON.stringify(dataWithNullValue)) - .once(JSON.stringify(historyJSON)); + + fetch.resetMocks(); + + fetch.mockResponses( + [ + JSON.stringify(dataWithNullValue), + { status: 200 }, + ], + [ + JSON.stringify(historyJSON), + { status: 200 }, + ], + ); const categoryId = 10101; jest.spyOn(reactRouterDom, 'useParams').mockImplementation(() => ({ diff --git a/src/signals/settings/categories/Detail/index.js b/src/signals/settings/categories/Detail/index.js index 0a7f13fd7e..45b725c3d1 100644 --- a/src/signals/settings/categories/Detail/index.js +++ b/src/signals/settings/categories/Detail/index.js @@ -79,11 +79,6 @@ const CategoryDetail = () => { (isExistingCategory && userCan('change_category')) || (!isExistingCategory && userCan('add_category')); - // console.log('isExistingCategory', isExistingCategory); - // console.log('data', data); - // console.log('shouldRenderForm', shouldRenderForm); - // console.log('userCanSubmitForm', userCanSubmitForm); - useFetchResponseNotification({ entityName, error, @@ -133,8 +128,6 @@ const CategoryDetail = () => { const combinedData = { ...initialData, ...formData }; const isPristine = isEqual(initialData, combinedData); - console.log('initialData', initialData); - console.log('combinedData', combinedData); confirmedCancel(isPristine); }, [confirmedCancel, data, getFormData] From 4ddea69b242c89147238ce3eb8d91668632b9c30 Mon Sep 17 00:00:00 2001 From: Jasper Poppe Date: Sat, 4 Apr 2020 11:42:13 +0200 Subject: [PATCH 03/80] added types, made it a bit more modular --- src/shared/types/index.js | 48 ++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/src/shared/types/index.js b/src/shared/types/index.js index 289b8d9066..ca7821ad54 100644 --- a/src/shared/types/index.js +++ b/src/shared/types/index.js @@ -52,6 +52,12 @@ const dataItemType = PropTypes.shape({ value: PropTypes.string.isRequired, }); +const linksType = PropTypes.shape({ + self: PropTypes.shape({ + href: PropTypes.string.isRequired, + }).isRequired, +}).isRequired; + /** * Filter type validation for the data structure that comes from and goes to the API */ @@ -112,11 +118,7 @@ export const locationType = PropTypes.shape({ export const incidentType = PropTypes.shape({ _display: PropTypes.string, - _links: PropTypes.shape({ - self: PropTypes.shape({ - href: PropTypes.string.isRequired, - }), - }), + _links: linksType, category: PropTypes.shape({ category_url: PropTypes.string.isRequired, departments: PropTypes.string, @@ -132,7 +134,6 @@ export const incidentType = PropTypes.shape({ incident_date_start: dateType, location: locationType, }), - location: locationType, notes: PropTypes.arrayOf( PropTypes.shape({ text: PropTypes.string, @@ -237,11 +238,7 @@ export const departmentCategory = PropTypes.shape({ is_responsible: PropTypes.bool, can_view: PropTypes.bool, category: PropTypes.shape({ - _links: PropTypes.shape({ - self: PropTypes.shape({ - href: PropTypes.string.isRequired, - }).isRequired, - }).isRequired, + _links: linksType, _display: PropTypes.string.isRequired, departments: PropTypes.arrayOf( PropTypes.shape({ @@ -265,3 +262,32 @@ export const permissionsType = PropTypes.arrayOf(PropTypes.shape({ name: PropTypes.string.isRequired, codename: PropTypes.string.isRequired, })); + +const userRolePermissionType = PropTypes.arrayOf(PropTypes.shape({ + id: PropTypes.number.isRequired, + name: PropTypes.string.isRequired, + codename: PropTypes.string.isRequired, + _display: PropTypes.string.isRequired, + _links: linksType, +})); + +const userRoleType = PropTypes.shape({ + id: PropTypes.number.isRequired, + name: PropTypes.string.isRequired, + _display: PropTypes.string.isRequired, + _links: linksType, + permissons: userRolePermissionType, +}); + +export const userType = PropTypes.shape({ + username: PropTypes.string, + first_name: PropTypes.string, + last_name: PropTypes.string, + is_active: PropTypes.bool, + roles: PropTypes.arrayOf(userRoleType), + profile: PropTypes.shape({ + departments: PropTypes.arrayOf(PropTypes.string), + note: PropTypes.string, + }), +}); + From cad35066ec189ad3bd786bf1897b4f94f174bc0f Mon Sep 17 00:00:00 2001 From: Jasper Poppe Date: Mon, 6 Apr 2020 09:30:59 +0200 Subject: [PATCH 04/80] draft commit --- src/models/roles/selectors.js | 26 +- src/models/roles/selectors.test.js | 2 +- src/shared/types/index.js | 24 +- .../RoleForm/__test__/RoleForm.test.js | 16 +- .../containers/RoleFormContainer/index.js | 2 +- .../RolesList/__test__/RolesList.test.js | 14 +- .../containers/RolesListContainer/index.js | 2 +- .../formatRoles/__test__/formatRoles.test.js | 42 +- .../users/Detail/__tests__/Detail.test.js | 25 +- .../UserForm/__tests__/UserForm.test.js | 75 +- .../users/Detail/components/UserForm/index.js | 49 +- .../users/Overview/__tests__/Overview.test.js | 18 +- src/signals/settings/users/Overview/index.js | 4 +- .../fixtures/inputCheckboxRolesSelector.json | 47 ++ ...tor.json => inputSelectRolesSelector.json} | 0 src/utils/__tests__/fixtures/roles.json | 759 +++++++++++++++++- src/utils/__tests__/fixtures/userNew.json | 226 ++++++ 17 files changed, 1210 insertions(+), 121 deletions(-) create mode 100644 src/utils/__tests__/fixtures/inputCheckboxRolesSelector.json rename src/utils/__tests__/fixtures/{inputRolesSelector.json => inputSelectRolesSelector.json} (100%) create mode 100644 src/utils/__tests__/fixtures/userNew.json diff --git a/src/models/roles/selectors.js b/src/models/roles/selectors.js index ea19b0bfb2..baf7e5b128 100644 --- a/src/models/roles/selectors.js +++ b/src/models/roles/selectors.js @@ -9,21 +9,23 @@ const selectRolesDomain = state => state.get('roles') || initialState; /** * Other specific selectors */ -export const inputRolesSelector = createSelector( +const rolesInputOptions = state => [...state.get('list').toJS().map(role => ({ + key: String(role.id), + name: role.name, + value: role.name, +}))]; + +export const inputSelectRolesSelector = createSelector( selectRolesDomain, - state => [ - { key: 'all', name: 'Alles', value: '*' }, - ...state.get('list').toJS().map(role => ({ - key: role.id, - name: role.name, - value: role.name, - })), - ] + state => [{ key: 'all', name: 'Alles', value: '*' }, ...rolesInputOptions(state)] +); + +export const inputCheckboxRolesSelector = createSelector( + selectRolesDomain, + state => rolesInputOptions[state] ); /** * Default selector used by roles */ -const rolesModelSelector = createSelector(selectRolesDomain, state => state.toJS()); - -export default rolesModelSelector; +export const rolesModelSelector = createSelector(selectRolesDomain, state => state.toJS()); diff --git a/src/models/roles/selectors.test.js b/src/models/roles/selectors.test.js index 58c7a0313d..2664e55ef1 100644 --- a/src/models/roles/selectors.test.js +++ b/src/models/roles/selectors.test.js @@ -1,5 +1,5 @@ import { fromJS } from 'immutable'; -import rolesModelSelector from './selectors'; +import { rolesModelSelector } from './selectors'; import { initialState } from './reducer'; diff --git a/src/shared/types/index.js b/src/shared/types/index.js index ca7821ad54..02c09536ee 100644 --- a/src/shared/types/index.js +++ b/src/shared/types/index.js @@ -52,12 +52,6 @@ const dataItemType = PropTypes.shape({ value: PropTypes.string.isRequired, }); -const linksType = PropTypes.shape({ - self: PropTypes.shape({ - href: PropTypes.string.isRequired, - }).isRequired, -}).isRequired; - /** * Filter type validation for the data structure that comes from and goes to the API */ @@ -118,7 +112,11 @@ export const locationType = PropTypes.shape({ export const incidentType = PropTypes.shape({ _display: PropTypes.string, - _links: linksType, + _links: PropTypes.shape({ + self: PropTypes.shape({ + href: PropTypes.string.isRequired, + }), + }), category: PropTypes.shape({ category_url: PropTypes.string.isRequired, departments: PropTypes.string, @@ -238,7 +236,11 @@ export const departmentCategory = PropTypes.shape({ is_responsible: PropTypes.bool, can_view: PropTypes.bool, category: PropTypes.shape({ - _links: linksType, + _links: PropTypes.shape({ + self: PropTypes.shape({ + href: PropTypes.string.isRequired, + }).isRequired, + }).isRequired, _display: PropTypes.string.isRequired, departments: PropTypes.arrayOf( PropTypes.shape({ @@ -263,6 +265,12 @@ export const permissionsType = PropTypes.arrayOf(PropTypes.shape({ codename: PropTypes.string.isRequired, })); +const linksType = PropTypes.shape({ + self: PropTypes.shape({ + href: PropTypes.string.isRequired, + }).isRequired, +}).isRequired; + const userRolePermissionType = PropTypes.arrayOf(PropTypes.shape({ id: PropTypes.number.isRequired, name: PropTypes.string.isRequired, diff --git a/src/signals/settings/roles/containers/RoleFormContainer/components/RoleForm/__test__/RoleForm.test.js b/src/signals/settings/roles/containers/RoleFormContainer/components/RoleForm/__test__/RoleForm.test.js index 513ff98b81..5e0e86e84a 100644 --- a/src/signals/settings/roles/containers/RoleFormContainer/components/RoleForm/__test__/RoleForm.test.js +++ b/src/signals/settings/roles/containers/RoleFormContainer/components/RoleForm/__test__/RoleForm.test.js @@ -27,19 +27,13 @@ describe('/signals/settings/roles/components/RoleForm', () => { }); it('should render correctly', () => { - const { container, queryByTestId } = render( - withAppContext() - ); + const { container, queryByTestId } = render(withAppContext()); - expect(queryByTestId('rolesFormFieldName')).toHaveValue('behandelaars'); + expect(queryByTestId('rolesFormFieldName')).toHaveValue('Behandelaar'); - expect(container.querySelectorAll('input[type="checkbox"]').length).toBe( - 12 - ); + expect(container.querySelectorAll('input[type="checkbox"]').length).toBe(16); - expect( - container.querySelectorAll('input[type="checkbox"]:checked').length - ).toBe(2); + expect(container.querySelectorAll('input[type="checkbox"]:checked').length).toBe(6); }); it('should show error in required name field', () => { @@ -94,7 +88,7 @@ describe('/signals/settings/roles/components/RoleForm', () => { expect(props.onPatchRole).toHaveBeenCalledWith({ id: 2, name: 'behandelaars', - permission_ids: [110, 164], + permission_ids: [110, 164, 162, 163, 161, 111], }); }); diff --git a/src/signals/settings/roles/containers/RoleFormContainer/index.js b/src/signals/settings/roles/containers/RoleFormContainer/index.js index 2bac433f4c..9ab64fe00f 100644 --- a/src/signals/settings/roles/containers/RoleFormContainer/index.js +++ b/src/signals/settings/roles/containers/RoleFormContainer/index.js @@ -19,7 +19,7 @@ import { makeSelectUserCan, } from 'containers/App/selectors'; -import rolesModelSelector from 'models/roles/selectors'; +import { rolesModelSelector } from 'models/roles/selectors'; import { patchRole, saveRole, resetResponse } from 'models/roles/actions'; import RoleForm from './components/RoleForm'; diff --git a/src/signals/settings/roles/containers/RolesListContainer/components/RolesList/__test__/RolesList.test.js b/src/signals/settings/roles/containers/RolesListContainer/components/RolesList/__test__/RolesList.test.js index 60762bbd0f..b00f5e2389 100644 --- a/src/signals/settings/roles/containers/RolesListContainer/components/RolesList/__test__/RolesList.test.js +++ b/src/signals/settings/roles/containers/RolesListContainer/components/RolesList/__test__/RolesList.test.js @@ -31,19 +31,17 @@ describe('signals/settings/roles/containers/RolesListContainer/components/RolesL expect( container.querySelector('tr:nth-child(1) td:nth-child(1)') - ).toHaveTextContent(/^behandelaars$/); + ).toHaveTextContent(/^Behandelaar$/); expect( container.querySelector('tr:nth-child(1) td:nth-child(2)') - ).toHaveTextContent( - /^Can read from SIA, Can change the status of a signal$/ - ); + ).toHaveTextContent(/^Can read from SIA, Can change the status of a signal, Can create new /); expect( - container.querySelector('tr:nth-child(2) td:nth-child(1)') - ).toHaveTextContent(/^coordinatoren$/); + container.querySelector('tr:nth-child(4) td:nth-child(1)') + ).toHaveTextContent(/^Hele beperkte rol$/); expect( - container.querySelector('tr:nth-child(2) td:nth-child(2)') - ).toHaveTextContent(/^$/); + container.querySelector('tr:nth-child(4) td:nth-child(2)') + ).toHaveTextContent(/^Can create new signals$/); props.list = []; rerender(withAppContext()); diff --git a/src/signals/settings/roles/containers/RolesListContainer/index.js b/src/signals/settings/roles/containers/RolesListContainer/index.js index 27a0b30a2a..c092f6b1f6 100644 --- a/src/signals/settings/roles/containers/RolesListContainer/index.js +++ b/src/signals/settings/roles/containers/RolesListContainer/index.js @@ -10,7 +10,7 @@ import LoadingIndicator from 'shared/components/LoadingIndicator'; import PageHeader from 'signals/settings/components/PageHeader'; import { makeSelectUserCan } from 'containers/App/selectors'; -import rolesModelSelector from 'models/roles/selectors'; +import { rolesModelSelector } from 'models/roles/selectors'; import { ROLE_URL } from 'signals/settings/routes'; import RolesList from './components/RolesList'; diff --git a/src/signals/settings/roles/services/formatRoles/__test__/formatRoles.test.js b/src/signals/settings/roles/services/formatRoles/__test__/formatRoles.test.js index d046cde47a..d65a556ae6 100644 --- a/src/signals/settings/roles/services/formatRoles/__test__/formatRoles.test.js +++ b/src/signals/settings/roles/services/formatRoles/__test__/formatRoles.test.js @@ -7,14 +7,46 @@ describe('formatRoles service', () => { expect(formatRoles(roles.list)).toEqual([ { id: 2, - Naam: 'behandelaars', - Rechten: 'Can read from SIA, Can change the status of a signal', + Naam: 'Behandelaar', + Rechten: 'Can read from SIA, Can change the status of a signal, Can create new signals, Can create notes for signals, Can split a signal into a parent with X children, Can write to SIA', }, { id: 3, - Naam: 'coordinatoren', - Rechten: '', + Naam: 'Coördinator', + Rechten: 'Can read from SIA, Can change the category of a signal, Can change the status of a signal, Can create new signals, Can create notes for signals, Can split a signal into a parent with X children, Can write to SIA', }, - ]); + { + id: 20, + Naam: 'Extern Systeem', + Rechten: 'Can read from SIA, Can change the status of a signal, Can create new signals, Can create notes for signals, Can write to SIA', + }, + { + id: 30, + Naam: 'Hele beperkte rol', + Rechten: 'Can create new signals', + }, + { + id: 1, + Naam: 'Monitor', + Rechten: 'View all categories (this will override the category permission based on the user/department relation), Can read from SIA, Can create notes for signals, Can write to SIA', + }, + { + id: 26, + Naam: 'Nieuwe rollen, nieuwe kansen', + Rechten: 'Can add note, Can add priority, Can read from SIA, Can create new signals, Can export signals, Can write to SIA, Push to Sigmax/CityControl', + }, + { + id: 19, + Naam: 'Regievoerder', + Rechten: 'View all categories (this will override the category permission based on the user/department relation), Can read from SIA, Can change the category of a signal, Can change the status of a signal, Can create new signals, Can create notes for signals, Can split a signal into a parent with X children, Can write to SIA, Push to Sigmax/CityControl', + }, + { + id: 22, + Naam: 'Regievoerder Plus', + Rechten: 'Can read from SIA, Can change the category of a signal, Can change the status of a signal, Can create new signals, Can create notes for signals, Can export signals, Can create reports for signals, Can split a signal into a parent with X children, Can write to SIA, Push to Sigmax/CityControl, Can write StatusMessageTemplates to SIA', + }, + { id: 28, Naam: 'Test', Rechten: 'Can create notes for signals' }, + ] + ); }); }); diff --git a/src/signals/settings/users/Detail/__tests__/Detail.test.js b/src/signals/settings/users/Detail/__tests__/Detail.test.js index 653ffe5b25..c8acbf461d 100644 --- a/src/signals/settings/users/Detail/__tests__/Detail.test.js +++ b/src/signals/settings/users/Detail/__tests__/Detail.test.js @@ -1,15 +1,23 @@ import React from 'react'; import { act } from 'react-dom/test-utils'; +import { withAppContext } from 'test/utils'; import { cleanup, fireEvent, render } from '@testing-library/react'; import * as reactRouterDom from 'react-router-dom'; -import { withAppContext } from 'test/utils'; +import configuration from 'shared/services/configuration/configuration'; + import routes from 'signals/settings/routes'; -import userJSON from 'utils/__tests__/fixtures/user.json'; + +import userJSON from 'utils/__tests__/fixtures/userNew.json'; +import rolesJson from 'utils/__tests__/fixtures/roles.json'; import departmentsJson from 'utils/__tests__/fixtures/departments.json'; +import inputCheckboxRolesSelectorJson from + 'utils/__tests__/fixtures/inputCheckboxRolesSelector.json'; + +import * as rolesSelectors from 'models/roles/selectors'; import * as modelSelectors from 'models/departments/selectors'; -import configuration from 'shared/services/configuration/configuration'; import * as appSelectors from 'containers/App/selectors'; + import useFetch from 'hooks/useFetch'; import UserDetail from '..'; @@ -62,8 +70,19 @@ jest.mock('models/departments/selectors', () => ({ ...jest.requireActual('models/departments/selectors'), })); +jest.mock('models/roles/selectors', () => ({ + __esModule: true, + ...jest.requireActual('models/roles/selectors'), +})); + jest.spyOn(modelSelectors, 'makeSelectDepartments').mockImplementation(() => departments); +jest.spyOn(rolesSelectors, 'inputCheckboxRolesSelector').mockImplementation(() => + inputCheckboxRolesSelectorJson +); + +jest.spyOn(rolesSelectors, 'rolesModelSelector').mockImplementation(() => rolesJson); + describe('signals/settings/users/containers/Detail', () => { beforeEach(() => { jest.spyOn(appSelectors, 'makeSelectUserCan').mockImplementation(() => () => true); diff --git a/src/signals/settings/users/Detail/components/UserForm/__tests__/UserForm.test.js b/src/signals/settings/users/Detail/components/UserForm/__tests__/UserForm.test.js index 91e4e5f966..327eb95426 100644 --- a/src/signals/settings/users/Detail/components/UserForm/__tests__/UserForm.test.js +++ b/src/signals/settings/users/Detail/components/UserForm/__tests__/UserForm.test.js @@ -2,8 +2,13 @@ import React from 'react'; import { act, fireEvent, render } from '@testing-library/react'; import { mount } from 'enzyme'; import { withAppContext } from 'test/utils'; -import * as modelSelectors from 'models/departments/selectors'; + import departmentsJson from 'utils/__tests__/fixtures/departments.json'; +import inputCheckboxRolesSelectorJson from + 'utils/__tests__/fixtures/inputCheckboxRolesSelector.json'; + +import * as modelSelectors from 'models/departments/selectors'; +import * as rolesSelectors from 'models/roles/selectors'; import UserForm from '..'; @@ -18,8 +23,15 @@ jest.mock('models/departments/selectors', () => ({ ...jest.requireActual('models/departments/selectors'), })); +jest.mock('models/roles/selectors', () => ({ + __esModule: true, + ...jest.requireActual('models/roles/selectors'), +})); + jest.spyOn(modelSelectors, 'makeSelectDepartments').mockImplementation(() => departments); +jest.spyOn(rolesSelectors, 'inputCheckboxRolesSelector').mockImplementation(() => inputCheckboxRolesSelectorJson); + describe('signals/settings/users/containers/Detail/components/UserForm', () => { it('should render the correct fields', () => { const { container } = render(withAppContext()); @@ -44,12 +56,51 @@ describe('signals/settings/users/containers/Detail/components/UserForm', () => { departmentsJson.results.find(({ name }) => name === 'Port of Amsterdam') ); - expect(container.querySelectorAll('[name="departments"]')[uncheckedDepartmentIndex].checked).toBe(false); + expect(container.querySelectorAll('[name="departments"]')[uncheckedDepartmentIndex].checked) + .toBe(false); + + expect(container.querySelectorAll('[name="roles"]')) + .toHaveLength(inputCheckboxRolesSelectorJson.length); + + const uncheckedRoleIndex = inputCheckboxRolesSelectorJson.indexOf( + inputCheckboxRolesSelectorJson.find(({ name }) => name === 'Behandelaar') + ); + + expect(container.querySelectorAll('[name="roles"]')[uncheckedRoleIndex].checked).toBe(false); + }); + + it('should check all role checkboxes and submit them', () => { + const onSubmit = jest.fn(); + + const { container, getByTestId } = render(withAppContext()); + + expect(container.querySelectorAll('[name="roles"]')) + .toHaveLength(inputCheckboxRolesSelectorJson.length); + + const uncheckedRoleIndex = inputCheckboxRolesSelectorJson.indexOf( + inputCheckboxRolesSelectorJson.find(({ name }) => name === 'Behandelaar') + ); + + expect(container.querySelectorAll('[name="roles"]')[uncheckedRoleIndex].checked).toBe(false); + + container.querySelectorAll('[name="roles"]').forEach(checkbox => { + act(() => { fireEvent.click(checkbox); }); + }); + + expect(container.querySelectorAll('input[type="checkbox"]:checked')) + .toHaveLength(inputCheckboxRolesSelectorJson.length); + + expect(onSubmit).not.toHaveBeenCalled(); + + + act(() => { fireEvent.click(getByTestId('submitBtn')); }); + + const submittedRoleIds = onSubmit.mock.calls[0][0].postPatch.role_ids; + expect(submittedRoleIds).toHaveLength(inputCheckboxRolesSelectorJson.length); }); it('should make fields disabled', () => { const { container, rerender, queryByText } = render(withAppContext()); - // const numFields = container.querySelectorAll('input').length; expect(container.querySelectorAll('[disabled]')).toHaveLength(0); expect(queryByText('Opslaan')).toBeInTheDocument(); @@ -136,13 +187,27 @@ describe('signals/settings/users/containers/Detail/components/UserForm', () => { expect(radio2.checked).toBe(true); }); - it('should check an unchecked checkbox', () => { + it('should check an unchecked role checkbox', async () => { + const { getByLabelText } = render(withAppContext()); + + const checkbox = getByLabelText('Regievoerder'); + + expect(checkbox.checked).toBe(false); + + act(() => { fireEvent.click(checkbox); }); + + expect(checkbox.checked).toBe(true); + }); + + it('should check an unchecked department checkbox', () => { const { getByLabelText } = render(withAppContext()); const checkbox = getByLabelText('Actie Service Centrum'); expect(checkbox.checked).toBe(false); - fireEvent.click(checkbox); + + act(() => { fireEvent.click(checkbox); }); + expect(checkbox.checked).toBe(true); }); }); diff --git a/src/signals/settings/users/Detail/components/UserForm/index.js b/src/signals/settings/users/Detail/components/UserForm/index.js index 1ec030f3b9..b5dbeb87eb 100644 --- a/src/signals/settings/users/Detail/components/UserForm/index.js +++ b/src/signals/settings/users/Detail/components/UserForm/index.js @@ -4,6 +4,10 @@ import { useSelector } from 'react-redux'; import { themeSpacing, Row, Column } from '@datapunt/asc-ui'; import styled from 'styled-components'; +import { userType } from 'shared/types'; + +import { rolesModelSelector, inputCheckboxRolesSelector } from 'models/roles/selectors'; + import { makeSelectDepartments } from 'models/departments/selectors'; import RadioButtonList from 'signals/incident-management/components/RadioButtonList'; import CheckboxList from 'signals/incident-management/components/CheckboxList'; @@ -43,13 +47,23 @@ const DEFAULT_STATUS_OPTION = 'true'; const reducer = (state, { field, value }) => ({ ...state, [field]: value }); const UserForm = ({ data, onCancel, onSubmit, readOnly }) => { + const inputRoles = useSelector(inputCheckboxRolesSelector); + const roles = useSelector(rolesModelSelector).list; + const departments = useSelector(makeSelectDepartments); const departmentList = departments.list.map(({ id, name }) => ({ id: String(id), value: name })); - const userDepartments = data?.profile?.departments + const userDepartments = data + ?.profile + ?.departments ?.map(department => departmentList.find(({ value }) => value === department)) .filter(Boolean) || []; + const userRoles = data + ?.roles + ?.map(role => inputRoles.find(({ name }) => name === role.name)) + .filter(Boolean) || []; + const [state, dispatch] = React.useReducer(reducer, { username: data.username, first_name: data.first_name, @@ -57,6 +71,7 @@ const UserForm = ({ data, onCancel, onSubmit, readOnly }) => { note: data.profile && data.profile.note, is_active: data.is_active === undefined ? DEFAULT_STATUS_OPTION : `${data.is_active}`, departments: userDepartments, + roles: userRoles, }); const onChangeEvent = useCallback(event => { @@ -77,14 +92,20 @@ const UserForm = ({ data, onCancel, onSubmit, readOnly }) => { form.profile.note = state.note; form.profile.departments = state.departments.map(({ value }) => value); + form.roles = state.roles.map(({ name: stateRoleName }) => + roles.filter(({ name: dataRoleName }) => dataRoleName === stateRoleName)[0] + ); + const postPatch = { ...form, profile: { ...form.profile } }; delete postPatch.profile.departments; + postPatch.profile.department_ids = Object.values(state.departments).map(({ id }) => id); - postPatch.profile.department_ids = Object.values(state.departments) .map(({ id }) => id); + delete postPatch.roles; + postPatch.role_ids = Object.values(state.roles).map(({ key }) => key); return { form, postPatch }; - }, [data, state]); + }, [data, roles, state]); const onSubmitForm = useCallback(event => { event.preventDefault(); @@ -146,6 +167,17 @@ const UserForm = ({ data, onCancel, onSubmit, readOnly }) => { /> + + { onChange(field, value); }} + /> + + { .mockImplementation(() => () => true); jest - .spyOn(rolesSelectors, 'inputRolesSelector') - .mockImplementation(() => inputRolesSelectorJSON); + .spyOn(rolesSelectors, 'inputSelectRolesSelector') + .mockImplementation(() => inputSelectRolesSelectorJSON); const { getByTestId } = render(usersOverviewWithAppContext()); @@ -524,8 +524,8 @@ describe('signals/settings/users/containers/Overview', () => { it('should check if default filter values have been set', async () => { jest - .spyOn(rolesSelectors, 'inputRolesSelector') - .mockImplementation(() => inputRolesSelectorJSON); + .spyOn(rolesSelectors, 'inputSelectRolesSelector') + .mockImplementation(() => inputSelectRolesSelectorJSON); const { getByTestId } = render(usersOverviewWithAppContext()); @@ -540,8 +540,8 @@ describe('signals/settings/users/containers/Overview', () => { it('should select "Behandelaar" as filter and dispatch a fetch action', async () => { jest - .spyOn(rolesSelectors, 'inputRolesSelector') - .mockImplementation(() => inputRolesSelectorJSON); + .spyOn(rolesSelectors, 'inputSelectRolesSelector') + .mockImplementation(() => inputSelectRolesSelectorJSON); const mockedState = { users: { filters: { role: 'Behandelaar' } } }; const { getByTestId } = render(usersOverviewWithAppContext({}, {}, mockedState)); @@ -590,8 +590,8 @@ describe('signals/settings/users/containers/Overview', () => { it('should select a value in the select filters and dispatch a fetch action', async () => { jest - .spyOn(rolesSelectors, 'inputRolesSelector') - .mockImplementation(() => inputRolesSelectorJSON); + .spyOn(rolesSelectors, 'inputSelectRolesSelector') + .mockImplementation(() => inputSelectRolesSelectorJSON); const mockedState = { users: { filters: { is_active: true, role: 'Behandelaar' } } }; diff --git a/src/signals/settings/users/Overview/index.js b/src/signals/settings/users/Overview/index.js index 4532db81b6..7aa3cab7de 100644 --- a/src/signals/settings/users/Overview/index.js +++ b/src/signals/settings/users/Overview/index.js @@ -20,7 +20,7 @@ import DataView from 'components/DataView'; import { USERS_PAGED_URL, USER_URL } from 'signals/settings/routes'; import SettingsContext from 'signals/settings/context'; import { setUserFilters } from 'signals/settings/actions'; -import { inputRolesSelector } from 'models/roles/selectors'; +import { inputSelectRolesSelector } from 'models/roles/selectors'; import { makeSelectUserCan } from 'containers/App/selectors'; import SelectInput from 'components/SelectInput'; import useFetchUsers from './hooks/useFetchUsers'; @@ -65,7 +65,7 @@ const UsersOverviewContainer = () => { users, } = useFetchUsers({ page, filters }); const userCan = useSelector(makeSelectUserCan); - const selectRoles = useSelector(inputRolesSelector); + const selectRoles = useSelector(inputSelectRolesSelector); /** * Get page number value from URL query string diff --git a/src/utils/__tests__/fixtures/inputCheckboxRolesSelector.json b/src/utils/__tests__/fixtures/inputCheckboxRolesSelector.json new file mode 100644 index 0000000000..b076a32b6f --- /dev/null +++ b/src/utils/__tests__/fixtures/inputCheckboxRolesSelector.json @@ -0,0 +1,47 @@ +[ + { + "key": 2, + "name": "Behandelaar", + "value": "Behandelaar" + }, + { + "key": 3, + "name": "Coördinator", + "value": "Coördinator" + }, + { + "key": 20, + "name": "Extern Systeem", + "value": "Extern Systeem" + }, + { + "key": 30, + "name": "Hele beperkte rol", + "value": "Hele beperkte rol" + }, + { + "key": 1, + "name": "Monitor", + "value": "Monitor" + }, + { + "key": 26, + "name": "Nieuwe rollen, nieuwe kansen", + "value": "Nieuwe rollen, nieuwe kansen" + }, + { + "key": 19, + "name": "Regievoerder", + "value": "Regievoerder" + }, + { + "key": 22, + "name": "Regievoerder+", + "value": "Regievoerder+" + }, + { + "key": 28, + "name": "Test", + "value": "Test" + } +] diff --git a/src/utils/__tests__/fixtures/inputRolesSelector.json b/src/utils/__tests__/fixtures/inputSelectRolesSelector.json similarity index 100% rename from src/utils/__tests__/fixtures/inputRolesSelector.json rename to src/utils/__tests__/fixtures/inputSelectRolesSelector.json diff --git a/src/utils/__tests__/fixtures/roles.json b/src/utils/__tests__/fixtures/roles.json index 1262951234..f8d3933e4c 100644 --- a/src/utils/__tests__/fixtures/roles.json +++ b/src/utils/__tests__/fixtures/roles.json @@ -1,62 +1,60 @@ { - "list": [ + "responseSuccess": false, + "permissions": [ { "_links": { "self": { - "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/roles/2" + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/168" } }, - "_display": "behandelaars", - "id": 2, - "name": "behandelaars", - "permissions": [ - { - "_links": { - "self": { - "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/110" - } - }, - "_display": "signals | signal | Can read from SIA", - "id": 110, - "name": "Can read from SIA", - "codename": "sia_read" - }, - { - "_links": { - "self": { - "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/164" - } - }, - "_display": "signals | signal | Can change the status of a signal", - "id": 164, - "name": "Can change the status of a signal", - "codename": "sia_signal_change_status" + "_display": "signals | category | View all categories (this will override the category permission based on the user/department relation)", + "id": 168, + "name": "View all categories (this will override the category permission based on the user/department relation)", + "codename": "sia_can_view_all_categories" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/175" } - ] + }, + "_display": "signals | category | Can read Categories from SIA", + "id": 175, + "name": "Can read Categories from SIA", + "codename": "sia_category_read" }, { "_links": { "self": { - "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/roles/3" + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/176" } }, - "_display": "coordinatoren", - "id": 3, - "name": "coordinatoren", - "permissions": [] - } - ], - "permissions": [ + "_display": "signals | category | Can write Categories to SIA", + "id": 176, + "name": "Can write Categories to SIA", + "codename": "sia_category_write" + }, { "_links": { "self": { - "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/168" + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/173" } }, - "_display": "signals | category | View all categories (this will override the category permission based on the user/department relation)", - "id": 168, - "name": "View all categories (this will override the category permission based on the user/department relation)", - "codename": "sia_can_view_all_categories" + "_display": "signals | department | Can add/change a department", + "id": 173, + "name": "Can add/change a department", + "codename": "sia_department_read" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/174" + } + }, + "_display": "signals | department | Can add/change a department", + "id": 174, + "name": "Can add/change a department", + "codename": "sia_department_write" }, { "_links": { @@ -179,5 +177,682 @@ "name": "Can write StatusMessageTemplates to SIA", "codename": "sia_statusmessagetemplate_write" } + ], + "responseError": false, + "loadingPermissions": false, + "error": false, + "patching": false, + "saving": false, + "loading": false, + "list": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/roles/2" + } + }, + "_display": "Behandelaar", + "id": 2, + "name": "Behandelaar", + "permissions": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/110" + } + }, + "_display": "signals | signal | Can read from SIA", + "id": 110, + "name": "Can read from SIA", + "codename": "sia_read" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/164" + } + }, + "_display": "signals | signal | Can change the status of a signal", + "id": 164, + "name": "Can change the status of a signal", + "codename": "sia_signal_change_status" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/162" + } + }, + "_display": "signals | signal | Can create new signals", + "id": 162, + "name": "Can create new signals", + "codename": "sia_signal_create_initial" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/163" + } + }, + "_display": "signals | signal | Can create notes for signals", + "id": 163, + "name": "Can create notes for signals", + "codename": "sia_signal_create_note" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/161" + } + }, + "_display": "signals | signal | Can split a signal into a parent with X children", + "id": 161, + "name": "Can split a signal into a parent with X children", + "codename": "sia_split" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/111" + } + }, + "_display": "signals | signal | Can write to SIA", + "id": 111, + "name": "Can write to SIA", + "codename": "sia_write" + } + ] + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/roles/3" + } + }, + "_display": "Coördinator", + "id": 3, + "name": "Coördinator", + "permissions": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/110" + } + }, + "_display": "signals | signal | Can read from SIA", + "id": 110, + "name": "Can read from SIA", + "codename": "sia_read" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/165" + } + }, + "_display": "signals | signal | Can change the category of a signal", + "id": 165, + "name": "Can change the category of a signal", + "codename": "sia_signal_change_category" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/164" + } + }, + "_display": "signals | signal | Can change the status of a signal", + "id": 164, + "name": "Can change the status of a signal", + "codename": "sia_signal_change_status" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/162" + } + }, + "_display": "signals | signal | Can create new signals", + "id": 162, + "name": "Can create new signals", + "codename": "sia_signal_create_initial" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/163" + } + }, + "_display": "signals | signal | Can create notes for signals", + "id": 163, + "name": "Can create notes for signals", + "codename": "sia_signal_create_note" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/161" + } + }, + "_display": "signals | signal | Can split a signal into a parent with X children", + "id": 161, + "name": "Can split a signal into a parent with X children", + "codename": "sia_split" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/111" + } + }, + "_display": "signals | signal | Can write to SIA", + "id": 111, + "name": "Can write to SIA", + "codename": "sia_write" + } + ] + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/roles/20" + } + }, + "_display": "Extern Systeem", + "id": 20, + "name": "Extern Systeem", + "permissions": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/110" + } + }, + "_display": "signals | signal | Can read from SIA", + "id": 110, + "name": "Can read from SIA", + "codename": "sia_read" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/164" + } + }, + "_display": "signals | signal | Can change the status of a signal", + "id": 164, + "name": "Can change the status of a signal", + "codename": "sia_signal_change_status" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/162" + } + }, + "_display": "signals | signal | Can create new signals", + "id": 162, + "name": "Can create new signals", + "codename": "sia_signal_create_initial" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/163" + } + }, + "_display": "signals | signal | Can create notes for signals", + "id": 163, + "name": "Can create notes for signals", + "codename": "sia_signal_create_note" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/111" + } + }, + "_display": "signals | signal | Can write to SIA", + "id": 111, + "name": "Can write to SIA", + "codename": "sia_write" + } + ] + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/roles/30" + } + }, + "_display": "Hele beperkte rol", + "id": 30, + "name": "Hele beperkte rol", + "permissions": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/162" + } + }, + "_display": "signals | signal | Can create new signals", + "id": 162, + "name": "Can create new signals", + "codename": "sia_signal_create_initial" + } + ] + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/roles/1" + } + }, + "_display": "Monitor", + "id": 1, + "name": "Monitor", + "permissions": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/168" + } + }, + "_display": "signals | category | View all categories (this will override the category permission based on the user/department relation)", + "id": 168, + "name": "View all categories (this will override the category permission based on the user/department relation)", + "codename": "sia_can_view_all_categories" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/110" + } + }, + "_display": "signals | signal | Can read from SIA", + "id": 110, + "name": "Can read from SIA", + "codename": "sia_read" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/163" + } + }, + "_display": "signals | signal | Can create notes for signals", + "id": 163, + "name": "Can create notes for signals", + "codename": "sia_signal_create_note" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/111" + } + }, + "_display": "signals | signal | Can write to SIA", + "id": 111, + "name": "Can write to SIA", + "codename": "sia_write" + } + ] + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/roles/26" + } + }, + "_display": "Nieuwe rollen, nieuwe kansen", + "id": 26, + "name": "Nieuwe rollen, nieuwe kansen", + "permissions": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/98" + } + }, + "_display": "signals | note | Can add note", + "id": 98, + "name": "Can add note", + "codename": "add_note" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/73" + } + }, + "_display": "signals | priority | Can add priority", + "id": 73, + "name": "Can add priority", + "codename": "add_priority" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/110" + } + }, + "_display": "signals | signal | Can read from SIA", + "id": 110, + "name": "Can read from SIA", + "codename": "sia_read" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/162" + } + }, + "_display": "signals | signal | Can create new signals", + "id": 162, + "name": "Can create new signals", + "codename": "sia_signal_create_initial" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/166" + } + }, + "_display": "signals | signal | Can export signals", + "id": 166, + "name": "Can export signals", + "codename": "sia_signal_export" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/111" + } + }, + "_display": "signals | signal | Can write to SIA", + "id": 111, + "name": "Can write to SIA", + "codename": "sia_write" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/97" + } + }, + "_display": "signals | status | Push to Sigmax/CityControl", + "id": 97, + "name": "Push to Sigmax/CityControl", + "codename": "push_to_sigmax" + } + ] + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/roles/19" + } + }, + "_display": "Regievoerder", + "id": 19, + "name": "Regievoerder", + "permissions": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/168" + } + }, + "_display": "signals | category | View all categories (this will override the category permission based on the user/department relation)", + "id": 168, + "name": "View all categories (this will override the category permission based on the user/department relation)", + "codename": "sia_can_view_all_categories" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/110" + } + }, + "_display": "signals | signal | Can read from SIA", + "id": 110, + "name": "Can read from SIA", + "codename": "sia_read" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/165" + } + }, + "_display": "signals | signal | Can change the category of a signal", + "id": 165, + "name": "Can change the category of a signal", + "codename": "sia_signal_change_category" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/164" + } + }, + "_display": "signals | signal | Can change the status of a signal", + "id": 164, + "name": "Can change the status of a signal", + "codename": "sia_signal_change_status" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/162" + } + }, + "_display": "signals | signal | Can create new signals", + "id": 162, + "name": "Can create new signals", + "codename": "sia_signal_create_initial" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/163" + } + }, + "_display": "signals | signal | Can create notes for signals", + "id": 163, + "name": "Can create notes for signals", + "codename": "sia_signal_create_note" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/161" + } + }, + "_display": "signals | signal | Can split a signal into a parent with X children", + "id": 161, + "name": "Can split a signal into a parent with X children", + "codename": "sia_split" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/111" + } + }, + "_display": "signals | signal | Can write to SIA", + "id": 111, + "name": "Can write to SIA", + "codename": "sia_write" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/97" + } + }, + "_display": "signals | status | Push to Sigmax/CityControl", + "id": 97, + "name": "Push to Sigmax/CityControl", + "codename": "push_to_sigmax" + } + ] + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/roles/22" + } + }, + "_display": "Regievoerder Plus", + "id": 22, + "name": "Regievoerder Plus", + "permissions": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/110" + } + }, + "_display": "signals | signal | Can read from SIA", + "id": 110, + "name": "Can read from SIA", + "codename": "sia_read" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/165" + } + }, + "_display": "signals | signal | Can change the category of a signal", + "id": 165, + "name": "Can change the category of a signal", + "codename": "sia_signal_change_category" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/164" + } + }, + "_display": "signals | signal | Can change the status of a signal", + "id": 164, + "name": "Can change the status of a signal", + "codename": "sia_signal_change_status" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/162" + } + }, + "_display": "signals | signal | Can create new signals", + "id": 162, + "name": "Can create new signals", + "codename": "sia_signal_create_initial" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/163" + } + }, + "_display": "signals | signal | Can create notes for signals", + "id": 163, + "name": "Can create notes for signals", + "codename": "sia_signal_create_note" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/166" + } + }, + "_display": "signals | signal | Can export signals", + "id": 166, + "name": "Can export signals", + "codename": "sia_signal_export" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/167" + } + }, + "_display": "signals | signal | Can create reports for signals", + "id": 167, + "name": "Can create reports for signals", + "codename": "sia_signal_report" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/161" + } + }, + "_display": "signals | signal | Can split a signal into a parent with X children", + "id": 161, + "name": "Can split a signal into a parent with X children", + "codename": "sia_split" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/111" + } + }, + "_display": "signals | signal | Can write to SIA", + "id": 111, + "name": "Can write to SIA", + "codename": "sia_write" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/97" + } + }, + "_display": "signals | status | Push to Sigmax/CityControl", + "id": 97, + "name": "Push to Sigmax/CityControl", + "codename": "push_to_sigmax" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/140" + } + }, + "_display": "signals | Standaard afmeldtekst | Can write StatusMessageTemplates to SIA", + "id": 140, + "name": "Can write StatusMessageTemplates to SIA", + "codename": "sia_statusmessagetemplate_write" + } + ] + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/roles/28" + } + }, + "_display": "Test", + "id": 28, + "name": "Test", + "permissions": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/163" + } + }, + "_display": "signals | signal | Can create notes for signals", + "id": 163, + "name": "Can create notes for signals", + "codename": "sia_signal_create_note" + } + ] + } ] -} \ No newline at end of file +} diff --git a/src/utils/__tests__/fixtures/userNew.json b/src/utils/__tests__/fixtures/userNew.json new file mode 100644 index 0000000000..2447dc330b --- /dev/null +++ b/src/utils/__tests__/fixtures/userNew.json @@ -0,0 +1,226 @@ +{ + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/users/255657600" + } + }, + "_display": "initial.lastname@amsterdam.nl", + "id": 255657600, + "username": "initial.lastname@amsterdam.nl", + "email": "initial.lastname@amsterdam.nl", + "first_name": "Firstname", + "last_name": "Lastname", + "is_active": true, + "is_staff": false, + "is_superuser": true, + "roles": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/roles/1" + } + }, + "_display": "Monitor", + "id": 1, + "name": "Monitor", + "permissions": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/168" + } + }, + "_display": "signals | category | View all categories (this will override the category permission based on the user/department relation)", + "id": 168, + "name": "View all categories (this will override the category permission based on the user/department relation)", + "codename": "sia_can_view_all_categories" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/110" + } + }, + "_display": "signals | signal | Can read from SIA", + "id": 110, + "name": "Can read from SIA", + "codename": "sia_read" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/163" + } + }, + "_display": "signals | signal | Can create notes for signals", + "id": 163, + "name": "Can create notes for signals", + "codename": "sia_signal_create_note" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/111" + } + }, + "_display": "signals | signal | Can write to SIA", + "id": 111, + "name": "Can write to SIA", + "codename": "sia_write" + } + ] + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/roles/20" + } + }, + "_display": "Extern Systeem", + "id": 20, + "name": "Extern Systeem", + "permissions": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/110" + } + }, + "_display": "signals | signal | Can read from SIA", + "id": 110, + "name": "Can read from SIA", + "codename": "sia_read" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/164" + } + }, + "_display": "signals | signal | Can change the status of a signal", + "id": 164, + "name": "Can change the status of a signal", + "codename": "sia_signal_change_status" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/162" + } + }, + "_display": "signals | signal | Can create new signals", + "id": 162, + "name": "Can create new signals", + "codename": "sia_signal_create_initial" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/163" + } + }, + "_display": "signals | signal | Can create notes for signals", + "id": 163, + "name": "Can create notes for signals", + "codename": "sia_signal_create_note" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/111" + } + }, + "_display": "signals | signal | Can write to SIA", + "id": 111, + "name": "Can write to SIA", + "codename": "sia_write" + } + ] + } + ], + "permissions": [ + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/1571875200" + } + }, + "_display": "auth | groep | Can add group", + "id": 1571875200, + "name": "Can add group", + "codename": "add_group" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/1571875210" + } + }, + "_display": "auth | groep | Can change group", + "id": 1571875210, + "name": "Can change group", + "codename": "change_group" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/1571875220" + } + }, + "_display": "auth | groep | Can view group", + "id": 1571875220, + "name": "Can view group", + "codename": "view_group" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/1571875230" + } + }, + "_display": "auth | recht | Can view permission", + "id": 1571875230, + "name": "Can view permission", + "codename": "view_permission" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/1571875240" + } + }, + "_display": "auth | gebruiker | Can add user", + "id": 1571875240, + "name": "Can add user", + "codename": "add_user" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/1571875250" + } + }, + "_display": "auth | gebruiker | Can change user", + "id": 1571875250, + "name": "Can change user", + "codename": "change_user" + }, + { + "_links": { + "self": { + "href": "https://acc.api.data.amsterdam.nl/signals/v1/private/permissions/1571875260" + } + }, + "_display": "auth | gebruiker | Can view user", + "id": 1571875260, + "name": "Can view user", + "codename": "view_user" + } + ], + "profile": { + "note": "een notitie", + "departments": ["Actie Service Centrum","Afval en Grondstoffen","CCA","FB"], + "created_at": "2019-10-24T10:25:48.874301+02:00", + "updated_at": "2019-10-24T10:25:48.874315+02:00" + } +} From a932bfb6b77519fcf61a931f786cfa33b0100cd9 Mon Sep 17 00:00:00 2001 From: Jasper Poppe Date: Mon, 6 Apr 2020 10:06:04 +0200 Subject: [PATCH 05/80] fixed typo --- src/models/roles/selectors.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/roles/selectors.js b/src/models/roles/selectors.js index baf7e5b128..5249918a90 100644 --- a/src/models/roles/selectors.js +++ b/src/models/roles/selectors.js @@ -22,7 +22,7 @@ export const inputSelectRolesSelector = createSelector( export const inputCheckboxRolesSelector = createSelector( selectRolesDomain, - state => rolesInputOptions[state] + state => rolesInputOptions(state) ); /** From 0e23980b08ddba1d318e7ac7e373a08430f96eb8 Mon Sep 17 00:00:00 2001 From: Boris Arkenaar Date: Tue, 14 Apr 2020 09:53:16 +0200 Subject: [PATCH 06/80] Run npm audit fix multiple times --- package-lock.json | 1241 ++++++++++++++++++++++++++++----------------- 1 file changed, 776 insertions(+), 465 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8274b05256..4e0bad6751 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4626,6 +4626,21 @@ "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==", "dev": true + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } } } }, @@ -6305,7 +6320,8 @@ "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true }, "abortcontroller-polyfill": { "version": "1.4.0", @@ -6322,9 +6338,9 @@ } }, "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", + "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", "dev": true }, "acorn-globals": { @@ -6338,9 +6354,9 @@ }, "dependencies": { "acorn": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", - "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true } } @@ -7777,6 +7793,16 @@ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", "dev": true }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, "bl": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", @@ -8474,7 +8500,8 @@ "chownr": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==" + "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", + "dev": true }, "chrome-trace-event": { "version": "1.0.2", @@ -9755,16 +9782,6 @@ "postcss-value-parser": "^3.3.0" } }, - "css-tree": { - "version": "1.0.0-alpha.33", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.33.tgz", - "integrity": "sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w==", - "dev": true, - "requires": { - "mdn-data": "2.0.4", - "source-map": "^0.5.3" - } - }, "css-unit-converter": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz", @@ -10090,9 +10107,9 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, "decompress": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", - "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", "dev": true, "optional": true, "requires": { @@ -10106,37 +10123,6 @@ "strip-dirs": "^2.0.0" }, "dependencies": { - "decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", - "dev": true, - "optional": true, - "requires": { - "file-type": "^3.8.0", - "get-stream": "^2.2.0", - "pify": "^2.3.0", - "yauzl": "^2.4.2" - } - }, - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "dev": true, - "optional": true - }, - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "dev": true, - "optional": true, - "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - } - }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -10221,6 +10207,46 @@ } } }, + "decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", + "dev": true, + "optional": true, + "requires": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "dependencies": { + "file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", + "dev": true, + "optional": true + }, + "get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "dev": true, + "optional": true, + "requires": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "optional": true + } + } + }, "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -10240,13 +10266,6 @@ "regexp.prototype.flags": "^1.2.0" } }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true, - "optional": true - }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -10536,13 +10555,6 @@ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true, - "optional": true - }, "detect-newline": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", @@ -11876,9 +11888,9 @@ }, "dependencies": { "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==", "dev": true } } @@ -12455,6 +12467,13 @@ "integrity": "sha512-4E4Esq9KLwjYCY32E7qSmd0h7LefcniZHX+XcdJ4Wfx1uGJX7QCigiqw/U0yT7WOslm28yhxl87DJ0wHYv0RAA==", "dev": true }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, "filename-reserved-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", @@ -12834,90 +12853,560 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", "dev": true, "optional": true, "requires": { + "bindings": "^1.5.0", "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" + "node-pre-gyp": "*" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, "requires": { - "ms": "^2.1.1" + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" } }, - "fs-minipass": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, "requires": { - "minipass": "^2.2.1" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "chownr": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true }, - "minipass": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", - "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "dev": true, + "optional": true, "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" + "ms": "^2.1.1" } }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "minipass": "^2.6.0" } }, - "tar": { - "version": "4.4.8", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", - "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" } }, - "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" - } - } - }, - "fsm-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fsm-iterator/-/fsm-iterator-1.1.0.tgz", - "integrity": "sha1-M33kXeGesgV4jPAuOpVewgZ2Dew=", + "glob": { + "version": "7.1.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "fsm-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fsm-iterator/-/fsm-iterator-1.1.0.tgz", + "integrity": "sha1-M33kXeGesgV4jPAuOpVewgZ2Dew=", "dev": true }, "fstream": { @@ -13368,15 +13857,16 @@ } }, "handlebars": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.3.tgz", - "integrity": "sha512-B0W4A2U1ww3q7VVthTKfh+epHx+q4mCt6iK+zEAzbMBpWQAwxCeKxEGpj/1oQTpzPXDNSOG7hmG14TsISH50yw==", + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", + "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", "dev": true, "requires": { + "minimist": "^1.2.5", "neo-async": "^2.6.0", - "optimist": "^0.6.1", "source-map": "^0.6.1", - "uglify-js": "^3.1.4" + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" }, "dependencies": { "source-map": { @@ -13673,6 +14163,12 @@ "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", "dev": true }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, "html-loader": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-0.5.5.tgz", @@ -13924,16 +14420,6 @@ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", "dev": true }, - "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, "image-webpack-loader": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/image-webpack-loader/-/image-webpack-loader-6.0.0.tgz", @@ -14274,26 +14760,16 @@ } }, "imagemin-svgo": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/imagemin-svgo/-/imagemin-svgo-7.0.0.tgz", - "integrity": "sha512-+iGJFaPIMx8TjFW6zN+EkOhlqcemdL7F3N3Y0wODvV2kCUBuUtZK7DRZc1+Zfu4U2W/lTMUyx2G8YMOrZntIWg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/imagemin-svgo/-/imagemin-svgo-7.1.0.tgz", + "integrity": "sha512-0JlIZNWP0Luasn1HT82uB9nU9aa+vUj6kpT+MjPW11LbprXC+iC4HDwn1r4Q2/91qj4iy9tRZNsFySMlEpLdpg==", "dev": true, "optional": true, "requires": { - "is-svg": "^3.0.0", - "svgo": "^1.0.5" + "is-svg": "^4.2.1", + "svgo": "^1.3.2" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "optional": true, - "requires": { - "color-convert": "^1.9.0" - } - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -14319,38 +14795,63 @@ } }, "css-select": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", - "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", "dev": true, "optional": true, "requires": { "boolbase": "^1.0.0", - "css-what": "^2.1.2", + "css-what": "^3.2.1", "domutils": "^1.7.0", "nth-check": "^1.0.2" } }, + "css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "optional": true, + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + } + }, + "css-what": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.1.tgz", + "integrity": "sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw==", + "dev": true, + "optional": true + }, "csso": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz", - "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", + "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", "dev": true, "optional": true, "requires": { - "css-tree": "1.0.0-alpha.29" + "css-tree": "1.0.0-alpha.39" }, "dependencies": { "css-tree": { - "version": "1.0.0-alpha.29", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz", - "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", + "version": "1.0.0-alpha.39", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", + "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", "dev": true, "optional": true, "requires": { - "mdn-data": "~1.1.0", - "source-map": "^0.5.3" + "mdn-data": "2.0.6", + "source-map": "^0.6.1" } + }, + "mdn-data": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", + "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", + "dev": true, + "optional": true } } }, @@ -14372,38 +14873,38 @@ "dev": true, "optional": true }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "is-svg": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-4.2.1.tgz", + "integrity": "sha512-PHx3ANecKsKNl5y5+Jvt53Y4J7MfMpbNZkv384QNiswMKAWIbvcqbPz+sYbFKJI8Xv3be01GSFniPmoaP+Ai5A==", "dev": true, "optional": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "html-comment-regex": "^1.1.2" } }, - "mdn-data": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", - "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==", - "dev": true, - "optional": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "optional": true, "requires": { - "has-flag": "^3.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + }, "svgo": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz", - "integrity": "sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", "dev": true, "optional": true, "requires": { @@ -14411,8 +14912,8 @@ "coa": "^2.0.2", "css-select": "^2.0.0", "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.33", - "csso": "^3.5.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", "js-yaml": "^3.13.1", "mkdirp": "~0.5.1", "object.values": "^1.1.0", @@ -15434,12 +15935,12 @@ } }, "istanbul-reports": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", - "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", + "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", "dev": true, "requires": { - "handlebars": "^4.1.2" + "html-escaper": "^2.0.0" } }, "isurl": { @@ -16711,9 +17212,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, "kleur": { @@ -18266,30 +18767,6 @@ "minipass": "^3.0.0" } }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "requires": { - "minipass": "^2.9.0" - }, - "dependencies": { - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - } - } - }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -18377,18 +18854,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": { @@ -18497,37 +18967,6 @@ "semver": "^5.4.1" } }, - "needle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.3.0.tgz", - "integrity": "sha512-QBZu7aAFR0522EyaXZM0FZ9GLpq6lvQ3uq8gteiDUp7wKdy0lSd2hPlgFwVuW1CBkfEs9PfDQsQzZghLs/psdg==", - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "optional": true - } - } - }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -19097,92 +19536,6 @@ } } }, - "node-pre-gyp": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz", - "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - }, - "dependencies": { - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "tar": { - "version": "4.4.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", - "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "optional": true - } - } - }, "node-releases": { "version": "1.1.36", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.36.tgz", @@ -22551,13 +22904,6 @@ } } }, - "npm-bundled": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", - "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", - "dev": true, - "optional": true - }, "npm-conf": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", @@ -22569,17 +22915,6 @@ "pify": "^3.0.0" } }, - "npm-packlist": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz", - "integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==", - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, "npm-run-all": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", @@ -23007,30 +23342,6 @@ "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", "dev": true }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - } - } - }, "optimize-css-assets-webpack-plugin": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz", @@ -23086,7 +23397,8 @@ "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true }, "os-locale": { "version": "1.4.0", @@ -23106,12 +23418,14 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true }, "osenv": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, "requires": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" @@ -24090,6 +24404,17 @@ "svgo": "^1.0.0" }, "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, "coa": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", @@ -24099,51 +24424,58 @@ "@types/q": "^1.5.1", "chalk": "^2.4.1", "q": "^1.1.2" - }, - "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - } } }, "css-select": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz", - "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", "dev": true, "requires": { "boolbase": "^1.0.0", - "css-what": "^2.1.2", + "css-what": "^3.2.1", "domutils": "^1.7.0", "nth-check": "^1.0.2" + }, + "dependencies": { + "css-what": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.2.1.tgz", + "integrity": "sha512-WwOrosiQTvyms+Ti5ZC5vGEK0Vod3FTt1ca+payZqvKuGJF+dq7bG63DstxtN0dpm6FxY27a/zS3Wten+gEtGw==", + "dev": true + } } }, "csso": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz", - "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", + "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", "dev": true, "requires": { - "css-tree": "1.0.0-alpha.29" + "css-tree": "1.0.0-alpha.39" }, "dependencies": { "css-tree": { - "version": "1.0.0-alpha.29", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz", - "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==", + "version": "1.0.0-alpha.39", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", + "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", "dev": true, "requires": { - "mdn-data": "~1.1.0", - "source-map": "^0.5.3" + "mdn-data": "2.0.6", + "source-map": "^0.6.1" } + }, + "mdn-data": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", + "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, @@ -24173,24 +24505,18 @@ "esprima": "^4.0.0" } }, - "mdn-data": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz", - "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==", - "dev": true - }, "svgo": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz", - "integrity": "sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", "dev": true, "requires": { "chalk": "^2.4.1", "coa": "^2.0.2", "css-select": "^2.0.0", "css-select-base-adapter": "^0.1.1", - "css-tree": "1.0.0-alpha.33", - "csso": "^3.5.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", "js-yaml": "^3.13.1", "mkdirp": "~0.5.1", "object.values": "^1.1.0", @@ -24200,16 +24526,21 @@ "util.promisify": "~1.0.0" }, "dependencies": { - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "mdn-data": "2.0.4", + "source-map": "^0.6.1" } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } } @@ -24607,19 +24938,6 @@ } } }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, "react": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", @@ -26866,13 +27184,6 @@ "get-stdin": "^4.0.1" } }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true, - "optional": true - }, "strip-outer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", @@ -27732,9 +28043,9 @@ } }, "unbzip2-stream": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz", - "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.1.tgz", + "integrity": "sha512-sgDYfSDPMsA4Hr2/w7vOlrJBlwzmyakk1+hW8ObLvxSp0LA36LcL2XItGvOT3OSblohSdevMuT8FQjLsqyy4sA==", "dev": true, "optional": true, "requires": { From 39969088dda6b8f7b2e55d15fa6f77523a0e55b7 Mon Sep 17 00:00:00 2001 From: Boris Arkenaar Date: Tue, 14 Apr 2020 09:58:51 +0200 Subject: [PATCH 07/80] Run npm update --- package-lock.json | 317 +++++++++++++++++++++++++++------------------- package.json | 12 +- 2 files changed, 190 insertions(+), 139 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4e0bad6751..f97eb66b35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -83,15 +83,15 @@ } }, "caniuse-lite": { - "version": "1.0.30001039", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001039.tgz", - "integrity": "sha512-SezbWCTT34eyFoWHgx8UWso7YtvtM7oosmFoXbCkdC6qJzRfBTeTgE9REtKtiuKXuMwWTZEvdnFNGAyVMorv8Q==", + "version": "1.0.30001041", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001041.tgz", + "integrity": "sha512-fqDtRCApddNrQuBxBS7kEiSGdBsgO4wiVw4G/IClfqzfhW45MbTumfN4cuUJGTM0YGFNn97DCXPJ683PS6zwvA==", "dev": true }, "electron-to-chromium": { - "version": "1.3.398", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.398.tgz", - "integrity": "sha512-BJjxuWLKFbM5axH3vES7HKMQgAknq9PZHBkMK/rEXUQG9i1Iw5R+6hGkm6GtsQSANjSUrh/a6m32nzCNDNo/+w==", + "version": "1.3.404", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.404.tgz", + "integrity": "sha512-G7XYSpNXv/GhFLgjGyBJAs9LjLHBWhsvjf6VI/VbptG9KiABHSItETTgDe1LDjbHA5P/Rn2MMDKOvhewM+w2Cg==", "dev": true }, "node-releases": { @@ -330,13 +330,19 @@ "@babel/types": "^7.8.3" }, "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.9.5", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -425,15 +431,15 @@ } }, "caniuse-lite": { - "version": "1.0.30001039", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001039.tgz", - "integrity": "sha512-SezbWCTT34eyFoWHgx8UWso7YtvtM7oosmFoXbCkdC6qJzRfBTeTgE9REtKtiuKXuMwWTZEvdnFNGAyVMorv8Q==", + "version": "1.0.30001041", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001041.tgz", + "integrity": "sha512-fqDtRCApddNrQuBxBS7kEiSGdBsgO4wiVw4G/IClfqzfhW45MbTumfN4cuUJGTM0YGFNn97DCXPJ683PS6zwvA==", "dev": true }, "electron-to-chromium": { - "version": "1.3.398", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.398.tgz", - "integrity": "sha512-BJjxuWLKFbM5axH3vES7HKMQgAknq9PZHBkMK/rEXUQG9i1Iw5R+6hGkm6GtsQSANjSUrh/a6m32nzCNDNo/+w==", + "version": "1.3.404", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.404.tgz", + "integrity": "sha512-G7XYSpNXv/GhFLgjGyBJAs9LjLHBWhsvjf6VI/VbptG9KiABHSItETTgDe1LDjbHA5P/Rn2MMDKOvhewM+w2Cg==", "dev": true }, "node-releases": { @@ -586,14 +592,14 @@ } }, "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/types": "^7.9.5" } }, "@babel/helper-get-function-arity": { @@ -605,6 +611,12 @@ "@babel/types": "^7.8.3" } }, + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, "@babel/highlight": { "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", @@ -634,12 +646,12 @@ } }, "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.9.5", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -677,26 +689,26 @@ } }, "@babel/generator": { - "version": "7.9.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.4.tgz", - "integrity": "sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz", + "integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==", "dev": true, "requires": { - "@babel/types": "^7.9.0", + "@babel/types": "^7.9.5", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" } }, "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/types": "^7.9.5" } }, "@babel/helper-get-function-arity": { @@ -746,31 +758,39 @@ } }, "@babel/traverse": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", - "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz", + "integrity": "sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.0", - "@babel/helper-function-name": "^7.8.3", + "@babel/generator": "^7.9.5", + "@babel/helper-function-name": "^7.9.5", "@babel/helper-split-export-declaration": "^7.8.3", "@babel/parser": "^7.9.0", - "@babel/types": "^7.9.0", + "@babel/types": "^7.9.5", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.9.5", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + } } }, "chalk": { @@ -828,13 +848,19 @@ "@babel/types": "^7.8.3" }, "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.9.5", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -1872,13 +1898,14 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.0.tgz", - "integrity": "sha512-UgqBv6bjq4fDb8uku9f+wcm1J7YxJ5nT7WO/jBr0cl0PLKb7t1O6RNR1kZbjgx2LQtsDI9hwoQVmn0yhXeQyow==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.5.tgz", + "integrity": "sha512-VP2oXvAf7KCYTthbUHwBlewbl1Iq059f6seJGsxMizaCdgHIeczOr7FBqELhSqfkIl04Fi8okzWzl63UKbQmmg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0" + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.9.5" }, "dependencies": { "@babel/helper-plugin-utils": { @@ -2206,14 +2233,14 @@ } }, "@babel/plugin-transform-classes": { - "version": "7.9.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.2.tgz", - "integrity": "sha512-TC2p3bPzsfvSsqBZo0kJnuelnoK9O3welkUpqSqBQuBF6R5MN2rysopri8kNvtlGIb2jmUO7i15IooAZJjZuMQ==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz", + "integrity": "sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.8.3", "@babel/helper-define-map": "^7.8.3", - "@babel/helper-function-name": "^7.8.3", + "@babel/helper-function-name": "^7.9.5", "@babel/helper-optimise-call-expression": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3", "@babel/helper-replace-supers": "^7.8.6", @@ -2231,26 +2258,26 @@ } }, "@babel/generator": { - "version": "7.9.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.4.tgz", - "integrity": "sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz", + "integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==", "dev": true, "requires": { - "@babel/types": "^7.9.0", + "@babel/types": "^7.9.5", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" } }, "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/types": "^7.9.5" } }, "@babel/helper-get-function-arity": { @@ -2289,6 +2316,12 @@ "@babel/types": "^7.8.3" } }, + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, "@babel/highlight": { "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", @@ -2318,29 +2351,29 @@ } }, "@babel/traverse": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", - "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz", + "integrity": "sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.0", - "@babel/helper-function-name": "^7.8.3", + "@babel/generator": "^7.9.5", + "@babel/helper-function-name": "^7.9.5", "@babel/helper-split-export-declaration": "^7.8.3", "@babel/parser": "^7.9.0", - "@babel/types": "^7.9.0", + "@babel/types": "^7.9.5", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.9.5", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -2391,9 +2424,9 @@ } }, "@babel/plugin-transform-destructuring": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.8.tgz", - "integrity": "sha512-eRJu4Vs2rmttFCdhPUM3bV0Yo/xPSdPw6ML9KHs/bjB4bLA5HXlbvYXPOD5yASodGod+krjYx21xm1QmL8dCJQ==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.9.5.tgz", + "integrity": "sha512-j3OEsGel8nHL/iusv/mRd5fYZ3DrOxWC82x0ogmdN/vHfAP4MYw+AFKYanzWlktNwikKvlzUV//afBW5FTp17Q==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" @@ -2497,14 +2530,14 @@ } }, "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/types": "^7.9.5" } }, "@babel/helper-get-function-arity": { @@ -2522,6 +2555,12 @@ "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", "dev": true }, + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, "@babel/highlight": { "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", @@ -2551,12 +2590,12 @@ } }, "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.9.5", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -2730,9 +2769,9 @@ } }, "@babel/plugin-transform-parameters": { - "version": "7.9.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.3.tgz", - "integrity": "sha512-fzrQFQhp7mIhOzmOtPiKffvCYQSK10NR8t6BBz2yPbeUHb9OLW8RZGtgDRBn8z2hGcwvKDL3vC7ojPTLNxmqEg==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.5.tgz", + "integrity": "sha512-0+1FhHnMfj6lIIhVvS4KGQJeuhe1GI//h5uptK4PvLt+BGBxsoUJbd3/IW002yk//6sZPlFgsG1hY6OHLcy6kA==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", @@ -2754,13 +2793,19 @@ "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", "dev": true }, + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.9.5", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -3059,9 +3104,9 @@ } }, "@babel/preset-env": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.0.tgz", - "integrity": "sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.9.5.tgz", + "integrity": "sha512-eWGYeADTlPJH+wq1F0wNfPbVS1w1wtmMJiYk55Td5Yu28AsdR9AsC97sZ0Qq8fHqQuslVSIYSGJMcblr345GfQ==", "dev": true, "requires": { "@babel/compat-data": "^7.9.0", @@ -3073,7 +3118,7 @@ "@babel/plugin-proposal-json-strings": "^7.8.3", "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-proposal-numeric-separator": "^7.8.3", - "@babel/plugin-proposal-object-rest-spread": "^7.9.0", + "@babel/plugin-proposal-object-rest-spread": "^7.9.5", "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", "@babel/plugin-proposal-optional-chaining": "^7.9.0", "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", @@ -3090,9 +3135,9 @@ "@babel/plugin-transform-async-to-generator": "^7.8.3", "@babel/plugin-transform-block-scoped-functions": "^7.8.3", "@babel/plugin-transform-block-scoping": "^7.8.3", - "@babel/plugin-transform-classes": "^7.9.0", + "@babel/plugin-transform-classes": "^7.9.5", "@babel/plugin-transform-computed-properties": "^7.8.3", - "@babel/plugin-transform-destructuring": "^7.8.3", + "@babel/plugin-transform-destructuring": "^7.9.5", "@babel/plugin-transform-dotall-regex": "^7.8.3", "@babel/plugin-transform-duplicate-keys": "^7.8.3", "@babel/plugin-transform-exponentiation-operator": "^7.8.3", @@ -3107,7 +3152,7 @@ "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", "@babel/plugin-transform-new-target": "^7.8.3", "@babel/plugin-transform-object-super": "^7.8.3", - "@babel/plugin-transform-parameters": "^7.8.7", + "@babel/plugin-transform-parameters": "^7.9.5", "@babel/plugin-transform-property-literals": "^7.8.3", "@babel/plugin-transform-regenerator": "^7.8.7", "@babel/plugin-transform-reserved-words": "^7.8.3", @@ -3118,7 +3163,7 @@ "@babel/plugin-transform-typeof-symbol": "^7.8.4", "@babel/plugin-transform-unicode-regex": "^7.8.3", "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.9.0", + "@babel/types": "^7.9.5", "browserslist": "^4.9.1", "core-js-compat": "^3.6.2", "invariant": "^2.2.2", @@ -3141,6 +3186,12 @@ "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", "dev": true }, + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, "@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", @@ -3151,12 +3202,12 @@ } }, "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", + "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.9.5", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -3174,15 +3225,15 @@ } }, "caniuse-lite": { - "version": "1.0.30001039", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001039.tgz", - "integrity": "sha512-SezbWCTT34eyFoWHgx8UWso7YtvtM7oosmFoXbCkdC6qJzRfBTeTgE9REtKtiuKXuMwWTZEvdnFNGAyVMorv8Q==", + "version": "1.0.30001041", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001041.tgz", + "integrity": "sha512-fqDtRCApddNrQuBxBS7kEiSGdBsgO4wiVw4G/IClfqzfhW45MbTumfN4cuUJGTM0YGFNn97DCXPJ683PS6zwvA==", "dev": true }, "electron-to-chromium": { - "version": "1.3.398", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.398.tgz", - "integrity": "sha512-BJjxuWLKFbM5axH3vES7HKMQgAknq9PZHBkMK/rEXUQG9i1Iw5R+6hGkm6GtsQSANjSUrh/a6m32nzCNDNo/+w==", + "version": "1.3.404", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.404.tgz", + "integrity": "sha512-G7XYSpNXv/GhFLgjGyBJAs9LjLHBWhsvjf6VI/VbptG9KiABHSItETTgDe1LDjbHA5P/Rn2MMDKOvhewM+w2Cg==", "dev": true }, "node-releases": { @@ -3474,9 +3525,9 @@ } }, "@datapunt/amsterdam-amaps": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@datapunt/amsterdam-amaps/-/amsterdam-amaps-3.0.2.tgz", - "integrity": "sha512-9PCvFD/1WnuDVX+LNkc/bpa/k0DZze3fdLglb/yapP8NTWdc+7vO1mSuxVrOuXgy+8xWgvDieXwISeNCL+TLNA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@datapunt/amsterdam-amaps/-/amsterdam-amaps-3.1.1.tgz", + "integrity": "sha512-q0DKd517C+4bNgL0/IRaeZAIoSShtmI/ErMk0ypaQilnY8ZQfWqfgQC0kY2e6m9D7ON2pZVpp+2aUeYGuUX6jg==", "requires": { "amsterdam-stijl": "^3.0.5", "babel-polyfill": "^6.26.0", @@ -9183,17 +9234,17 @@ } }, "core-js": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", - "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==" + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.5.tgz", + "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" }, "core-js-compat": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.4.tgz", - "integrity": "sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA==", + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", + "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", "dev": true, "requires": { - "browserslist": "^4.8.3", + "browserslist": "^4.8.5", "semver": "7.0.0" }, "dependencies": { @@ -9210,15 +9261,15 @@ } }, "caniuse-lite": { - "version": "1.0.30001039", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001039.tgz", - "integrity": "sha512-SezbWCTT34eyFoWHgx8UWso7YtvtM7oosmFoXbCkdC6qJzRfBTeTgE9REtKtiuKXuMwWTZEvdnFNGAyVMorv8Q==", + "version": "1.0.30001041", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001041.tgz", + "integrity": "sha512-fqDtRCApddNrQuBxBS7kEiSGdBsgO4wiVw4G/IClfqzfhW45MbTumfN4cuUJGTM0YGFNn97DCXPJ683PS6zwvA==", "dev": true }, "electron-to-chromium": { - "version": "1.3.398", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.398.tgz", - "integrity": "sha512-BJjxuWLKFbM5axH3vES7HKMQgAknq9PZHBkMK/rEXUQG9i1Iw5R+6hGkm6GtsQSANjSUrh/a6m32nzCNDNo/+w==", + "version": "1.3.404", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.404.tgz", + "integrity": "sha512-G7XYSpNXv/GhFLgjGyBJAs9LjLHBWhsvjf6VI/VbptG9KiABHSItETTgDe1LDjbHA5P/Rn2MMDKOvhewM+w2Cg==", "dev": true }, "node-releases": { @@ -9471,9 +9522,9 @@ } }, "css-loader": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.5.0.tgz", - "integrity": "sha512-zed7D7JNZEq7htpu3H9oBUVWVgI6s8FgigejbVq+dc5zHV3SUPsyYBozXLIC9Eb73ahAYmnVdnn/SAB4WA75AQ==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.5.2.tgz", + "integrity": "sha512-hDL0DPopg6zQQSRlZm0hyeaqIRnL0wbWjay9BZxoiJBpbfOW4WHfbaYQhwnDmEa0kZUc1CJ3IFo15ot1yULMIQ==", "dev": true, "requires": { "camelcase": "^5.3.1", @@ -11689,9 +11740,9 @@ } }, "eslint-plugin-prettier": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.2.tgz", - "integrity": "sha512-GlolCC9y3XZfv3RQfwGew7NnuFDKsfI4lbvRK+PIIo23SFH+LemGs4cKwzAaRa+Mdb+lQO/STaIayno8T5sJJA==", + "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" @@ -28677,9 +28728,9 @@ } }, "webpack-bundle-analyzer": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.6.1.tgz", - "integrity": "sha512-Nfd8HDwfSx1xBwC+P8QMGvHAOITxNBSvu/J/mCJvOwv+G4VWkU7zir9SSenTtyCi0LnVtmsc7G5SZo1uV+bxRw==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.7.0.tgz", + "integrity": "sha512-mETdjZ30a3Yf+NTB/wqTgACK7rAYQl5uxKK0WVTNmF0sM3Uv8s3R58YZMW7Rhu0Lk2Rmuhdj5dcH5Q76zCDVdA==", "dev": true, "requires": { "acorn": "^7.1.1", diff --git a/package.json b/package.json index ae5ce518fe..7351fab638 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ ], "dependencies": { "@babel/polyfill": "^7.8.7", - "@datapunt/amsterdam-amaps": "^3.0.2", + "@datapunt/amsterdam-amaps": "^3.1.1", "@datapunt/amsterdam-react-maps": "0.1.2-alpha.1", "@datapunt/asc-assets": "^0.18.1", "@datapunt/asc-core": "^0.18.1", @@ -126,7 +126,7 @@ "@babel/plugin-transform-modules-commonjs": "^7.9.0", "@babel/plugin-transform-react-constant-elements": "^7.9.0", "@babel/plugin-transform-react-inline-elements": "^7.9.0", - "@babel/preset-env": "^7.9.0", + "@babel/preset-env": "^7.9.5", "@babel/preset-react": "^7.9.4", "@babel/register": "^7.9.0", "@redux-saga/is": "^1.1.2", @@ -148,9 +148,9 @@ "circular-dependency-plugin": "^5.2.0", "compression-webpack-plugin": "^3.1.0", "copy-webpack-plugin": "^5.1.1", - "core-js": "^3.6.4", + "core-js": "^3.6.5", "cross-env": "^6.0.3", - "css-loader": "^3.5.0", + "css-loader": "^3.5.2", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.2", "enzyme-to-json": "^3.4.4", @@ -161,7 +161,7 @@ "eslint-import-resolver-webpack": "^0.12.1", "eslint-plugin-import": "^2.20.2", "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-prettier": "^3.1.2", + "eslint-plugin-prettier": "^3.1.3", "eslint-plugin-react": "^7.19.0", "eslint-plugin-react-hooks": "^2.5.1", "eslint-plugin-redux-saga": "^1.1.3", @@ -210,7 +210,7 @@ "url-polyfill": "^1.1.8", "uuid": "^3.4.0", "webpack": "^4.42.1", - "webpack-bundle-analyzer": "^3.6.1", + "webpack-bundle-analyzer": "^3.7.0", "webpack-cli": "^3.3.11", "webpack-dev-middleware": "^3.7.2", "webpack-hot-middleware": "^2.25.0", From 3778f9dd6d5cd05231bc0f12ca3b079323d3825c Mon Sep 17 00:00:00 2001 From: Boris Arkenaar Date: Tue, 14 Apr 2020 10:05:07 +0200 Subject: [PATCH 08/80] Remove and re-add leaflet-headless --- package-lock.json | 265 +++++++++++++--------------------------------- 1 file changed, 72 insertions(+), 193 deletions(-) diff --git a/package-lock.json b/package-lock.json index f97eb66b35..992c9ae873 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6888,9 +6888,9 @@ } }, "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, "assign-symbols": { @@ -6955,9 +6955,9 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" }, "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true }, "aws4": { @@ -7929,15 +7929,6 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.x.x" - } - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -8393,9 +8384,9 @@ } }, "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, "caw": { @@ -9454,15 +9445,6 @@ "which": "^1.2.9" } }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "requires": { - "boom": "2.x.x" - } - }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -12806,13 +12788,13 @@ "dev": true }, "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } }, @@ -13582,24 +13564,6 @@ "globule": "^1.0.0" } }, - "generate-function": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", - "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "dev": true, - "requires": { - "is-property": "^1.0.2" - } - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "^1.0.0" - } - }, "gensync": { "version": "1.0.0-beta.1", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", @@ -13935,42 +13899,13 @@ "dev": true }, "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", "dev": true, "requires": { - "chalk": "^1.1.1", - "commander": "^2.9.0", - "is-my-json-valid": "^2.12.4", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } + "ajv": "^6.5.5", + "har-schema": "^2.0.0" } }, "hard-prop": { @@ -14080,18 +14015,6 @@ "minimalistic-assert": "^1.0.1" } }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" - } - }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -14138,12 +14061,6 @@ "minimalistic-crypto-utils": "^1.0.1" } }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, "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", @@ -14419,12 +14336,12 @@ } }, "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { - "assert-plus": "^0.2.0", + "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" } @@ -15615,25 +15532,6 @@ "lower-case": "^1.1.0" } }, - "is-my-ip-valid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", - "dev": true - }, - "is-my-json-valid": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.0.tgz", - "integrity": "sha512-XTHBZSIIxNsIsZXg7XB5l8z/OBFosl1Wao4tXLpeC7eKU4Vm/kdop2azkPqULwnfGQjmeDIyey9g7afMMtdWAA==", - "dev": true, - "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" - } - }, "is-natural-number": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", @@ -15726,12 +15624,6 @@ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", @@ -17192,12 +17084,6 @@ "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", "dev": true }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true - }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -17344,11 +17230,6 @@ "acorn": "^2.1.0" } }, - "core-js": { - "version": "2.6.10", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.10.tgz", - "integrity": "sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==" - }, "cssstyle": { "version": "0.2.37", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", @@ -17358,14 +17239,6 @@ "cssom": "0.3.x" } }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, "jsdom": { "version": "9.8.3", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-9.8.3.tgz", @@ -23101,9 +22974,9 @@ "dev": true }, "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, "object-assign": { @@ -24893,9 +24766,9 @@ "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=" }, "qs": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", - "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, "query-string": { @@ -25653,31 +25526,49 @@ "dev": true }, "request": { - "version": "2.79.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", - "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "dev": true, "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "caseless": "~0.11.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", + "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.1.1", - "har-validator": "~2.0.6", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", + "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.7", - "oauth-sign": "~0.8.1", - "qs": "~6.3.0", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "~0.4.1", - "uuid": "^3.0.0" + "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" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } } }, "request-promise-core": { @@ -26640,15 +26531,6 @@ } } }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "requires": { - "hoek": "2.x.x" - } - }, "sort-keys": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", @@ -27183,12 +27065,6 @@ "is-regexp": "^1.0.0" } }, - "stringstream": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz", - "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==", - "dev": true - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -28001,10 +27877,13 @@ "dev": true }, "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } }, "tweetnacl": { "version": "0.14.5", From c1a95b6342d98885fc72354f752fac1abafcb3d7 Mon Sep 17 00:00:00 2001 From: Boris Arkenaar Date: Tue, 14 Apr 2020 10:35:03 +0200 Subject: [PATCH 09/80] Run npm remove build --- package-lock.json | 250 ++++------------------------------------------ package.json | 1 - 2 files changed, 17 insertions(+), 234 deletions(-) diff --git a/package-lock.json b/package-lock.json index 992c9ae873..e188e407cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6917,14 +6917,6 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "requires": { - "lodash": "^4.17.14" - } - }, "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", @@ -8147,30 +8139,6 @@ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", "dev": true }, - "build": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/build/-/build-0.1.4.tgz", - "integrity": "sha1-cH/gJv/O3crL/c3zVur9pk8VEEY=", - "requires": { - "cssmin": "0.3.x", - "jsmin": "1.x", - "jxLoader": "*", - "moo-server": "*", - "promised-io": "*", - "timespan": "2.x", - "uglify-js": "1.x", - "walker": "1.x", - "winston": "*", - "wrench": "1.3.x" - }, - "dependencies": { - "uglify-js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.3.5.tgz", - "integrity": "sha1-S1v/+Rhu/7qoiOTJ6UvZ/EyUkp0=" - } - } - }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", @@ -8780,42 +8748,18 @@ "version": "1.5.3", "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "dev": true, "requires": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, - "colornames": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz", - "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=" - }, "colors": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", "dev": true }, - "colorspace": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", - "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", - "requires": { - "color": "3.0.x", - "text-hex": "1.0.x" - }, - "dependencies": { - "color": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", - "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", - "requires": { - "color-convert": "^1.9.1", - "color-string": "^1.5.2" - } - } - } - }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -9286,7 +9230,8 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true }, "cosmiconfig": { "version": "5.2.1", @@ -9838,11 +9783,6 @@ "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true }, - "cssmin": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/cssmin/-/cssmin-0.3.2.tgz", - "integrity": "sha1-3c5MVHtRCuDVlKjx+/iq+OLFwA0=" - }, "cssnano": { "version": "4.1.10", "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", @@ -10594,16 +10534,6 @@ "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", "dev": true }, - "diagnostics": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz", - "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==", - "requires": { - "colorspace": "1.1.x", - "enabled": "1.0.x", - "kuler": "1.0.x" - } - }, "diff-sequences": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", @@ -10862,14 +10792,6 @@ "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", "dev": true }, - "enabled": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", - "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=", - "requires": { - "env-variable": "0.0.x" - } - }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -10901,11 +10823,6 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" }, - "env-variable": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.6.tgz", - "integrity": "sha512-bHz59NlBbtS0NhftmR8+ExBEekE7br0e01jw+kk0NDro7TtZzBYZ5ScGPs3OmwnpyfHTHOtr1Y6uedCdrIldtg==" - }, "enzyme": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/enzyme/-/enzyme-3.11.0.tgz", @@ -12388,11 +12305,6 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, - "fast-safe-stringify": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", - "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" - }, "fastparse": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", @@ -12427,11 +12339,6 @@ "pend": "~1.2.0" } }, - "fecha": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", - "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" - }, "figgy-pudding": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", @@ -15654,7 +15561,8 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true }, "is-string": { "version": "1.0.5", @@ -17009,11 +16917,6 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" }, - "jsmin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/jsmin/-/jsmin-1.0.1.tgz", - "integrity": "sha1-570NzWSWw79IYyNb9GGj2YqjuYw=" - }, "json-buffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", @@ -17120,24 +17023,6 @@ "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", "dev": true }, - "jxLoader": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jxLoader/-/jxLoader-0.1.1.tgz", - "integrity": "sha1-ATTqUUTlM7WU/B/yX/GU4jXFPs0=", - "requires": { - "js-yaml": "0.3.x", - "moo-server": "1.3.x", - "promised-io": "*", - "walker": "1.x" - }, - "dependencies": { - "js-yaml": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-0.3.7.tgz", - "integrity": "sha1-1znY7oZGHlSzVNan19HyrZoWf2I=" - } - } - }, "keyv": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", @@ -17160,14 +17045,6 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, - "kuler": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", - "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==", - "requires": { - "colornames": "^1.1.1" - } - }, "last-call-webpack-plugin": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", @@ -18085,30 +17962,6 @@ "squeak": "^1.0.0" } }, - "logform": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz", - "integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==", - "requires": { - "colors": "^1.2.1", - "fast-safe-stringify": "^2.0.4", - "fecha": "^2.3.3", - "ms": "^2.1.1", - "triple-beam": "^1.3.0" - }, - "dependencies": { - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -18193,6 +18046,7 @@ "version": "1.0.11", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, "requires": { "tmpl": "1.0.x" } @@ -18795,11 +18649,6 @@ "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.1.tgz", "integrity": "sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w==" }, - "moo-server": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/moo-server/-/moo-server-1.3.0.tgz", - "integrity": "sha1-XceVaVZaENbv7VQ5SR5p0jkuWPE=" - }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -23228,11 +23077,6 @@ "wrappy": "1" } }, - "one-time": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", - "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=" - }, "onetime": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", @@ -24599,7 +24443,8 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true }, "progress": { "version": "2.0.3", @@ -24636,11 +24481,6 @@ "integrity": "sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==", "dev": true }, - "promised-io": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/promised-io/-/promised-io-0.3.5.tgz", - "integrity": "sha1-StIXuzZYvKrplGsXqGaOzYUeE1Y=" - }, "prompts": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.2.1.tgz", @@ -25122,6 +24962,7 @@ "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -25135,7 +24976,8 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true } } }, @@ -26381,6 +26223,7 @@ "version": "0.2.2", "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dev": true, "requires": { "is-arrayish": "^0.3.1" }, @@ -26388,7 +26231,8 @@ "is-arrayish": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true } } }, @@ -26734,11 +26578,6 @@ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==" }, - "stack-trace": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" - }, "stack-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", @@ -27616,11 +27455,6 @@ } } }, - "text-hex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", - "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -27665,11 +27499,6 @@ "setimmediate": "^1.0.4" } }, - "timespan": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", - "integrity": "sha1-SQLOBAvRPYRcj1myfp1ZutbzmSk=" - }, "timm": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/timm/-/timm-1.6.2.tgz", @@ -27720,7 +27549,8 @@ "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true }, "to-arraybuffer": { "version": "1.0.1", @@ -27845,11 +27675,6 @@ "escape-string-regexp": "^1.0.2" } }, - "triple-beam": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", - "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" - }, "true-case-path": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", @@ -28380,6 +28205,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, "requires": { "makeerror": "1.0.x" } @@ -29069,43 +28895,6 @@ "string-width": "^1.0.2 || 2" } }, - "winston": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz", - "integrity": "sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==", - "requires": { - "async": "^2.6.1", - "diagnostics": "^1.1.1", - "is-stream": "^1.1.0", - "logform": "^2.1.1", - "one-time": "0.0.4", - "readable-stream": "^3.1.1", - "stack-trace": "0.0.x", - "triple-beam": "^1.3.0", - "winston-transport": "^4.3.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "winston-transport": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz", - "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==", - "requires": { - "readable-stream": "^2.3.6", - "triple-beam": "^1.2.0" - } - }, "wkt-parser": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/wkt-parser/-/wkt-parser-1.2.4.tgz", @@ -29147,11 +28936,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, - "wrench": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/wrench/-/wrench-1.3.9.tgz", - "integrity": "sha1-bxPsNRRTF+spLKX2UxORskQRFBE=" - }, "write": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", diff --git a/package.json b/package.json index 7351fab638..009936915c 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,6 @@ "@datapunt/react-maps": "^0.8.0", "@sentry/browser": "^5.15.4", "abortcontroller-polyfill": "^1.4.0", - "build": "^0.1.4", "classnames": "^2.2.6", "compression": "^1.7.3", "connected-react-router": "^6.8.0", From 07d60e37b94afe49c16c05423098e1b629e0ca5a Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Wed, 15 Apr 2020 08:11:52 +0200 Subject: [PATCH 10/80] Adds test --- .../Detail/__tests__/Detail.test.js | 78 +++++++++---------- .../settings/categories/Detail/index.js | 26 ++----- 2 files changed, 46 insertions(+), 58 deletions(-) diff --git a/src/signals/settings/categories/Detail/__tests__/Detail.test.js b/src/signals/settings/categories/Detail/__tests__/Detail.test.js index f34b0db34b..cb82789048 100644 --- a/src/signals/settings/categories/Detail/__tests__/Detail.test.js +++ b/src/signals/settings/categories/Detail/__tests__/Detail.test.js @@ -32,9 +32,7 @@ jest.mock('models/categories/actions', () => ({ jest.mock('../../../hooks/useConfirmedCancel'); const userCan = jest.fn(() => () => true); -jest - .spyOn(appSelectors, 'makeSelectUserCan') - .mockImplementation(userCan); +jest.spyOn(appSelectors, 'makeSelectUserCan').mockImplementation(userCan); const dispatch = jest.fn(); jest.spyOn(reactRedux, 'useDispatch').mockImplementation(() => dispatch); @@ -50,14 +48,8 @@ useConfirmedCancel.mockImplementation(() => confirmedCancel); describe('signals/settings/categories/Detail', () => { beforeEach(() => { fetch.mockResponses( - [ - JSON.stringify(categoryJSON), - { status: 200 }, - ], - [ - JSON.stringify(historyJSON), - { status: 200 }, - ], + [JSON.stringify(categoryJSON), { status: 200 }], + [JSON.stringify(historyJSON), { status: 200 }] ); dispatch.mockReset(); @@ -74,9 +66,7 @@ describe('signals/settings/categories/Detail', () => { await wait(() => container.querySelector('a')); - expect(container.querySelector('a').getAttribute('href')).toEqual( - routes.categories - ); + expect(container.querySelector('a').getAttribute('href')).toEqual(routes.categories); }); it('should render a backlink with the proper referrer', async () => { @@ -121,11 +111,9 @@ describe('signals/settings/categories/Detail', () => { await wait(() => getByTestId('detailCategoryForm')); expect(getByTestId('detailCategoryForm')).toBeInTheDocument(); - document - .querySelectorAll('input[type="text"], textarea') - .forEach(element => { - expect(element.value).toEqual(''); - }); + document.querySelectorAll('input[type="text"], textarea').forEach(element => { + expect(element.value).toEqual(''); + }); }); it('should render a form for an existing category', async () => { @@ -138,9 +126,7 @@ describe('signals/settings/categories/Detail', () => { await findByTestId('detailCategoryForm'); expect(document.querySelector('#name').value).toEqual(categoryJSON.name); - expect(document.querySelector('#description').value).toEqual( - categoryJSON.description - ); + expect(document.querySelector('#description').value).toEqual(categoryJSON.description); }); it('should call confirmedCancel', async () => { @@ -148,9 +134,7 @@ describe('signals/settings/categories/Detail', () => { categoryId: 456, })); - const { container, getByTestId, findByTestId } = render( - withAppContext() - ); + const { container, getByTestId, findByTestId } = render(withAppContext()); await findByTestId('detailCategoryForm'); @@ -196,14 +180,8 @@ describe('signals/settings/categories/Detail', () => { fetch.resetMocks(); fetch.mockResponses( - [ - JSON.stringify(dataWithNullValue), - { status: 200 }, - ], - [ - JSON.stringify(historyJSON), - { status: 200 }, - ], + [JSON.stringify(dataWithNullValue), { status: 200 }], + [JSON.stringify(historyJSON), { status: 200 }] ); const categoryId = 10101; @@ -211,9 +189,7 @@ describe('signals/settings/categories/Detail', () => { categoryId, })); - const { container, getByTestId, findByTestId } = render( - withAppContext() - ); + const { container, getByTestId, findByTestId } = render(withAppContext()); await findByTestId('detailCategoryForm'); @@ -321,10 +297,34 @@ describe('signals/settings/categories/Detail', () => { await wait(() => getByTestId('detailCategoryForm')); - expect(dispatch).toHaveBeenCalledWith( - showGlobalNotification(expect.any(Object)) - ); + expect(dispatch).toHaveBeenCalledWith(showGlobalNotification(expect.any(Object))); expect(push).toHaveBeenCalledTimes(1); }); + + it('should request history for existing category', async () => { + jest.spyOn(reactRouterDom, 'useParams').mockImplementation(() => ({ + categoryId: undefined, + })); + + const { getByTestId } = render(withAppContext()); + + await wait(() => getByTestId('detailCategoryForm')); + + expect(fetch).not.toHaveBeenLastCalledWith(expect.stringContaining('/history'), expect.any(Object)); + + jest.spyOn(reactRouterDom, 'useParams').mockImplementation(() => ({ + categoryId: 900, + })); + + fetch + .once(JSON.stringify(categoryJSON)) // GET response (category) + .once(JSON.stringify(historyJSON)); // GET response (history) + + render(withAppContext()); + + await wait(() => getByTestId('detailCategoryForm')); + + expect(fetch).toHaveBeenLastCalledWith(expect.stringContaining('/history'), expect.any(Object)); + }); }); diff --git a/src/signals/settings/categories/Detail/index.js b/src/signals/settings/categories/Detail/index.js index 45b725c3d1..eee1127883 100644 --- a/src/signals/settings/categories/Detail/index.js +++ b/src/signals/settings/categories/Detail/index.js @@ -39,10 +39,7 @@ const getTransformedData = formData => { * @param {Object} - Second object to compare against the first object * @returns {Boolean} */ -const isEqual = ( - { description, handling_message, is_active, name, sla }, - othValue -) => +const isEqual = ({ description, handling_message, is_active, name, sla }, othValue) => [ description === othValue.description, handling_message === othValue.handling_message, @@ -70,14 +67,13 @@ const CategoryDetail = () => { const categoryURL = `${configuration.CATEGORIES_PRIVATE_ENDPOINT}${categoryId}`; - const shouldRenderForm = - !isExistingCategory || (isExistingCategory && Boolean(data)); + const shouldRenderForm = !isExistingCategory || (isExistingCategory && Boolean(data)); const userCan = useSelector(makeSelectUserCan); const userCanSubmitForm = - (isExistingCategory && userCan('change_category')) || - (!isExistingCategory && userCan('add_category')); + (isExistingCategory && userCan('change_category')) || (!isExistingCategory && userCan('add_category')); + useFetchResponseNotification({ entityName, @@ -88,9 +84,7 @@ const CategoryDetail = () => { redirectURL, }); - const title = `${entityName} ${ - isExistingCategory ? 'wijzigen' : 'toevoegen' - }`; + const title = `${entityName} ${isExistingCategory ? 'wijzigen' : 'toevoegen'}`; const getFormData = useCallback( event => { @@ -99,10 +93,7 @@ const CategoryDetail = () => { .map(([key, val]) => [key, key === 'is_active' ? val === 'true' : val]) // convert line endings // by spec, the HTML value should contain \r\n, but the API only contains \n - .map(([key, val]) => [ - key, - typeof val === 'string' ? val.replace(/\r\n/g, '\n') : val, - ]) + .map(([key, val]) => [key, typeof val === 'string' ? val.replace(/\r\n/g, '\n') : val]) // reduce the entries() array to an object, merging it with the initial data .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), { ...data }); @@ -163,10 +154,7 @@ const CategoryDetail = () => { return ( - Terug naar overzicht} - /> + Terug naar overzicht} /> {isLoading && } From 934bd4d6c65784770f69c17aa1b69e5119ee0d78 Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Wed, 15 Apr 2020 08:15:33 +0200 Subject: [PATCH 11/80] Unifies mock once --- .../settings/categories/Detail/__tests__/Detail.test.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/signals/settings/categories/Detail/__tests__/Detail.test.js b/src/signals/settings/categories/Detail/__tests__/Detail.test.js index cb82789048..3088b27457 100644 --- a/src/signals/settings/categories/Detail/__tests__/Detail.test.js +++ b/src/signals/settings/categories/Detail/__tests__/Detail.test.js @@ -47,10 +47,7 @@ useConfirmedCancel.mockImplementation(() => confirmedCancel); describe('signals/settings/categories/Detail', () => { beforeEach(() => { - fetch.mockResponses( - [JSON.stringify(categoryJSON), { status: 200 }], - [JSON.stringify(historyJSON), { status: 200 }] - ); + fetch.once(JSON.stringify(categoryJSON)).once(JSON.stringify(historyJSON)); dispatch.mockReset(); push.mockReset(); From d800e37d01fa3901f2e40fbbee7bf1032cb6199f Mon Sep 17 00:00:00 2001 From: Adrian Tudorache Date: Tue, 14 Apr 2020 17:10:33 +0200 Subject: [PATCH 12/80] zooms back to the incident when navigating from summary --- src/components/MapInput/index.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/MapInput/index.js b/src/components/MapInput/index.js index f4b0901f65..c5ec970375 100644 --- a/src/components/MapInput/index.js +++ b/src/components/MapInput/index.js @@ -12,6 +12,7 @@ import MapContext from 'containers/MapContext/context'; import { setLocationAction, setValuesAction } from 'containers/MapContext/actions'; import useDelayedDoubleClick from 'hooks/useDelayedDoubleClick'; +import isEqual from 'lodash.isequal'; import Map from '../Map'; import PDOKAutoSuggest from '../PDOKAutoSuggest'; import reverseGeocoderService, { getStadsdeel } from './services/reverseGeocoderService'; @@ -115,10 +116,18 @@ const MapInput = ({ className, value, onChange, mapOptions, ...otherProps }) => }, [marker, location, hasLocation]); useEffect(() => { - if (!value?.geometrie?.coordinates && !value?.addressText) return; + if (!map) return; + if (!value?.location && !value?.addressText) return; + + if (value?.location?.lat > 0) { + if (map && !isEqual(value?.location, state.location)) { + const currentZoom = map.getZoom(); + map.flyTo(value?.location, currentZoom); + } + } dispatch(setValuesAction(value)); - }, [value, dispatch]); + }, [value, dispatch, map, state.location]); return ( From 03e402289e5928beda2b756d85d22c49594ecce6 Mon Sep 17 00:00:00 2001 From: Adrian Tudorache Date: Wed, 15 Apr 2020 10:49:11 +0200 Subject: [PATCH 13/80] uses reference for selections in MapSelect component --- src/components/MapSelect/index.js | 73 +++++++++++++++---------------- 1 file changed, 36 insertions(+), 37 deletions(-) diff --git a/src/components/MapSelect/index.js b/src/components/MapSelect/index.js index 86368295b3..740e63fbfd 100644 --- a/src/components/MapSelect/index.js +++ b/src/components/MapSelect/index.js @@ -38,7 +38,7 @@ const MapSelect = ({ const zoomMin = 13; const featuresLayer = useRef(); const [mapInstance, setMapInstance] = useState(); - const selection = new MaxSelection(SELECTION_MAX_COUNT, value); + const selection = useRef(new MaxSelection(SELECTION_MAX_COUNT, value)); const mapOptions = { ...MAP_OPTIONS, center: [latlng.latitude, latlng.longitude], @@ -66,59 +66,58 @@ const MapSelect = ({ ); const bboxGeoJsonLayer = useMemo( - () => - BboxGeojsonLayer( - { - fetchRequest, - }, - { - zoomMin, + () => BboxGeojsonLayer( + { + fetchRequest, + }, + { + zoomMin, - zoomMax: 15, + zoomMax: 15, - /** + /** * Function that will be used to decide whether to include a feature or not. The default is to include all * features. * * Note that this behaviour is difficult to test, hence the istanbul ignore */ - filter: /* istanbul ignore next */ feature => - selectionOnly ? selection.has(feature.properties[idField]) : true, + filter: /* istanbul ignore next */ feature => + selectionOnly ? selection.current.has(feature.properties[idField]) : true, - /** + /** * Function defining how GeoJSON points spawn Leaflet layers. It is internally called when data is added, * passing the GeoJSON point feature and its LatLng. * Return value overridden to have it return a marker with a specific icon * * Note that this behaviour is difficult to test, hence the istanbul ignore */ - pointToLayer: /* istanbul ignore next */ (feature, latlong) => - L.marker(latlong, { - icon: getIcon(feature.properties[iconField], selection.has(feature.properties[idField])), - }), + pointToLayer: /* istanbul ignore next */ (feature, latlong) => + L.marker(latlong, { + icon: getIcon(feature.properties[iconField], selection.current.has(feature.properties[idField])), + }), - /** + /** * Function called once for each created Feature, after it has been created and styled. * Attaches click handler to markers that are rendered on the map * * Note that this behaviour is difficult to test, hence the istanbul ignore */ - onEachFeature: /* istanbul ignore next */ (feature, layer) => { - if (onSelectionChange) { - // Check that the component is in write mode - layer.on({ - click: e => { - const _layer = e.target; - const id = _layer.feature.properties[idField]; - selection.toggle(id); - - onSelectionChange(selection); - }, - }); - } - }, - } - ), + onEachFeature: /* istanbul ignore next */ (feature, layer) => { + if (onSelectionChange) { + // Check that the component is in write mode + layer.on({ + click: e => { + const _layer = e.target; + const id = _layer.feature.properties[idField]; + selection.current.toggle(id); + + onSelectionChange(selection.current); + }, + }); + } + }, + } + ), [fetchRequest, getIcon, iconField, idField, onSelectionChange, selection, selectionOnly] ); @@ -187,10 +186,10 @@ const MapSelect = ({ /* istanbul ignore next */ () => { if (!featuresLayer.current) return; - selection.set.clear(); + selection.current.set.clear(); for (const id of value) { - selection.add(id); + selection.current.add(id); } // Let icons reflect new selection @@ -198,7 +197,7 @@ const MapSelect = ({ const properties = layer.feature.properties; const id = properties[idField]; const iconType = properties[iconField]; - const icon = getIcon(iconType, selection.has(id)); + const icon = getIcon(iconType, selection.current.has(id)); layer.setIcon(icon); }); From 3fe98897419fabc3e933196607f90e3139a91083 Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Wed, 15 Apr 2020 11:51:36 +0200 Subject: [PATCH 14/80] (Chore) Exception message assignment --- src/hooks/useFetch.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/hooks/useFetch.js b/src/hooks/useFetch.js index 3442d19f7b..d6c3c853ef 100644 --- a/src/hooks/useFetch.js +++ b/src/hooks/useFetch.js @@ -70,9 +70,13 @@ export default () => { } setData(responseData); - } catch (e) { - e.message = getErrorMessage(e); - setError(e); + } catch (exception) { + Object.defineProperty(exception, 'message', { + value: getErrorMessage(exception), + writable: false, + }); + + setError(exception); } finally { setLoading(false); } @@ -105,10 +109,13 @@ export default () => { setData(responseData); setSuccess(true); - } catch (e) { - e.message = getErrorMessage(e); + } catch (exception) { + Object.defineProperty(exception, 'message', { + value: getErrorMessage(exception), + writable: false, + }); - setError(e); + setError(exception); setSuccess(false); } finally { setLoading(false); From c04c5c116b6f9c139863f9697c3df1f817c55b90 Mon Sep 17 00:00:00 2001 From: Adrian Tudorache Date: Wed, 15 Apr 2020 11:54:40 +0200 Subject: [PATCH 15/80] fixes unittests --- src/components/MapInput/__tests__/MapInput.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/MapInput/__tests__/MapInput.test.js b/src/components/MapInput/__tests__/MapInput.test.js index 984b5ca27d..c1fc1cafe8 100644 --- a/src/components/MapInput/__tests__/MapInput.test.js +++ b/src/components/MapInput/__tests__/MapInput.test.js @@ -87,9 +87,9 @@ describe('components/MapInput', () => { }); const testLocation = { - geometrie: { - type: 'Point', - coordinates: [4, 52], + location: { + lat: 52.374386493456036, + lng: 4.908941378935603, }, }; From 9a2acc3f0e847766cf868bdb565b8f2051d96903 Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Wed, 15 Apr 2020 13:23:19 +0200 Subject: [PATCH 16/80] [SIG-2540] Remove marker on input clear --- .../AutoSuggest/__tests__/AutoSuggest.test.js | 37 +++++++++++++--- src/components/AutoSuggest/index.js | 22 ++++++++-- .../MapInput/__tests__/MapInput.test.js | 44 +++++++++++++++++-- src/components/MapInput/index.js | 11 +++-- src/test/utils.js | 2 + 5 files changed, 102 insertions(+), 14 deletions(-) diff --git a/src/components/AutoSuggest/__tests__/AutoSuggest.test.js b/src/components/AutoSuggest/__tests__/AutoSuggest.test.js index 7150b42174..230a88bf25 100644 --- a/src/components/AutoSuggest/__tests__/AutoSuggest.test.js +++ b/src/components/AutoSuggest/__tests__/AutoSuggest.test.js @@ -1,6 +1,6 @@ import React, { Fragment } from 'react'; import { render, fireEvent, wait, act } from '@testing-library/react'; -import { withAppContext } from 'test/utils'; +import { withAppContext, resolveAfterMs } from 'test/utils'; import AutoSuggest, { INPUT_DELAY } from '..'; import JSONResponse from './mockResponse.json'; @@ -19,8 +19,6 @@ const props = { url, }; -const resolveAfterMs = timeMs => new Promise(resolve => setTimeout(resolve, timeMs)); - describe('src/components/AutoSuggest', () => { beforeEach(() => { fetch.mockResponse(mockResponse); @@ -217,7 +215,10 @@ describe('src/components/AutoSuggest', () => { }); test('Esc', async () => { - const { container, findByTestId, queryByTestId } = render(withAppContext()); + const onClear = jest.fn(); + const { container, findByTestId, queryByTestId } = render( + withAppContext() + ); const input = container.querySelector('input'); input.focus(); @@ -234,11 +235,13 @@ describe('src/components/AutoSuggest', () => { }); expect(document.activeElement).toEqual(firstElement); + expect(onClear).not.toHaveBeenCalled(); act(() => { fireEvent.keyDown(input, { key: 'Escape', code: 13, keyCode: 13 }); }); + expect(onClear).toHaveBeenCalled(); expect(input.value).toEqual(''); expect(document.activeElement).toEqual(input); expect(queryByTestId('suggestList')).not.toBeInTheDocument(); @@ -365,7 +368,7 @@ describe('src/components/AutoSuggest', () => { expect(suggestList).not.toBeInTheDocument(); }); - test('Any key (yes, such a key exists)', async() => { + test('Any key (yes, such a key exists)', async () => { const { container, findByTestId } = render(withAppContext()); const input = container.querySelector('input'); @@ -425,4 +428,28 @@ describe('src/components/AutoSuggest', () => { expect(onSelect).toHaveBeenCalledTimes(1); expect(onSelect).toHaveBeenCalledWith(firstOption); }); + + it('should call onClear', async () => { + const onClear = jest.fn(); + const { container } = render( + withAppContext() + ); + const input = container.querySelector('input'); + + act(() => { + fireEvent.change(input, { target: { value: 'Rembrandt' } }); + }); + + await wait(() => resolveAfterMs(INPUT_DELAY)); + + expect(onClear).not.toHaveBeenCalled(); + + act(() => { + fireEvent.change(input, { target: { value: '' } }); + }); + + await wait(() => resolveAfterMs(INPUT_DELAY)); + + expect(onClear).toHaveBeenCalled(); + }); }); diff --git a/src/components/AutoSuggest/index.js b/src/components/AutoSuggest/index.js index 0bed9880f0..5e5e019cab 100644 --- a/src/components/AutoSuggest/index.js +++ b/src/components/AutoSuggest/index.js @@ -33,7 +33,16 @@ const AbsoluteList = styled(SuggestList)` * - Home key focuses the input field at the first character * - End key focuses the input field at the last character */ -const AutoSuggest = ({ className, formatResponse, numOptionsDeterminer, onSelect, placeholder, url, value }) => { +const AutoSuggest = ({ + className, + formatResponse, + numOptionsDeterminer, + onClear, + onSelect, + placeholder, + url, + value, +}) => { const { get, data } = useFetch(); const [initialRender, setInitialRender] = useState(false); const [showList, setShowList] = useState(false); @@ -80,6 +89,7 @@ const AutoSuggest = ({ className, formatResponse, numOptionsDeterminer, onSelect inputRef.current.value = ''; setActiveIndex(-1); setShowList(false); + onClear(); break; case 'Home': @@ -103,7 +113,7 @@ const AutoSuggest = ({ className, formatResponse, numOptionsDeterminer, onSelect break; } }, - [data, numOptionsDeterminer, showList] + [data, numOptionsDeterminer, showList, onClear] ); useEffect(() => { @@ -174,9 +184,13 @@ const AutoSuggest = ({ className, formatResponse, numOptionsDeterminer, onSelect get(`${url}${encodeURIComponent(inputValue)}`); } else { setShowList(false); + + if (inputValue.length === 0) { + onClear(); + } } }, - [get, url] + [get, onClear, url] ); const onSelectOption = useCallback( @@ -242,6 +256,8 @@ AutoSuggest.propTypes = { * @return {Number} The amount of options returned from the request */ numOptionsDeterminer: PropTypes.func.isRequired, + /** Callback function that is called whenever the input field */ + onClear: PropTypes.func, /** * Option select callback * @param {Object} option - The selected option diff --git a/src/components/MapInput/__tests__/MapInput.test.js b/src/components/MapInput/__tests__/MapInput.test.js index 18d997ecad..1bb4467c14 100644 --- a/src/components/MapInput/__tests__/MapInput.test.js +++ b/src/components/MapInput/__tests__/MapInput.test.js @@ -1,9 +1,10 @@ import React from 'react'; -import { render, fireEvent, act } from '@testing-library/react'; +import { render, fireEvent, act, wait } from '@testing-library/react'; + import MapContext from 'containers/MapContext'; import context from 'containers/MapContext/context'; - -import { withAppContext } from 'test/utils'; +import { INPUT_DELAY } from 'components/AutoSuggest'; +import { withAppContext, resolveAfterMs } from 'test/utils'; import MAP_OPTIONS from 'shared/services/configuration/map-options'; import { markerIcon } from 'shared/services/configuration/map-markers'; import * as actions from 'containers/MapContext/actions'; @@ -225,4 +226,41 @@ describe('components/MapInput', () => { expect(container.querySelector(`.${markerIcon.options.className}`)).toBeInTheDocument(); }); + + it.only('should clear location and not render marker', async () => { + const location = { + lat: 52.36058599633851, + lng: 4.894292258032637, + }; + const addressText = 'Foo bar street 10'; + + const { findByTestId } = render( + withAppContext( + {} }}> + + + ) + ); + + const autoSuggest = await findByTestId('autoSuggest'); + const input = autoSuggest.querySelector('input'); + + expect(setLocationSpy).not.toHaveBeenCalled(); + + act(() => { + fireEvent.change(input, { target: { value: addressText } }); + }); + + await wait(() => resolveAfterMs(INPUT_DELAY)); + + expect(setLocationSpy).not.toHaveBeenCalled(); + + act(() => { + fireEvent.change(input, { target: { value: '' } }); + }); + + await wait(() => resolveAfterMs(INPUT_DELAY)); + + expect(setLocationSpy).toHaveBeenCalledWith(); + }); }); diff --git a/src/components/MapInput/index.js b/src/components/MapInput/index.js index 966cfdc868..1e0050f848 100644 --- a/src/components/MapInput/index.js +++ b/src/components/MapInput/index.js @@ -111,6 +111,10 @@ const MapInput = ({ className, value, onChange, mapOptions, ...otherProps }) => [map, dispatch, onChange] ); + const onClear = useCallback(() => { + dispatch(setLocationAction()); + }, [dispatch]); + useEffect(() => { if (!marker || !hasLocation) return; @@ -131,11 +135,12 @@ const MapInput = ({ className, value, onChange, mapOptions, ...otherProps }) => } /> diff --git a/src/test/utils.js b/src/test/utils.js index 0bef3be724..e9b404df15 100644 --- a/src/test/utils.js +++ b/src/test/utils.js @@ -104,3 +104,5 @@ export const userObjects = (users = usersJSON) => return obj; }, {}) ); + +export const resolveAfterMs = timeMs => new Promise(resolve => setTimeout(resolve, timeMs)); From a51f6634c1aa1ae5bc01c4e3bd9d866362be73e0 Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Wed, 15 Apr 2020 14:04:28 +0200 Subject: [PATCH 17/80] [SIG-2549] Remove translations --- Dockerfile | 4 - internals/generators/ams-component/index.js | 15 -- .../generators/ams-component/messages.js.hbs | 8 - .../generators/ams-component/stateless.js.hbs | 8 - .../generators/ams-container/class.js.hbs | 9 - internals/generators/ams-container/index.js | 15 -- .../generators/ams-container/index.js.hbs | 9 - .../generators/ams-container/messages.js.hbs | 8 - .../generators/ams-container/stateless.js.hbs | 9 - internals/generators/component/class.js.hbs | 7 - internals/generators/component/index.js | 15 -- .../generators/component/messages.js.hbs | 13 -- .../generators/component/stateless.js.hbs | 8 - internals/generators/container/class.js.hbs | 9 - internals/generators/container/index.js | 15 -- internals/generators/container/index.js.hbs | 9 - .../generators/container/messages.js.hbs | 13 -- .../generators/container/stateless.js.hbs | 9 - internals/generators/index.js | 6 - .../generators/language/add-locale-data.hbs | 1 - internals/generators/language/app-locale.hbs | 1 - .../language/format-translation-messages.hbs | 1 - internals/generators/language/index.js | 91 ---------- .../generators/language/intl-locale-data.hbs | 1 - .../language/polyfill-intl-locale.hbs | 1 - .../language/translation-messages.hbs | 1 - .../generators/language/translations-json.hbs | 1 - internals/scripts/extract-intl.js | 160 ------------------ .../scripts/generate-templates-for-linting.js | 13 +- package-lock.json | 89 ---------- package.json | 4 - src/app.js | 55 +----- src/containers/LanguageProvider/actions.js | 16 -- .../LanguageProvider/actions.test.js | 19 --- src/containers/LanguageProvider/constants.js | 7 - src/containers/LanguageProvider/index.js | 38 ----- src/containers/LanguageProvider/index.test.js | 39 ----- src/containers/LanguageProvider/reducer.js | 30 ---- .../LanguageProvider/reducer.test.js | 18 -- src/containers/LanguageProvider/selectors.js | 20 --- .../LanguageProvider/selectors.test.js | 15 -- src/hooks/useFetch.js | 19 ++- src/i18n.js | 39 ----- src/i18n.test.js | 32 ---- src/reducers.js | 2 - .../__tests__/FilterTagList.test.js | 18 +- src/test/utils.js | 12 -- src/translations/en.json | 13 -- src/translations/nl.json | 10 -- 49 files changed, 31 insertions(+), 924 deletions(-) delete mode 100644 internals/generators/ams-component/messages.js.hbs delete mode 100644 internals/generators/ams-container/messages.js.hbs delete mode 100644 internals/generators/component/messages.js.hbs delete mode 100644 internals/generators/container/messages.js.hbs delete mode 100644 internals/generators/language/add-locale-data.hbs delete mode 100644 internals/generators/language/app-locale.hbs delete mode 100644 internals/generators/language/format-translation-messages.hbs delete mode 100644 internals/generators/language/index.js delete mode 100644 internals/generators/language/intl-locale-data.hbs delete mode 100644 internals/generators/language/polyfill-intl-locale.hbs delete mode 100644 internals/generators/language/translation-messages.hbs delete mode 100644 internals/generators/language/translations-json.hbs delete mode 100644 internals/scripts/extract-intl.js delete mode 100644 src/containers/LanguageProvider/actions.js delete mode 100644 src/containers/LanguageProvider/actions.test.js delete mode 100644 src/containers/LanguageProvider/constants.js delete mode 100644 src/containers/LanguageProvider/index.js delete mode 100644 src/containers/LanguageProvider/index.test.js delete mode 100644 src/containers/LanguageProvider/reducer.js delete mode 100644 src/containers/LanguageProvider/reducer.test.js delete mode 100644 src/containers/LanguageProvider/selectors.js delete mode 100644 src/containers/LanguageProvider/selectors.test.js delete mode 100644 src/i18n.js delete mode 100644 src/i18n.test.js delete mode 100644 src/translations/en.json delete mode 100644 src/translations/nl.json diff --git a/Dockerfile b/Dockerfile index c7ee035872..6a043de0db 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,10 +25,6 @@ COPY .gitignore \ babel.config.js \ /app/ -# Install language packs -RUN npm install --unsafe-perm -g full-icu -ENV NODE_ICU_DATA="/usr/local/lib/node_modules/full-icu" - COPY package.json \ package-lock.json \ /app/ diff --git a/internals/generators/ams-component/index.js b/internals/generators/ams-component/index.js index 41c2f84b38..00f602781e 100644 --- a/internals/generators/ams-component/index.js +++ b/internals/generators/ams-component/index.js @@ -28,11 +28,6 @@ module.exports = { return 'The name is required'; }, - }, { - type: 'confirm', - name: 'wantMessages', - default: false, - message: 'Do you want i18n messages (i.e. will this component use text)?', }, { type: 'confirm', name: 'wantLoadable', @@ -63,16 +58,6 @@ module.exports = { abortOnFail: true, }]; - // If they want a i18n messages file - if (data.wantMessages) { - actions.push({ - type: 'add', - path: '../../src/components/{{properCase name}}/messages.js', - templateFile: './ams-component/messages.js.hbs', - abortOnFail: true, - }); - } - actions.push({ type: 'add', path: '../../src/components/{{properCase name}}/style.scss', diff --git a/internals/generators/ams-component/messages.js.hbs b/internals/generators/ams-component/messages.js.hbs deleted file mode 100644 index 62f50d479a..0000000000 --- a/internals/generators/ams-component/messages.js.hbs +++ /dev/null @@ -1,8 +0,0 @@ -import { defineMessages } from 'react-intl'; - -export default defineMessages({ - header: { - id: 'app.components.{{ properCase name }}.header', - defaultMessage: 'This is the {{ properCase name}} component !', - }, -}); diff --git a/internals/generators/ams-component/stateless.js.hbs b/internals/generators/ams-component/stateless.js.hbs index 6fc8334f0e..cda4752442 100644 --- a/internals/generators/ams-component/stateless.js.hbs +++ b/internals/generators/ams-component/stateless.js.hbs @@ -1,18 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; -{{#if wantMessages}} -import { FormattedMessage } from 'react-intl'; -import messages from './messages'; -{{/if}} - import './style.scss'; const {{ properCase name }} = () => (
- {{#if wantMessages}} - - {{/if}}
); diff --git a/internals/generators/ams-container/class.js.hbs b/internals/generators/ams-container/class.js.hbs index de9e742359..a42c65e64e 100644 --- a/internals/generators/ams-container/class.js.hbs +++ b/internals/generators/ams-container/class.js.hbs @@ -4,9 +4,6 @@ import { connect } from 'react-redux'; {{#if wantHeaders}} import { Helmet } from 'react-helmet'; {{/if}} -{{#if wantMessages}} -import { FormattedMessage } from 'react-intl'; -{{/if}} {{#if wantActionsAndReducer}} import { createStructuredSelector } from 'reselect'; {{/if}} @@ -23,9 +20,6 @@ import reducer from './reducer'; {{#if wantSaga}} import saga from './saga'; {{/if}} -{{#if wantMessages}} -import messages from './messages'; -{{/if}} import './style.scss'; @@ -39,9 +33,6 @@ export class {{ properCase name }} extends {{{ type }}} { // eslint-disable-line {{/if}} - {{#if wantMessages}} - - {{/if}} ); } diff --git a/internals/generators/ams-container/index.js b/internals/generators/ams-container/index.js index 09330efe0a..38d4186d3e 100644 --- a/internals/generators/ams-container/index.js +++ b/internals/generators/ams-container/index.js @@ -39,11 +39,6 @@ module.exports = { name: 'wantSaga', default: true, message: 'Do you want sagas for asynchronous flows? (e.g. fetching data)', - }, { - type: 'confirm', - name: 'wantMessages', - default: false, - message: 'Do you want i18n messages (i.e. will this component use text)?', }], actions: data => { // Generate index.js and index.test.js @@ -69,16 +64,6 @@ module.exports = { abortOnFail: true, }]; - // If component wants messages - if (data.wantMessages) { - actions.push({ - type: 'add', - path: '../../src/containers/{{properCase name}}/messages.js', - templateFile: './ams-container/messages.js.hbs', - abortOnFail: true, - }); - } - // If they want actions and a reducer, generate actions.js, constants.js, // reducer.js and the corresponding tests for actions and the reducer if (data.wantActionsAndReducer) { diff --git a/internals/generators/ams-container/index.js.hbs b/internals/generators/ams-container/index.js.hbs index 4d2dd638a2..1ddd5cc6f7 100644 --- a/internals/generators/ams-container/index.js.hbs +++ b/internals/generators/ams-container/index.js.hbs @@ -4,16 +4,10 @@ import { connect } from 'react-redux'; {{#if wantHeaders}} import { Helmet } from 'react-helmet'; {{/if}} -{{#if wantMessages}} -import { FormattedMessage } from 'react-intl'; -{{/if}} {{#if wantActionsAndReducer}} import { createStructuredSelector } from 'reselect'; import makeSelect{{properCase name}} from './selectors'; {{/if}} -{{#if wantMessages}} -import messages from './messages'; -{{/if}} export class {{ properCase name }} extends React.{{{ component }}} { // eslint-disable-line react/prefer-stateless-function render() { @@ -25,9 +19,6 @@ export class {{ properCase name }} extends React.{{{ component }}} { // eslint-d {{/if}} - {{#if wantMessages}} - - {{/if}} ); } diff --git a/internals/generators/ams-container/messages.js.hbs b/internals/generators/ams-container/messages.js.hbs deleted file mode 100644 index e9b73b43c4..0000000000 --- a/internals/generators/ams-container/messages.js.hbs +++ /dev/null @@ -1,8 +0,0 @@ -import { defineMessages } from 'react-intl'; - -export default defineMessages({ - header: { - id: 'app.containers.{{properCase name }}.header', - defaultMessage: 'This is {{properCase name}} container !', - }, -}); diff --git a/internals/generators/ams-container/stateless.js.hbs b/internals/generators/ams-container/stateless.js.hbs index 0f8927159f..6ed50a9610 100644 --- a/internals/generators/ams-container/stateless.js.hbs +++ b/internals/generators/ams-container/stateless.js.hbs @@ -4,9 +4,6 @@ import { connect } from 'react-redux'; {{#if wantHeaders}} import { Helmet } from 'react-helmet'; {{/if}} -{{#if wantMessages}} -import { FormattedMessage } from 'react-intl'; -{{/if}} {{#if wantActionsAndReducer}} import { createStructuredSelector } from 'reselect'; {{/if}} @@ -23,9 +20,6 @@ import reducer from './reducer'; {{#if wantSaga}} import saga from './saga'; {{/if}} -{{#if wantMessages}} -import messages from './messages'; -{{/if}} import './style.scss'; const {{ properCase name }} = () => ( @@ -36,9 +30,6 @@ const {{ properCase name }} = () => ( {{/if}} - {{#if wantMessages}} - - {{/if}} ); diff --git a/internals/generators/component/class.js.hbs b/internals/generators/component/class.js.hbs index d68d9b654f..efef2b2791 100644 --- a/internals/generators/component/class.js.hbs +++ b/internals/generators/component/class.js.hbs @@ -7,18 +7,11 @@ import React from 'react'; // import styled from 'styled-components'; -{{#if wantMessages}} -import { FormattedMessage } from 'react-intl'; -import messages from './messages'; -{{/if}} class {{ properCase name }} extends {{{ type }}} { // eslint-disable-line react/prefer-stateless-function render() { return (
- {{#if wantMessages}} - - {{/if}}
); } diff --git a/internals/generators/component/index.js b/internals/generators/component/index.js index 89b5a99789..4670f2904c 100644 --- a/internals/generators/component/index.js +++ b/internals/generators/component/index.js @@ -28,11 +28,6 @@ module.exports = { return 'The name is required'; }, - }, { - type: 'confirm', - name: 'wantMessages', - default: true, - message: 'Do you want i18n messages (i.e. will this component use text)?', }, { type: 'confirm', name: 'wantLoadable', @@ -65,16 +60,6 @@ module.exports = { abortOnFail: true, }]; - // If they want a i18n messages file - if (data.wantMessages) { - actions.push({ - type: 'add', - path: '../../src/components/{{properCase name}}/messages.js', - templateFile: './component/messages.js.hbs', - abortOnFail: true, - }); - } - return actions; }, }; diff --git a/internals/generators/component/messages.js.hbs b/internals/generators/component/messages.js.hbs deleted file mode 100644 index ef317e90bf..0000000000 --- a/internals/generators/component/messages.js.hbs +++ /dev/null @@ -1,13 +0,0 @@ -/* - * {{ properCase name }} Messages - * - * This contains all the text for the {{ properCase name }} component. - */ -import { defineMessages } from 'react-intl'; - -export default defineMessages({ - header: { - id: 'app.components.{{ properCase name }}.header', - defaultMessage: 'This is the {{ properCase name}} component !', - }, -}); diff --git a/internals/generators/component/stateless.js.hbs b/internals/generators/component/stateless.js.hbs index fbf8f7cfec..87614903c8 100644 --- a/internals/generators/component/stateless.js.hbs +++ b/internals/generators/component/stateless.js.hbs @@ -7,17 +7,9 @@ import React from 'react'; // import styled from 'styled-components'; -{{#if wantMessages}} -import { FormattedMessage } from 'react-intl'; -import messages from './messages'; -{{/if}} - function {{ properCase name }}() { return (
- {{#if wantMessages}} - - {{/if}}
); } diff --git a/internals/generators/container/class.js.hbs b/internals/generators/container/class.js.hbs index 367d21883d..be77deab94 100644 --- a/internals/generators/container/class.js.hbs +++ b/internals/generators/container/class.js.hbs @@ -10,9 +10,6 @@ import { connect } from 'react-redux'; {{#if wantHeaders}} import { Helmet } from 'react-helmet'; {{/if}} -{{#if wantMessages}} -import { FormattedMessage } from 'react-intl'; -{{/if}} {{#if wantActionsAndReducer}} import { createStructuredSelector } from 'reselect'; {{/if}} @@ -29,9 +26,6 @@ import reducer from './reducer'; {{#if wantSaga}} import saga from './saga'; {{/if}} -{{#if wantMessages}} -import messages from './messages'; -{{/if}} export class {{ properCase name }} extends {{{ type }}} { // eslint-disable-line react/prefer-stateless-function render() { @@ -43,9 +37,6 @@ export class {{ properCase name }} extends {{{ type }}} { // eslint-disable-line {{/if}} - {{#if wantMessages}} - - {{/if}} ); } diff --git a/internals/generators/container/index.js b/internals/generators/container/index.js index 0b23cd7c9d..1265cf3492 100644 --- a/internals/generators/container/index.js +++ b/internals/generators/container/index.js @@ -39,11 +39,6 @@ module.exports = { name: 'wantSaga', default: true, message: 'Do you want sagas for asynchronous flows? (e.g. fetching data)', - }, { - type: 'confirm', - name: 'wantMessages', - default: true, - message: 'Do you want i18n messages (i.e. will this component use text)?', }, { type: 'confirm', name: 'wantLoadable', @@ -76,16 +71,6 @@ module.exports = { abortOnFail: true, }]; - // If component wants messages - if (data.wantMessages) { - actions.push({ - type: 'add', - path: '../../src/containers/{{properCase name}}/messages.js', - templateFile: './container/messages.js.hbs', - abortOnFail: true, - }); - } - // If they want actions and a reducer, generate actions.js, constants.js, // reducer.js and the corresponding tests for actions and the reducer if (data.wantActionsAndReducer) { diff --git a/internals/generators/container/index.js.hbs b/internals/generators/container/index.js.hbs index bae265bb06..5d79ca6663 100644 --- a/internals/generators/container/index.js.hbs +++ b/internals/generators/container/index.js.hbs @@ -10,16 +10,10 @@ import { connect } from 'react-redux'; {{#if wantHeaders}} import { Helmet } from 'react-helmet'; {{/if}} -{{#if wantMessages}} -import { FormattedMessage } from 'react-intl'; -{{/if}} {{#if wantActionsAndReducer}} import { createStructuredSelector } from 'reselect'; import makeSelect{{properCase name}} from './selectors'; {{/if}} -{{#if wantMessages}} -import messages from './messages'; -{{/if}} export class {{ properCase name }} extends React.{{{ component }}} { // eslint-disable-line react/prefer-stateless-function render() { @@ -31,9 +25,6 @@ export class {{ properCase name }} extends React.{{{ component }}} { // eslint-d {{/if}} - {{#if wantMessages}} - - {{/if}} ); } diff --git a/internals/generators/container/messages.js.hbs b/internals/generators/container/messages.js.hbs deleted file mode 100644 index 32dc1aa3da..0000000000 --- a/internals/generators/container/messages.js.hbs +++ /dev/null @@ -1,13 +0,0 @@ -/* - * {{properCase name }} Messages - * - * This contains all the text for the {{properCase name }} component. - */ -import { defineMessages } from 'react-intl'; - -export default defineMessages({ - header: { - id: 'app.containers.{{properCase name }}.header', - defaultMessage: 'This is {{properCase name}} container !', - }, -}); diff --git a/internals/generators/container/stateless.js.hbs b/internals/generators/container/stateless.js.hbs index 2f7994ad55..f789972086 100644 --- a/internals/generators/container/stateless.js.hbs +++ b/internals/generators/container/stateless.js.hbs @@ -10,9 +10,6 @@ import { connect } from 'react-redux'; {{#if wantHeaders}} import { Helmet } from 'react-helmet'; {{/if}} -{{#if wantMessages}} -import { FormattedMessage } from 'react-intl'; -{{/if}} {{#if wantActionsAndReducer}} import { createStructuredSelector } from 'reselect'; {{/if}} @@ -29,9 +26,6 @@ import reducer from './reducer'; {{#if wantSaga}} import saga from './saga'; {{/if}} -{{#if wantMessages}} -import messages from './messages'; -{{/if}} function {{ properCase name }}() { return ( @@ -42,9 +36,6 @@ function {{ properCase name }}() { {{/if}} - {{#if wantMessages}} - - {{/if}} ); } diff --git a/internals/generators/index.js b/internals/generators/index.js index 3ed0161adc..faeb198d79 100644 --- a/internals/generators/index.js +++ b/internals/generators/index.js @@ -6,17 +6,11 @@ const fs = require('fs'); const path = require('path'); -// const componentGenerator = require('./component/index.js'); -// const containerGenerator = require('./container/index.js'); -// const languageGenerator = require('./language/index.js'); const dpComponentGenerator = require('./ams-component/index.js'); const dpContainerGenerator = require('./ams-container/index.js'); const dpModelGenerator = require('./ams-model/index.js'); module.exports = plop => { - // plop.setGenerator('component', componentGenerator); - // plop.setGenerator('container', containerGenerator); - // plop.setGenerator('language', languageGenerator); plop.setGenerator('ams-component', dpComponentGenerator); plop.setGenerator('ams-container', dpContainerGenerator); plop.setGenerator('ams-model', dpModelGenerator); diff --git a/internals/generators/language/add-locale-data.hbs b/internals/generators/language/add-locale-data.hbs deleted file mode 100644 index 80727c73cd..0000000000 --- a/internals/generators/language/add-locale-data.hbs +++ /dev/null @@ -1 +0,0 @@ -$1addLocaleData({{language}}LocaleData); diff --git a/internals/generators/language/app-locale.hbs b/internals/generators/language/app-locale.hbs deleted file mode 100644 index 08753eb5ee..0000000000 --- a/internals/generators/language/app-locale.hbs +++ /dev/null @@ -1 +0,0 @@ -$1 '{{language}}', diff --git a/internals/generators/language/format-translation-messages.hbs b/internals/generators/language/format-translation-messages.hbs deleted file mode 100644 index 143601fe95..0000000000 --- a/internals/generators/language/format-translation-messages.hbs +++ /dev/null @@ -1 +0,0 @@ -$1 {{language}}: formatTranslationMessages('{{language}}', {{language}}TranslationMessages), diff --git a/internals/generators/language/index.js b/internals/generators/language/index.js deleted file mode 100644 index 105da0fbe7..0000000000 --- a/internals/generators/language/index.js +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Language Generator - */ -const fs = require('fs'); -const exec = require('child_process').exec; - -function languageIsSupported(language) { - try { - fs.accessSync(`src/translations/${language}.json`, fs.F_OK); - return true; - } catch (e) { - return false; - } -} - -module.exports = { - description: 'Add a language', - prompts: [{ - type: 'input', - name: 'language', - message: 'What is the language you want to add i18n support for (e.g. "fr", "de")?', - default: 'fr', - validate: value => { - if ((/.+/).test(value) && value.length === 2) { - return languageIsSupported(value) ? `The language "${value}" is already supported.` : true; - } - - return '2 character language specifier is required'; - }, - }], - - actions: () => { - const actions = []; - actions.push({ - type: 'modify', - path: '../../src/i18n.js', - pattern: /('react-intl\/locale-data\/[a-z]+';\n)(?!.*'react-intl\/locale-data\/[a-z]+';)/g, - templateFile: './language/intl-locale-data.hbs', - }); - actions.push({ - type: 'modify', - path: '../../src/i18n.js', - pattern: /(\s+'[a-z]+',\n)(?!.*\s+'[a-z]+',)/g, - templateFile: './language/app-locale.hbs', - }); - actions.push({ - type: 'modify', - path: '../../src/i18n.js', - pattern: /(from\s'.\/translations\/[a-z]+.json';\n)(?!.*from\s'.\/translations\/[a-z]+.json';)/g, - templateFile: './language/translation-messages.hbs', - }); - actions.push({ - type: 'modify', - path: '../../src/i18n.js', - pattern: /(addLocaleData\([a-z]+LocaleData\);\n)(?!.*addLocaleData\([a-z]+LocaleData\);)/g, - templateFile: './language/add-locale-data.hbs', - }); - actions.push({ - type: 'modify', - path: '../../src/i18n.js', - pattern: /([a-z]+:\sformatTranslationMessages\('[a-z]+',\s[a-z]+TranslationMessages\),\n)(?!.*[a-z]+:\sformatTranslationMessages\('[a-z]+',\s[a-z]+TranslationMessages\),)/g, - templateFile: './language/format-translation-messages.hbs', - }); - actions.push({ - type: 'add', - path: '../../src/translations/{{language}}.json', - templateFile: './language/translations-json.hbs', - abortOnFail: true, - }); - actions.push({ - type: 'modify', - path: '../../src/app.js', - pattern: /(import\('intl\/locale-data\/jsonp\/[a-z]+\.js'\),\n)(?!.*import\('intl\/locale-data\/jsonp\/[a-z]+\.js'\),)/g, - templateFile: './language/polyfill-intl-locale.hbs', - }); - actions.push( - () => { - const cmd = 'npm run extract-intl'; - exec(cmd, (err, result, stderr) => { - if (err || stderr) { - throw err || stderr; - } - process.stdout.write(result); - }); - return 'modify translation messages'; - } - ); - - return actions; - }, -}; diff --git a/internals/generators/language/intl-locale-data.hbs b/internals/generators/language/intl-locale-data.hbs deleted file mode 100644 index b790a1333f..0000000000 --- a/internals/generators/language/intl-locale-data.hbs +++ /dev/null @@ -1 +0,0 @@ -$1import {{language}}LocaleData from 'react-intl/locale-data/{{language}}'; diff --git a/internals/generators/language/polyfill-intl-locale.hbs b/internals/generators/language/polyfill-intl-locale.hbs deleted file mode 100644 index cdf997c0d8..0000000000 --- a/internals/generators/language/polyfill-intl-locale.hbs +++ /dev/null @@ -1 +0,0 @@ -$1 import('intl/locale-data/jsonp/{{language}}.js'), diff --git a/internals/generators/language/translation-messages.hbs b/internals/generators/language/translation-messages.hbs deleted file mode 100644 index 0682d22ed0..0000000000 --- a/internals/generators/language/translation-messages.hbs +++ /dev/null @@ -1 +0,0 @@ -$1import {{language}}TranslationMessages from './translations/{{language}}.json'; diff --git a/internals/generators/language/translations-json.hbs b/internals/generators/language/translations-json.hbs deleted file mode 100644 index fe51488c70..0000000000 --- a/internals/generators/language/translations-json.hbs +++ /dev/null @@ -1 +0,0 @@ -[] diff --git a/internals/scripts/extract-intl.js b/internals/scripts/extract-intl.js deleted file mode 100644 index d0af7afdf9..0000000000 --- a/internals/scripts/extract-intl.js +++ /dev/null @@ -1,160 +0,0 @@ -/* eslint-disable */ -/** - * This script will extract the internationalization messages from all components - and package them in the translation json files in the translations file. - */ -const fs = require('fs'); -const nodeGlob = require('glob'); -const transform = require('babel-core').transform; - -const animateProgress = require('./helpers/progress'); -const addCheckmark = require('./helpers/checkmark'); - -const pkg = require('../../package.json'); -const presets = pkg.babel.presets; -const plugins = pkg.babel.plugins || []; - -const i18n = require('../../src/i18n'); -import { DEFAULT_LOCALE } from '../../src/containers/src/constants'; - -require('shelljs/global'); - -// Glob to match all js files except test files -const FILES_TO_PARSE = 'src/**/!(*.test).js'; -const locales = i18n.appLocales; - -const newLine = () => process.stdout.write('\n'); - -// Progress Logger -let progress; -const task = (message) => { - progress = animateProgress(message); - process.stdout.write(message); - - return (error) => { - if (error) { - process.stderr.write(error); - } - clearTimeout(progress); - return addCheckmark(() => newLine()); - } -} - -// Wrap async functions below into a promise -const glob = (pattern) => new Promise((resolve, reject) => { - nodeGlob(pattern, (error, value) => (error ? reject(error) : resolve(value))); -}); - -const readFile = (fileName) => new Promise((resolve, reject) => { - fs.readFile(fileName, (error, value) => (error ? reject(error) : resolve(value))); -}); - -const writeFile = (fileName, data) => new Promise((resolve, reject) => { - fs.writeFile(fileName, data, (error, value) => (error ? reject(error) : resolve(value))); -}); - -// Store existing translations into memory -const oldLocaleMappings = []; -const localeMappings = []; -// Loop to run once per locale -for (const locale of locales) { - oldLocaleMappings[locale] = {}; - localeMappings[locale] = {}; - // File to store translation messages into - const translationFileName = `src/translations/${locale}.json`; - try { - // Parse the old translation message JSON files - const messages = JSON.parse(fs.readFileSync(translationFileName)); - const messageKeys = Object.keys(messages); - for (const messageKey of messageKeys) { - oldLocaleMappings[locale][messageKey] = messages[messageKey]; - } - } catch (error) { - if (error.code !== 'ENOENT') { - process.stderr.write( - `There was an error loading this translation file: ${translationFileName} - \n${error}` - ); - } - } -} - -/* push `react-intl` plugin to the existing plugins that are already configured in `package.json` - Example: - ``` - "babel": { - "plugins": [ - ["transform-object-rest-spread", { "useBuiltIns": true }] - ], - "presets": [ - "env", - "react" - ] - } - ``` -*/ -plugins.push(['react-intl']) - -const extractFromFile = async (fileName) => { - try { - const code = await readFile(fileName); - // Use babel plugin to extract instances where react-intl is used - const { metadata: result } = await transform(code, { presets, plugins }); // object-shorthand - for (const message of result['react-intl'].messages) { - for (const locale of locales) { - const oldLocaleMapping = oldLocaleMappings[locale][message.id]; - // Merge old translations into the babel extracted instances where react-intl is used - const newMsg = ( locale === DEFAULT_LOCALE) ? message.defaultMessage : ''; - localeMappings[locale][message.id] = (oldLocaleMapping) - ? oldLocaleMapping - : newMsg; - } - } - } catch (error) { - process.stderr.write(`Error transforming file: ${fileName}\n${error}`); - } -}; - -(async function main() { - const memoryTaskDone = task('Storing language files in memory'); - const files = await glob(FILES_TO_PARSE); - memoryTaskDone() - - const extractTaskDone = task('Run extraction on all files'); - // Run extraction on all files that match the glob on line 16 - await Promise.all(files.map((fileName) => extractFromFile(fileName))); - extractTaskDone() - - // Make the directory if it doesn't exist, especially for first run - mkdir('-p', 'src/translations'); - for (const locale of locales) { - const translationFileName = `src/translations/${locale}.json`; - - try { - const localeTaskDone = task( - `Writing translation messages for ${locale} to: ${translationFileName}` - ); - - // Sort the translation JSON file so that git diffing is easier - // Otherwise the translation messages will jump around every time we extract - let messages = {}; - Object.keys(localeMappings[locale]).sort().forEach(function(key) { - messages[key] = localeMappings[locale][key]; - }); - - // Write to file the JSON representation of the translation messages - const prettified = `${JSON.stringify(messages, null, 2)}\n`; - - await writeFile(translationFileName, prettified); - - localeTaskDone(); - } catch (error) { - localeTaskDone( - `There was an error saving this translation file: ${translationFileName} - \n${error}` - ); - } - } - - process.exit() -}()); diff --git a/internals/scripts/generate-templates-for-linting.js b/internals/scripts/generate-templates-for-linting.js index a8829188cc..5b6d71bf33 100644 --- a/internals/scripts/generate-templates-for-linting.js +++ b/internals/scripts/generate-templates-for-linting.js @@ -33,17 +33,17 @@ const removeTestsDirFrom = (relativePath) => () => rimraf.sync(path.join(__dirna const plop = nodePlop('./index'); const componentGen = plop.getGenerator('component'); -componentGen.runActions({ name: 'RbGeneratedComponentEsclass', type: 'React.Component', wantMessages: true, wantLoadable: true, }) +componentGen.runActions({ name: 'RbGeneratedComponentEsclass', type: 'React.Component', wantLoadable: true, }) .then(checkForErrors) .then(removeTestsDirFrom('components/RbGeneratedComponentEsclass')) .catch(reportErrorsFor('component/React.Component')); -componentGen.runActions({ name: 'RbGeneratedComponentEsclasspure', type: 'React.PureComponent', wantMessages: true, wantLoadable: true }) +componentGen.runActions({ name: 'RbGeneratedComponentEsclasspure', type: 'React.PureComponent', wantLoadable: true }) .then(checkForErrors) .then(removeTestsDirFrom('components/RbGeneratedComponentEsclasspure')) .catch(reportErrorsFor('component/React.PureComponent')); -componentGen.runActions({ name: 'RbGeneratedComponentStatelessfunction', type: 'Stateless Function', wantMessages: true, wantLoadable: true }) +componentGen.runActions({ name: 'RbGeneratedComponentStatelessfunction', type: 'Stateless Function', wantLoadable: true }) .then(checkForErrors) .then(removeTestsDirFrom('components/RbGeneratedComponentStatelessfunction')) .catch(reportErrorsFor('component/Stateless Function')); @@ -55,7 +55,6 @@ containerGen.runActions({ wantHeaders: true, wantActionsAndReducer: true, wantSagas: true, - wantMessages: true, wantLoadable: true, }) .then(checkForErrors) @@ -68,7 +67,6 @@ containerGen.runActions({ wantHeaders: true, wantActionsAndReducer: true, wantSagas: true, - wantMessages: true, wantLoadable: true, }) .then(checkForErrors) @@ -81,13 +79,8 @@ containerGen.runActions({ wantHeaders: true, wantActionsAndReducer: true, wantSagas: true, - wantMessages: true, wantLoadable: true, }) .then(checkForErrors) .then(removeTestsDirFrom('containers/RbGeneratedContainerStateless')) .catch(reportErrorsFor('container/Stateless')); - -const languageGen = plop.getGenerator('language'); -languageGen.runActions({ language: 'fr' }) - .catch(reportErrorsFor('language')); diff --git a/package-lock.json b/package-lock.json index 2ad9c560e4..0cc43eb2ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1580,21 +1580,6 @@ "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, - "@formatjs/intl-unified-numberformat": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@formatjs/intl-unified-numberformat/-/intl-unified-numberformat-3.3.0.tgz", - "integrity": "sha512-wLT3myYq6fUhJYUh53tt5fMok+sUqO3Jy1XeSqYTphP7MmQl38tHqAIL65Dxh7M6/QlDEQTOkMZNpQcnT0AzaQ==", - "dev": true, - "requires": { - "@formatjs/intl-utils": "^2.2.0" - } - }, - "@formatjs/intl-utils": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@formatjs/intl-utils/-/intl-utils-2.2.1.tgz", - "integrity": "sha512-WF3oU6l2WqJjN4OWvnjF9AHyQjHpjcfpyuckM7euFeX6ZGRPpPj+ZCqzf41g81MSksf9aZI4fFCZXWTBusgcWA==", - "dev": true - }, "@jest/console": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", @@ -3107,12 +3092,6 @@ "@types/react": "*" } }, - "@types/schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-YesPanU1+WCigC/Aj1Mga8UCOjHIfMNHZ3zzDsUY7lI8GlKnh/Kv2QwJOQ+jNQ36Ru7IfzSedlG14hppYaN13A==", - "dev": true - }, "@types/sinon": { "version": "7.5.1", "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.5.1.tgz", @@ -4205,32 +4184,6 @@ "@types/babel__traverse": "^7.0.6" } }, - "babel-plugin-react-intl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-react-intl/-/babel-plugin-react-intl-4.3.0.tgz", - "integrity": "sha512-X4R9ZrQ6LR6EaNqk7DCA39GamD8Deo1XOeQGEbsswV741AgQ8HfuXtQ7FKCiDnfWp2nhVVio+BAIrhwS5JxHdQ==", - "dev": true, - "requires": { - "@babel/core": "^7.6.2", - "@babel/helper-plugin-utils": "^7.0.0", - "@types/babel__core": "^7.1.2", - "@types/schema-utils": "^1.0.0", - "fs-extra": "^8.0.1", - "intl-messageformat-parser": "^3.2.2", - "schema-utils": "^2.2.0" - }, - "dependencies": { - "intl-messageformat-parser": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-3.6.4.tgz", - "integrity": "sha512-RgPGwue0mJtoX2Ax8EmMzJzttxjnva7gx0Q7mKJ4oALrTZvtmCeAw5Msz2PcjW4dtCh/h7vN/8GJCxZO1uv+OA==", - "dev": true, - "requires": { - "@formatjs/intl-unified-numberformat": "^3.2.0" - } - } - } - }, "babel-plugin-styled-components": { "version": "1.10.7", "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.7.tgz", @@ -11430,37 +11383,6 @@ "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", "dev": true }, - "intl": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/intl/-/intl-1.2.5.tgz", - "integrity": "sha1-giRKIZDE5Bn4Nx9ao02qNCDiq94=" - }, - "intl-format-cache": { - "version": "2.2.9", - "resolved": "https://registry.npmjs.org/intl-format-cache/-/intl-format-cache-2.2.9.tgz", - "integrity": "sha512-Zv/u8wRpekckv0cLkwpVdABYST4hZNTDaX7reFetrYTJwxExR2VyTqQm+l0WmL0Qo8Mjb9Tf33qnfj0T7pjxdQ==" - }, - "intl-messageformat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-1.3.0.tgz", - "integrity": "sha1-99kmre16OrGbLcYB79VOmaS9Tq4=", - "requires": { - "intl-messageformat-parser": "1.2.0" - } - }, - "intl-messageformat-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-1.2.0.tgz", - "integrity": "sha1-WQa3+VOrdHDg3IVJCXtki5kYkv8=" - }, - "intl-relativeformat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/intl-relativeformat/-/intl-relativeformat-1.3.0.tgz", - "integrity": "sha1-iT3HB2/M04DPCRojAMOA+les5Fs=", - "requires": { - "intl-messageformat": "1.3.0" - } - }, "into-stream": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", @@ -20180,17 +20102,6 @@ "scheduler": "^0.19.1" } }, - "react-intl": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-2.3.0.tgz", - "integrity": "sha1-4d9q9WZ/3wHL5KqyDhNyUeKuUUI=", - "requires": { - "intl-format-cache": "^2.0.5", - "intl-messageformat": "^1.3.0", - "intl-relativeformat": "^1.3.0", - "invariant": "^2.1.1" - } - }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/package.json b/package.json index 4d0878fb9f..f90838dd57 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,6 @@ "clean": "shjs ./internals/scripts/clean.js", "coveralls": "cat ./coverage/lcov.info | coveralls", "cy:open": "cypress open", - "extract-intl": "babel-node --presets env,stage-0 -- ./internals/scripts/extract-intl.js", "generate": "plop --plopfile internals/generators/index.js", "lint:eslint": "eslint --ignore-path .gitignore --ignore-pattern internals/scripts", "lint:js": "npm run lint:eslint -- . ", @@ -73,7 +72,6 @@ "history": "^4.10.1", "hoist-non-react-statics": "^3.3.2", "immutable": "^3.8.2", - "intl": "1.2.5", "invariant": "^2.2.4", "leaflet": "^1.6.0", "leaflet.markercluster": "^1.4.1", @@ -103,7 +101,6 @@ "react-app-polyfill": "^1.0.6", "react-datepicker": "^1.8.0", "react-dom": "^16.13.1", - "react-intl": "2.3.0", "react-media": "^1.10.0", "react-reactive-form": "1.0.27", "react-redux": "^7.2.0", @@ -142,7 +139,6 @@ "babel-loader": "^8.1.0", "babel-plugin-dynamic-import-node": "^2.2.0", "babel-plugin-inline-react-svg": "^1.1.1", - "babel-plugin-react-intl": "^4.3.0", "babel-plugin-styled-components": "^1.10.7", "babel-plugin-transform-react-remove-prop-types": "0.4.24", "chalk": "^3.0.0", diff --git a/src/app.js b/src/app.js index 6674f4aa67..b8a1529c8f 100644 --- a/src/app.js +++ b/src/app.js @@ -1,17 +1,7 @@ -/** - * app.js - * - * This is the entry file for the application, only setup and boilerplate - * code. - */ - -// Import all the third party stuff import React from 'react'; import ReactDOM from 'react-dom'; import { Provider } from 'react-redux'; import { ConnectedRouter } from 'connected-react-router/immutable'; -import moment from 'moment'; -import 'moment/src/locale/nl'; import * as Sentry from '@sentry/browser'; import MatomoTracker from '@datapunt/matomo-tracker-js'; import Immutable from 'immutable'; @@ -23,12 +13,8 @@ import { authenticateUser } from 'containers/App/actions'; import { authenticate } from 'shared/services/auth/auth'; import loadModels from 'models'; -// Import Language Provider -import LanguageProvider from 'containers/LanguageProvider'; - -/* eslint-disable import/no-webpack-loader-syntax */ +// eslint-disable-next-lin import/no-webpack-loader-syntax import '!file-loader?name=[name].[ext]!./images/favicon.png'; -/* eslint-enable import/no-webpack-loader-syntax */ // Import CSS and Global Styles import 'amsterdam-stijl/dist/css/ams-stijl.css'; @@ -37,9 +23,6 @@ import './polyfills'; import configureStore from './configureStore'; -// Import i18n messages -import { translationMessages } from './i18n'; - const environment = process.env.NODE_ENV; const release = process.env.GIT_COMMIT; @@ -49,9 +32,6 @@ Sentry.init({ release, }); -// load locale for date formatting -moment.locale('nl'); - // Create redux store with history const initialState = Immutable.Map(); const store = configureStore(initialState, history); @@ -68,14 +48,12 @@ const MatomoInstance = new MatomoTracker({ MatomoInstance.trackPageView(); -const render = messages => { +const render = () => { ReactDOM.render( - - - - - + + + , MOUNT_NODE ); @@ -85,30 +63,13 @@ if (module.hot) { // Hot reloadable React components and translation json files // modules.hot.accept does not accept dynamic dependencies, // have to be constants at compile-time - module.hot.accept(['./i18n', 'containers/App'], () => { + module.hot.accept(['containers/App'], () => { ReactDOM.unmountComponentAtNode(MOUNT_NODE); - render(translationMessages); + render(); }); } -// Chunked polyfill for browsers without Intl support -if (!window.Intl) { - new Promise(resolve => { - resolve(import('intl')); - }) - .then(() => - Promise.all([ - import('intl/locale-data/jsonp/en.js'), - import('intl/locale-data/jsonp/nl.js'), - ]) - ) - .then(() => render(translationMessages)) - .catch(err => { - throw err; - }); -} else { - render(translationMessages); -} +render(); // Authenticate and start the authorization process const credentials = authenticate(); diff --git a/src/containers/LanguageProvider/actions.js b/src/containers/LanguageProvider/actions.js deleted file mode 100644 index 779eed0a12..0000000000 --- a/src/containers/LanguageProvider/actions.js +++ /dev/null @@ -1,16 +0,0 @@ -/* - * - * LanguageProvider actions - * - */ - -import { - CHANGE_LOCALE, -} from './constants'; - -export function changeLocale(languageLocale) { - return { - type: CHANGE_LOCALE, - locale: languageLocale, - }; -} diff --git a/src/containers/LanguageProvider/actions.test.js b/src/containers/LanguageProvider/actions.test.js deleted file mode 100644 index 492717713b..0000000000 --- a/src/containers/LanguageProvider/actions.test.js +++ /dev/null @@ -1,19 +0,0 @@ -import { - changeLocale, -} from './actions'; - -import { - CHANGE_LOCALE, -} from './constants'; - -describe('LanguageProvider actions', () => { - describe('Change Local Action', () => { - it('has a type of CHANGE_LOCALE', () => { - const expected = { - type: CHANGE_LOCALE, - locale: 'de', - }; - expect(changeLocale('de')).toEqual(expected); - }); - }); -}); diff --git a/src/containers/LanguageProvider/constants.js b/src/containers/LanguageProvider/constants.js deleted file mode 100644 index 9b23c1d295..0000000000 --- a/src/containers/LanguageProvider/constants.js +++ /dev/null @@ -1,7 +0,0 @@ -/* - * - * LanguageProvider constants - * - */ - -export const CHANGE_LOCALE = 'src/LanguageToggle/CHANGE_LOCALE'; diff --git a/src/containers/LanguageProvider/index.js b/src/containers/LanguageProvider/index.js deleted file mode 100644 index b2f4e6d3b6..0000000000 --- a/src/containers/LanguageProvider/index.js +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * LanguageProvider - * - * this component connects the redux state language locale to the - * IntlProvider component and i18n messages (loaded from `src/translations`) - */ - -import React from 'react'; -import PropTypes from 'prop-types'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { IntlProvider } from 'react-intl'; - -import { makeSelectLocale } from './selectors'; - -export class LanguageProvider extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function - render() { - return ( - - {React.Children.only(this.props.children)} - - ); - } -} - -LanguageProvider.propTypes = { - locale: PropTypes.string, - messages: PropTypes.object, - children: PropTypes.element.isRequired, -}; - -const mapStateToProps = createSelector( - makeSelectLocale(), - locale => ({ locale }) -); - -export default connect(mapStateToProps)(LanguageProvider); diff --git a/src/containers/LanguageProvider/index.test.js b/src/containers/LanguageProvider/index.test.js deleted file mode 100644 index 34be8f3330..0000000000 --- a/src/containers/LanguageProvider/index.test.js +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; -import { shallow, mount } from 'enzyme'; -import { FormattedMessage, defineMessages } from 'react-intl'; -import { withIntlAppContext } from 'test/utils'; - -import ConnectedLanguageProvider, { LanguageProvider } from './index'; - -import { translationMessages } from '../../i18n'; - -const messages = defineMessages({ - someMessage: { - id: 'some.id', - defaultMessage: 'This is some default message', - en: 'This is some en message', - }, -}); - -describe('', () => { - it('should render its children', () => { - const children = (

Test

); - const wrapper = shallow( - - {children} - - ); - expect(wrapper.contains(children)).toBe(true); - }); -}); - -describe('', () => { - it('should render the default language messages', () => { - const wrapper = mount(withIntlAppContext( - - - - )); - expect(wrapper.contains()).toBe(true); - }); -}); diff --git a/src/containers/LanguageProvider/reducer.js b/src/containers/LanguageProvider/reducer.js deleted file mode 100644 index ee3f295d5e..0000000000 --- a/src/containers/LanguageProvider/reducer.js +++ /dev/null @@ -1,30 +0,0 @@ -/* - * - * LanguageProvider reducer - * - */ - -import { fromJS } from 'immutable'; - -import { - CHANGE_LOCALE, -} from './constants'; -import { - DEFAULT_LOCALE, -} from '../App/constants'; - -export const initialState = fromJS({ - locale: DEFAULT_LOCALE, -}); - -function languageProviderReducer(state = initialState, action) { - switch (action.type) { - case CHANGE_LOCALE: - return state - .set('locale', action.locale); - default: - return state; - } -} - -export default languageProviderReducer; diff --git a/src/containers/LanguageProvider/reducer.test.js b/src/containers/LanguageProvider/reducer.test.js deleted file mode 100644 index 3a2b0a4818..0000000000 --- a/src/containers/LanguageProvider/reducer.test.js +++ /dev/null @@ -1,18 +0,0 @@ -import { fromJS } from 'immutable'; - -import languageProviderReducer, { initialState } from './reducer'; -import { - CHANGE_LOCALE, -} from './constants'; - -describe('languageProviderReducer', () => { - it('returns the initial state', () => { - expect(languageProviderReducer(undefined, {})).toEqual(fromJS(initialState)); - }); - - it('changes the locale', () => { - expect(languageProviderReducer(undefined, { type: CHANGE_LOCALE, locale: 'en' }).toJS()).toEqual({ - locale: 'en', - }); - }); -}); diff --git a/src/containers/LanguageProvider/selectors.js b/src/containers/LanguageProvider/selectors.js deleted file mode 100644 index 09e647bf4d..0000000000 --- a/src/containers/LanguageProvider/selectors.js +++ /dev/null @@ -1,20 +0,0 @@ -import { createSelector } from 'reselect'; -import { initialState } from './reducer'; - -/** - * Direct selector to the languageToggle state domain - */ -const selectLanguage = state => - (state && state.get('language')) || initialState; - -/** - * Select the language locale - */ - -const makeSelectLocale = () => - createSelector( - selectLanguage, - languageState => languageState.get('locale') - ); - -export { selectLanguage, makeSelectLocale }; diff --git a/src/containers/LanguageProvider/selectors.test.js b/src/containers/LanguageProvider/selectors.test.js deleted file mode 100644 index 6cf9d415cb..0000000000 --- a/src/containers/LanguageProvider/selectors.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import { fromJS } from 'immutable'; - -import { - selectLanguage, -} from './selectors'; - -describe('selectLanguage', () => { - it('should select the global state', () => { - const globalState = fromJS({}); - const mockedState = fromJS({ - language: globalState, - }); - expect(selectLanguage(mockedState)).toEqual(globalState); - }); -}); diff --git a/src/hooks/useFetch.js b/src/hooks/useFetch.js index 3442d19f7b..d6c3c853ef 100644 --- a/src/hooks/useFetch.js +++ b/src/hooks/useFetch.js @@ -70,9 +70,13 @@ export default () => { } setData(responseData); - } catch (e) { - e.message = getErrorMessage(e); - setError(e); + } catch (exception) { + Object.defineProperty(exception, 'message', { + value: getErrorMessage(exception), + writable: false, + }); + + setError(exception); } finally { setLoading(false); } @@ -105,10 +109,13 @@ export default () => { setData(responseData); setSuccess(true); - } catch (e) { - e.message = getErrorMessage(e); + } catch (exception) { + Object.defineProperty(exception, 'message', { + value: getErrorMessage(exception), + writable: false, + }); - setError(e); + setError(exception); setSuccess(false); } finally { setLoading(false); diff --git a/src/i18n.js b/src/i18n.js deleted file mode 100644 index 942081bb45..0000000000 --- a/src/i18n.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * i18n.js - * - * This will setup the i18n language files and locale data for your app. - * - */ -import { addLocaleData } from 'react-intl'; -import enLocaleData from 'react-intl/locale-data/en'; -import nlLocaleData from 'react-intl/locale-data/nl'; - -import { DEFAULT_LOCALE } from './containers/App/constants'; - -import enTranslationMessages from './translations/en.json'; -import nlTranslationMessages from './translations/nl.json'; - -addLocaleData(enLocaleData); -addLocaleData(nlLocaleData); - -export const appLocales = [ - 'en', - 'nl', -]; - -export const formatTranslationMessages = (locale, messages) => { - const defaultFormattedMessages = locale !== DEFAULT_LOCALE - ? formatTranslationMessages(DEFAULT_LOCALE, enTranslationMessages) - : {}; - return Object.keys(messages).reduce((formattedMessages, key) => { - const formattedMessage = !messages[key] && locale !== DEFAULT_LOCALE - ? defaultFormattedMessages[key] - : messages[key]; - return Object.assign(formattedMessages, { [key]: formattedMessage }); - }, {}); -}; - -export const translationMessages = { - en: formatTranslationMessages('en', enTranslationMessages), - nl: formatTranslationMessages('nl', nlTranslationMessages), -}; diff --git a/src/i18n.test.js b/src/i18n.test.js deleted file mode 100644 index b06c541dac..0000000000 --- a/src/i18n.test.js +++ /dev/null @@ -1,32 +0,0 @@ -import { DEFAULT_LOCALE } from './containers/App/constants'; -import { formatTranslationMessages } from './i18n'; - -jest.mock('./translations/en.json', () => ( - { - message1: 'default message', - message2: 'default message 2', - } -)); - -const esTranslationMessages = { - message1: 'mensaje predeterminado', - message2: '', -}; - -describe('formatTranslationMessages', () => { - it('should build only defaults when DEFAULT_LOCALE', () => { - const result = formatTranslationMessages(DEFAULT_LOCALE, { a: 'a' }); - - expect(result).toEqual({ a: 'a' }); - }); - - - it('should combine default locale and current locale when not DEFAULT_LOCALE', () => { - const result = formatTranslationMessages('', esTranslationMessages); - - expect(result).toEqual({ - message1: 'mensaje predeterminado', - message2: 'default message 2', - }); - }); -}); diff --git a/src/reducers.js b/src/reducers.js index fa30cb369b..84825bf504 100644 --- a/src/reducers.js +++ b/src/reducers.js @@ -7,7 +7,6 @@ import { connectRouter } from 'connected-react-router/immutable'; import history from 'utils/history'; import globalReducer from 'containers/App/reducer'; -import languageProviderReducer from 'containers/LanguageProvider/reducer'; /** * Merges the main reducer with the router state and dynamically injected reducers @@ -15,7 +14,6 @@ import languageProviderReducer from 'containers/LanguageProvider/reducer'; export default function createReducer(injectedReducers = {}) { const rootReducer = combineReducers({ global: globalReducer, - language: languageProviderReducer, router: connectRouter(history), ...injectedReducers, }); diff --git a/src/signals/incident-management/containers/FilterTagList/__tests__/FilterTagList.test.js b/src/signals/incident-management/containers/FilterTagList/__tests__/FilterTagList.test.js index de9c1623ad..11b42b67bb 100644 --- a/src/signals/incident-management/containers/FilterTagList/__tests__/FilterTagList.test.js +++ b/src/signals/incident-management/containers/FilterTagList/__tests__/FilterTagList.test.js @@ -1,7 +1,7 @@ import React from 'react'; import { mount } from 'enzyme'; import { render } from '@testing-library/react'; -import { withAppContext, withIntlAppContext } from 'test/utils'; +import { withAppContext } from 'test/utils'; import * as definitions from 'signals/incident-management/definitions'; import { mainCategories, subCategories } from 'utils/__tests__/fixtures'; @@ -10,7 +10,6 @@ import FilterTagList, { allLabelAppend, mapKeys, } from '..'; -import translations from '../../../../../translations/nl.json'; const dataLists = { priority: definitions.priorityList, @@ -52,14 +51,13 @@ describe('signals/incident-management/containers/FilterTagList', () => { describe('date formatting', () => { it('renders created before', () => { const { queryByText } = render( - withIntlAppContext( + withAppContext( , - translations + /> ) ); @@ -70,14 +68,13 @@ describe('signals/incident-management/containers/FilterTagList', () => { it('renders date after', () => { const { queryByText } = render( - withIntlAppContext( + withAppContext( , - translations + /> ) ); @@ -88,7 +85,7 @@ describe('signals/incident-management/containers/FilterTagList', () => { it('renders both date after and date before', () => { const { queryByText } = render( - withIntlAppContext( + withAppContext( { }} subCategories={subCategories} mainCategories={mainCategories} - />, - translations + /> ) ); diff --git a/src/test/utils.js b/src/test/utils.js index 0bef3be724..c77df5dda3 100644 --- a/src/test/utils.js +++ b/src/test/utils.js @@ -4,7 +4,6 @@ import { createMemoryHistory } from 'history'; import { Provider } from 'react-redux'; import { ThemeProvider } from '@datapunt/asc-ui'; import MatchMediaMock from 'match-media-mock'; -import { IntlProvider } from 'react-intl'; import Immutable from 'immutable'; import isObject from 'lodash.isobject'; import usersJSON from 'utils/__tests__/fixtures/users.json'; @@ -74,17 +73,6 @@ export const withCustomAppContext = Component => ({ ); -// eslint-disable-next-line -export const withIntlAppContext = (Component, messages, locale = 'nl') => ( - - - - {Component} - - - -); - /** * Get a list of users from JSON data that is coming from the API endpoint * Invalid keys are filtered out of the return value. diff --git a/src/translations/en.json b/src/translations/en.json deleted file mode 100644 index 8a23457bf7..0000000000 --- a/src/translations/en.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "boilerplate.components.Footer.author.message": "Made with love by {author}.", - "boilerplate.components.Footer.license.message": "This project is licensed under the MIT license.", - "boilerplate.components.Header.features": "Features", - "boilerplate.components.Header.home": "Home", - "boilerplate.containers.HomePage.start_project.header": "Start your next react project in seconds", - "boilerplate.containers.HomePage.start_project.message": "A highly scalable, offline-first foundation with the best DX and a focus on performance and best practices", - "boilerplate.containers.HomePage.tryme.atPrefix": "@", - "boilerplate.containers.HomePage.tryme.header": "Try me!", - "boilerplate.containers.HomePage.tryme.message": "Show Github repositories by", - "boilerplate.containers.LocaleToggle.nl": "nl", - "boilerplate.containers.LocaleToggle.en": "en" -} diff --git a/src/translations/nl.json b/src/translations/nl.json deleted file mode 100644 index 4207a9d0a8..0000000000 --- a/src/translations/nl.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "boilerplate.components.Footer.author.message": "Met liefde gemaakt door {author}.", - "boilerplate.components.Footer.license.message": "Dit project valt onder Mozilla Public License 2.0.", - "boilerplate.components.Header.features": "", - "boilerplate.components.Header.home": "", - "boilerplate.containers.HomePage.start_project.header": "Welkom bij de Signalen Informatievoorziening Amsterdam", - "boilerplate.containers.HomePage.start_project.message": "Ontwikkeld door Datapunt Amsterdam", - "boilerplate.containers.LocaleToggle.nl": "", - "boilerplate.containers.LocaleToggle.en": "" -} From 451bf793e0c8dc740a32bd4dbe9c8594a30fb66e Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Wed, 15 Apr 2020 14:23:22 +0200 Subject: [PATCH 18/80] Removes newlines from fixture --- src/components/History/index.test.js | 4 +--- src/utils/__tests__/fixtures/history.json | 8 ++++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/components/History/index.test.js b/src/components/History/index.test.js index b542c8c799..d2d8814952 100644 --- a/src/components/History/index.test.js +++ b/src/components/History/index.test.js @@ -1,5 +1,5 @@ import React from 'react'; -import { render, cleanup } from '@testing-library/react'; +import { render } from '@testing-library/react'; import { withAppContext } from 'test/utils'; import historyJSON from 'utils/__tests__/fixtures/history.json'; @@ -15,8 +15,6 @@ describe('', () => { }; }); - afterEach(cleanup); - describe('rendering', () => { it('should render all items when list is defined', () => { const { getByText } = render( diff --git a/src/utils/__tests__/fixtures/history.json b/src/utils/__tests__/fixtures/history.json index 55db80b0da..f0c9c64780 100644 --- a/src/utils/__tests__/fixtures/history.json +++ b/src/utils/__tests__/fixtures/history.json @@ -3,7 +3,7 @@ "identifier": "UPDATED_CATEGORY_7", "when": "2020-03-25T14:07:23.351516+01:00", "what": "UPDATED_CATEGORY", - "action": "Service level agreement wijziging:\n 4 werkdagen", + "action": "Service level agreement wijziging: 4 werkdagen", "description": null, "who": "me@mail.com", "_category": 145 @@ -12,7 +12,7 @@ "identifier": "UPDATED_CATEGORY_6", "when": "2020-03-25T11:14:17.266316+01:00", "what": "UPDATED_CATEGORY", - "action": "Service level agreement wijziging:\n 5 werkdagen\nE-mail tekst wijziging:\n Wij beoordelen uw melding. Urgente meldingen pakken we zo snel mogelijk op.\n\nOverige meldingen handelen we binnen een week af. We houden u op de hoogte via e-mail.", + "action": "Service level agreement wijziging: 5 werkdagen E-mail tekst wijziging: Wij beoordelen uw melding. Urgente meldingen pakken we zo snel mogelijk op. Overige meldingen handelen we binnen een week af. We houden u op de hoogte via e-mail.", "description": null, "who": "you@mail.com", "_category": 145 @@ -21,7 +21,7 @@ "identifier": "UPDATED_CATEGORY_4", "when": "2020-03-17T16:59:27.902955+01:00", "what": "UPDATED_CATEGORY", - "action": "Service level agreement wijziging:\n 5 werkdagen", + "action": "Service level agreement wijziging: 5 werkdagen", "description": null, "who": "us@mail.com", "_category": 145 @@ -30,7 +30,7 @@ "identifier": "UPDATED_CATEGORY_3", "when": "2020-03-17T16:59:22.110095+01:00", "what": "UPDATED_CATEGORY", - "action": "Service level agreement wijziging:\n 2 werkdagen", + "action": "Service level agreement wijziging: 2 werkdagen", "description": null, "who": "him@mail.com", "_category": 145 From 5852741d98662513dde756869dae2b30b1017f9a Mon Sep 17 00:00:00 2001 From: Adrian Tudorache Date: Wed, 15 Apr 2020 15:03:29 +0200 Subject: [PATCH 19/80] removes unneeded existance tests and improves code coverage --- .../MapInput/__tests__/MapInput.test.js | 34 +++++++++++++++++-- src/components/MapInput/index.js | 10 +++--- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/components/MapInput/__tests__/MapInput.test.js b/src/components/MapInput/__tests__/MapInput.test.js index c1fc1cafe8..ea9dd8ad8e 100644 --- a/src/components/MapInput/__tests__/MapInput.test.js +++ b/src/components/MapInput/__tests__/MapInput.test.js @@ -100,20 +100,48 @@ describe('components/MapInput', () => { expect(getByTestId('autoSuggest')).toBeInTheDocument(); }); - it('should dispatch setValuesAction', () => { + it('should dispatch setValuesAction and move to the location', () => { + const movestartSpy = jest.fn(); + const moveSpy = jest.fn(); const { rerender } = render(withMapContext()); expect(setValuesSpy).not.toHaveBeenCalled(); const value = { addressText: 'Foo' }; - rerender(withMapContext()); + rerender( + withMapContext( + + ) + ); + expect(movestartSpy).not.toHaveBeenCalled(); + expect(moveSpy).not.toHaveBeenCalled(); expect(setValuesSpy).toHaveBeenCalledTimes(1); expect(setValuesSpy).toHaveBeenCalledWith(value); - rerender(withMapContext()); + rerender( + withMapContext( + + ) + ); + expect(movestartSpy).toHaveBeenCalled(); + expect(moveSpy).toHaveBeenCalled(); expect(setValuesSpy).toHaveBeenCalledTimes(2); expect(setValuesSpy).toHaveBeenCalledWith(testLocation); }); diff --git a/src/components/MapInput/index.js b/src/components/MapInput/index.js index c5ec970375..ae93f50bd4 100644 --- a/src/components/MapInput/index.js +++ b/src/components/MapInput/index.js @@ -120,9 +120,9 @@ const MapInput = ({ className, value, onChange, mapOptions, ...otherProps }) => if (!value?.location && !value?.addressText) return; if (value?.location?.lat > 0) { - if (map && !isEqual(value?.location, state.location)) { + if (!isEqual(value?.location, state.location)) { const currentZoom = map.getZoom(); - map.flyTo(value?.location, currentZoom); + map.flyTo(value.location, currentZoom); } } @@ -175,9 +175,9 @@ MapInput.propTypes = { */ onChange: PropTypes.func, value: PropTypes.shape({ - geometrie: PropTypes.shape({ - type: PropTypes.string, - coordinates: PropTypes.arrayOf(PropTypes.number).isRequired, + location: PropTypes.shape({ + lat: PropTypes.number.isRequired, + lng: PropTypes.number.isRequired, }), addressText: PropTypes.string, }), From 80a36d76fbf80103274ae65963f61749a7f35681 Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Wed, 15 Apr 2020 15:47:10 +0200 Subject: [PATCH 20/80] Removes only --- src/components/MapInput/__tests__/MapInput.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MapInput/__tests__/MapInput.test.js b/src/components/MapInput/__tests__/MapInput.test.js index 1bb4467c14..18b8a43742 100644 --- a/src/components/MapInput/__tests__/MapInput.test.js +++ b/src/components/MapInput/__tests__/MapInput.test.js @@ -227,7 +227,7 @@ describe('components/MapInput', () => { expect(container.querySelector(`.${markerIcon.options.className}`)).toBeInTheDocument(); }); - it.only('should clear location and not render marker', async () => { + it('should clear location and not render marker', async () => { const location = { lat: 52.36058599633851, lng: 4.894292258032637, From d6d527d30d3608571fd24431d74e579d4133d0e4 Mon Sep 17 00:00:00 2001 From: Adrian Tudorache Date: Thu, 16 Apr 2020 07:57:49 +0200 Subject: [PATCH 21/80] improves coverage in MapInput --- .../MapInput/__tests__/MapInput.test.js | 73 +++++++++++-------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/src/components/MapInput/__tests__/MapInput.test.js b/src/components/MapInput/__tests__/MapInput.test.js index ea9dd8ad8e..9df61807c9 100644 --- a/src/components/MapInput/__tests__/MapInput.test.js +++ b/src/components/MapInput/__tests__/MapInput.test.js @@ -13,6 +13,8 @@ import { DOUBLE_CLICK_TIMEOUT } from 'hooks/useDelayedDoubleClick'; import { findFeatureByType } from '../services/reverseGeocoderService'; import MapInput from '..'; +import { initialState } from '../../../containers/MapContext/reducer'; + jest.mock('containers/MapContext/actions', () => ({ __esModule: true, ...jest.requireActual('containers/MapContext/actions'), @@ -100,50 +102,61 @@ describe('components/MapInput', () => { expect(getByTestId('autoSuggest')).toBeInTheDocument(); }); - it('should dispatch setValuesAction and move to the location', () => { - const movestartSpy = jest.fn(); - const moveSpy = jest.fn(); + it('should dispatch setValuesAction', () => { const { rerender } = render(withMapContext()); expect(setValuesSpy).not.toHaveBeenCalled(); const value = { addressText: 'Foo' }; - rerender( - withMapContext( - - ) - ); + rerender(withMapContext()); - expect(movestartSpy).not.toHaveBeenCalled(); - expect(moveSpy).not.toHaveBeenCalled(); expect(setValuesSpy).toHaveBeenCalledTimes(1); expect(setValuesSpy).toHaveBeenCalledWith(value); + rerender(withMapContext()); + + expect(setValuesSpy).toHaveBeenCalledTimes(2); + expect(setValuesSpy).toHaveBeenCalledWith(testLocation); + + setValuesSpy.mockClear(); + setLocationSpy.mockClear(); + + rerender(withMapContext()); + + expect(setValuesSpy).not.toHaveBeenCalled(); + }); + + it('should move the map to the location when location is passed as parameter', async () => { + const movestartSpy = jest.fn(); + const mapEvents = { + movestart: movestartSpy, + }; + + const withMapContextState = Component => state => + withAppContext( {} }}>{Component}); + + const state = { ...initialState }; + + const { rerender } = render( + withMapContextState()(state) + ); + + expect(movestartSpy).not.toHaveBeenCalled(); + + rerender(withMapContextState()(state)); + + expect(movestartSpy).toHaveBeenCalled(); + movestartSpy.mockClear(); + + const stateWithLocation = { ...state, ...testLocation }; rerender( - withMapContext( - + withMapContextState()( + stateWithLocation ) ); - expect(movestartSpy).toHaveBeenCalled(); - expect(moveSpy).toHaveBeenCalled(); - expect(setValuesSpy).toHaveBeenCalledTimes(2); - expect(setValuesSpy).toHaveBeenCalledWith(testLocation); + expect(movestartSpy).not.toHaveBeenCalled(); }); it('should handle click', async () => { From 251eafe374e51156ecc7bdfb2647060e97c1e27c Mon Sep 17 00:00:00 2001 From: Adrian Tudorache Date: Thu, 16 Apr 2020 08:31:46 +0200 Subject: [PATCH 22/80] removes the explicit font-family from the ovl legend --- src/components/MapSelect/style.scss | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/MapSelect/style.scss b/src/components/MapSelect/style.scss index 91da43e136..db0fb24b2d 100644 --- a/src/components/MapSelect/style.scss +++ b/src/components/MapSelect/style.scss @@ -30,7 +30,6 @@ .zoom-control { background-color: #FEC813; color: $ams-zwart; - font-family: Avenir; font-size: 16px; line-height: 22px; padding: 13px; @@ -39,7 +38,6 @@ .legend-control { background-color: $ams-wit; color: $ams-zwart; - font-family: Avenir; font-size: 16px; line-height: 16px; min-width: 240px; @@ -47,7 +45,6 @@ .legend-header { padding: 14px; - font-family: Avenir; color: $ams-zwart; background-color: #F5F5F5;; From 172301c95637ead3bc8221fbe23732e0b553f56d Mon Sep 17 00:00:00 2001 From: Adrian Tudorache Date: Thu, 16 Apr 2020 08:43:45 +0200 Subject: [PATCH 23/80] adds relative positioning around the MapSelect control --- src/components/MapSelect/index.js | 85 +++++++++++++++++-------------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/src/components/MapSelect/index.js b/src/components/MapSelect/index.js index 740e63fbfd..863493605c 100644 --- a/src/components/MapSelect/index.js +++ b/src/components/MapSelect/index.js @@ -19,6 +19,10 @@ import './style.scss'; const SELECTION_MAX_COUNT = 30; +const Wrapper = styled.div` + position: relative; +`; + const StyledMap = styled(Map)` height: 450px; width: 100%; @@ -66,58 +70,59 @@ const MapSelect = ({ ); const bboxGeoJsonLayer = useMemo( - () => BboxGeojsonLayer( - { - fetchRequest, - }, - { - zoomMin, + () => + BboxGeojsonLayer( + { + fetchRequest, + }, + { + zoomMin, - zoomMax: 15, + zoomMax: 15, - /** + /** * Function that will be used to decide whether to include a feature or not. The default is to include all * features. * * Note that this behaviour is difficult to test, hence the istanbul ignore */ - filter: /* istanbul ignore next */ feature => - selectionOnly ? selection.current.has(feature.properties[idField]) : true, + filter: /* istanbul ignore next */ feature => + selectionOnly ? selection.current.has(feature.properties[idField]) : true, - /** + /** * Function defining how GeoJSON points spawn Leaflet layers. It is internally called when data is added, * passing the GeoJSON point feature and its LatLng. * Return value overridden to have it return a marker with a specific icon * * Note that this behaviour is difficult to test, hence the istanbul ignore */ - pointToLayer: /* istanbul ignore next */ (feature, latlong) => - L.marker(latlong, { - icon: getIcon(feature.properties[iconField], selection.current.has(feature.properties[idField])), - }), + pointToLayer: /* istanbul ignore next */ (feature, latlong) => + L.marker(latlong, { + icon: getIcon(feature.properties[iconField], selection.current.has(feature.properties[idField])), + }), - /** + /** * Function called once for each created Feature, after it has been created and styled. * Attaches click handler to markers that are rendered on the map * * Note that this behaviour is difficult to test, hence the istanbul ignore */ - onEachFeature: /* istanbul ignore next */ (feature, layer) => { - if (onSelectionChange) { - // Check that the component is in write mode - layer.on({ - click: e => { - const _layer = e.target; - const id = _layer.feature.properties[idField]; - selection.current.toggle(id); - - onSelectionChange(selection.current); - }, - }); - } - }, - } - ), + onEachFeature: /* istanbul ignore next */ (feature, layer) => { + if (onSelectionChange) { + // Check that the component is in write mode + layer.on({ + click: e => { + const _layer = e.target; + const id = _layer.feature.properties[idField]; + selection.current.toggle(id); + + onSelectionChange(selection.current); + }, + }); + } + }, + } + ), [fetchRequest, getIcon, iconField, idField, onSelectionChange, selection, selectionOnly] ); @@ -208,13 +213,15 @@ const MapSelect = ({ ); return ( - + + + ); }; From c536c2e777f152809733f621a39c16f986942089 Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Thu, 16 Apr 2020 09:53:56 +0200 Subject: [PATCH 24/80] [SIG-2539] Static map component --- .../MapStatic/__tests__/MapStatic.test.js | 142 ++++++++++++++++ src/components/MapStatic/__tests__/static.jpg | Bin 0 -> 28071 bytes src/components/MapStatic/index.js | 158 ++++++++++++++++++ 3 files changed, 300 insertions(+) create mode 100644 src/components/MapStatic/__tests__/MapStatic.test.js create mode 100644 src/components/MapStatic/__tests__/static.jpg create mode 100644 src/components/MapStatic/index.js diff --git a/src/components/MapStatic/__tests__/MapStatic.test.js b/src/components/MapStatic/__tests__/MapStatic.test.js new file mode 100644 index 0000000000..479a702b51 --- /dev/null +++ b/src/components/MapStatic/__tests__/MapStatic.test.js @@ -0,0 +1,142 @@ +import React from 'react'; +import { render, cleanup } from '@testing-library/react'; +import { withAppContext } from 'test/utils'; + +import MapStatic from '..'; +import blob from './static.jpg'; + +const latitude = 52.37553393844094; +const longitude = 4.879890711122719; + +global.URL.createObjectURL = jest.fn(() => 'https://url-from-data/image.jpg'); + +fetch.mockResponse(new Blob([blob], { type: 'image/png' })); + +describe('components/MapStatic', () => { + it('should render a loading message and image placeholder', async () => { + const { queryByTestId, findByTestId } = render( + withAppContext() + ); + + expect(queryByTestId('mapStaticLoadingMessage')).toBeInTheDocument(); + expect(queryByTestId('mapStaticPlaceholder')).toBeInTheDocument(); + + await findByTestId('mapStatic'); + + expect(queryByTestId('mapStaticLoadingMessage')).not.toBeInTheDocument(); + }); + + it('should not render a loading message', async () => { + const { queryByTestId, findByTestId } = render( + withAppContext() + ); + + expect(queryByTestId('mapStaticLoadingMessage')).not.toBeInTheDocument(); + + await findByTestId('mapStatic'); + + expect(queryByTestId('mapStaticLoadingMessage')).not.toBeInTheDocument(); + }); + + it('should render an error message', async () => { + const error = new Error(); + fetch.mockRejectOnce(error); + + const { queryByTestId, findByTestId } = render( + withAppContext() + ); + + expect(queryByTestId('mapStaticError')).not.toBeInTheDocument(); + + await findByTestId('mapStatic'); + + expect(queryByTestId('mapStaticError')).toBeInTheDocument(); + }); + + it('should render a static map image', async () => { + const { queryByTestId, findByTestId } = render( + withAppContext() + ); + + expect(queryByTestId('mapStaticMap')).not.toBeInTheDocument(); + + await findByTestId('mapStatic'); + + expect(queryByTestId('mapStaticImage')).toBeInTheDocument(); + }); + + it('should render a marker', async () => { + const { queryByTestId, findByTestId, rerender } = render( + withAppContext() + ); + + await findByTestId('mapStatic'); + + expect(queryByTestId('mapStaticMarker')).toBeInTheDocument(); + + rerender( + withAppContext() + ); + + await findByTestId('mapStatic'); + + expect(queryByTestId('mapStaticMarker')).not.toBeInTheDocument(); + }); + + it('should request different formats', async () => { + const { findByTestId } = render( + withAppContext() + ); + + await findByTestId('mapStatic'); + + expect(fetch).toHaveBeenLastCalledWith(expect.stringContaining('format=jpeg'), expect.objectContaining({ responseType: 'blob' })); + + cleanup(); + + render( + withAppContext() + ); + + await findByTestId('mapStatic'); + + expect(fetch).toHaveBeenLastCalledWith(expect.stringContaining('format=gif'), expect.objectContaining({ responseType: 'blob' })); + }); + + it('should request a specific image size', async () => { + const width = 1000; + const height = 500; + + const { findByTestId } = render( + withAppContext() + ); + + await findByTestId('mapStatic'); + + const re = new RegExp(`width=${width}|height=${height}`); + + expect(fetch).toHaveBeenLastCalledWith(expect.stringMatching(re), expect.objectContaining({ responseType: 'blob' })); + }); + + it('should request specific map layers', async () => { + const layers = 'basiskaart-light'; + + const { findByTestId } = render( + withAppContext() + ); + + await findByTestId('mapStatic'); + + expect(fetch).toHaveBeenLastCalledWith(expect.stringContaining('layers=basiskaart'), expect.objectContaining({ responseType: 'blob' })); + + cleanup(); + + render( + withAppContext() + ); + + await findByTestId('mapStatic'); + + expect(fetch).toHaveBeenLastCalledWith(expect.stringContaining(`layers=${layers}`), expect.objectContaining({ responseType: 'blob' })); + }); +}); diff --git a/src/components/MapStatic/__tests__/static.jpg b/src/components/MapStatic/__tests__/static.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7a549f1e34ca736594c32ad4661b852245bda74d GIT binary patch literal 28071 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 literal 0 HcmV?d00001 diff --git a/src/components/MapStatic/index.js b/src/components/MapStatic/index.js new file mode 100644 index 0000000000..480811c53f --- /dev/null +++ b/src/components/MapStatic/index.js @@ -0,0 +1,158 @@ +import React, { Fragment, useEffect, useState } from 'react'; +import PropTypes from 'prop-types'; +import styled from 'styled-components'; +import { themeColor } from '@datapunt/asc-ui'; + +import useFetch from 'hooks/useFetch'; +import { wgs84ToRd } from 'shared/services/crs-converter/crs-converter'; + +const ImgWrapper = styled.div` + position: relative; + width: auto; + max-width: 100%; + z-index: 0; + + & > img:not(:first-of-type):last-of-type { + position: absolute; + left: calc(50% - 20px); + top: calc(50% - 20px); + pointer-events: none; + } +`; + +const Image = styled.img` + max-width: 100%; + height: auto; +`; + +const LoadingMessage = styled.small` + position: absolute; + top: calc(50% - 20px); + text-align: center; + width: 100%; +`; + +const Placeholder = styled.img` + border: 1px dashed ${themeColor('tint', 'level3')}; + background-color: ${themeColor('tint', 'level2')}; +`; + +const Error = styled(LoadingMessage)` + color: ${themeColor('secondary')}; +`; + +/** + * Component that renders a map tile of a given width and height around a center point + */ +const MapStatic = ({ + boundsScaleFactor, + className, + format, + height, + latitude, + layers, + longitude, + showLoadingMessage, + showMarker, + width, +}) => { + const { data, error, get, isLoading } = useFetch(); + const [src, setSrc] = useState(); + const { x, y } = wgs84ToRd({ latitude, longitude }); + const bbox = [ + x - width / boundsScaleFactor, + y - height / boundsScaleFactor, + x + width / boundsScaleFactor, + y + height / boundsScaleFactor, + ].join(','); + + useEffect(() => { + const params = { + bbox, + format, + height, + layers, + request: 'getmap', + srs: 'EPSG:28992', + version: '1.1.1', + width, + }; + + get('https://map.data.amsterdam.nl/maps/topografie', params, { responseType: 'blob' }); + // only execute on mount; disabling linter + // eslint-disable-next-line + }, []); + + useEffect(() => { + if (!data) return; + + setSrc(global.URL.createObjectURL(data)); + }, [data]); + + return ( + + {!src && ( + + {showLoadingMessage && isLoading && ( + Preview laden... + )} + {error && Preview kon niet geladen worden} + + + )} + + {src && ( + + + {showMarker && ( + Gepinde locatie + )} + + )} + + ); +}; + +MapStatic.defaultProps = { + boundsScaleFactor: 2, + className: '', + format: 'jpeg', + height: 300, + layers: 'basiskaart', + showMarker: true, + showLoadingMessage: true, + width: 460, +}; + +MapStatic.propTypes = { + /* The bigger the number, the higher the zoom level */ + boundsScaleFactor: PropTypes.number, + /** @ignore */ + className: PropTypes.string, + /** Supported image formats */ + format: PropTypes.oneOf(['png', 'jpeg', 'gif']), + /** Height in pixels of the image tile that should be generated */ + height: PropTypes.number, + latitude: PropTypes.number.isRequired, + layers: PropTypes.oneOf(['basiskaart', 'basiskaart-light', 'basiskaart-zwartwit']), + longitude: PropTypes.number.isRequired, + /** When false, will not show the loading message */ + showLoadingMessage: PropTypes.bool, + /** When false, will not render marker at given latitude and longitude */ + showMarker: PropTypes.bool, + /** Width in pixels of the image tile that should be generated */ + width: PropTypes.number, +}; + +export default MapStatic; From 703128faffb07298809d1172d8257ac05b27e31a Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Thu, 16 Apr 2020 12:55:01 +0200 Subject: [PATCH 25/80] Assets error message --- src/hooks/__tests__/useFetch.test.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hooks/__tests__/useFetch.test.js b/src/hooks/__tests__/useFetch.test.js index 758334e6e4..70a7faac7d 100644 --- a/src/hooks/__tests__/useFetch.test.js +++ b/src/hooks/__tests__/useFetch.test.js @@ -4,7 +4,7 @@ import { getErrorMessage } from 'shared/services/api/api'; import useFetch from '../useFetch'; -jest.mock('shared/services/api/api'); +// jest.mock('shared/services/api/api'); const URL = 'https://here-is-my.api/someId/6'; @@ -88,6 +88,7 @@ describe('hooks/useFetch', () => { it('should return errors that are thrown during fetch', async () => { const error = new Error(); + const message = getErrorMessage(error); fetch.mockRejectOnce(error); const { result, waitForNextUpdate } = renderHook(() => useFetch()); @@ -102,6 +103,7 @@ describe('hooks/useFetch', () => { await waitForNextUpdate(); expect(result.current.error).toEqual(error); + expect(result.current.error.message).toEqual(message); expect(result.current.isLoading).toEqual(false); }); From 062a08c29bf0c3678bd9b04a1d2e76956c6c47c1 Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Thu, 16 Apr 2020 12:55:43 +0200 Subject: [PATCH 26/80] Removes commented line --- src/hooks/__tests__/useFetch.test.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hooks/__tests__/useFetch.test.js b/src/hooks/__tests__/useFetch.test.js index 70a7faac7d..ff8b158750 100644 --- a/src/hooks/__tests__/useFetch.test.js +++ b/src/hooks/__tests__/useFetch.test.js @@ -4,8 +4,6 @@ import { getErrorMessage } from 'shared/services/api/api'; import useFetch from '../useFetch'; -// jest.mock('shared/services/api/api'); - const URL = 'https://here-is-my.api/someId/6'; describe('hooks/useFetch', () => { From dcac2d30f10b39f66e5228342d222918495e81ba Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Thu, 16 Apr 2020 12:58:05 +0200 Subject: [PATCH 27/80] Adds error message assertions --- src/hooks/__tests__/useFetch.test.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hooks/__tests__/useFetch.test.js b/src/hooks/__tests__/useFetch.test.js index ff8b158750..796b3b5ae0 100644 --- a/src/hooks/__tests__/useFetch.test.js +++ b/src/hooks/__tests__/useFetch.test.js @@ -127,6 +127,7 @@ describe('hooks/useFetch', () => { it('should throw on error response', async () => { const response = { status: 401, ok: false, statusText: 'Unauthorized' }; + const message = getErrorMessage(response); fetch.mockImplementation(() => response); @@ -141,8 +142,8 @@ describe('hooks/useFetch', () => { await waitForNextUpdate(); - expect(getErrorMessage).toHaveBeenCalledWith(response); expect(result.current.error).toEqual(response); + expect(result.current.error.message).toEqual(message); expect(result.current.isLoading).toEqual(false); }); @@ -204,6 +205,7 @@ describe('hooks/useFetch', () => { it('should throw on error response', async () => { const response = { status: 401, ok: false, statusText: 'Unauthorized' }; + const message = getErrorMessage(response); const formData = { ...JSONresponse, is_active: false }; const { result, waitForNextUpdate } = renderHook(() => useFetch()); @@ -222,6 +224,7 @@ describe('hooks/useFetch', () => { await waitForNextUpdate(); expect(result.current.error).toEqual(response); + expect(result.current.error.message).toEqual(message); expect(result.current.isSuccess).toEqual(false); expect(result.current.isLoading).toEqual(false); }); @@ -286,6 +289,7 @@ describe('hooks/useFetch', () => { it('should throw on error response', async () => { const response = { status: 401, ok: false, statusText: 'Unauthorized' }; + const message = getErrorMessage(response); const formData = { ...JSONresponse, is_active: false }; const { result, waitForNextUpdate } = renderHook(() => useFetch()); @@ -303,6 +307,7 @@ describe('hooks/useFetch', () => { await waitForNextUpdate(); expect(result.current.error).toEqual(response); + expect(result.current.error.message).toEqual(message); expect(result.current.isSuccess).toEqual(false); expect(result.current.isLoading).toEqual(false); }); From c98ec5f26e32f582b56d251271d136b63e137add Mon Sep 17 00:00:00 2001 From: Jasper Poppe Date: Thu, 16 Apr 2020 13:18:03 +0200 Subject: [PATCH 28/80] fix selection of all checkboxes whene onToggle prop is unset --- .../components/CheckboxList/__tests__/CheckboxList.test.js | 4 ++++ .../incident-management/components/CheckboxList/index.js | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/signals/incident-management/components/CheckboxList/__tests__/CheckboxList.test.js b/src/signals/incident-management/components/CheckboxList/__tests__/CheckboxList.test.js index 70cf95bee2..cfa9d4d214 100644 --- a/src/signals/incident-management/components/CheckboxList/__tests__/CheckboxList.test.js +++ b/src/signals/incident-management/components/CheckboxList/__tests__/CheckboxList.test.js @@ -236,6 +236,7 @@ describe('signals/incident-management/components/CheckboxList', () => { groupName="statuses" hasToggle name="status" + onToggle={() => {}} options={statuses} toggleAllLabel={toggleAllLabel} toggleNothingLabel={toggleNothingLabel} @@ -247,6 +248,7 @@ describe('signals/incident-management/components/CheckboxList', () => { const nodeListIterator = container .querySelectorAll('input[type="checkbox"]:not(:last-of-type)') .values(); + for (const checkbox of nodeListIterator) { act(() => { fireEvent.click(checkbox); @@ -316,6 +318,7 @@ describe('signals/incident-management/components/CheckboxList', () => { {}} options={statuses} toggleAllLabel={toggleAllLabel} toggleNothingLabel={toggleNothingLabel} @@ -359,6 +362,7 @@ describe('signals/incident-management/components/CheckboxList', () => { {}} options={statuses} toggleAllLabel={toggleAllLabel} toggleNothingLabel={toggleNothingLabel} diff --git a/src/signals/incident-management/components/CheckboxList/index.js b/src/signals/incident-management/components/CheckboxList/index.js index 586564b0ad..65fe682c7f 100644 --- a/src/signals/incident-management/components/CheckboxList/index.js +++ b/src/signals/incident-management/components/CheckboxList/index.js @@ -200,8 +200,8 @@ const CheckboxList = ({ setToggled(allOptionsChecked); // in case that a list of options contains of only one item, we need to call the `onToggle` - // callback function instead of the `onChange` callback - if (allOptionsChecked) { + // callback function instead of the `onChange` callback unless the `onToggle` is undefined + if (onToggle && allOptionsChecked) { onToggle(groupValue || name, allOptionsChecked); } else { onChange(groupValue || name, Array.from(modifiedState)); @@ -289,7 +289,7 @@ CheckboxList.defaultProps = { groupValue: '', hasToggle: false, onChange: () => {}, - onToggle: () => {}, + onToggle: undefined, title: null, toggleAllLabel: 'Alles selecteren', toggleNothingLabel: 'Niets selecteren', From 8b1f8ab4f822bb1d20e3f74bcaded04c5228d8fa Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Thu, 16 Apr 2020 13:40:58 +0200 Subject: [PATCH 29/80] [SIG-2539] Static map replacements --- src/components/MapStatic/index.js | 28 ++++++++----- .../services/crs-converter/crs-converter.js | 41 +++++++++++++------ .../Detail/components/Location/index.js | 24 ++++++----- .../IncidentPreview/components/Map/index.js | 30 +++----------- 4 files changed, 64 insertions(+), 59 deletions(-) diff --git a/src/components/MapStatic/index.js b/src/components/MapStatic/index.js index 480811c53f..a1d1688556 100644 --- a/src/components/MapStatic/index.js +++ b/src/components/MapStatic/index.js @@ -1,4 +1,4 @@ -import React, { Fragment, useEffect, useState } from 'react'; +import React, { Fragment, useEffect, useState, memo } from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import { themeColor } from '@datapunt/asc-ui'; @@ -8,14 +8,15 @@ import { wgs84ToRd } from 'shared/services/crs-converter/crs-converter'; const ImgWrapper = styled.div` position: relative; - width: auto; - max-width: 100%; + width: 100%; + max-width: ${({ maxWidth }) => maxWidth}px; z-index: 0; + display: block; & > img:not(:first-of-type):last-of-type { position: absolute; - left: calc(50% - 20px); - top: calc(50% - 20px); + left: calc(50% - ${({ markerSize }) => markerSize / 2}px); + top: calc(50% - ${({ markerSize }) => markerSize}px); pointer-events: none; } `; @@ -52,6 +53,7 @@ const MapStatic = ({ latitude, layers, longitude, + markerSize, showLoadingMessage, showMarker, width, @@ -90,8 +92,8 @@ const MapStatic = ({ }, [data]); return ( - - {!src && ( + + {!src ? ( {showLoadingMessage && isLoading && ( Preview laden... @@ -105,9 +107,7 @@ const MapStatic = ({ height={height} /> - )} - - {src && ( + ) : ( {showMarker && ( @@ -115,6 +115,8 @@ const MapStatic = ({ data-testid="mapStaticMarker" src="https://map.data.amsterdam.nl/dist/images/svg/marker.svg" alt="Gepinde locatie" + width={markerSize} + height={markerSize} tabIndex="-1" /> )} @@ -130,6 +132,7 @@ MapStatic.defaultProps = { format: 'jpeg', height: 300, layers: 'basiskaart', + markerSize: 40, showMarker: true, showLoadingMessage: true, width: 460, @@ -145,8 +148,11 @@ MapStatic.propTypes = { /** Height in pixels of the image tile that should be generated */ height: PropTypes.number, latitude: PropTypes.number.isRequired, + /** Indicator of the map style */ layers: PropTypes.oneOf(['basiskaart', 'basiskaart-light', 'basiskaart-zwartwit']), longitude: PropTypes.number.isRequired, + /** Size in pixels of the marker */ + markerSize: PropTypes.number, /** When false, will not show the loading message */ showLoadingMessage: PropTypes.bool, /** When false, will not render marker at given latitude and longitude */ @@ -155,4 +161,4 @@ MapStatic.propTypes = { width: PropTypes.number, }; -export default MapStatic; +export default memo(MapStatic); diff --git a/src/shared/services/crs-converter/crs-converter.js b/src/shared/services/crs-converter/crs-converter.js index 19101d26b2..730dd4d4b1 100644 --- a/src/shared/services/crs-converter/crs-converter.js +++ b/src/shared/services/crs-converter/crs-converter.js @@ -3,13 +3,29 @@ import proj4 from 'proj4'; const config = { rd: { code: 'EPSG:28992', - projection: '+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +' - + 'y_0=463000 +ellps=bessel +units=m +towgs84=565.2369,50.0087,465.658,-0.406857330322398,0.3507326' - + '76542563,-1.8703473836068,4.0812 +no_defs', + projection: + '+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +' + + 'y_0=463000 +ellps=bessel +units=m +towgs84=565.2369,50.0087,465.658,-0.406857330322398,0.3507326' + + '76542563,-1.8703473836068,4.0812 +no_defs', transformation: { resolutions: [ - 3440.640, 1720.320, 860.160, 430.080, 215.040, 107.520, 53.760, 26.880, 13.440, 6.720, - 3.360, 1.680, 0.840, 0.420, 0.210, 0.105, 0.0525, + 3440.64, + 1720.32, + 860.16, + 430.08, + 215.04, + 107.52, + 53.76, + 26.88, + 13.44, + 6.72, + 3.36, + 1.68, + 0.84, + 0.42, + 0.21, + 0.105, + 0.0525, ], bounds: [ [-285401.92, 22598.08], @@ -35,14 +51,14 @@ const config = { * * @returns {Object.} RD coordinates with keys `x` and `y`. */ -export function wgs84ToRd(wgs84Coordinates) { - const rdCoordinates = proj4(config.rd.projection, - [wgs84Coordinates.longitude, wgs84Coordinates.latitude]); +export const wgs84ToRd = wgs84Coordinates => { + const rdCoordinates = proj4(config.rd.projection, [wgs84Coordinates.longitude, wgs84Coordinates.latitude]); + return { x: rdCoordinates[0], y: rdCoordinates[1], }; -} +}; /** * Converts the given RD coordinates to WGS84 coordinates (lat, lon). @@ -54,11 +70,10 @@ export function wgs84ToRd(wgs84Coordinates) { * @returns {Object.} WGS84 coordinates with keys `latitude` * and `longitude`. */ -export function rdToWgs84(rdCoordinates) { - const wgs84Coordinates = proj4(config.rd.projection, config.wgs84.projection, - [rdCoordinates.x, rdCoordinates.y]); +export const rdToWgs84 = rdCoordinates => { + const wgs84Coordinates = proj4(config.rd.projection, config.wgs84.projection, [rdCoordinates.x, rdCoordinates.y]); return { latitude: wgs84Coordinates[1], longitude: wgs84Coordinates[0], }; -} +}; diff --git a/src/signals/incident-management/containers/IncidentDetail/components/Detail/components/Location/index.js b/src/signals/incident-management/containers/IncidentDetail/components/Detail/components/Location/index.js index 4087a050d5..4323bbb878 100644 --- a/src/signals/incident-management/containers/IncidentDetail/components/Detail/components/Location/index.js +++ b/src/signals/incident-management/containers/IncidentDetail/components/Detail/components/Location/index.js @@ -4,11 +4,11 @@ import styled from 'styled-components'; import { Button, themeSpacing } from '@datapunt/asc-ui'; import { getListValueByKey } from 'shared/services/list-helper/list-helper'; -import { smallMarkerIcon } from 'shared/services/configuration/map-markers'; import { incidentType } from 'shared/types'; import { stadsdeelList } from 'signals/incident-management/definitions'; +import MapStatic from 'components/MapStatic'; + import IconEdit from '../../../../../../../../shared/images/icon-edit.svg'; -import MapDetail from '../../../MapDetail'; const MapTile = styled.div` float: left; @@ -18,11 +18,6 @@ const MapTile = styled.div` cursor: pointer; `; -const StyledMap = styled(MapDetail)` - height: 80px; - width: 80px; -`; - const Description = styled.dd` position: relative; display: flex; @@ -52,7 +47,14 @@ const Location = ({ incident: { location }, onShowLocation, onEditLocation }) => /> - + {location.address_text ? ( @@ -64,13 +66,15 @@ const Location = ({ incident: { location }, onShowLocation, onEditLocation }) => )}
- {location.address.openbare_ruimte && location.address.openbare_ruimte} {location.address.huisnummer && location.address.huisnummer} + {location.address.openbare_ruimte && location.address.openbare_ruimte}{' '} + {location.address.huisnummer && location.address.huisnummer} {location.address.huisletter && location.address.huisletter} {location.address.huisnummer_toevoeging ? `-${location.address.huisnummer_toevoeging}` : ''}
- {location.address.postcode && location.address.postcode} {location.address.woonplaats && location.address.woonplaats} + {location.address.postcode && location.address.postcode}{' '} + {location.address.woonplaats && location.address.woonplaats}
) : ( diff --git a/src/signals/incident/components/IncidentPreview/components/Map/index.js b/src/signals/incident/components/IncidentPreview/components/Map/index.js index cc6719cdba..3b13f80818 100644 --- a/src/signals/incident/components/IncidentPreview/components/Map/index.js +++ b/src/signals/incident/components/IncidentPreview/components/Map/index.js @@ -1,18 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; -import MAP_OPTIONS from 'shared/services/configuration/map-options'; -import Map from 'components/Map'; import styled from 'styled-components'; import { Row, Column, themeSpacing } from '@datapunt/asc-ui'; import { formatAddress } from 'shared/services/map-location'; -import { Marker } from '@datapunt/react-maps'; -import { markerIcon } from 'shared/services/configuration/map-markers'; - -const StyledMap = styled(Map)` - margin-top: ${themeSpacing(4)}; - height: 300px; -`; +import MapStatic from 'components/MapStatic'; const ItemWrapper = styled.div` padding: ${themeSpacing(5, 0)}; @@ -23,15 +15,8 @@ const ItemWrapper = styled.div` * Map preview with one or more markers */ const MapPreview = ({ label, value }) => { - const location = value?.geometrie?.coordinates; - - const lat = location && location[1]; - const lng = location && location[0]; - const options = { - ...MAP_OPTIONS, - attributionControl: false, - center: [lat, lng], - }; + const longitude = value.geometrie.coordinates[0]; + const latitude = value.geometrie.coordinates[1]; return ( @@ -39,16 +24,12 @@ const MapPreview = ({ label, value }) => { {label} + {value && (
{value.address ? formatAddress(value.address) : 'Geen adres gevonden'}
- - {lat && lng && ( - - - - )} +
)}
@@ -63,7 +44,6 @@ MapPreview.propTypes = { address: PropTypes.object, geometrie: PropTypes.object, }), - mapOptions: PropTypes.shape({}) /** leaflet options */, }; export default MapPreview; From af948c83c9ea5c365013ec0a53ec29ca6b6ba971 Mon Sep 17 00:00:00 2001 From: Adrian Tudorache Date: Fri, 17 Apr 2020 08:17:56 +0200 Subject: [PATCH 30/80] fixes centering the map on click --- .../MapInput/__tests__/MapInput.test.js | 12 ++++++------ src/components/MapInput/index.js | 15 +++++++-------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/components/MapInput/__tests__/MapInput.test.js b/src/components/MapInput/__tests__/MapInput.test.js index 46772d96de..dd2c4ba391 100644 --- a/src/components/MapInput/__tests__/MapInput.test.js +++ b/src/components/MapInput/__tests__/MapInput.test.js @@ -108,7 +108,7 @@ describe('components/MapInput', () => { expect(setValuesSpy).not.toHaveBeenCalled(); - const value = { addressText: 'Foo' }; + const value = { addressText: 'Foo', ...testLocation }; rerender(withMapContext()); @@ -134,26 +134,26 @@ describe('components/MapInput', () => { movestart: movestartSpy, }; - const withMapContextState = Component => state => + const withMapContextState = state => Component => withAppContext( {} }}>{Component}); const state = { ...initialState }; const { rerender } = render( - withMapContextState()(state) + withMapContextState(state)() ); expect(movestartSpy).not.toHaveBeenCalled(); - rerender(withMapContextState()(state)); + rerender(withMapContextState(state)()); expect(movestartSpy).toHaveBeenCalled(); movestartSpy.mockClear(); const stateWithLocation = { ...state, ...testLocation }; rerender( - withMapContextState()( - stateWithLocation + withMapContextState(stateWithLocation)( + ) ); diff --git a/src/components/MapInput/index.js b/src/components/MapInput/index.js index cd5caf86d5..444bd8bf36 100644 --- a/src/components/MapInput/index.js +++ b/src/components/MapInput/index.js @@ -12,7 +12,6 @@ import MapContext from 'containers/MapContext/context'; import { setLocationAction, setValuesAction } from 'containers/MapContext/actions'; import useDelayedDoubleClick from 'hooks/useDelayedDoubleClick'; -import isEqual from 'lodash.isequal'; import Map from '../Map'; import PDOKAutoSuggest from '../PDOKAutoSuggest'; import reverseGeocoderService, { getStadsdeel } from './services/reverseGeocoderService'; @@ -121,17 +120,17 @@ const MapInput = ({ className, value, onChange, mapOptions, ...otherProps }) => useEffect(() => { if (!map) return; - if (!value?.location && !value?.addressText) return; + if (!value?.location) return; - if (value?.location?.lat > 0) { - if (!isEqual(value?.location, state.location)) { - const currentZoom = map.getZoom(); - map.flyTo(value.location, currentZoom); - } + // This ensures that the map is centered on the location only the first time the map recieves a location from outside + // because state.location.lat is 0 only when the map is initialized. + if (state.location?.lat === 0) { + const currentZoom = map.getZoom(); + map.flyTo(value.location, currentZoom); } dispatch(setValuesAction(value)); - }, [value, dispatch, map, state.location]); + }, [value, dispatch, map, state]); return ( From 727f156b4cf9ac3c153e32a1ee208bdf168ae909 Mon Sep 17 00:00:00 2001 From: Adrian Tudorache Date: Fri, 17 Apr 2020 10:44:14 +0200 Subject: [PATCH 31/80] fixes infinite loop of the state. --- src/components/MapInput/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MapInput/index.js b/src/components/MapInput/index.js index 444bd8bf36..41420b9344 100644 --- a/src/components/MapInput/index.js +++ b/src/components/MapInput/index.js @@ -130,7 +130,7 @@ const MapInput = ({ className, value, onChange, mapOptions, ...otherProps }) => } dispatch(setValuesAction(value)); - }, [value, dispatch, map, state]); + }, [value, dispatch, map, state.location]); return ( From c57b5bcf90bafd5a198ca00ef2b8d249aa2d9d60 Mon Sep 17 00:00:00 2001 From: Jasper Poppe Date: Sat, 18 Apr 2020 10:37:47 +0200 Subject: [PATCH 32/80] added tests for onChange and onToggle events --- .../__tests__/CheckboxList.test.js | 67 ++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/src/signals/incident-management/components/CheckboxList/__tests__/CheckboxList.test.js b/src/signals/incident-management/components/CheckboxList/__tests__/CheckboxList.test.js index cfa9d4d214..c739aaae63 100644 --- a/src/signals/incident-management/components/CheckboxList/__tests__/CheckboxList.test.js +++ b/src/signals/incident-management/components/CheckboxList/__tests__/CheckboxList.test.js @@ -226,6 +226,7 @@ describe('signals/incident-management/components/CheckboxList', () => { }); it('should set toggled when all boxes are checked', async () => { + const onToggleMock = jest.fn(); const groupId = 'barbazbaz'; const toggleAllLabel = 'Select all'; const toggleNothingLabel = 'Select none'; @@ -236,7 +237,7 @@ describe('signals/incident-management/components/CheckboxList', () => { groupName="statuses" hasToggle name="status" - onToggle={() => {}} + onToggle={onToggleMock} options={statuses} toggleAllLabel={toggleAllLabel} toggleNothingLabel={toggleNothingLabel} @@ -244,6 +245,8 @@ describe('signals/incident-management/components/CheckboxList', () => { ) ); + expect(onToggleMock).not.toHaveBeenCalled(); + // loop over all checkboxes but one and check them manually const nodeListIterator = container .querySelectorAll('input[type="checkbox"]:not(:last-of-type)') @@ -264,6 +267,8 @@ describe('signals/incident-management/components/CheckboxList', () => { ); }); + expect(onToggleMock).toHaveBeenCalledTimes(1); + expect(queryByText(toggleAllLabel)).not.toBeInTheDocument(); expect(getByText(toggleNothingLabel)).toBeInTheDocument(); }); @@ -491,4 +496,64 @@ describe('signals/incident-management/components/CheckboxList', () => { expect(container.querySelectorAll('input[type=checkbox][disabled]')).toHaveLength(statuses.length); }); + + it('should fire the right amount of events with onToggle set and unset', () => { + const onChangeMock = jest.fn(); + const onToggleMock = jest.fn(); + + const toggleAllLabel = 'Click here to select all'; + const toggleNothingLabel = 'Click here to undo selection'; + + const { container, rerender } = render( + withAppContext( + + ) + ); + + expect(onChangeMock).not.toHaveBeenCalled(); + expect(onToggleMock).not.toHaveBeenCalled(); + + for (const checkbox of container.querySelectorAll('input[type="checkbox"]').values()) { + act(() => { fireEvent.click(checkbox); }); + } + + // since the onToggle prop has been defined it should call it + // when all the checkboxes have been selected + expect(onChangeMock).toHaveBeenCalledTimes(statuses.length - 1); + expect(onToggleMock).toHaveBeenCalledTimes(1); + + onToggleMock.mockClear(); + onChangeMock.mockClear(); + + rerender( + withAppContext( + + ) + ); + + expect(onToggleMock).not.toHaveBeenCalled(); + + for (const checkbox of container.querySelectorAll('input[type="checkbox"]').values()) { + act(() => { fireEvent.click(checkbox); }); + } + + // since the onToggle prop has not been defined it should call the onChange event + // on every checkbox selection + expect(onToggleMock).not.toHaveBeenCalled(); + expect(onChangeMock).toHaveBeenCalledTimes(statuses.length); + }); }); From 5e42d48c4c0d3ab1d388a815e594ccba45e7667c Mon Sep 17 00:00:00 2001 From: Jasper Poppe Date: Sat, 18 Apr 2020 11:26:51 +0200 Subject: [PATCH 33/80] changed properties to alphabetical order --- .../Detail/components/UserForm/__tests__/UserForm.test.js | 1 - .../settings/users/Detail/components/UserForm/index.js | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/signals/settings/users/Detail/components/UserForm/__tests__/UserForm.test.js b/src/signals/settings/users/Detail/components/UserForm/__tests__/UserForm.test.js index 327eb95426..a07eb6831e 100644 --- a/src/signals/settings/users/Detail/components/UserForm/__tests__/UserForm.test.js +++ b/src/signals/settings/users/Detail/components/UserForm/__tests__/UserForm.test.js @@ -92,7 +92,6 @@ describe('signals/settings/users/containers/Detail/components/UserForm', () => { expect(onSubmit).not.toHaveBeenCalled(); - act(() => { fireEvent.click(getByTestId('submitBtn')); }); const submittedRoleIds = onSubmit.mock.calls[0][0].postPatch.role_ids; diff --git a/src/signals/settings/users/Detail/components/UserForm/index.js b/src/signals/settings/users/Detail/components/UserForm/index.js index b5dbeb87eb..fb3cc7fcb7 100644 --- a/src/signals/settings/users/Detail/components/UserForm/index.js +++ b/src/signals/settings/users/Detail/components/UserForm/index.js @@ -170,10 +170,10 @@ const UserForm = ({ data, onCancel, onSubmit, readOnly }) => { { onChange(field, value); }} /> @@ -182,10 +182,10 @@ const UserForm = ({ data, onCancel, onSubmit, readOnly }) => { { onChange(field, value); }} />
From cfd258d41dabffcbe22822da8c683515331afc4c Mon Sep 17 00:00:00 2001 From: JJM van Deursen Date: Mon, 20 Apr 2020 07:48:42 +0200 Subject: [PATCH 34/80] Sets image and column widths --- src/components/MapStatic/index.js | 3 ++- .../components/IncidentPreview/components/Map/index.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/MapStatic/index.js b/src/components/MapStatic/index.js index a1d1688556..b298a493a9 100644 --- a/src/components/MapStatic/index.js +++ b/src/components/MapStatic/index.js @@ -36,6 +36,7 @@ const LoadingMessage = styled.small` const Placeholder = styled.img` border: 1px dashed ${themeColor('tint', 'level3')}; background-color: ${themeColor('tint', 'level2')}; + max-width: 100%; `; const Error = styled(LoadingMessage)` @@ -109,7 +110,7 @@ const MapStatic = ({ ) : ( - + {showMarker && ( { return ( - + {label} - + {value && (
{value.address ? formatAddress(value.address) : 'Geen adres gevonden'}
From c0f9b8a13a404f6ca1477b1ae45cb589118d075b Mon Sep 17 00:00:00 2001 From: Adrian Tudorache Date: Mon, 20 Apr 2020 07:55:45 +0200 Subject: [PATCH 35/80] uses the Avenir Next font in the MapSelect controls --- src/components/MapSelect/style.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/MapSelect/style.scss b/src/components/MapSelect/style.scss index db0fb24b2d..fed0ab3673 100644 --- a/src/components/MapSelect/style.scss +++ b/src/components/MapSelect/style.scss @@ -30,6 +30,7 @@ .zoom-control { background-color: #FEC813; color: $ams-zwart; + font-family: Avenir Next LT W01, arial, sans-serif; font-size: 16px; line-height: 22px; padding: 13px; @@ -38,6 +39,7 @@ .legend-control { background-color: $ams-wit; color: $ams-zwart; + font-family: Avenir Next LT W01, arial, sans-serif; font-size: 16px; line-height: 16px; min-width: 240px; @@ -95,6 +97,7 @@ .loading-control { background-color: $ams-wit; + font-family: Avenir Next LT W01, arial, sans-serif; font-size: 16px; line-height: 22px; padding: 13px 17px; @@ -103,6 +106,7 @@ .error-control { background-color: $ams-wit; + font-family: Avenir Next LT W01, arial, sans-serif; font-size: 16px; line-height: 22px; padding: 13px 17px; From b5a165f992736b126dc4b9fda9f5bb174efb0a5b Mon Sep 17 00:00:00 2001 From: Adrian Tudorache Date: Thu, 16 Apr 2020 15:37:08 +0200 Subject: [PATCH 36/80] fixes styling in 24 hour map --- .../Map/components/DetailPanel/index.js | 20 +++++++++++++++---- .../components/Map/index.js | 2 +- .../components/SubNav/index.js | 2 ++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/signals/incident-management/containers/IncidentOverviewPage/components/Map/components/DetailPanel/index.js b/src/signals/incident-management/containers/IncidentOverviewPage/components/Map/components/DetailPanel/index.js index 8834aa8ead..550e79f284 100644 --- a/src/signals/incident-management/containers/IncidentOverviewPage/components/Map/components/DetailPanel/index.js +++ b/src/signals/incident-management/containers/IncidentOverviewPage/components/Map/components/DetailPanel/index.js @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; -import { Button, Link as AscLink } from '@datapunt/asc-ui'; +import { Button, Link as AscLink, themeColor } from '@datapunt/asc-ui'; import { Close } from '@datapunt/asc-assets'; import { Link } from 'react-router-dom'; import { INCIDENT_URL } from 'signals/incident-management/routes'; @@ -9,7 +9,7 @@ import { INCIDENT_URL } from 'signals/incident-management/routes'; const Panel = styled.div` padding: 12px; background: white; - border: 1px solid rgba(0, 0, 0, 0.1); + border: 2px solid rgba(0, 0, 0, 0.1); z-index: 401; display: flex; align-items: center; @@ -18,11 +18,23 @@ const Panel = styled.div` justify-content: space-between; `; +const IncidentLink = styled(AscLink)` + font-size: 16px; + color: ${themeColor('primary')}; + font-weight: 700; + text-decoration: none; + + &:hover { + color: ${themeColor('secondary')}; + text-decoration: underline; + } +`; + const DetailPanel = ({ incidentId, onClose }) => ( - + Melding {incidentId} - +