From ba0a20812d42ec3f0323209f69848d0080998bbe Mon Sep 17 00:00:00 2001 From: Amitkanswal Date: Wed, 24 Apr 2024 01:01:35 +0530 Subject: [PATCH 1/3] feat:delete functionality Signed-off-by: Amitkanswal --- .../src/audiencePlugin/AudienceComponent.tsx | 30 ++++--- .../src/audiencePlugin/AudienceModal.tsx | 19 +++-- .../plugin/src/audiencePlugin/lib/index.ts | 8 ++ audience-app/plugin/src/plugin.tsx | 83 +------------------ 4 files changed, 41 insertions(+), 99 deletions(-) diff --git a/audience-app/plugin/src/audiencePlugin/AudienceComponent.tsx b/audience-app/plugin/src/audiencePlugin/AudienceComponent.tsx index 8f59ad43..a07d0736 100644 --- a/audience-app/plugin/src/audiencePlugin/AudienceComponent.tsx +++ b/audience-app/plugin/src/audiencePlugin/AudienceComponent.tsx @@ -1,8 +1,10 @@ import React from "react"; import { cbModal } from "@contentstack/venus-components"; import AudienceModal from "./AudienceModal"; +import { isPrePostTagsPresent } from "./lib"; import "./style.css"; +import { IRteParam } from "@contentstack/app-sdk/dist/src/RTE/types"; export const AudiencePreTag = (props) => { const { @@ -15,8 +17,6 @@ export const AudiencePreTag = (props) => { invalidConfig } = props; - console.error("props", props, attrs.audiences); - const handleMouseDown = (event) => { if (event) event.preventDefault(); cbModal({ @@ -46,7 +46,7 @@ export const AudiencePreTag = (props) => { {...attributes} className="audience-plugin" data-attrs={JSON.stringify(attrs)} - contentEditable={false} + contentEditable={true} style={{ userSelect: "none", margin: "0 2px" }} data-type="audience-pre" > @@ -65,7 +65,7 @@ export const AudiencePostTag = (props) => { className="audience-plugin" data-type="audience-post" data-attrs={JSON.stringify(attrs)} - contentEditable={false} + contentEditable={true} style={{ userSelect: "none", margin: "0 3px" }} > {"[AudienceEnd]"} @@ -74,12 +74,21 @@ export const AudiencePostTag = (props) => { ); }; -export const AudienceWrapperComponent = (props) => { - const { attributes, attrs, children } = props; - console.log("AudienceWrapperComponent.props", props); +export const AudienceWrapperComponent = (props:{attributes:any;attrs:any, children:any, element:any, rte:IRteParam}) => { + const { attributes, attrs, children,element,rte } = props; + const isWrapperTagsPresent = isPrePostTagsPresent(element.children); + const childNode = [] - return ( - { + if(node.type === "audience-pre" || node.type === "audience-post"){ + rte.removeNode(node); + } + childNode.push(node) + }) + } + + return isWrapperTagsPresent? { style={{ userSelect: "none", margin: "0 3px" }} > {children} - - ); + :<>{children} }; \ No newline at end of file diff --git a/audience-app/plugin/src/audiencePlugin/AudienceModal.tsx b/audience-app/plugin/src/audiencePlugin/AudienceModal.tsx index 03243f52..a17ba08b 100644 --- a/audience-app/plugin/src/audiencePlugin/AudienceModal.tsx +++ b/audience-app/plugin/src/audiencePlugin/AudienceModal.tsx @@ -22,9 +22,8 @@ import CheckboxTree from "react-checkbox-tree"; import EmptyStateComponent from "./UnconfiguredState"; import 'react-checkbox-tree/lib/react-checkbox-tree.css'; import "./modal.css"; -import { log } from "console"; -const AudienceModal = (props: any) => { +const AudienceModal = (props) => { let { rte, savedSelection, audiences, attrs = {}, slatePath, invalidConfig } = props; const [checked, setChecked] = useState(attrs.checked || []); const [expanded, setExpanded] = useState(attrs.expanded || []); @@ -108,11 +107,17 @@ const AudienceModal = (props: any) => { } else { const selectedElements = rte.selection.get(); const [getNode, path] = rte.getNode(selectedElements); - const newNode = [{...audiencePre} ,getNode , {...audiencePost} ] - const newNode1 = audienceWrapper(newNode) - rte.removeNode(getNode); - rte.insertNode(newNode1, {at: path}); - + const newNode = [{ ...audiencePre }, { + type: "fragment", uid: v4() + .split("-") + .join(""), children: [getNode], + elementType:"block", + }, { ...audiencePost }] + + const newNode1 = audienceWrapper(newNode) + rte.removeNode(getNode); + rte.insertNode(newNode1, { at: path }); + } const savedSelectionPath = savedSelection.anchor.path; diff --git a/audience-app/plugin/src/audiencePlugin/lib/index.ts b/audience-app/plugin/src/audiencePlugin/lib/index.ts index d6ca7328..4ee4d1de 100644 --- a/audience-app/plugin/src/audiencePlugin/lib/index.ts +++ b/audience-app/plugin/src/audiencePlugin/lib/index.ts @@ -1,3 +1,5 @@ +import { ReactNode } from "react"; + export const fieldExtractor = (group: any[] = [], group_title) => { return group.map((field) => { if (!field[group_title]) throw new Error("field is missing"); @@ -8,3 +10,9 @@ export const fieldExtractor = (group: any[] = [], group_title) => { }); }; + +export const isPrePostTagsPresent = (nodeList: {type: string; uid: string; attrs: any; children: ReactNode[]}[]): boolean => { + const isPreTagPresent = nodeList.some(node => node.type === "audience-pre"); + const isPostTagPresent = nodeList.some(node => node.type === "audience-post"); + return isPreTagPresent && isPostTagPresent; +} \ No newline at end of file diff --git a/audience-app/plugin/src/plugin.tsx b/audience-app/plugin/src/plugin.tsx index a85cde68..f94d1f81 100644 --- a/audience-app/plugin/src/plugin.tsx +++ b/audience-app/plugin/src/plugin.tsx @@ -112,7 +112,7 @@ export default ContentstackSDK.init() /> ); }, - elementType: ["block"], + elementType: ["block","void"], dnd: { disable: true, hideSelectionBackground: true, @@ -122,7 +122,7 @@ export default ContentstackSDK.init() const AudiencePost = RTE("audience-post", () => ({ render: AudiencePostTag, - elementType: ["block"], + elementType: ["block", "void"], dnd: { disable: true, hideSelectionBackground: true, @@ -172,85 +172,6 @@ export default ContentstackSDK.init() }); }); - AudiencePre.on("deleteBackward", (props) => { - const { rte } = props; - - const selection = rte.selection.get(); - const previousElementLocation = rte.selection.before(selection); - - if (previousElementLocation) { - const [match] = rte.getNodes({ - at: previousElementLocation, - match: (n) => n.type === "audience-pre", - mode: "lowest", - }); - - if (match) { - const element: any = match[0]; - const path = match[1]; - - const start = { - offset: 0, - path: [...path, 0], - }; - - if (rte.selection.isPointEqual(previousElementLocation, start)) { - const audienceId = element?.attrs?.audienceId; - if (audienceId) { - for (const [element] of rte.generators.elements()) { - const entry: any = { ...element }; - if (entry.type === "audience-post") { - if (audienceId === entry?.attrs?.audienceId) { - rte.removeNode(element); - return; - } - } - } - } - } - } - } - }); - - AudiencePost.on("deleteBackward", (props) => { - const { rte } = props; - - const selection = rte.selection.get(); - const previousElementLocation = rte.selection.before(selection); - - if (previousElementLocation) { - const [match] = rte.getNodes({ - at: previousElementLocation, - match: (n) => n.type === "audience-post", - mode: "lowest", - }); - - if (match) { - const element: any = match[0]; - const path = match[1]; - - const start = { - offset: 0, - path: [...path, 0], - }; - - if (rte.selection.isPointEqual(previousElementLocation, start)) { - const audienceId = element?.attrs?.audienceId; - if (audienceId) { - for (const [element] of rte.generators.elements()) { - const entry: any = { ...element }; - if (entry.type === "audience-pre") { - if (audienceId === entry?.attrs?.audienceId) { - rte.removeNode(element); - return; - } - } - } - } - } - } - } - }); AudiencePre.on("beforeRender", (rte) => { if (rte.element.type === "audience-pre") { From 0925c4ca49e473bca606948669059a9a675ab3ad Mon Sep 17 00:00:00 2001 From: Amitkanswal Date: Wed, 24 Apr 2024 19:44:35 +0530 Subject: [PATCH 2/3] feat:updated backward compatibility Signed-off-by: Amitkanswal --- .../src/audiencePlugin/AudienceComponent.tsx | 38 +++---- .../src/audiencePlugin/AudienceModal.tsx | 101 +++++++++--------- .../plugin/src/audiencePlugin/style.css | 4 +- audience-app/plugin/src/plugin.tsx | 72 ++++++------- 4 files changed, 108 insertions(+), 107 deletions(-) diff --git a/audience-app/plugin/src/audiencePlugin/AudienceComponent.tsx b/audience-app/plugin/src/audiencePlugin/AudienceComponent.tsx index a07d0736..ff93ff45 100644 --- a/audience-app/plugin/src/audiencePlugin/AudienceComponent.tsx +++ b/audience-app/plugin/src/audiencePlugin/AudienceComponent.tsx @@ -44,7 +44,7 @@ export const AudiencePreTag = (props) => { { export const AudiencePostTag = (props) => { const { attributes, attrs, children } = props; - + return ( { ); }; -export const AudienceWrapperComponent = (props:{attributes:any;attrs:any, children:any, element:any, rte:IRteParam}) => { - const { attributes, attrs, children,element,rte } = props; +export const AudienceWrapperComponent = (props: { attributes: any; attrs: any, children: any, element: any, rte: IRteParam }) => { + const { attributes, attrs, children, element, rte } = props; const isWrapperTagsPresent = isPrePostTagsPresent(element.children); const childNode = [] - + if (!isWrapperTagsPresent) { - element.children.forEach((node)=>{ - if(node.type === "audience-pre" || node.type === "audience-post"){ + element.children.forEach((node) => { + if (node.type === "audience-pre" || node.type === "audience-post") { rte.removeNode(node); } childNode.push(node) }) } - - return isWrapperTagsPresent? - {children} - :<>{children} + + return isWrapperTagsPresent ? + {children} + : <>{children} }; \ No newline at end of file diff --git a/audience-app/plugin/src/audiencePlugin/AudienceModal.tsx b/audience-app/plugin/src/audiencePlugin/AudienceModal.tsx index a17ba08b..000988e2 100644 --- a/audience-app/plugin/src/audiencePlugin/AudienceModal.tsx +++ b/audience-app/plugin/src/audiencePlugin/AudienceModal.tsx @@ -19,22 +19,19 @@ import { } from "./icons"; import CheckboxTree from "react-checkbox-tree"; -import EmptyStateComponent from "./UnconfiguredState"; import 'react-checkbox-tree/lib/react-checkbox-tree.css'; import "./modal.css"; -const AudienceModal = (props) => { - let { rte, savedSelection, audiences, attrs = {}, slatePath, invalidConfig } = props; +const AudienceModal = (props: any) => { + let { rte, savedSelection, audiences, attrs = {}, slatePath } = props; const [checked, setChecked] = useState(attrs.checked || []); const [expanded, setExpanded] = useState(attrs.expanded || []); - const [isConfigured, setIsConfigured] = useState(audiences ? true : false) + const config = rte.getConfig().then((config) => config).catch((err) => console.error(err)); useEffect(() => { }, [checked, expanded]); const handleAddRegion = (event) => { event.preventDefault(); - console.log("event...", event); - savedSelection = savedSelection || { anchor: rte.selection.getEnd([]), focus: rte.selection.getEnd([]) @@ -93,7 +90,6 @@ const AudienceModal = (props) => { }); if (props.attrs) { - rte.setAttrs(audiencePre, { at: slatePath, }); @@ -105,19 +101,26 @@ const AudienceModal = (props) => { at: endPath.path, }); } else { - const selectedElements = rte.selection.get(); - const [getNode, path] = rte.getNode(selectedElements); - const newNode = [{ ...audiencePre }, { - type: "fragment", uid: v4() - .split("-") - .join(""), children: [getNode], - elementType:"block", - }, { ...audiencePost }] - + if (!config?.useNewAudienceSchema) { + rte.insertNode(audiencePost, { at: savedSelection.focus }); + rte.insertNode(audiencePre, { at: savedSelection.anchor }); + } else { + const selectedElements = rte.selection.get(); + const [getNode, path] = rte.getNode(selectedElements); + const newNode = [{ ...audiencePre }, { + type: "fragment", + uid: v4() + .split("-") + .join(""), + attrs:{class:"fragment-inline"}, + className:"fragment-inline", + children: [getNode], + }, { ...audiencePost }] + const newNode1 = audienceWrapper(newNode) rte.removeNode(getNode); rte.insertNode(newNode1, { at: path }); - + } } const savedSelectionPath = savedSelection.anchor.path; @@ -129,6 +132,7 @@ const AudienceModal = (props) => { ], offset: 0, }; + rte.selection.set(rte.selection.getEnd([])); } @@ -138,38 +142,36 @@ const AudienceModal = (props) => {
- -
- - { - setChecked(checked); - }} - onExpand={(expanded) => { - setExpanded(expanded); - }} - // nativeCheckboxes={true} - checkModel="all" - icons={{ - check: , - uncheck: , - halfCheck: , - expandOpen: , - expandClose: , - }} - /> - -
-
+
+ + { + setChecked(checked); + }} + onExpand={(expanded) => { + setExpanded(expanded); + }} + // nativeCheckboxes={true} + checkModel="all" + icons={{ + check: , + uncheck: , + halfCheck: , + expandOpen: , + expandClose: , + }} + /> + +
@@ -178,7 +180,6 @@ const AudienceModal = (props) => { Cancel