Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 22 additions & 1 deletion src/editors/containers/PdfEditor/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useQuery } from '@tanstack/react-query';
import { useMutation, useQuery } from '@tanstack/react-query';
import { useSelector } from 'react-redux';
import { selectors } from '@src/editors/data/redux';
import { camelizeKeys } from '@src/editors/utils';
Expand Down Expand Up @@ -72,3 +72,24 @@ export const useBlockHandlerData = <T>({
},
});
};

export const usePdfConversion = (blockId: string) => {
const studioEndpointUrl = useSelector(selectors.app.studioEndpointUrl)!;
const isLibrary = useSelector(selectors.app.isLibrary);
const client = getAuthenticatedHttpClient();
return useMutation({
mutationFn: async (url: string) => {
const result = await client.post(
await deriveHandlerUrl({
blockId,
studioEndpointUrl,
handlerName: 'convert_pdf',
isLibrary,
client,
}),
{ url },
);
return result.data.url as string;
},
});
};
34 changes: 32 additions & 2 deletions src/editors/containers/PdfEditor/components/PdfEditingModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { UploadWidget } from '@src/editors/sharedComponents/UploadWidget';
import { Spinner } from '@openedx/paragon';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import messages from './messages';
import { FieldSaverArgs } from '@src/editors/sharedComponents/UploadWidget/UploadWidget';
import { usePdfConversion } from '@src/editors/containers/PdfEditor/api';

const EditorWrapper: React.FC<PropsWithChildren> = ({ children }) => {
const intl = useIntl();
Expand Down Expand Up @@ -44,6 +46,7 @@ const PdfEditingModal: React.FC<EditorComponent> = (props) => {
const { fields, blockId, isLibrary } = useContext(PdfBlockContext);
const originalState = useRef({ ...fields });
const { values, setValues } = useFormikContext<PdfState>();
const mutation = usePdfConversion(blockId);

useEffect(() => {
// Form is initialized before we get these values, so we have to set them
Expand All @@ -57,19 +60,46 @@ const PdfEditingModal: React.FC<EditorComponent> = (props) => {
const settings = { ...values };
// disableAllDownload is not a setting we control, but a backend flag. Have to remove it or the
// backend will reject.
return Object.fromEntries(Object.entries(settings).filter(([key]) => key !== 'disableAllDownload'));
const ignored = ['disableAllDownload', 'conversionAvailable'];
return Object.fromEntries(Object.entries(settings).filter(([key]) => !ignored.includes(key)));
};

const supportedFormats = ['application/pdf'];
if (values.conversionAvailable) {
supportedFormats.push(
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.oasis.opendocument.presentation',
'application/vnd.oasis.opendocument.spreadsheet',
'application/vnd.oasis.opendocument.text',
'application/vnd.ms-powerpoint',
'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'application/rtf',
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
);
}

const saver = async (args: FieldSaverArgs<string>) => {
if (!values.conversionAvailable || args.sourceFile.type == 'application/pdf') {
// No conversion means no swapping of file values-- just set the field value and be done.
return args.control.setValue(args.value);
}
const pdfUrl = await mutation.mutateAsync(args.value);
await setValues({ ...values, url: pdfUrl, sourceUrl: args.value });
};

return (
<EditorContainer {...props} isDirty={isDirty} getContent={getContent}>
<EditorWrapper>
<div className="mt-2">
<UploadWidget
supportedFileFormats="application/pdf"
supportedFileFormats={supportedFormats}
urlFieldName="url"
label={intl.formatMessage(messages.urlFieldLabel)}
blockId={blockId}
isLibrary={isLibrary}
saveField={saver}
id="pdf-url"
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import React, { useContext } from 'react';
import { useFormikContext } from 'formik';
import { PdfState } from '@src/editors/containers/PdfEditor/contexts';
import { PdfBlockContext, PdfState } from '@src/editors/containers/PdfEditor/contexts';
import { optional, useUrlValidator } from '@src/editors/utils/validators';
import { useIntl } from '@edx/frontend-platform/i18n';
import CheckboxField from '@src/editors/sharedComponents/CheckboxField';
Expand All @@ -10,7 +10,8 @@ import messages from './messages';
const DownloadOptions: React.FC = () => {
const intl = useIntl();
const { values } = useFormikContext<PdfState>();
const urlValidator = optional(useUrlValidator());
const { isLibrary } = useContext(PdfBlockContext);
const urlValidator = optional(useUrlValidator({ allowAbsolute: isLibrary }));
if (values.disableAllDownload) {
// Download configuration is disabled at the instance-level, so don't even show these options.
return <></>; // eslint-disable-line react/jsx-no-useless-fragment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ const messages = defineMessages({
},
sourceUrlHint: {
id: 'authoring.pdfEditor.formGroups.downloadOptions.sourceUrl.hint',
defaultMessage: 'Add a link to the original or editable file (e.g. Word or PowerPoint). Appears as a separate link.',
defaultMessage: 'Add a link to the original or editable file (e.g. Word or PowerPoint). Appears as a separate '
+ 'link. You are encouraged to provide this link when auto-generating PDFs, and to ensure this source document '
+ 'conforms to accessibility standards.',
description: 'Hint for the field used to specify the URL of a source document a PDF was generated from.',
},
});
Expand Down
5 changes: 4 additions & 1 deletion src/editors/containers/PdfEditor/contexts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ export interface PdfState {
allowDownload: boolean;
sourceText: string;
sourceUrl: string;
// Note: Not a field, so can't be set.
// Note: The following are not fields, so can't be set.
// They're indicators of backend settings.
disableAllDownload: boolean;
conversionAvailable: boolean;
}

declare interface PdfBlockContextInterface {
Expand All @@ -35,6 +37,7 @@ export const initialPdfState: () => PdfState = () => ({
sourceText: '',
sourceUrl: '',
disableAllDownload: false,
conversionAvailable: false,
});

export const PdfBlockContext = createContext<PdfBlockContextInterface>({
Expand Down
Loading