Skip to content

Commit

Permalink
adds conditional cookie banner for notifying users that data is being…
Browse files Browse the repository at this point in the history
… collected
  • Loading branch information
seanfeld committed Jul 20, 2023
1 parent 5679f91 commit 3e45953
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 1 deletion.
110 changes: 110 additions & 0 deletions app/cdap/components/CookieBanner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright © 2023 Cask Data, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
import React, { useState } from 'react';
import styled from 'styled-components';
import Modal from '@material-ui/core/modal';
import Button from '@material-ui/core/Button';
import Container from '@material-ui/core/Container';
import Cookies from 'universal-cookie';
import T from 'i18n-react';

const okText = 'commons.gotIt';
const learnMore = 'commons.learnMore';

const thirteenMonths = new Date();
thirteenMonths.setMonth(thirteenMonths.getMonth() + 13);

const cookies = new Cookies();
const cdapDataCookieWithTag = (tag: string) => {
return `CDAP_DATA_CONSENT_COOKIE_${tag}`;
};

interface IBannerProps {
cookieName: string;
cookieLink: string;
cookieText: string;
}

type IModalBodyProps = Omit<IBannerProps, 'cookieName'> & {
closeModal: () => void;
};

const ModalContainer = styled(Container)`
background-color: white;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 20px;
`;

const ModalBody = ({ cookieLink, cookieText, closeModal }: IModalBodyProps) => {
return (
<ModalContainer fixed maxWidth="sm">
<div>
<span>
{cookieText} <a href={cookieLink}>{T.translate(learnMore).toString()}</a>
</span>
</div>
<Button style={{ float: 'right' }} onClick={closeModal}>
{T.translate(okText).toString()}
</Button>
</ModalContainer>
);
};

/**
* If the user has analytics enabled and if the consent cookie doesn't exist
* on their computer, show the cookie banner
*/
export const CookieBanner = () => {
const gtm = window.CDAP_CONFIG.googleTagManager;
if (gtm === '') {
return null;
}
const cookieText = window.CDAP_CONFIG.cookieBannerText;
const cookieLink = window.CDAP_CONFIG.cookieBannerLink;
const dataCookie = cdapDataCookieWithTag(gtm);
const cdapDataConsented = cookies.get(dataCookie);
if (!cdapDataConsented && cookieLink !== '' && cookieText !== '') {
return <Banner cookieName={dataCookie} cookieLink={cookieLink} cookieText={cookieText} />;
}

return null;
};

const Banner = ({ cookieName, cookieLink, cookieText }: IBannerProps) => {
const [modalOpen, setModalOpen] = useState(true);

const handleClose = () => {
setModalOpen(false);
cookies.set(cookieName, true, {
expires: thirteenMonths,
path: '/',
});
};

return (
<Modal
open={modalOpen}
onClose={handleClose}
aria-labelledby="simple-modal-title"
aria-describedby="simple-modal-description"
>
<ModalBody closeModal={handleClose} cookieLink={cookieLink} cookieText={cookieText} />
</Modal>
);
};
2 changes: 2 additions & 0 deletions app/cdap/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import ee from 'event-emitter';
import globalEvents from 'services/global-events';
import { handlePageLevelError, objectQuery, setupExperiments } from 'services/helpers';
import history from 'services/history';
import { CookieBanner } from 'components/CookieBanner';
// See ./graphql/fragements/README.md
import introspectionQueryResultData from '../../graphql/fragments/fragmentTypes.json';

Expand Down Expand Up @@ -365,6 +366,7 @@ class CDAP extends Component {
objectQuery(this.state, 'pageLevelError', 'errorCode') === 403;
return (
<Router history={history}>
<CookieBanner />
<ApolloProvider client={client}>
<div className="cdap-container">
<Helmet title={Theme.productName} />
Expand Down
2 changes: 2 additions & 0 deletions app/cdap/text/text-en.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ commons:
apply: Apply
as: as
back: Back
learnMore: Learn More
gotIt: Ok, Got it.
cask: CASK
cdap: CDAP
clickhere: click here
Expand Down
4 changes: 3 additions & 1 deletion server/config/development/cdap.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@
"session.secret.key": "sample-secret-key-for-encryption",
"feature.lifecycle.management.edit.enabled": "true",
"ui.analyticsTag": "",
"ui.GTM": ""
"ui.GTM": "",
"ui.cookieBannerText": "",
"ui.cookieBannerLink": ""
}
3 changes: 3 additions & 0 deletions server/express.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ function makeApp(authAddress, cdapConfig, uiSettings) {
featureFlags: cdapConfig.featureFlags,
analyticsTag: cdapConfig['ui.analyticsTag'],
googleTagManager: cdapConfig['ui.GTM'],
cookieBannerText: cdapConfig['ui.cookieBannerText'],
cookieBannerLink: cdapConfig['ui.cookieBannerLink']

});

res.header({
Expand Down

0 comments on commit 3e45953

Please sign in to comment.