dotCMS / core

Headless/Hybrid Content Management System for Enterprises
http://dotcms.com
Other
860 stars 467 forks source link

Edit Page V2: Unable to Add Contentlets to Empty Containers in VTL Pages #27911

Closed fmontes closed 6 months ago

fmontes commented 7 months ago

Parent

27546

Problem Statement

As a user, I am unable to add contentlets to empty containers in VTL pages because there is no indication that the container exists.

Steps to Reproduce

https://github.com/dotCMS/core/assets/751424/b0f856a6-c21d-4b69-8203-efd20f2cd3df

### Acceptance Criteria
- [ ] Users should be able to see and interact with empty containers in VTL pages.
- [ ] Users should be able to add, create, drag and drop, or move contentlets to empty containers.
- [ ] The system should restrict the content types that can be added to the empty container based on the container's settings.

External Links

N/A

Assumptions & Initiation Needs

Quality Assurance Notes & Workarounds

N/A

KevinDavilaDotCMS commented 7 months ago

I added the functionality but I think this should be done from the backend. Currently the content of VTL pages comes as an HTML String like "<html> <head>... </head> <body>.... </body></html>"

And to get the empty containers to be rendered, you must do the following:

-Add a Fake Contentlet inside the containers that do not have any contentlet inside.

So, from the Frontend, I take the HTML string, create a temporary HTML element using document,createElement(), then search for containers without child elements with querySelector and manually add a div with the necessary characteristics.

This works, but it causes 2 problems

  1. By manipulating the DOM so much (which comes from a string), styles or meta tags can be broken or lost, which can cause problems on client websites.
  2. Manipulating the DOM from Angular is very expensive for the user, since we would be rendering the HTML twice (One to modify it, another to add it to the iframe), in addition to going through all the content and creating n number of divs for the containers .

Both problems would be solved if it were done from the backend, since it is less expensive there and the Frontend would only take the HTMLString and render them once (which is already being done)

From the backend, the steps to add this functionality would be:

  1. Search and filter all the elements that contain the data attribute data-dot-object="container", and only keep those that DO NOT contain any child elements.
  2. To each of these elements, a child element (a div) will be added with the following data attributes
data-dot-object="contentlet"
data-dot-identifier="TEMP_EMPTY_CONTENTLET"
data-dot-title="TEMP_EMPTY_CONTENTLET"
data-dot-inode="TEMPY_EMPTY_CONTENTLET_INODE"
data-dot-type="TEMP_EMPTY_CONTENTLET_TYPE"
data-dot-container = An stringified object with this structure:
{
acceptTypes = AcceptTypes from the parent (the div with data attribute data-dot-object="container")
identifier = Identifier from the parent (the div with data attribute data-dot-object="container")
maxContentlets = maxContentlets from the parent (the div with data attribute data-dot-object="container")
uuid = from the parent (the div with data attribute data-dot-object="container")
}
Basically this is a resume from the data of container parent.

Also the following styles: style="width: 100%; background-color: rgb(236, 240, 253); display: flex; justify-content: center; align-items: center; color: rgb(3, 14, 50); height: 10rem;" And the following Text: This container is empty => Maybe this needs a translation

The final result is like

<div
 data-dot-object="container"
... all container data, this div already have that info, dont change anything here
>
<!-- This is the fake contentlet to add -->
<div
  data-dot-object="contentlet"
  data-dot-identifier="TEMP_EMPTY_CONTENTLET"
  data-dot-title="TEMP_EMPTY_CONTENTLET"
  data-dot-inode="TEMPY_EMPTY_CONTENTLET_INODE"
  data-dot-type="TEMP_EMPTY_CONTENTLET_TYPE"
  data-dot-container='{"acceptTypes":"CallToAction,webPageContent,calendarEvent,Image,Product,Video,dotAsset,Blog,Banner,Activity,WIDGET,FORM","identifier":"//demo.dotcms.com/application/containers/default/","maxContentlets":"25","uuid":null}'
  style="width: 100%; background-color: rgb(236, 240, 253); display: flex; justify-content: center; align-items: center; color: rgb(3, 14, 50); height: 10rem;"
>
  This container is empty
</div>;

</div>

In this video i show the result and the problem with this approach from frontend way

https://github.com/dotCMS/core/assets/144152756/67001300-db44-49b4-9db3-293be3b0c628

KevinDavilaDotCMS commented 6 months ago

Failed IQA

The empty container is rendered, but when i try to add content, this silence error appears

https://github.com/dotCMS/core/assets/144152756/4fe9c4e0-660b-409d-a2e0-0527bf03dd7e

I debugged the front and i found is for the container uuid, that must to be string, but now is number Changing this, the bug is fixed

https://github.com/dotCMS/core/assets/144152756/1969f655-1f7f-4653-aa4e-f8cdaf5f976b

zJaaal commented 6 months ago

I will take care of this PR

fmontes commented 6 months ago

We had to revert the first idea and come up with another, that's why it took that much.

fmontes commented 6 months ago

Fixed, tested in master-qa and latest trunk.

josemejias11 commented 6 months ago

Approved: Tested on trunk_1afdb08, Docker, macOS 13.0, FF v124.0.2

QA Note: I'm having problems editing vtl files whiting the container. Maybe this is expected, not sure.

Screenshot 2024-04-22 at 8 49 45 AM