-
Notifications
You must be signed in to change notification settings - Fork 269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[UX] Stored Playgrounds (no more data loss), multiple Playgrounds, UI WebApp Redesign #1731
Conversation
I've been reading over this and hope to contribute later today. (But if you happen to finish it, @adamziel, that is fine and good too :) |
}, | ||
reducers: { | ||
setPlaygroundClient: ( | ||
setActiveSite: (state, action: PayloadAction<SiteInfo>) => { | ||
state.activeSite = action.payload; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we check whether the site is part of the current sites list?
Yay! I'm wrapping up for now so feel free to take over |
@@ -22,7 +23,8 @@ const SITE_METADATA_FILENAME = 'playground-site-metadata.json'; | |||
* NOTE: We are using different storage terms than our query API in order | |||
* to be more explicit about storage medium in the site metadata format. | |||
*/ | |||
export type SiteStorageType = 'temporary' | 'opfs' | 'local-fs'; | |||
export const SiteStorageTypes = ['opfs', 'local-fs', 'none'] as const; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I temporarily changed all the storage options naming to these three, but before this PR is merged I'd love to ensure the Query API keeps working with today's storage options names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be great if we could block merging PRs that contain changes with some special TODO pattern like @BEFORE-MERGE
, so we could leave inline notes for ourselves and be stopped from merging if we forget to address them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, we could just do this with a CI test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would love that!
With this particular change, though, we may not need to do that since the storage
Query API parameter is gone. Developer documentation will need updating for sure.
wpVersion: | ||
resolvedBlueprint.preferredVersions?.wp || | ||
LatestMinifiedWordPressVersion, | ||
phpVersion: resolveVersion( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if we allow site info to specify an unsupported PHP version and simply warn in the UI and tell the user how it will be handled by the runtime?
Over time, previous site configurations may have PHP versions that are no longer supported, and IMO, it would be better not to lose the information that a site was created for a now-unsupported PHP version. And if a site is now fataling due to back-compat breaks between the requested and actual PHP versions, it would give the user a chance to understand why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great point ❤️ Let's do that.
...ges/playground/website/src/components/ensure-playground-site/ensure-playground-site-slug.tsx
Outdated
Show resolved
Hide resolved
...ges/playground/website/src/components/ensure-playground-site/ensure-playground-site-slug.tsx
Outdated
Show resolved
Hide resolved
if (requestedSiteSlug !== 'create') { | ||
const siteInfo = await getSiteInfoBySlug(requestedSiteSlug!); | ||
console.log({ siteInfo }); | ||
dispatch(setActiveSite(siteInfo!)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the identified site does not exist?
One scenario:
- User bookmarks Playground link for specific site slug/ID
- User deletes site, perhaps unintentionally, or clears browser storage
- User visits bookmark
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need a notification system to tell the user what happened as we redirect to the first site that exists. There are WordPress components for that. It should be fine to delay that to another PR.
packages/playground/website/src/components/ensure-playground-site/index.tsx
Outdated
Show resolved
Hide resolved
I found an timing issue with converting legacy OPFS sites in Chrome Canary. Sometimes deleting the old site directory after mounting the new one fails due to a write conflict, and I wonder if it has something to do with journaling FS events to the legacy dir. |
OK, this is fixed now by falling back to the |
I added the few remaining items to the checklist:
|
OK, I fixed the bottom site info buttons being hidden for some mobile screen dimensions.
This is not a logic bug but is currently a UX bug. The truth is that update settings for a Temporary site actually creates a new temporary site. Yet the link people click to do this says "Edit Site Settings", and the submit button on the settings dialog says "Update" which implies updating rather than creating a new thing. |
For this PR, I think it makes more sense to have this button just edit the actual temp site settings, and if we want a way to create a fork of the current temp site, that should be via a separate button in a follow-up PR. Updated the TODO to be:
|
Yes, on small screens when the preview isn't available. On mobile, you will first see the menu, click on the menu to see your settings, and click on the Homepage button to get to the actual site. This isn't an issue when the preview is visible because you can see the site and the full view is just one click away. |
We don't have the plumbing to, e.g., change the WordPress version. I'd just change the label on that button to "Create a similar Playground" or so for now. |
The GH OAuth issue appears to be related to a testing detail on my end. And @adamziel fixed the temp site editing concern. I think we are good to ship this. |
Let's make sure we don't default to the sidebar view on mobile. Edit: Done in a415c79 |
## Motivation for the change, related issues #1731 introduced multiple Playground management. However, visiting a URL containing a Blueprint sometimes led to a creation of multiple temporary sites due to a React effect running twice. This PR prevents that error by delaying the new site creation until the effect settles down. In particular, we're waiting for the site list to either get loaded or error out. ## Testing Instructions (or ideally a Blueprint) Go to http://localhost:5400/website-server/?plugin=classic-editor&blueprint-url=https%3A%2F%2Fwordpress.org%2Fplugins%2Fwp-json%2Fplugins%2Fv1%2Fplugin%2Fclassic-editor%2Fblueprint.json%3Frev%3D3158978%26lang%3Den_US and confirm you only got a single temporary site
## Motivation for the change, related issues Some Playwright tests were broken by last-minute changes to #1731. Fixes #1818 ## Implementation details - Fix selection of "edit settings" and "save settings" buttons to select "Create a similar Playground" and "Create" buttons instead. - Change playground viewport selection to account for there being multiple possible viewports now. We were using an ID, but now we're using a CSS class. - Some expect() calls were failing, at least locally, and that was fixed by awaiting them. They need to be async. ## Testing Instructions (or ideally a Blueprint) - CI
## Motivation for the change, related issues Restores the easily accessible "Edit settings" button Playground had before merging #1731, and refocuses the user experience on a single, temporary Playground. Multiple Playgrounds are still possible, but now they're less emphasized. As we've learned from @annezazu and other users, the recent [Multiple Playgrounds UI update](#1731) made rapid fire iterations in Playground more difficult. Before #1731, we've had an easily accessible button to update WP and PHP versions. After #1731, that feature required multiple clicks and finding the right button. This PR introduces the following changes: * Add an easily-accessible "Site settings" button for quick PHP/WP version updates * The URL reflects the Query API values used to create the temporary Playground. * Limit the number of temporary Playground sites to exactly one – just like before #1731. The temporary Playground is always there and cannot be deleted. * The only way to create a stored Playground is by saving the temporary Playground. Once you do that, you get a fresh temporary Playground. Kudos to @jarekmorawski for thinking through and designing multiple variations of the user flows ❤️ ## Technical details The implementation is straightforward and focused on rearranging React components and CSS. There's one gotcha in the process of saving temporary site settings. The settings form submission calls `window.history.pushState()` and the `EnsurePlaygroundIsSelected` component watches for the URL changes. However, the user may click the "Update Settings & Reset Playground" button even without changing any form value. Normally, this would mean we can't detect a change and reset the Playground. This PR, thus, adds the `?random=<random string>` parameter to the query string to allow Playground notice the change and recreate the temporary site. ## Visuals ![CleanShot 2024-10-06 at 23 19 12@2x](https://github.com/user-attachments/assets/11e69587-a6ca-4f73-8d51-f15997950e71) ![CleanShot 2024-10-07 at 01 35 12@2x](https://github.com/user-attachments/assets/0e13f94a-adef-4f5a-8fc3-f3f4b9a577c6) Here's the video walkthrough – note I've recorded it before this PR was fully ready for a review: https://github.com/user-attachments/assets/b2f04fa6-d7d5-43ad-93e2-975a2a9cea21 ## Follow up work There are more design elements to consider, e.g. Snackbar notices. @jarekmorawski already designed some improvements and is working more. I would still like to get this PR in and continue iterating based on the feedback we get. ## UI updates checklist - [x] Tested mobile interactions - [x] Resolved accessibility issues reported by Axe Devtools ## Testing plan CI aside, interact with the design proposed in this PR and confirm it feels right.
This is a cleanup of a few components we aren't using anymore after [the recent website redesign](#1731) (Select, VersionSelect). Nothing fancy. Confirm the CI checks pass and merge.
I am working on "We could bring over all the PR previewers and demos". I didn't find a related task, so I'm posting it here :) |
Description
Implements a large part of the website redesign:
High-level changes shipped in this PR:
This work is a convergence of 18+ months of effort and discussions. The new UI opens relieves the users from juggling ephemeral Playgrounds and losing their work. It opens up space for long-lived site configurations and additional integrations. We could bring over all the PR previewers and demos right into the Playground app.
Here's just a few features unblocked by this PR:
Use Theme Unit Test Data as a starter content #718.
Breaking changes
TODO
Remaining work
Unhandled Promise Rejection: UnknownError: Invalid platform file handle
when saving a temporary Playground to OPFS.name=""
etc. accessibility attributes we need, see AXE tools for Chrome.storage
query arg (it's removed in this PR)TODOs
added in this PR and decide whether to solve or punt themLocal Filesystem
UI in browsers that don't support them. Don't just hide them, though. Provide a help text to explain why are they disabled.updateSite
in redux-store.ts vsupdateSite
insite-storage.ts
. What would an unambiguous code pattern look like?updateSite(slug, newConfig)
in a React Component and being done without thinking "ughh I still need to update OPFS" or "I also have to adjust that .json file over there"Follow up work
packages/docs/site/docs/main/about/build.md
cc @juanmaguitar.list()
, still return that site's info but make note of the error. Not showing that site on a list could greatly confuse the user ("Hey, where did my site go?"). Let's be explicit about problems.console.js:288 TypeError: Cannot read properties of undefined (reading 'apply') at comlink.ts:314:51 at Array.reduce (<anonymous>) at callback (comlink.ts:314:29)
– it seems to happen at trunk, too.URL
,runtimeConfiguration
,Blueprint
, andsite settings form state
for both OPFS sites and in-memory sites. Let's see if we can make it reusable in Playground CLI."password"
. (Solved by passwordless login)Closes #1719
cc @brandonpayton