Skip to content

Commit

Permalink
[UX] Stored Playgrounds (no more data loss), multiple Playgrounds, UI…
Browse files Browse the repository at this point in the history
… WebApp Redesign (#1731)

## Description

Implements a large part of the [website
redesign](#1561):

![CleanShot 2024-09-14 at 10 24
57@2x](https://github.com/user-attachments/assets/f245c7ac-cb8c-4e5a-b90a-b4aeff802e7b)


High-level changes shipped in this PR:

* Multiple Playgrounds. Every temporary Playground can be saved either
in the browser storage (OPFS) or in a local directory (Chrome desktop
only for now).
* New Playground settings options: Name name, language, multisite
* URL as the source of truth for the application state
* State management via Redux

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](https://playground.wordpress.net/demos/) right into the
Playground app.

Here's just a few features unblocked by this PR:

* #1438 – no
more losing your work by accident 🎉
* #797 – with
multiple sites we can progressively build features we'll eventually
propose for WordPress core:
* A Playground export and import feature, pioneering the standard export
format for WordPress sites.
* A "Clone this Playground" feature, pioneering the [Site Transfer
Protocol](https://core.trac.wordpress.org/ticket/60375).
   * A "Sync two Playgrounds" feature, pioneering the Site Sync Protocol
* #1445 – better
git support is in top 5 most highly requested features. With multiple
Playgrounds, we can save your work and get rid of the "save your work
before connecting GitHub or you'll lose it" and cumbersome "repo setup"
forms on every interaction. Instead, we can make git operations like
Pull, Commit, etc. very easy and even enable auto-syncing with a git
repository.
* #1025 – as we
bring in more PHP plumbing into this repository, we'll replace the
TypeScript parts with PHP parts to create a WordPress core-first
Blueprints engine
* #1056 – Site
transfer protocol will unlocks seamlessly passing Playgrounds between
the browser and a local development environment
* #1558 – we'll
integrate [the Blueprints directory] and offer single-click Playground
setups, e.g. an Ecommerce store or a Slide deck editor.
#718.
* #539 – the
recorded Blueprints would be directly editable in Playground and perhaps
saved as a new Playground template
* #696 – the new
interaction model creates space for additional integrations.
* #707 – you
could create a "GitHub–synchronized" Playground
* #760 – we can
bootstrap one inside Playground using a Blueprint and benefit the users
immediately, and then gradually work towards enabling it on
WordPress.org
* #768 – the new
UI has space for a "new in Playground" section, similar to what Chrome
Devtools do
* #629  
* #32
* #104
* #497
* #562
* #580 

### Remaining work

- [ ] Write a release note for https://make.wordpress.org/playground/
- [x] Make sure GitHub integration is working. Looks like OAuth
connection leads to 404.
- [x] Fix temp site "Edit Settings" functionality to actually edit
settings (forking a temp site can come in a follow-up PR)
- [x] Fix style issue with overlapping site name label with narrow site
info views
- [x] Fix style issue with bottom "Open Site" and "WP Admin" buttons
missing for mobile viewports
- [x] Make sure there is a path for existing OPFS sites to continue to
load
- [x] Adjust E2E tests.
- [x] Reflect OPFS write error in UI when saving temp site fails
- [x] Find a path forward for
[try-wordpress](https://github.com/WordPress/try-wordpress) to continue
working after this PR
- [x] Figure out why does the browser get so choppy during OPFS save. It
looks as if there was a lot of synchronous work going on. Shouldn't all
the effort be done by a worker a non-blocking way?
- [x] Test with Safari and Firefox. Might require a local production
setup as FF won't work with the Playground dev server.
- [x] Fix Safari error: `Unhandled Promise Rejection: UnknownError:
Invalid platform file handle` when saving a temporary Playground to
OPFS.
- [x] Fix to allow deleting site that fails to boot. This is possible
when saving a temp site fails partway through.
- [x] Fix this crash:

```ts
		/**
		 * @todo: Fix OPFS site storage write timeout that happens alongside 2000
		 *        "Cannot read properties of undefined (reading 'apply')" errors here:
		 * I suspect the postMessage call we do to the safari worker causes it to
		 * respond with another message and these unexpected exchange throws off
		 * Comlink. We should make Comlink ignore those.
		 */
		// redirectTo(PlaygroundRoute.site(selectSiteBySlug(state, siteSlug)));
```
- [x] Test different scenarios manually, in particular those involving
Blueprints passed via hash
- [x] Ensure we have all the aria, `name=""` etc. accessibility
attributes we need, see AXE tools for Chrome.
- [x] Update developer documentation on the `storage` query arg (it's
removed in this PR)
- [x] Go through all the `TODOs` added in this PR and decide whether to
solve or punt them
- [x] Handle errors like "site not found in OPFS", "files missing from a
local directory"
- [x] Disable any `Local 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.
- [x] Reduce the naming confusion, e.g. `updateSite` in redux-store.ts
vs `updateSite` in `site-storage.ts`. What would an unambiguous code
pattern look like?
- [x] Find a reliable and intuitive way of updating these deeply nested
redux state properties. Right now we do an ad-hoc recursive merge that's
slightly different for sites and clients. Which patterns used in other
apps would make it intuitive?
- [x] Have a single entrypoint for each logical action such as "Create a
new site", "Update site", "Select site" etc. that will take care of
updating the redux store, updating OPFS, and updating the URL. My ideal
scenario is calling something 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"
- [x] Fix all the tiny design imperfections, e.g. cut-off labels in the
site settings form.

### Follow up work

- [ ] Mark all the related blocked issues as unblocked on the project
board, e.g.
#1703,
#1731, and more –
[see the All Tasks
view](https://github.com/orgs/WordPress/projects/180/views/2?query=sort%3Aupdated-desc+is%3Aopen&filterQuery=status%3A%22Up+next%22%2C%22In+progress%22%2C%22Needs+review%22%2C%22Reviewed%22%2C%22Done%22%2CBlocked)
- [ ] Update WordPress/Learn#1583 with info
that the redesign is now in and we're good to record a video tutorial.
- [ ] #1746
- [ ] Write a note in [What's new for developers? (October
2024)](WordPress/developer-blog-content#309)
- [ ] Document the new site saving flow in
`packages/docs/site/docs/main/about/build.md` cc @juanmaguitar
- [ ] Update all the screenshots in the documentation cc @juanmaguitar 
- [ ] When the site fails to load via `.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.
- [ ] Introduce notifications system to provide feedback about outcomes
of various user actions.
- [ ] Add non-minified WordPress versions to the "New site" modal.
- [ ] Fix `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.
- [ ] Attribute log messages to the site that triggered them.
- [ ] Take note of any interactions that we find frustrating or
confusing. We can perhaps adjust them in a follow-up PR, but let's make
sure we notice and document them here.
- [ ] Solidify the functional tooling for transforming between `URL`,
`runtimeConfiguration`, `Blueprint`, and `site settings form state` for
both OPFS sites and in-memory sites. Let's see if we can make it
reusable in Playground CLI.
- [ ] Speed up OPFS interactions, saving a site can take quite a while.
- [ ] A mobile-friendly modal architecture that doesn't stack modals,
allows dismissing, and understands some modals (e.g. fatal error report)
might have priority over other modals (e.g. connect to GitHub). Discuss
whether modals should be declared at the top level, like here, or
contextual to where the "Show modal" button is rendered.
- [ ] Discuss the need to support strong, masked passwords over a simple
password that's just `"password"`.
- [ ] Duplicate site feature implemented as "Export site + import site"
with the new core-first PHP tools from
adamziel/wxr-normalize#1 and
https://github.com/adamziel/site-transfer-protocol
- [x] Retain temporary sites between site changes. Don't just trash
their iframe and state when the user switches to another site.

Closes #1719

cc @brandonpayton

---------

Co-authored-by: Brandon Payton <[email protected]>
Co-authored-by: Bero <[email protected]>
Co-authored-by: Bart Kalisz <[email protected]>
  • Loading branch information
4 people authored Sep 27, 2024
1 parent c82a441 commit 39d0023
Show file tree
Hide file tree
Showing 114 changed files with 5,178 additions and 3,669 deletions.
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ packages/playground/sync/src/test/wp-*
packages/php-wasm/node/src/test/__test*
*.timestamp-1678999213403.mjs
.local
.vscode
.vscode
playwright-report
17 changes: 16 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,22 @@ jobs:
with:
name: cypress-screenshots
path: dist/cypress/packages/playground/website/screenshots

test-e2e-playwright:
runs-on: ubuntu-latest
needs: [lint-and-typecheck]
# Run as root to allow node to bind to port 80
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/prepare-playground
- name: Install Playwright Browsers
run: sudo npx playwright install --with-deps
- name: Run Playwright tests
run: sudo CI=true npx nx run playground-website:e2e:playwright:ci
- uses: actions/upload-artifact@v4
if: ${{ !cancelled() }}
with:
name: playwright-report
path: playwright-report/
build:
runs-on: ubuntu-latest
needs: [lint-and-typecheck]
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,6 @@ Thumbs.db

# Playground artifacts
php.js.bak
**/test-results/
**/playwright-report/
**/blob-report/
50 changes: 22 additions & 28 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,89 +25,83 @@ The following contributors merged PRs in this release:

### Documentation

- Docs: Better paths for links. ([#1765](https://github.com/WordPress/wordpress-playground/pull/1765))
- Docs: I18n setup. ([#1766](https://github.com/WordPress/wordpress-playground/pull/1766))
- Docs: Remove the outdated "data rependencies" page. ([#1785](https://github.com/WordPress/wordpress-playground/pull/1785))
- Docs: Better paths for links. ([#1765](https://github.com/WordPress/wordpress-playground/pull/1765))
- Docs: I18n setup. ([#1766](https://github.com/WordPress/wordpress-playground/pull/1766))
- Docs: Remove the outdated "data rependencies" page. ([#1785](https://github.com/WordPress/wordpress-playground/pull/1785))

### Website

- Fix troubleshoot-and-debug link. ([#1782](https://github.com/WordPress/wordpress-playground/pull/1782))
- Fix troubleshoot-and-debug link. ([#1782](https://github.com/WordPress/wordpress-playground/pull/1782))

### Various

- Update link for contributor day. ([#1775](https://github.com/WordPress/wordpress-playground/pull/1775))
- Update link for contributor day. ([#1775](https://github.com/WordPress/wordpress-playground/pull/1775))

### Contributors

The following contributors merged PRs in this release:

@adamziel @bgrgicak @juanmaguitar @n8finch


## [v0.9.42] (2024-09-17)
## [v0.9.42] (2024-09-17)

### PHP WebAssembly

- FS: Use the correct rm/rmdir method when moving files between mounts. ([#1770](https://github.com/WordPress/wordpress-playground/pull/1770))
- FS: Use the correct rm/rmdir method when moving files between mounts. ([#1770](https://github.com/WordPress/wordpress-playground/pull/1770))

### Contributors

The following contributors merged PRs in this release:

@adamziel

## [v0.9.41] (2024-09-16)

## [v0.9.41] (2024-09-16)




## [v0.9.40] (2024-09-16)
## [v0.9.40] (2024-09-16)

### Enhancements

- Extend allowable resources available via WordPress/WordPress. ([#1721](https://github.com/WordPress/wordpress-playground/pull/1721))
- Extend allowable resources available via WordPress/WordPress. ([#1721](https://github.com/WordPress/wordpress-playground/pull/1721))

### Tools

- Update actions/upload-artifact version to 4. ([#1748](https://github.com/WordPress/wordpress-playground/pull/1748))
- Update actions/upload-artifact version to 4. ([#1748](https://github.com/WordPress/wordpress-playground/pull/1748))

### Documentation

- Docs/Blueprints resources: Grammar and typo fixes. ([#1741](https://github.com/WordPress/wordpress-playground/pull/1741))
- Docs/Blueprints resources: Grammar and typo fixes. ([#1741](https://github.com/WordPress/wordpress-playground/pull/1741))

### PHP WebAssembly

- @php-wasm/universal : Add Phar support in php-wasm. ([#1716](https://github.com/WordPress/wordpress-playground/pull/1716))
- @php-wasm/universal : Add Phar support in php-wasm. ([#1716](https://github.com/WordPress/wordpress-playground/pull/1716))

### Website

- Add the `components` package with PathMappingControl. ([#1608](https://github.com/WordPress/wordpress-playground/pull/1608))
- Add the `components` package with PathMappingControl. ([#1608](https://github.com/WordPress/wordpress-playground/pull/1608))

### Bug Fixes

- Fix CLI --skipWordPressSetup option. ([#1760](https://github.com/WordPress/wordpress-playground/pull/1760))
- Fix CLI --skipWordPressSetup option. ([#1760](https://github.com/WordPress/wordpress-playground/pull/1760))

### Reliability

- Improve Playground CLI logging and fix quiet mode. ([#1751](https://github.com/WordPress/wordpress-playground/pull/1751))
- Improve Playground CLI logging and fix quiet mode. ([#1751](https://github.com/WordPress/wordpress-playground/pull/1751))

### Various

- Docs/Guides: Guides introductions and some minor adjustments. ([#1754](https://github.com/WordPress/wordpress-playground/pull/1754))
- Docs/Guides: Normalized and fixed guides links. ([#1756](https://github.com/WordPress/wordpress-playground/pull/1756))
- Docs/Guides: Providing content for your demo. ([#1747](https://github.com/WordPress/wordpress-playground/pull/1747))
- Docs/Guides: WordPress Playground for plugin developers. ([#1750](https://github.com/WordPress/wordpress-playground/pull/1750))
- Docs/Guides: WordPress Playground for theme developers. ([#1732](https://github.com/WordPress/wordpress-playground/pull/1732))
- Docs: Links redirections. ([#1758](https://github.com/WordPress/wordpress-playground/pull/1758))
- Docs/Guides: Guides introductions and some minor adjustments. ([#1754](https://github.com/WordPress/wordpress-playground/pull/1754))
- Docs/Guides: Normalized and fixed guides links. ([#1756](https://github.com/WordPress/wordpress-playground/pull/1756))
- Docs/Guides: Providing content for your demo. ([#1747](https://github.com/WordPress/wordpress-playground/pull/1747))
- Docs/Guides: WordPress Playground for plugin developers. ([#1750](https://github.com/WordPress/wordpress-playground/pull/1750))
- Docs/Guides: WordPress Playground for theme developers. ([#1732](https://github.com/WordPress/wordpress-playground/pull/1732))
- Docs: Links redirections. ([#1758](https://github.com/WordPress/wordpress-playground/pull/1758))

### Contributors

The following contributors merged PRs in this release:

@adamziel @bgrgicak @brandonpayton @juanmaguitar @mho22 @peterwilsoncc


## [v0.9.39] (2024-09-09)

### Bug Fixes
Expand Down
96 changes: 96 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,13 @@
"octokit-plugin-create-pull-request": "5.1.1",
"react": "^18.2.25",
"react-dom": "^18.2.25",
"react-hook-form": "7.53.0",
"react-modal": "^3.16.1",
"react-redux": "8.1.3",
"react-transition-group": "4.4.5",
"unzipper": "0.10.11",
"vite-plugin-api": "1.0.4",
"wouter": "3.3.5",
"xterm": "5.3.0",
"xterm-addon-fit": "0.8.0",
"yargs": "17.7.2"
Expand Down Expand Up @@ -104,6 +106,7 @@
"@nx/web": "16.9.0",
"@nx/webpack": "16.9.0",
"@nx/workspace": "16.9.0",
"@playwright/test": "1.47.1",
"@rollup/plugin-url": "^8.0.1",
"@swc-node/register": "~1.6.7",
"@swc/core": "~1.3.85",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@ You can go ahead and try it out. The Playground will automatically install the t
| `lazy` | | Defer loading the Playground assets until someone clicks on the "Run" button. Does not accept any values. If `lazy` is added as a URL parameter, loading will be deferred. |
| `login` | `yes` | Log the user in as an admin. Accepts `yes` or `no`. |
| `multisite` | `no` | Enables the WordPress multisite mode. Accepts `yes` or `no`. |
| `storage` | `none` | Selects the storage for Playground: `none` gets erased on page refresh, `browser` is stored in the browser, and `device` is stored in the selected directory on a device. The last two protect the user from accidentally losing their work upon page refresh. |
| `import-site` | | Imports site files and database from a ZIP file specified by a URL. |
| `import-wxr` | | Imports site content from a WXR file specified by a URL. It uses the WordPress Importer plugin, so the default admin user must be logged in. |
| `site-slug` | | Selects which site to load from browser storage. This must be used in combination with `storage=browser`. |
| `site-slug` | | Selects which site to load from browser storage. |
| `language` | `en_US` | Sets the locale for the WordPress instance. This must be used in combination with `networking=yes` otherwise WordPress won't be able to download translations. |

For example, the following code embeds a Playground with a preinstalled Gutenberg plugin and opens the post editor:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Playground [disables network connections](/blueprints/data-format#features) by d

### Temporary by design

As Playground [streams rather than serves](/about#streamed-not-served) WordPress, all database changes and uploads will be gone when you refresh the page. To avoid losing your work, either [export your work](/quick-start-guide#save-your-site) before or enable storage in the browser/device via the [Query API](/developers/apis/query-api#available-options) or the UI.
As Playground [streams rather than serves](/about#streamed-not-served) WordPress, all database changes and uploads will be gone when you refresh the page. To avoid losing your work, either [export your work](/quick-start-guide#save-your-site) before or enable storage in the browser/device via the "Save" button in the UI.

## When developing with Playground

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 39d0023

Please sign in to comment.