Repository navigation
side menu for sidedocs, planning whiteboard, and backpack - #11609
Joey Wunderlich (jwunderl) wants to merge 57 commits into
Conversation
|
This is cool! Definitely feels more polished than our side docs, but it does obscure more of the workspace and isn't as responsive. But I like this idea of some sort of floating (or pinned) window for a variety of things - docs, saved snippets/assets (backpack), AI code explainer/helper? |
|
Yeah that was goal, having an extensible place to add 'workspace' level pieces like that to add more bubbles for those sorts of things as we make them. had it review existing sizing for side docs & make it so the horizontal bubbles last until the wide desktop breakpoint to try and reclaim some space. It had horizontal resizing but also added indicator / vertical resizing https://arcade.makecode.com/app/39e9673146d93e17e95597856fdbafe42facfc51-9f561c88ba |
… blocks from custom files
| @@ -0,0 +1,74 @@ | |||
| # Project tools | |||
There was a problem hiding this comment.
same as richard mentioned noticing on documentation for his stuff, a lot of this is referencing nitpicky decisions i made -- i'll probably just cut this file out but figured potentially some use in skimming since it is a decently long list of very tiny requests i made along the way (though i trimmed a decent bit from it already
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Conflict resolution can overwrite selected saved notes, and scoped key handling can leave the image editor stuck on a temporary tool.
Review effort: Balanced
Findings: 1
Open (2)
What changed in this PR
Adds a unified project-tools side panel containing documentation, private whiteboards, and a portable Backpack for blocks/assets.
Changes:
- Adds responsive project-tools UI, whiteboard persistence, and cloud privacy boundaries.
- Adds Backpack storage, search, previews, asset editing, and dependency-aware imports.
- Isolates embedded image-editor state and adds extensive project-tools tests.
| File | Description |
|---|---|
webapp/src/workspace.ts |
Persists private notes while excluding them from shares. |
webapp/src/projectToolsState.ts |
Defines visibility and pin defaults. |
webapp/src/projectNotes.ts |
Validates and manages whiteboards. |
webapp/src/container.tsx |
Integrates project tools with side docs. |
webapp/src/components/ProjectWhiteboardMenu.tsx |
Adds whiteboard management UI. |
webapp/src/components/ProjectWhiteboard.tsx |
Implements whiteboard editing and autosave. |
webapp/src/components/pianoRoll/AssetNameModal.tsx |
Uses isolated asset context. |
webapp/src/components/musicEditor/EditControls.tsx |
Uses isolated asset context. |
webapp/src/components/ImageFieldEditor.tsx |
Supports injected stores and projects. |
webapp/src/components/ImageEditor/tilemap/TilePalette.tsx |
Creates tiles in the contextual project. |
webapp/src/components/ImageEditor/store/imageReducer.ts |
Supports contextual tile lookup. |
webapp/src/components/ImageEditor/keyboardShortcuts.ts |
Scopes shortcuts across editor instances. |
webapp/src/components/ImageEditor/ImageEditor.tsx |
Supports isolated editors and stores. |
webapp/src/components/ImageEditor/ImageCanvas.tsx |
Scopes canvas events and asset creation. |
webapp/src/components/ImageEditor/BottomBar.tsx |
Applies contextual naming and resize state. |
webapp/src/components/BackpackPreview.tsx |
Lazily renders private previews. |
webapp/src/components/BackpackAssetEditDialog.tsx |
Adds isolated native asset editing. |
webapp/src/components/AssetEditorContext.ts |
Defines contextual asset projects. |
webapp/src/cloud.ts |
Handles concurrent note synchronization. |
webapp/src/blockSnippet.ts |
Validates and prepares portable snippets. |
webapp/src/blocks.tsx |
Integrates Backpack with Blockly and clipboard operations. |
webapp/src/backpackStorage.ts |
Exposes Backpack storage adapters. |
webapp/src/backpackSearch.ts |
Adds local fuzzy search. |
webapp/src/backpackProject.ts |
Imports snippets and required extensions. |
webapp/src/backpackPreview.ts |
Generates block thumbnails. |
webapp/src/backpackAssetPreview.ts |
Generates isolated asset previews. |
webapp/src/backpackAssetEditor.ts |
Implements scratch-project asset editing. |
webapp/src/assets.ts |
Accepts explicit asset projects. |
webapp/src/assetEditor.tsx |
Fixes iframe responses and disposal. |
webapp/src/app.tsx |
Enables and renders project tools. |
theme/sidedoc.less |
Imports project-tools styles. |
theme/project-backpack.less |
Styles Backpack UI and dialogs. |
tests/pxt-editor-test/editorrunner.ts |
Tests project-tools state and note validation. |
tests/project-tools-test/whiteboard.spec.js |
Tests whiteboard UI and persistence. |
tests/project-tools-test/whiteboard.fixture.js |
Provides the whiteboard browser fixture. |
tests/project-tools-test/storage.spec.js |
Tests note privacy and synchronization. |
tests/project-tools-test/README.md |
Documents project-tools testing. |
tests/project-tools-test/launcher.spec.js |
Tests responsive launcher behavior. |
tests/project-tools-test/clipboard.spec.js |
Tests clipboard serialization. |
tests/project-tools-test/browser.js |
Configures browser tests. |
tests/project-tools-test/backpack-search.spec.js |
Tests Backpack search. |
tests/project-tools-test/backpack-project.spec.js |
Tests dependency-aware imports. |
tests/project-tools-test/backpack-blocks.spec.js |
Tests block serialization and undo. |
tests/project-tools-test/backpack-assets.spec.js |
Tests asset portability. |
tests/project-tools-test/backpack-asset-edit.spec.js |
Tests isolated asset editing. |
pxtservices/iframeDriver.ts |
Restricts pre-handshake iframe messages. |
pxtlib/auth.ts |
Defines Backpack API types. |
pxtblocks/index.ts |
Exports Backpack APIs. |
pxtblocks/fields/field_utils.ts |
Extends portable asset serialization. |
pxtblocks/fields/field_tileset.ts |
Enables tiles as Backpack assets. |
pxtblocks/fields/field_melodySandbox.ts |
Enables melodies as Backpack assets. |
pxtblocks/fields/field_gridpicker.ts |
Adds asset-gallery opt-in. |
pxtblocks/fields/field_asset.ts |
Enables native fields as Backpack assets. |
pxtblocks/blockDragger.ts |
Adds Backpack drag targets and cleanup. |
localtypings/pxteditor.d.ts |
Adds project-tools and response types. |
localtypings/pxtarget.d.ts |
Adds target feature flags. |
localtypings/projectheader.d.ts |
Defines private project-note metadata. |
gulpfile.js |
Adds the project-tools test task. |
docs/project-tools.md |
Documents project tools and Backpack. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| {conflict && <div role="alert" className="project-whiteboard__conflict"> | ||
| <p>{lf("Saved notes changed while you were editing. Choose which version to keep.")}</p> | ||
| <button type="button" onClick={() => { conflictPending.current = false; setConflict(undefined); dirty.current = true; flush(); }}>{lf("Keep my notes")}</button> | ||
| <button type="button" onClick={() => loadNotes(conflict.notes)}>{lf("Load saved notes")}</button> |
| } | ||
|
|
||
| protected onKeyUp = (ev: KeyboardEvent): void => { | ||
| if (!this.shouldHandleEvent(ev)) return; |
Richard Knoll (riknoll)
left a comment
There was a problem hiding this comment.
review part 1
all of the new react files are really difficult to read, can we do some formatting to make them a little bit nicer? e.g. group related effects/items, split things up, actually put empty lines between things, split JSX up so that it's one attribute per line, etc.
| } | ||
|
|
||
| export interface FieldGridPickerOptions extends FieldCustomDropdownOptions { | ||
| /** Opt asset galleries into Backpack; ordinary enum pickers remain code. */ |
There was a problem hiding this comment.
been reading this comment for a while and i still have no idea what it means.
we don't really use the gridpicker for any assets, so i guess i'm curious as to why this file was edited? it's mostly just used for dropdowns like the pin picker in microbit and the blocks picker in minecraft.
There was a problem hiding this comment.
🙃 a few of these i had rewritten / removed while cleaning up last night, but i'm guessing the portion i had changed got overwritten / checked out at some point while i had it running a playwright test pass to try and check for any accessibility edge cases i hadn't thought of, since they they didn't end up making it into commit. Sorry for the bad comments still being there / will fix
| return getAssetSaveState(asset) | ||
| } | ||
| // Full captures need the gallery's qualified API name, not a display-name | ||
| // assets.tile reference, so dependency collection can find its package. |
There was a problem hiding this comment.
again, another indecipherable comment
|
|
||
| export interface FieldCustom { | ||
| isFieldCustom_: boolean; | ||
| /** Can be saved/edited as an asset when this is a literal block's only editable field. */ |
There was a problem hiding this comment.
what is a "literal block"?
| isEnabled: () => boolean; | ||
| canSave?: (block: Blockly.Block) => boolean; | ||
| save: (block: Blockly.BlockSvg) => void; | ||
| /** Open without moving focus (including when invoked by a dwell timer). */ |
| await props.onSave({ ...props.item, ...result, ...requirements, name: result.name || props.item.name, | ||
| versions: { target: pxt.appTarget.versions.target, pxt: pxt.appTarget.versions.pxt } }); | ||
| } catch (reason) { | ||
| if (session.current === current) setError(reason instanceof Error ? reason.message : lf("Could not save this asset. Please try again.")); |
There was a problem hiding this comment.
this seems fragile, should we be surfacing the error message from Error objects directly? if these are errors being thrown by other parts of this code, let's make sure we validate that they are expected to be shown to the usert.
There was a problem hiding this comment.
went through and marked as BackpackUserError for things it felt like user could potentially fix / deal with and untranslated rest
| blocksInfo: props.context.blocksInfo, hideMyAssets: true, headerVisible: true | ||
| }); | ||
| }, [asset]); | ||
| return ReactDOM.createPortal(<div ref={overlay} className="project-backpack__asset-modal-overlay" |
There was a problem hiding this comment.
this whole JSX chunk could do with some formatting
| }, [asset]); | ||
| return ReactDOM.createPortal(<div ref={overlay} className="project-backpack__asset-modal-overlay" | ||
| onMouseDown={event => { if (event.target === event.currentTarget) dismiss(); }}> | ||
| <FocusTrap className="project-backpack__asset-modal" role="dialog" ariaModal ariaLabel={lf("Backpack asset editor")} |
There was a problem hiding this comment.
weird css class format with the double underscores
| @@ -0,0 +1,141 @@ | |||
| import * as React from "react"; | |||
There was a problem hiding this comment.
this whole file could use formatting
| {...props} tutorial={tutorial} userId={userId} assetsEnabled={assetsEnabled} />; | ||
| } | ||
|
|
||
| function BackpackContents(props: ProjectBackpackProps & { userId?: string; assetsEnabled: boolean }): JSX.Element { |
There was a problem hiding this comment.
i feel like this needs to be broken up
… and dedupe w/ copy/paste to helper
|
We've deployed backend change with the associated new backend parts, so here's an update to date arcade build since i had to validate that deployed / set up correctly as well https://arcade.makecode.com/app/6040b25a2553dd756714bb5bb7e25c8dab29d5a1-d25fe19c2b#editor |
|
(doing one more pass of compressing things down a bit one sec) |


riffing off #10888 and adding a saved whiteboard / notes area for planning purposes.
i haven't looked at code at all for this (why it's a draft) since have a bit of a headache / basically just kicked off idea with a long rambling prompt and complained about things that felt bad / wanted fixed every few minutes when i took a look at it. could potentially see using the mobile behavior (a ... bubble that animates out the options) for all but not sure since it adds extra clicks / on desktop the size isn't that much of a concern.
on thing need to think of, right now i have clicking outside dismiss it, but that's not sidedocs behavior -- probably need to either have it as an option (like a pin button that makes it stay open) or just retain the behavior and force user to explicitly press the hide button if they want it gone.implementedimplemented as an experiment and the bug where the experiment banner shifts things wrong and messes up website layout annoyed me so fixed that along the way
https://arcade.makecode.com/app/a838201445c9989555277f1e21c1128dbb184abc-aa661c99d9