-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* add roles and packages * BE: create model, migration, add new role to constants, add basic resource * create reducer, add to root, add keys to routes * create HelpGuide component. Copy in rich text editor from prototype, improve later * add to CORE header. Refactor CORE navbar * change MS Header to TS and add in help guide. Add in basic CSS rules for tooltips in editor * fix bugs, add missing functionality * extract HelpGuide interface * fix a couple style things on MS, make sure delete is disabled properly * fix a bug on MS, sanitize HTML, and test sanitization of HTML on MS * BE testing * MDS-4971 Updated webpack css chunk filename for MiniCssExtractPlugin to fix webpack bundle issue --------- Co-authored-by: Simen Fivelstad Smaaberg <66635118+simensma-fresh@users.noreply.github.com>
- Loading branch information
1 parent
626d094
commit ad29b1a
Showing
58 changed files
with
3,404 additions
and
823 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
CREATE TABLE IF NOT EXISTS help ( | ||
help_guid uuid DEFAULT gen_random_uuid() PRIMARY KEY, | ||
help_key VARCHAR(30) NOT NULL, | ||
system VARCHAR(9) NOT NULL, | ||
page_tab VARCHAR(50) DEFAULT 'all_tabs', | ||
content VARCHAR, | ||
is_draft BOOLEAN DEFAULT false, | ||
create_user VARCHAR(60) NOT NULL, | ||
create_timestamp timestamp with time zone DEFAULT now() NOT NULL, | ||
update_user VARCHAR(60) NOT NULL, | ||
update_timestamp timestamp with time zone DEFAULT now() NOT NULL | ||
); | ||
|
||
INSERT INTO help ( | ||
help_key, system, page_tab, content, is_draft, create_user, update_user | ||
) VALUES ( | ||
'default', 'CORE', 'all_tabs', '<p>Check back soon for updates. Thank you for your patience.</p>', false, 'system', 'system' | ||
); | ||
|
||
INSERT INTO help ( | ||
help_key, system, page_tab, content, is_draft, create_user, update_user | ||
) VALUES ( | ||
'default', 'MineSpace', 'all_tabs', '<p>Check back soon for updates. Thank you for your patience.</p>', false, 'system', 'system' | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
86 changes: 86 additions & 0 deletions
86
services/common/src/components/forms/RenderRichTextEditor.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import React, { FC, useContext, useMemo } from "react"; | ||
import { Form } from "antd"; | ||
import { BaseInputProps, BaseViewInput, getFormItemLabel } from "./BaseInput"; | ||
import { FormContext } from "./FormWrapper"; | ||
import ReactQuill from "react-quill"; | ||
import "react-quill/dist/quill.snow.css"; | ||
import parse from "html-react-parser"; | ||
import DOMPurify from "dompurify"; | ||
|
||
const RenderRichTextEditor: FC<BaseInputProps> = ({ | ||
label, | ||
labelSubtitle, | ||
meta, | ||
input, | ||
disabled, | ||
help, | ||
required, | ||
defaultValue, | ||
id, | ||
placeholder, | ||
}) => { | ||
const { isEditMode } = useContext(FormContext); | ||
|
||
const handleAddImage = (data) => { | ||
// just a click handler for the image button, | ||
// everything else will have to be implemented | ||
console.log("image data", data); | ||
}; | ||
const colorOptions = ["#003366", "white", "#fcba19", "#d8292f", "#2e8540", "#313132", "black"]; | ||
const toolbarOptions = [ | ||
[{ header: [1, 2, 3, 4, 5, 6, false] }], | ||
["bold", "italic", "underline", "strike"], | ||
["blockquote"], | ||
[{ list: "ordered" }, { list: "bullet" }], | ||
[{ color: colorOptions }, { background: colorOptions }, "font", "align"], | ||
["link", "video"], | ||
]; | ||
|
||
const modules = useMemo( | ||
() => ({ | ||
toolbar: { | ||
container: toolbarOptions, | ||
// handlers: { image: handleAddImage },// TODO: add image to toolBarOptions and implement handler | ||
}, | ||
}), | ||
[] | ||
); | ||
|
||
const handleChange = (newValue) => { | ||
input.onChange(newValue); | ||
}; | ||
|
||
if (!isEditMode) { | ||
return <BaseViewInput value={parse(DOMPurify.sanitize(input.value))} label={label} />; | ||
} | ||
|
||
return ( | ||
<Form.Item | ||
id={id} | ||
getValueProps={() => ({ value: input.value })} | ||
name={input.name} | ||
required={required} | ||
validateStatus={meta.touched ? (meta.error && "error") || (meta.warning && "warning") : ""} | ||
help={ | ||
meta.touched && | ||
((meta.error && <span>{meta.error}</span>) || (meta.warning && <span>{meta.warning}</span>)) | ||
} | ||
label={getFormItemLabel(label, required, labelSubtitle)} | ||
> | ||
<> | ||
<ReactQuill | ||
readOnly={disabled} | ||
defaultValue={defaultValue} | ||
placeholder={placeholder} | ||
theme="snow" | ||
value={input.value} | ||
onChange={handleChange} | ||
modules={modules} | ||
/> | ||
{help && <div className={`form-item-help ${input.name}-form-help`}>{help}</div>} | ||
</> | ||
</Form.Item> | ||
); | ||
}; | ||
|
||
export default RenderRichTextEditor; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
services/common/src/components/help/HelpGuide-core.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import React from "react"; | ||
import { render, fireEvent } from "@testing-library/react"; | ||
import { ReduxWrapper } from "@mds/common/tests/utils/ReduxWrapper"; | ||
import { HelpGuideContent } from "./HelpGuide"; | ||
import { AUTHENTICATION } from "@mds/common/constants/reducerTypes"; | ||
import { SystemFlagEnum } from "@mds/common/constants"; | ||
import { HELP_GUIDE_CORE, USER_ACCESS_DATA } from "@mds/common/tests/mocks/dataMocks"; | ||
import { EMPTY_HELP_KEY, helpReducerType } from "@mds/common/redux/slices/helpSlice"; | ||
|
||
const coreState = { | ||
[AUTHENTICATION]: { | ||
systemFlag: SystemFlagEnum.core, | ||
userAccessData: [...USER_ACCESS_DATA, "core_helpdesk"], | ||
isAuthenticated: true, | ||
}, | ||
[helpReducerType]: { | ||
helpGuides: { | ||
[EMPTY_HELP_KEY]: HELP_GUIDE_CORE.default, | ||
}, | ||
}, | ||
}; | ||
|
||
function mockFunction() { | ||
const original = jest.requireActual("react-router-dom"); | ||
return { | ||
...original, | ||
useParams: jest.fn().mockReturnValue({ | ||
tab: "overview", | ||
}), | ||
}; | ||
} | ||
|
||
jest.mock("react-router-dom", () => mockFunction()); | ||
|
||
describe("HelpGuide", () => { | ||
it("renders CORE properly", async () => { | ||
const helpKey = "Not-Exists"; | ||
|
||
const { findByTestId, findByText } = render( | ||
<ReduxWrapper initialState={coreState}> | ||
<HelpGuideContent helpKey={helpKey} /> | ||
</ReduxWrapper> | ||
); | ||
|
||
const helpButton = await findByTestId("help-open"); | ||
fireEvent.click(helpButton); | ||
|
||
const defaultContent = await findByText("CORE default content"); | ||
expect(defaultContent).toBeInTheDocument(); | ||
|
||
const editButton = await findByText("Edit Help Guide"); | ||
fireEvent.click(editButton); | ||
|
||
const helpContent = await findByTestId("help-content"); | ||
expect(helpContent).toMatchSnapshot(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import React from "react"; | ||
import { render, fireEvent } from "@testing-library/react"; | ||
import { ReduxWrapper } from "@mds/common/tests/utils/ReduxWrapper"; | ||
import HelpGuide, { HelpGuideContent } from "./HelpGuide"; | ||
import { AUTHENTICATION } from "@mds/common/constants/reducerTypes"; | ||
import { SystemFlagEnum } from "@mds/common/constants"; | ||
import { MS_USER_ACCESS_DATA } from "@mds/common/tests/mocks/dataMocks"; | ||
import { helpReducerType } from "@mds/common/redux/slices/helpSlice"; | ||
import { BrowserRouter } from "react-router-dom"; | ||
|
||
const msState = { | ||
[AUTHENTICATION]: { | ||
systemFlag: SystemFlagEnum.ms, | ||
userAccessData: MS_USER_ACCESS_DATA, | ||
isAuthenticated: true, | ||
}, | ||
[helpReducerType]: { | ||
helpGuides: {}, | ||
}, | ||
}; | ||
|
||
function mockFunction() { | ||
const original = jest.requireActual("react-router-dom"); | ||
return { | ||
...original, | ||
useParams: jest.fn().mockReturnValue({ | ||
tab: "overview", | ||
}), | ||
}; | ||
} | ||
|
||
jest.mock("react-router-dom", () => mockFunction()); | ||
|
||
describe("HelpGuide", () => { | ||
it("renders MS properly with default content", async () => { | ||
const helpKey = "Not-Exists"; | ||
const { findByTestId } = render( | ||
<BrowserRouter> | ||
<ReduxWrapper initialState={msState}> | ||
<HelpGuide /> | ||
<HelpGuideContent helpKey={helpKey} /> | ||
</ReduxWrapper> | ||
</BrowserRouter> | ||
); | ||
const helpButton = await findByTestId("help-open"); | ||
fireEvent.click(helpButton); | ||
|
||
const helpContent = await findByTestId("help-content"); | ||
|
||
expect(helpContent).toMatchSnapshot(); | ||
}); | ||
}); |
Oops, something went wrong.