Skip to content

Commit

Permalink
feat [ISEEC-4459] UI: Carbon Addons react-query integration (#88)
Browse files Browse the repository at this point in the history
* feat: use react-query

* feat: add react query provider to uishell

* Update package.json

Co-authored-by: Lucas Grimauth Evangelista <Lucas.Grimauth@ibm.com>
Co-authored-by: Tim Bula <timrbula@gmail.com>
  • Loading branch information
3 people authored Oct 7, 2022
1 parent 314b7a6 commit 2dd0c89
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 146 deletions.
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@boomerang-io/carbon-addons-boomerang-react",
"description": "Carbon Addons for Boomerang apps",
"version": "2.0.12",
"version": "2.0.14",
"author": {
"name": "Tim Bula",
"email": "timrbula@gmail.com"
Expand Down Expand Up @@ -65,19 +65,21 @@
"match-sorter": "6.3.1",
"react-autosuggest": "10.1.0",
"react-modal": "3.15.1",
"react-query": "3.34.12",
"react-toastify": "9.0.7",
"window-or-global": "1.0.1"
},
"peerDependencies": {
"@carbon/icons-react": "^10.38.0",
"axios": ">=0.26.0",
"axios": ">= 0.26.0 < 1"
"carbon-components": "^10.25.0",
"carbon-components-react": "^7.25.0",
"carbon-icons": "^7.0.7",
"formik": "^2.1.5",
"prop-types": "^15.7.2",
"react": "^17.0.0 || ^16.14.0",
"react-dom": "^17.0.0 || ^16.14.0",
"react-query": "3.34.12",
"react-router-dom": "^5.3.0",
"yup": ">=0.32.11"
},
Expand Down Expand Up @@ -112,7 +114,7 @@
"@testing-library/dom": "^8.11.2",
"@testing-library/jest-dom": "^5.11.6",
"@testing-library/react": "12.1.2",
"axios": "0.26.0",
"axios": "0.27.2"
"axios-mock-adapter": "^1.20.0",
"babel-plugin-dev-expression": "^0.2.3",
"browserslist-config-carbon": "^10.6.1",
Expand Down
87 changes: 40 additions & 47 deletions src/components/PrivacyStatement/PrivacyStatement.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { useState, useEffect } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import axios from 'axios';
import { useQuery, useMutation } from 'react-query';
import dompurify from 'dompurify';
import { Accordion, AccordionItem, Button } from 'carbon-components-react';
import { ModalHeader, ModalBody, ModalFooter } from 'carbon-components-react';
import { settings } from 'carbon-components';
import { serviceUrl, resolver } from '../../config/servicesConfig';
import window from 'window-or-global';

import HeaderMenuModalWrapper from '../../internal/HeaderMenuModalWrapper';
Expand Down Expand Up @@ -39,44 +40,41 @@ PrivacyStatement.defaultProps = {
};

function PrivacyStatement({ baseServiceUrl, platformName, platformEmail }) {
const [statement, setStatement] = useState();
const [error, setError] = useState();
const [alertError, setAlertError] = useState();
const statementUrl = serviceUrl.getStatement({ baseServiceUrl });

useEffect(() => {
axios(`${baseServiceUrl}/users/consents`)
.then((response) => setStatement(response.data))
.catch((err) => setError(err));
}, [baseServiceUrl]);
const { data: statement, error: statementError } = useQuery({
queryKey: statementUrl,
queryFn: resolver.query(statementUrl),
});

function handleSubmit({ closeAlertModal, closeModal }) {
axios
.put(`${baseServiceUrl}/users/consent`, {
version: statement.version,
hasConsented: false,
})
.then(() => {
notify(
<ToastNotification
subtitle="Successfully requested account deletion"
title="Delete Account"
kind="success"
/>,
{ containerId: `${prefix}--bmrg-header-notifications` }
);
// want to clear out any error state
setError(false);
setAlertError(false);
closeAlertModal();
closeModal();
if (window.location) {
window.location.reload(true);
}
})
.catch((err) => {
setAlertError(err);
closeAlertModal();
});
const { mutateAsync: mutateUserConsent, error: mutateUserConsentError } = useMutation(resolver.putUserConsent);

const error = statementError || mutateUserConsentError;

async function handleSubmit({ closeAlertModal, closeModal }) {
const body = {
hasConsented: false,
version: statement.version,
}

try {
await mutateUserConsent({ baseServiceUrl, body });
notify(
<ToastNotification
subtitle="Successfully requested account deletion"
title="Delete Account"
kind="success"
/>,
{ containerId: `${prefix}--bmrg-header-notifications` }
);
closeAlertModal();
closeModal();
if (window.location) {
window.location.reload(true);
}
} catch {
closeAlertModal();
}
}

// TOOD: decide to do something if there is an error or not
Expand All @@ -94,13 +92,8 @@ function PrivacyStatement({ baseServiceUrl, platformName, platformEmail }) {
return (
<>
<ModalHeader
closeModal={() => {
closeModal();
setError('');
setAlertError('');
}}
label={`Effective as of ${statement ? formatDateTimestamp(statement.effectiveDate) : ''
}`}
closeModal={closeModal}
label={`Effective as of ${statement ? formatDateTimestamp(statement.effectiveDate) : ''}`}
title="Privacy Statement"
/>

Expand Down Expand Up @@ -130,9 +123,9 @@ function PrivacyStatement({ baseServiceUrl, platformName, platformEmail }) {
</a>
.
</p>
{alertError && (
{mutateUserConsentError && (
<p className={`${prefix}--bmrg-privacy-statement__error`}>
Failed to recieve deletion request. Please try again.
Failed to receive deletion request. Please try again.
</p>
)}
</div>
Expand Down
17 changes: 14 additions & 3 deletions src/components/PrivacyStatement/PrivacyStatement.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from 'react';
import { QueryClient, QueryClientProvider } from "react-query";
import { render, fireEvent, waitFor } from '@testing-library/react';

import PrivacyStatement from './PrivacyStatement.js';
Expand All @@ -10,6 +11,10 @@ import { PRIVACY_DATA } from './constants';

const baseServiceUrl = 'http://boomerang.com';

const queryClient = new QueryClient({
defaultOptions: { queries: { refetchOnWindowFocus: false }, mutations: { throwOnError: true } },
});

test('Privacy Statement error', async () => {
/**
* Simulate deleting account
Expand All @@ -29,7 +34,9 @@ test('Privacy Statement error', async () => {
mock.onPut(`${baseServiceUrl}/users/consent`).networkError();

const { getByText, getByRole, findByRole } = render(
<PrivacyStatement baseServiceUrl={baseServiceUrl} />
<QueryClientProvider client={queryClient}>
<PrivacyStatement baseServiceUrl={baseServiceUrl} />
</QueryClientProvider>
);

const btn = getByRole('button', { name: /Privacy Statement/i });
Expand All @@ -42,7 +49,7 @@ test('Privacy Statement error', async () => {
fireEvent.click(confirmButton);

await waitFor(() =>
expect(getByText(/Failed to recieve deletion request. Please try again./i)).toBeInTheDocument()
expect(getByText(/Failed to receive deletion request. Please try again./i)).toBeInTheDocument()
);
});

Expand All @@ -55,7 +62,11 @@ test('Privacy Statement success', async () => {
mock.onGet(`${baseServiceUrl}/users/consents`).reply(200, PRIVACY_DATA);
mock.onPut(`${baseServiceUrl}/users/consent`).reply(200);

const { getByRole, findByRole } = render(<PrivacyStatement baseServiceUrl={baseServiceUrl} />);
const { getByRole, findByRole } = render(
<QueryClientProvider client={queryClient}>
<PrivacyStatement baseServiceUrl={baseServiceUrl} />
</QueryClientProvider>
);

const btn = getByRole('button', { name: /Privacy Statement/i });
fireEvent.click(btn);
Expand Down
11 changes: 10 additions & 1 deletion src/components/PrivacyStatement/PrivacyStatement.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// /* eslint-disable no-console */

import React from 'react';
import { QueryClient, QueryClientProvider } from "react-query";
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';

Expand All @@ -16,6 +17,10 @@ import { PRIVACY_DATA } from './constants';

const mock = new MockAdapter(axios);

const queryClient = new QueryClient({
defaultOptions: { queries: { refetchOnWindowFocus: false }, mutations: { throwOnError: true } },
});

const props = () => ({
baseServiceUrl: 'http://ibm.com',
});
Expand All @@ -26,7 +31,11 @@ export default {

export const Default = () => {
mock.onGet('http://ibm.com/users/consents').reply(200, PRIVACY_DATA);
return <PrivacyStatement {...props()} />;
return (
<QueryClientProvider client={queryClient}>
<PrivacyStatement {...props()} />
</QueryClientProvider>
);
};

Default.story = {
Expand Down
Loading

0 comments on commit 2dd0c89

Please sign in to comment.