WIP/iterative improvements (Not intended as final)

This issue is to add the ability to edit the props of a selected component using the contextual sidebar (right side). We still need to wait for new endpoints to actually make changes to the backend so this is still in early stages.

The current end goal is to render the Drupal form in JSX in the sidebar so we can hook up redux and undo/redo functionality to it. We want the redux on the form to see real-time updates to the preview when a form value is changed.

How to approach building this even though the UI is not currently tied to an entity

  • At least for now, the best way to generate a props edit form is via a field widget for the component_tree field type
  • HOWEVER! The XB UI is not currently coupled to an entity, and field widgets are difficult to render without belonging to an entity (I'm sure there is a way but not an easy one)

For the time being, we will take advantage of XB adding a component_tree to article with the field name field_xb_demo. When we need to access an edit form for one of these SDCs, we can generate a form for creating a new article entity and populate the field_xb_demo field with the prop values to be edited.

Obviously hard-coding to a specific entity type & field name is not how to do this long term, but this provides a means of progressing on the props edit without being blocked on how this UI is coupled to a given entity.

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

  • edit-3 Comparechanges, plain diff MR !53
  • edit-component Comparecompare
  • 2 hidden branches
  • 3452512-edit-2 Comparecompare
  • 3452512-noop Comparecompare

Comments

jessebaker created an issue. See original summary.

bnjmnm made their first commit to this issue’s fork.

hooroomoo made their first commit to this issue’s fork.

hooroomoo changed the visibility of the branch 3452512-edit-2 to hidden.

hooroomoo’s picture

Started on edit-3 branch which is off the most recent 0.x that has #3452497: [MR Only] Edit any component prop, powered by a new FieldForComponentSuggester service, which will power the JS UI. Didn't get very far yet, currently the branch is just rendering the values from field.feld..node.article.field_xb_demo which is hard-coded in layout-default.json. Not sure if there's an endpoint that exists yet that I can fetch the tree and props/model from.

wim leers’s picture

See gitlab MR description for more details...

There isn't any 😅

hooroomoo’s picture

Title: [MR only] Add component edit form to contextual panel » Add component edit form to contextual panel
Assigned: bnjmnm » hooroomoo
Issue summary: View changes
Issue tags: -Needs issue summary update

hooroomoo changed the visibility of the branch 3452512-noop to hidden.

wim leers’s picture

Issue summary: View changes
Status: Active » Needs work
StatusFileSize
new150.01 KB

@hooroomoo shared a screenshot in Slack, attaching here:

👆 Unfortunately, I can’t get to that point locally — maybe because of

$ npm run build

> vite-template-redux@0.0.0 build
> tsc && vite build

nsrc/features/panel/ContextualPanel.tsx:30:35 - error TS7031: Binding element 'htmlString' implicitly has an 'any' type.

30 const BadHtmlParserComponent = ({ htmlString }) => {
                                     ~~~~~~~~~~

src/features/panel/ContextualPanel.tsx:43:62 - error TS2345: Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
  Type 'undefined' is not assignable to type 'string'.

43   const responseAsDocument = new DOMParser().parseFromString(response.data, 'text/html');
                                                                ~~~~~~~~~~~~~


Found 2 errors in the same file, starting at: src/features/panel/ContextualPanel.tsx:30

wim.leers at MacBookPro-WimLeers in ~/core/modules/contrib/experience_builder/ui on edit-3*
hooroomoo’s picture

Ah yeah I see there are TS errors that cause the build to fail. But if you run in development mode npm run dev you should be able to reproduce it. I will fix the build errors though.

hooroomoo’s picture

Issue summary: View changes
lauriii’s picture

We still need to wait for new endpoints to actually make changes to the backend so this is still in early stages.

What are the missing endpoints? Are there Drupal.org issues for these endpoints already? Can we link them here for clarity?

bnjmnm’s picture

Issue summary: View changes

Updated IS with details of how the form is being generated.

hooroomoo’s picture

Current state it only has the text prop from Drupal rendering as JSX right now:

hooroomoo’s picture

hooroomoo’s picture

Status: Needs work » Active
hooroomoo’s picture

Issue summary: View changes
StatusFileSize
new96.46 KB

Radix tooltip that shows unique data to prove JSX-ified drupal form can be integrated with our frontend (at least for this simple case)

hooroomoo’s picture

Issue summary: View changes
StatusFileSize
new11.84 KB

This is using Drupal's autocomplete behavior

wim leers’s picture

Status: Active » Needs work

@hooroomoo Could you please provide a GIF of that in action?

Also: posted a high-level review! 🏓

Needs work for:

  1. For the remarks I posted.
  2. Now that #3452895-23: Undo/redo - user can undo the loading of the initial state landed, we can and should write a functional ('end-to-end') Cypress test — you should be able to expand what tests/src/Cypress/cypress/e2e/xb-general.cy.js does. That will help subsequent steps by @bnjmnm (see below.
  3. Plus, @effulgentsia just requested that "undo" support works correctly even when the autocomplete is used — that's indeed worth verifying that it works correctly.

After my remarks + @effulgentsia's is addressed, please assign this to @bnjmnm. When he gets back from PTO next week, I think he'd be the best person to extract pieces that can land today. No pieces that call/reuse TwoTerribleTextAreasWidget should land, and instead we should work on the next steps under HTTP API in #3450586: [META] Back-end Kanban issue tracker.


@lauriii in a#12: those missing endpoints did not yet exist but now they do now — see HTTP API in #3450586: [META] Back-end Kanban issue tracker 👍

hooroomoo’s picture

StatusFileSize
new1.63 MB

hooroomoo’s picture

Assigned: hooroomoo » bnjmnm
lauriii’s picture

Priority: Normal » Critical
wim leers’s picture

I'm working to unblock @bnjmnm here by finishing #3452397: Allow specifying default props values when opting an SDC in for XB and then landing #3455942: HTTP API: update /xb-components to use Component config entity's default values — together, they will ensure that it becomes feasible to edit components without the horrors of TwoTerribleTextAreasWidget 🧟‍♀️

Crucially, that will allow @bnjmnm to fix the one inescapable bug he's been running into here: dragging in a new component onto the canvas results in fatal responses from the server to the client's request to preview an additional component (and then subsequently edit it).

wim leers’s picture

#3459992: Add some basic example SDCs landed — this MR can now be rebased and should become ~240 LoC smaller.

EDIT: I see that @bnjmnm already removed these 👍

@bnjmnm I'll get the PHPStan things out of the way for you. 😊

wim leers’s picture

PHPStan & phpunit CI jobs are now passing.

I unfortunately can't locally see your awesome work in action, because I get this:

$ npm run build

> vite-template-redux@0.0.0 build
> tsc --noEmit && vite build

error TS6305: Output file '/Users/wim.leers/core/modules/contrib/experience_builder/ui/vite.config.d.ts' has not been built from source file '/Users/wim.leers/core/modules/contrib/experience_builder/ui/vite.config.ts'.
  The file is in the program because:
    Matched by default include pattern '**/*'


Found 1 error.

I wondered if something was wrong about my node setup (I'm still on version 18 😅), but then I discovered that very same error appears on the Cypress CI job: https://git.drupalcode.org/project/experience_builder/-/jobs/2082413

bnjmnm’s picture

I'm getting the same dang thing as #26 if I run npm run build

error TS6305: Output file '/Users/austin.powers/core/modules/contrib/experience_builder/ui/vite.config.d.ts' has not been built from source file

It will, however, work with the npm run drupaldev I added as part of this MR.

bnjmnm’s picture

Assigned: bnjmnm » Unassigned
Status: Needs work » Needs review
wim leers’s picture

Assigned: Unassigned » wim leers

Reviewing! 🤩

The MR is not running all tests currently, due to #3460778: CI: do not run PHP-only jobs if an MR only changes the UI. I just merged a follow-up MR that fixes that problem: #3460778-6: CI: do not run PHP-only jobs if an MR only changes the UI. Merging in upstream to get all tests running in this MR 😅👍

wim leers’s picture

Assigned: wim leers » bnjmnm
Status: Needs review » Needs work

Both @jessebaker and I posted our reviews :)

bnjmnm’s picture

Assigned: bnjmnm » Unassigned
Status: Needs work » Needs review
wim leers’s picture

Title: Add component edit form to contextual panel » Add component instance edit form to contextual panel
Assigned: Unassigned » jessebaker
Related issues: +#3461422: Evolve component instance edit form to become simpler: generate a Field Widget directly

I created the critical follow-up #3461422: Evolve component instance edit form to become simpler: generate a Field Widget directly to make this no longer rely on TwoTerribleTextAreasWidget. See that issue for details.

#3455942: HTTP API: update /xb-components to use Component config entity's default values is a pre-existing issue that will simplify a narrower piece of this issue.

(This issue should land first, because it introduces a lot of infrastructure critical to deliver the envisioned UX, and simplifying something hacky that works, is much simpler than requiring completeness or perfection here.)

From a back-end POV, this is ready to land (to unblock subsequent issues).


Assigning to @jessebaker, because he just merged #3458617: Close menu on drag in primary menu, which conflicts with this. Also to address the last N bits of front-end related feedback:

wim leers’s picture

Status: Needs review » Reviewed & tested by the community

Signaling this is ready, and that @jessebaker should feel comfortable fixing himself whichever nits he still spots, to allow @bnjmnm (and all of us, really) to move on to the next steps! 😊

wim leers’s picture

One more follow-up issue, which is the next issue @bnjmnm should work on: #3461435: End-to-end test that tests both the client (UI) and server. Ben and I already discussed this last Thursday. This would have prevented #3461430: TypeError on a clean installation.

wim leers’s picture

Assigned: jessebaker » Unassigned
Status: Reviewed & tested by the community » Fixed
larowlan’s picture

This feels like a lot of smoke and mirrors. I understand we're trying to have a demo up for Barcelona, but a lot of the code in the MR makes me uncomfortable. I realise I was on leave and the ship has sailed but I would expect to see a lot more follow-ups than #36

wim leers’s picture

Assigned: Unassigned » bnjmnm
Status: Fixed » Reviewed & tested by the community
Issue tags: +Needs followup

There's no smoke and mirrors, it actually works. But it is very complex. It's the price for the product decisions that:

  1. we'd use #3440578: [PP-2] JSON-based data storage proposal for component-based page building, which means Drupal field types will the contain values for SDC props
  2. most importantly: the existing Drupal ecosystem must be brought along for the ride, which includes being able to use existing field types and field widgets

Note that that second decision does not mean that only existing field widget plugins can provide the input user experience. It just means that that this is the default input UX; in the future we'd want to add support for more optimized widgets. (Paraphrasing what IIRC @lauriii told me a number of weeks ago, when I voiced concerns similar to yours. I do think that )

You're absolutely right that #36 is not the full set of follow-ups. We don't know the full set of follow-ups yet. This landed because it's a big leap forward, not because it is a polished whole! We know there's a lot of things left to be done, but this having landed is precisely what will allow us to discover unknown unknowns and convert them to known unknowns.

IOW: the follow-ups listed there are only the immediate next steps, with the most important one being #3461422: Evolve component instance edit form to become simpler: generate a Field Widget directly — because that will allow us to evolve to something solid/maintainable — as the comments in the merged code and on the MR indicate: we're very well aware that we built a Frankenstein monster 🧟‍♀️ But at least now it's alive, now we just need to evolve it to be less monstrous 😄


All the above being said: reopening this and assigning to @bnjmnm, to ask him to create follow-up issues for the things that he already identified as logical next steps. He's the only one who can do that because he's the only one who so deeply understands how this works.

catch’s picture

we'd use #3440578: JSON-based data storage proposal for component-based page building, which means Drupal field types will the contain values for SDC props

This still has major unresolved questions around it. It may or may not affect the editing experience, but for example the 'field union JSON' proposal might well provide alternatives, while fulfilling the existing product requirements.

wim leers’s picture

Assigned: bnjmnm » Unassigned
Status: Reviewed & tested by the community » Fixed
Issue tags: -Needs followup

#39: Yes, there are still plenty of unresolved questions. But given the early stages of this project, I think that's unavoidable. Especially because we're working based on 64 concise product requirements and @lauriii is working to get designs

Regarding smoke and mirrors: I think #3462441: Contextual form values need to be integrated with Redux: start with single-property field types and its follow-ups (#3463618: Include component props form in undo , #3463842: [META] Redux sync on ALL prop types, not just ones with a single [value] property, more to come) are getting rid of the smoke (and hence revealing there are no mirrors, except maybe broken ones — sorry, the temptation was too great 🙈). Yes, it will all need to become clearer. But we're iterating towards more clarity, and to discover ASAP whether what each individual thinks (based on their expertise) should work, actually works.

Yes, there will be many more follow-ups. But no, they're not all created ahead of time. Yes, that makes it more difficult for others to see where this is going exactly. But we don't know where this is going exactly either!

It's obvious to everyone that XB is nowhere near production-ready (and nowhere near many other things), but we are developing this in the open from day 1.

#3459259: UX design tracker is growing steadily, so it's gradually becoming easier for everyone, including us working on XB full time, what the exact intended end goal is.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.