Problem/Motivation
We started to iterate over the primary widget and improved it a lot.
Now we start to experiment with more radical changes and we want to be careful.
Still lots of these steps are needed to transform the content editing experience into the next level.
Proposed resolution
Let's create a second widget and declare it experimental.
We still can transform the parent widget into better modularity, so subclass overrides are more simple.
The parent / original will stay the classic default widget - at least for a while.
The new experimental one will allow us to do progressive changes without the need that everyone agrees.
People can easily switch the widget and give the new experience a try.
We will then decide if we keep both in the long run, if we migrate some features back, or if we deprecate the classic one in the long run.
Nothing is decided yet except the fact that we need both for now.
Some changes, expecially the "Remove" => "X" transformation will be reverted.
We can also already discuss if we should revert the "Removed" / "Confirm removal" state too. But IMHO we should focus on the client side delete confirmation.
Remaining tasks
We should identify other isolated changes that we want to revert.
Implement. :-)
User interface changes
A second experimental widget. Needs a name...
API changes
Comment | File | Size | Author |
---|---|---|---|
#40 | Screenshot from 2017-01-11 08-31-30.png | 12.61 KB | johnchque |
#40 | interdiff-2837855-39-40.txt | 1.61 KB | johnchque |
#40 | offer_a_second-2837855-40.patch | 47.93 KB | johnchque |
#39 | offer_a_second-2837855-39.patch | 46.64 KB | johnchque |
#39 | interdiff-2837855-38-39.txt | 40.05 KB | johnchque |
Comments
Comment #2
BerdirOne thing to consider is test coverage. How are we going to ensure that both the old and the new widget have sufficient test coverage?
How exactly are we going to define the widget as experimental? put it in th label? Make it part of an optional module?
Comment #3
johnchqueGonna work on this.
Comment #4
johnchqueFirst try, not sure about naming yet. Css cloned.
Comment #6
johnchqueTests fixed.
Comment #7
miro_dietikerWe need a name that is is made to stay. At one day it is no more experimental. And a description about its purpose.
We said the label MUST contain EXPERIMENTAL to create awareness.
What is missing:
- The revert of the "Remove" => "X" change - and make it an override of the widget.
- Test coverage.
We will need tests.
Comment #8
johnchqueNot sure if that is the best way to do it, neither if it is the right approach but certainly, it works. :)
Comment #10
johnchqueFixing tests.
Comment #11
HongPong CreditAttribution: HongPong at kor group commentedI would change "paragraphs.experimental.css" to "paragraphs.alternative.css" or similar, it would make sense to label it as experimental in the body and labels but it would be best to not use in the file names. Thank you for developing this.
Comment #12
miro_dietikerWe still need to define a better naming and a clearer description. Will discuss tomorrow and make a proposal.
Comment #13
miro_dietikerComment #14
johnchqueDiscussed with @miro_dietiker this approach might be better. I was thinking, what if instead we create methods for all parts of the widget, like buildTop which it can call to buildTitle and buildActions. But it is just a thought.
Comment #16
miro_dietikerLet's do it like this:
The original widget:
The experimental widget
But yeah, i'm giving up to find a better name. xyz.experimental.abc is fine. We will need to do config updates anyway once we switch things as in default or deprecate something.
Comment #17
miro_dietikerKeep in mind that certain methods only work if we have the same structure in a new widget. It's also likely a widget drops certain elements or outsputs different structure (such as no table - thus no table head) or adds new concepts such as a template selection, a drag and drop mode with completely different output (that should suppress regular form build processing) and many things more from our fancy roadmap.
Comment #18
johnchqueFixed tests and changed the widget id's. I really think we should provide a buildTop(). :)
Comment #20
johnchqueAdding schema. No idea why it passes with php 7. :)
Comment #21
johnchqueTests added. :).
Comment #22
johnchqueChanged array by [].
Comment #23
Berdirone idea to avoid "experimental":
make separate css files or even libraries,name them after what they're actualy for. So this would be paragraphs.delete.css or something like that.
Hm.
I was wondering if we should do it like this or if we should just copy the file completely.
This saves duplicate code now, but everything we want to do here will be more complicated and it will likely result in changes and refactoring of the existing widget.
I'm not sure if we rather just want to copy it 1:1. One problem that I see test coverage, how do we ensure to not break any existing functionality if we don't run all the test we have with both widgets?
Comment #24
miro_dietikerYeah definitively, we will need to test both or the whole separation idea is pretty artificial.
Comment #25
johnchqueChanged approach, copied file. Still need to work on tests. :)
Comment #26
johnchqueOK, duplicated most of the tests. Thinking about if we should create a new test environment as diff module has now. That would speed up the tests. :)
Comment #27
johnchqueDuplicated all tests. :)
Comment #29
johnchqueSome changes.
Comment #30
tduong CreditAttribution: tduong at MD Systems GmbH commentedWas requested to review this patch.
Is this intended to be capitalised (or was it for a personal test) ?
This actually is $admin_permissions. You could either give the permissions array as anonymous varable, save $admin_user = $this->loginAsAdmin(...) and then use a normal drupalLogin() below, or just rename this variable :P
If there is just one item and it fits in the 80-char-length rule, I guess you can keep it in one single line.
As these two lines, or at least addParagraphedContentType(), (are)/is executed first for each test method, you could add it to setUp() in this class (for every test class).
This code is done multiple times in the new tests added.
There is a helper method similar already,
setAddMode($content_type, $paragraphs_field, $mode, $experimental = FALSE)
, that sets'settings' => ['add_mode' => $mode]
also.Should we have a more general method with:
- $id to be loaded ($id seen so far: node.paragraphed_test.default, node.paragraphed_content_demo.default, node.article.default, contact_message.test_contact_form.default)
- and the component $name to be set ($name seen so far: paragraphs, paragraphs_field, field_paragraphs, field_paragraphs_demo, paragraph.nested_paragraph.default),
something like
setParagraphsFormDisplayComponent($id, $name)
in ParagraphsTestBase to reduce more lines everywhere?I've seen many asserts (and other kind of helper methods) duplicated (not only because of the cloned experimental X test). Maybe we could move all these helper methods in ParagraphsTestBase ?
Unused property.
Not entirely sure if your goal is to then keep these duplicated tests and later extend them for more experimental widget functionality, or it is just a temporary situation and they will be merged in the existing tests. But if these tests will be kept, couldn't we provide helper methods in something like a trait, or better rename the existing testBla to doTestBla and add
testBla() { $this->doTestBla(); }
andsince most of the new tests are adding something at the beginning of each test ?
Ok no, you are going to extend these tests so trying to avoid duplication won't work for later purpose...
Comment #31
miro_dietikerWe clone, because we want to divert without thinking:
What the old widget does should remain. What the new widget does should never affect the old one.
Thus cloning with initially having everything duplicated is the solution.
Comment #32
BerdirWhat about using a namespace for the tests?
Drupal\paragraphs\Tests\Classic
Drupal\paragraphs\Tests\Experimental
not sure about keeping the experimental in the class name too, but this should be easier to for example do a search and replace only in the new tests?
Comment #33
tduong CreditAttribution: tduong at MD Systems GmbH commentedI was thinking about it as well.
Ok for duplicated code. But I still think we could provide helper methods to "encapsulate" pieces of tests, like
...
Since, even without duplicating the tests, some processes are repeated in different tests. Sure it is not related to this issue though.
About naming this experimental widget, if I got it right what differs this from the classic one is that some "labeled buttons" are "reduced" to an icon or some processes (confirm remove, ...) are "reduced", all made for "imagery – guide visual treatments" or similar.
What about something like "Printed-based Design"/"Print Design" or if it is too confusing for an end-user maybe something like "Graphic Print Design"/"Graphic Design" (not sure about this one though)... Got inspired from material design principles explanations.
Comment #34
BerdirThat's the difference now, we want to make a lot more changes, so I think just sticking with Experimental is fine for now.
What about behaviors? Should we remove that from the classic widget completely as well? Will not be able to provide anything that's even remotely useful for users. Might need a notice then in the paragraph type settings that behaviors are only support with the experimental widget?
Comment #35
BerdirSame with helper functions, we could add them for non-widget related things but that's something that can be done later.
Comment #36
johnchqueAddressed changes from previous comments. Open issues for helper methods and behavior plugins.
Comment #38
johnchqueAdding per-paragraph-type config tests. :)
Comment #39
johnchqueOK, so behavior plugins were removed from the classic plugin, tests were split. :)
Comment #40
johnchqueAdded warning message for using behavior plugins with the experimental widget.
Comment #42
miro_dietikerCommitted with resolving a conflict (removal in widget).
Tiny nitpick fixes (codestyle, missing .), committed. Now many patches need a reroll.
Comment #44
groovedork CreditAttribution: groovedork commentedCould the front page of this module perhaps explain the difference between 'classic' and 'experimental'? It's a bit mysterious now.
Comment #45
miro_dietiker@groovedork Best is you create a new separate issue for this task.