Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Production deploy #553

Merged
merged 37 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
7b0679f
Add basic page view for journal pdf
frozenhelium Aug 16, 2023
b0619c9
Add contents for journal pdf preview
frozenhelium Aug 23, 2023
2f91526
Add download button for journal pdf
frozenhelium Aug 29, 2023
8036326
Update end-point for journal pdf download
frozenhelium Aug 29, 2023
013cfc6
update text for pdf mode
kamicut Aug 30, 2023
ea8bc10
Match cases where retry=true is not the first query param
sunu Aug 31, 2023
ae72ac9
Merge pull request #539 from NASA-IMPACT/feature/journal-pdf
wrynearson Aug 31, 2023
35d5784
Merge pull request #540 from NASA-IMPACT/feature/756-pdf-modal
wrynearson Aug 31, 2023
742f3eb
Fix failing build due to wrong import (#541)
frozenhelium Aug 31, 2023
999920b
Fix MFA prompt when user initially skips it (#542)
frozenhelium Sep 7, 2023
befb13c
get errors from server
kamicut Sep 12, 2023
187b46b
Add reviewer info in the PDF type atbd
frozenhelium Sep 17, 2023
86c9ffe
Hide sections without content in journal pdf
frozenhelium Sep 18, 2023
e161d5b
Add contacts and references section in journal pdf export
frozenhelium Sep 18, 2023
b411e36
Merge pull request #544 from NASA-IMPACT/fix/779-title-error
wrynearson Sep 25, 2023
43f52cb
Merge pull request #546 from NASA-IMPACT/feature/journal-pdf-contact-…
wrynearson Sep 25, 2023
d7008f8
Merge pull request #545 from NASA-IMPACT/feature/pdf-atbd-reviewer-info
wrynearson Sep 25, 2023
e05b30b
Add MFA tooltip
kamicut Sep 26, 2023
c0e037c
Merge pull request #547 from NASA-IMPACT/feature/mfa-tooltip
wrynearson Sep 26, 2023
75dd331
center title in journal PDF
kamicut Sep 28, 2023
3d58f2a
rm Version, Release Date and DOI from journal PDF
kamicut Sep 28, 2023
26efc4d
rm double colon in keywords
kamicut Sep 28, 2023
d7567cc
Fix affiliations section in header - journal
kamicut Sep 28, 2023
eb6313a
bullet point after line breaks in journal
kamicut Sep 28, 2023
6acc581
add a break before the abstract
kamicut Sep 28, 2023
31e0995
Add table numbers
vgeorge Oct 3, 2023
a68f9ac
Add table numbers to document pdf
vgeorge Oct 3, 2023
82efd4e
Align captions left
vgeorge Oct 4, 2023
cc20a6d
Merge pull request #549 from NASA-IMPACT/add/table-numbers
vgeorge Oct 4, 2023
5654f85
Use same style for view mode & edit mode in lists
kamicut Oct 4, 2023
fa8d957
Add secondary button link to video
kamicut Oct 4, 2023
793d4a5
Merge pull request #548 from NASA-IMPACT/fix/journal-styling
wrynearson Oct 5, 2023
6d3262d
update-mathmatical-theory-tooltips
wrynearson Oct 5, 2023
fe40a2f
update prompt to include retrieval uncertainties
wrynearson Oct 5, 2023
9c4695e
update performance assessment - uncertainties tooltip
wrynearson Oct 5, 2023
1d0edc7
Merge pull request #551 from NASA-IMPACT/feature/request-review-video
wrynearson Oct 5, 2023
c334d3c
Merge pull request #552 from NASA-IMPACT/fix/update-mathmatical-theor…
wrynearson Oct 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 32 additions & 2 deletions app/assets/scripts/a11n/signin.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { SectionFieldset } from '../components/common/forms/section-fieldset';
import { FormikInputText } from '../components/common/forms/input-text';
import { createProcessToast } from '../components/common/toasts';
import { useUser } from '../context/user';
import FormInfoTip from '../components/common/forms/form-info-tooltip';

const OTPModal = styled(Modal)`
max-width: 24rem;
Expand Down Expand Up @@ -114,7 +115,10 @@ function SignIn() {
const loggedUser = await Auth.signIn(email, password);
setUser(loggedUser);

if (loggedUser.preferredMFA === 'NOMFA') {
if (
loggedUser.challengeName === 'MFA_SETUP' ||
loggedUser.preferredMFA === 'NOMFA'
) {
toastRef.current.update('Please setup OTP using Authenticator app.');
const secretCode = await Auth.setupTOTP(loggedUser);
setMfaCode(secretCode);
Expand Down Expand Up @@ -189,7 +193,33 @@ function SignIn() {
{!mfaEnabled && mfaCode && (
<Backdrop>
<OTPModal>
<h2>Set-up OTP</h2>
<h2>
Set-up OTP
<FormInfoTip
html={
<p>
A one-time password (OTP) increases the security of your APT
account. To use OTP with APT, you&apos;ll need to download
an application (sometimes referred to as MFA) that generates
a time-sensitive code (OTP) that is entered upon login. APT
doesn&apos;t endorse any particular application, but some
include{' '}
<a href='https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2'>
Google Authenticator
</a>{' '}
(Android, iOS),{' '}
<a href='https://www.microsoft.com/en/security/mobile-authenticator-app'>
Microsoft Authenticator
</a>{' '}
(Android, iOS), and{' '}
<a href='https://1password.com/'>1Password</a> (Android,
iOS, Mac, PC, Linux, web browser). Please follow the
respective application&apos;s instructions for how to
install and setup the OTP generator.
</p>
}
/>
</h2>
<div>
Please use the following code or QR to generate Time-based OTP
from the Authenticator app.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ const TooltipTagComponent = React.forwardRef((props, ref) => (

TooltipTagComponent.displayName = 'TooltipTagComponent';

export default function FormInfoTip({ title }) {
export default function FormInfoTip({ title, ...rest }) {
return (
<Tip title={title} tag={TooltipTagComponent} interactive>
<Tip title={title} tag={TooltipTagComponent} interactive {...rest}>
More information
</Tip>
);
Expand Down
8 changes: 5 additions & 3 deletions app/assets/scripts/components/common/forms/input-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { FormHelperMessage } from '@devseed-ui/form';

import FormGroupStructure from './form-group-structure';
import { RichTextEditor, InlineRichTextEditor } from '../../slate';
import { IMAGE_BLOCK } from '../../slate/plugins/constants';

function validateImageBlock(value) {
const imageBlocks = value?.children?.filter(
(slateElement) => slateElement.type === 'image-block'
);
const imageBlocks =
value?.children?.filter(
(slateElement) => slateElement.type === IMAGE_BLOCK
) ?? [];

if (imageBlocks.length > 0) {
const captions = imageBlocks.map(
Expand Down
124 changes: 85 additions & 39 deletions app/assets/scripts/components/documents/document-download-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { createProcessToast } from '../common/toasts';

import { apiUrl } from '../../config';
import { useAuthToken } from '../../context/user';
import { axiosAPI } from '../../utils/axios';

function DropMenuItemOutboundLink(props) {
const { eventLabel, menuItem, active, ...rest } = props;
Expand Down Expand Up @@ -40,35 +41,46 @@ export default function DocumentDownloadMenu(props) {
// Temporarily disable journal PDF downloading https://github.com/nasa-impact/nasa-apt/issues/744
// const ability = useContextualAbility();
//const canDownloadJournalPdf = ability.can('download-journal-pdf', atbd);
const canDownloadJournalPdf = false;
const [canDownloadJournalPdf, setCanDownloadJournalPdf] =
React.useState(false);

const handlePdfDownloadClick = React.useCallback(() => {
const processToast = createProcessToast('Downloading PDF, please wait...');
React.useEffect(() => {
async function fetchBootstrap() {
try {
const headers = {};
const response = await axiosAPI({
url: 'bootstrap',
headers
});

if (atbd.documentType === 'PDF' && !atbd.pdf) {
processToast.error("This ATBD doesn't have the attachment");
return;
if (response?.data?.feature_flags?.JOURNAL_PDF_EXPORT_ENABLED) {
setCanDownloadJournalPdf(true);
}
} catch (error) {
// eslint-disable-next-line no-console
console.error(error);
setCanDownloadJournalPdf(false);
}
}

const { id, version, alias } = atbd;
const pdfUrl =
atbd.documentType === 'PDF'
? atbd.pdf.file_path
: `${apiUrl}/atbds/${id}/versions/${version}/pdf`;

const pdfFileName = `${alias}-v${version}.pdf`;
const maxRetries = 50;
const waitBetweenTries = 5000;
const initialWait = 10000;
let retryCount = 0;
if (atbd.document_type === 'HTML') {
fetchBootstrap();
}
}, [atbd]);

async function fetchPdf(url) {
const fetchPdf = React.useCallback(
async (url, fileName, processToast, retryCount = 0) => {
if (retryCount > 0) {
processToast.update(
'Generating the PDF. This may take up to 5 minutes.'
);
}

const retryUrl =
retryCount === 0
? `${url}${url.includes('?') ? '&' : '?'}retry=true`
: url;

try {
let user;
let headers = {};
Expand Down Expand Up @@ -104,18 +116,22 @@ export default function DocumentDownloadMenu(props) {
headers
});

const maxRetries = 50;
const waitBetweenTries = 5000;
const initialWait = 10000;
let retryCount = 0;

// If we get a 404 on retry, it means the PDF is not ready yet.
// Keep retrying until we reach the max retry count.
if (
response.status === 404 &&
response.headers.get('content-type') === 'application/json' &&
url.includes('?retry=true')
url.includes('retry=true')
) {
if (retryCount < maxRetries) {
setTimeout(() => {
fetchPdf(`${pdfUrl}?retry=true`);
fetchPdf(retryUrl, fileName, processToast, retryCount + 1);
}, waitBetweenTries);
++retryCount;
} else {
processToast.error(
'Failed to download PDF. Please retry after several minutes. If this error persists, please contact the APT team.'
Expand All @@ -137,9 +153,8 @@ export default function DocumentDownloadMenu(props) {
}

setTimeout(() => {
fetchPdf(`${pdfUrl}?retry=true`);
fetchPdf(retryUrl, fileName, processToast, retryCount + 1);
}, initialWait);
++retryCount;

return;
}
Expand All @@ -152,7 +167,7 @@ export default function DocumentDownloadMenu(props) {
) {
const result = await response.json();

saveAs(result.pdf_url, pdfFileName);
saveAs(result.pdf_url, fileName);
processToast.success(
'PDF downloaded successfully! If the PDF did not open automatically, your browser may have blocked the download. Please make sure that popups are allowed on this site.'
);
Expand All @@ -163,12 +178,41 @@ export default function DocumentDownloadMenu(props) {
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
processToast.error('Failed to download PDF!');
processToast.error('Failed to download the PDF!');
}
},
[token, atbd]
);

const handlePdfDownloadClick = React.useCallback(() => {
const processToast = createProcessToast('Downloading PDF, please wait...');

if (atbd.document_type === 'PDF' && !atbd.pdf) {
processToast.error("This ATBD doesn't have the attachment");
return;
}

fetchPdf(pdfUrl);
}, [token, atbd]);
const { id, version, alias } = atbd;
const pdfUrl =
atbd.document_type === 'PDF'
? atbd.pdf.file_path
: `${apiUrl}/atbds/${id}/versions/${version}/pdf`;

const pdfFileName = `${alias}-v${version}.pdf`;
fetchPdf(pdfUrl, pdfFileName, processToast);
}, [atbd, fetchPdf]);

const handleJournalPdfDownloadClick = React.useCallback(() => {
const processToast = createProcessToast(
'Downloading Journal PDF, please wait...'
);

const { id, version, alias } = atbd;
const pdfUrl = `${apiUrl}/atbds/${id}/versions/${version}/pdf?journal=true`;

const pdfFileName = `Journal-${alias}-v${version}.pdf`;
fetchPdf(pdfUrl, pdfFileName, processToast);
}, [atbd, fetchPdf]);

const dropProps = useMemo(() => {
const triggerProps = {
Expand All @@ -184,21 +228,24 @@ export default function DocumentDownloadMenu(props) {
// Therefore if the minor version is a 4, we know that there are also pdf
// for minor 3, 2, 1 and 0. The urls are constructed dynamically.
let pdfLinks = [];
const { id, version } = atbd;
const pdfUrl = `${apiUrl}/atbds/${id}/versions/${version}/pdf`;
const { version } = atbd;

if (canDownloadJournalPdf) {
pdfLinks.push({
id: `${version}-journal`,
id: `${version}-journal-pdf`,
label: `${version} Journal PDF`,
title: `Download journal for version ${version}`,
href: `${pdfUrl}?journal=true${token ? `&token=${token}` : ''}`,
/* eslint-disable-next-line react/display-name */
render: (props) => (
<DropMenuItemOutboundLink
{...props}
eventLabel={`Journal PDF ${id}/${version}`}
/>
render: (p) => (
<DropMenuItemEnhanced
data-dropdown='click.close'
key={p.id}
eventLabel={`Journal PDF ${atbd.id}/${version}`}
onClick={handleJournalPdfDownloadClick}
title={p.menuItem.title}
>
{p.menuItem.label}
</DropMenuItemEnhanced>
)
});
}
Expand All @@ -207,7 +254,6 @@ export default function DocumentDownloadMenu(props) {
id: `${version}-document`,
label: `${version} Document PDF`,
title: `Download document for version ${version}`,
href: `${pdfUrl}${token ? `?token=${token}` : ''}`,
/* eslint-disable-next-line react/display-name */
render: (p) => {
return (
Expand All @@ -234,10 +280,10 @@ export default function DocumentDownloadMenu(props) {
}, [
hideText,
variation,
token,
atbd,
canDownloadJournalPdf,
handlePdfDownloadClick
handlePdfDownloadClick,
handleJournalPdfDownloadClick
]);

return (
Expand Down
Loading
Loading