Skip to content

Commit

Permalink
allow html for request description
Browse files Browse the repository at this point in the history
  • Loading branch information
Ducica committed Nov 26, 2024
1 parent 47c5c06 commit 08f5f9d
Show file tree
Hide file tree
Showing 13 changed files with 79 additions and 13 deletions.
Binary file modified oarepo_requests/translations/cs/LC_MESSAGES/messages.mo
Binary file not shown.
2 changes: 1 addition & 1 deletion oarepo_requests/translations/cs/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ msgid "requestDeleted"
msgstr "{{creatorLabel}} smazal(a) tuto žádost"

msgid "requestCommented"
msgstr "{{creatorLabel}} komentoval(a)"
msgstr "komentoval(a)"

#: /home/ron/prace/oarepo-requests/oarepo_requests/actions/delete_published_record.py:9
msgid "Permanently delete"
Expand Down
Binary file modified oarepo_requests/translations/en/LC_MESSAGES/messages.mo
Binary file not shown.
2 changes: 1 addition & 1 deletion oarepo_requests/translations/en/LC_MESSAGES/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ msgid "requestDeleted"
msgstr "{{creatorLabel}} deleted this request"

msgid "requestCommented"
msgstr "{{creatorLabel}} commented"
msgstr "commented"

#: /home/ron/prace/oarepo-requests/oarepo_requests/actions/delete_published_record.py:9
msgid "Permanently delete"
Expand Down
Binary file modified oarepo_requests/translations/messages.mo
Binary file not shown.
2 changes: 1 addition & 1 deletion oarepo_requests/translations/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-11-25 22:02+0100\n"
"POT-Creation-Date: 2024-11-26 11:39+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,32 @@ import React from "react";
import { RichEditor } from "react-invenio-forms";
import sanitizeHtml from "sanitize-html";
import PropTypes from "prop-types";
import { useQueryClient } from "@tanstack/react-query";

export const RequestCommentInput = ({
comment,
handleChange,
initialValue,
}) => {
// when focused move the cursor at the end of any existing content
const handleFocus = (event, editor) => {
editor.selection.select(editor.getBody(), true);
editor.selection.collapse(false);
};

const queryClient = useQueryClient();
// the request for request specific info, shall be already fetched at this point
const data = queryClient.getQueriesData({
queryKey: ["applicableCustomFields"],
});

let allowedHtmlAttrs;
let allowedHtmlTags;
if (data.length > 0) {
allowedHtmlAttrs = data[0][1]?.data?.allowedHtmlAttrs;
allowedHtmlTags = data[0][1]?.data?.allowedHtmlTags;
}

return (
<RichEditor
initialValue={initialValue}
Expand All @@ -24,8 +39,10 @@ export const RequestCommentInput = ({
"blocks | bold italic | bullist numlist | outdent indent | undo redo",
}}
onEditorChange={(event, editor) => {
console.log(editor.getContent());
const cleanedContent = sanitizeHtml(editor.getContent());
const cleanedContent = sanitizeHtml(editor.getContent(), {
allowedTags: allowedHtmlTags,
allowedAttributes: allowedHtmlAttrs,
});
handleChange(event, cleanedContent);
}}
onFocus={handleFocus}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from "react";
import PropTypes from "prop-types";
import { Grid } from "semantic-ui-react";
import {} from "react-invenio-forms";
import {
SideRequestInfo,
RequestCustomFields,
Timeline,
} from "@js/oarepo_requests_common";
import { i18next } from "@translations/oarepo_requests_ui/i18next";
import sanitizeHtml from "sanitize-html";

/**
* @typedef {import("../../record-requests/types").Request} Request
Expand All @@ -20,16 +20,24 @@ export const RequestModalContent = ({
request,
customFields,
modalActions,
allowedHtmlAttrs,
allowedHtmlTags,
}) => {
/** @type {{requests: Request[], setRequests: (requests: Request[]) => void}} */

const description = request?.stateful_description || request?.description;

const sanitizedDescription = sanitizeHtml(description, {
allowedTags: allowedHtmlTags,
allowedAttributes: allowedHtmlAttrs,
});

return (
<Grid doubling stackable>
<Grid.Row>
{description && (
<Grid.Column as="p" id="request-modal-desc">
{description}{" "}
<span dangerouslySetInnerHTML={{ __html: sanitizedDescription }} />{" "}
<a
href={request?.links?.self_html}
target="_blank"
Expand Down Expand Up @@ -63,4 +71,6 @@ RequestModalContent.propTypes = {
request: PropTypes.object.isRequired,
customFields: PropTypes.object,
modalActions: PropTypes.array,
allowedHtmlAttrs: PropTypes.object,
allowedHtmlTags: PropTypes.array,
};
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ export const RequestModalContentAndActions = ({
}
);
const customFields = data?.data?.custom_fields;
const allowedHtmlAttrs = data?.data?.allowedHtmlAttrs;
const allowedHtmlTags = data?.data?.allowedHtmlTags;

const requestTypeProperties = data?.data?.request_type_properties;
const isMutating = useIsMutating();
const modalActions = mapLinksToActions(
Expand Down Expand Up @@ -74,6 +77,8 @@ export const RequestModalContentAndActions = ({
onCompletedAction={onSubmit}
customFields={customFields}
modalActions={modalActions}
allowedHtmlAttrs={allowedHtmlAttrs}
allowedHtmlTags={allowedHtmlTags}
/>
</Modal.Content>
<Modal.Actions>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,43 @@ import React from "react";
import PropTypes from "prop-types";
import { Form, Divider } from "semantic-ui-react";
import { CustomFields } from "react-invenio-forms";
import sanitizeHtml from "sanitize-html";

/**
* @typedef {import("../../record-requests/types").RequestType} RequestType
* @typedef {import("formik").FormikConfig} FormikConfig
*/

/** @param {{ requestType: RequestType, customSubmitHandler: (e) => void }} props */
export const CreateRequestModalContent = ({ requestType, customFields }) => {
export const CreateRequestModalContent = ({
requestType,
customFields,
allowedHtmlAttrs,
allowedHtmlTags,
}) => {
const description =
requestType?.stateful_description || requestType?.description;

const sanitizedDescription = sanitizeHtml(description, {
allowedTags: allowedHtmlTags,
allowedAttributes: allowedHtmlAttrs,
});

return (
<>
{description && <p id="request-modal-desc">{description}</p>}
{description && (
<p
id="request-modal-desc"
dangerouslySetInnerHTML={{ __html: sanitizedDescription }}
></p>
)}
{customFields?.ui && (
<Form id="request-form">
<CustomFields
config={customFields?.ui}
templateLoaders={[
(widget) => import(`@templates/custom_fields/${widget}.js`),
() => import(`react-invenio-forms`),
(widget) => import(`react-invenio-forms`),
]}
fieldPathPrefix="payload"
/>
Expand All @@ -35,4 +52,6 @@ export const CreateRequestModalContent = ({ requestType, customFields }) => {
CreateRequestModalContent.propTypes = {
requestType: PropTypes.object.isRequired,
customFields: PropTypes.object,
allowedHtmlAttrs: PropTypes.object,
allowedHtmlTags: PropTypes.array,
};
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
} from "@js/oarepo_requests_common";
import { Formik } from "formik";
import _isEmpty from "lodash/isEmpty";
import sanitizeHtml from "sanitize-html";

export const RequestDetail = ({
request,
Expand All @@ -45,6 +46,9 @@ export const RequestDetail = ({
}
);
const customFields = data?.data?.custom_fields;
const allowedHtmlAttrs = data?.data?.allowedHtmlAttrs;
const allowedHtmlTags = data?.data?.allowedHtmlTags;

const requestTypeProperties = data?.data?.request_type_properties;
const actions = mapLinksToActions(
request,
Expand Down Expand Up @@ -72,6 +76,11 @@ export const RequestDetail = ({

const requestHeader = request?.stateful_name || request?.name;
const description = request?.stateful_description || request?.description;
const sanitizedDescription = sanitizeHtml(description, {
allowedTags: allowedHtmlTags,
allowedAttributes: allowedHtmlAttrs,
});

return (
<CallbackContextProvider
value={{ onBeforeAction, onAfterAction, onActionError }}
Expand Down Expand Up @@ -122,7 +131,13 @@ export const RequestDetail = ({
<Grid.Row>
<Grid.Column>
<Header as="h1">{requestHeader}</Header>
{description && <p>{description}</p>}
{description && (
<p
dangerouslySetInnerHTML={{
__html: sanitizedDescription,
}}
></p>
)}
<SideRequestInfo request={request} />
</Grid.Column>
</Grid.Row>
Expand Down
Loading

0 comments on commit 08f5f9d

Please sign in to comment.