Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fix(site): revamp UI for batch-updating workspaces#18895

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Parkreiner merged 38 commits intomainfrommes/batch-update-02
Sep 18, 2025

Conversation

Parkreiner
Copy link
Member

@ParkreinerParkreiner commentedJul 16, 2025
edited
Loading

Closes#18879
Builds on#18895

Changes made

  • DeletedBatchUpdateConfirmation component, replacing it withBatchUpdateModalForm
  • Added stories for the new component, trying to capture every variant I could think of

Screenshots

image

Notes

  • There's too many problems to list, but look at the issue to see all the problems we had with the old implementation
  • It's definitely helpful to look at the stories to see all the things the component is meant to cover

@ParkreinerParkreiner self-assigned thisJul 16, 2025
isLoading={batchActions.isProcessing}
onClose={()=>setActiveBatchAction(undefined)}
onConfirm={async()=>{
workspacesToUpdate={checkedWorkspaces}
Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Renamed prop because I don't think that a component should need to be aware of how its parent chooses to represent workspace selections

@Parkreiner
Copy link
MemberAuthor

@aslilac I don't think there's a good way to ping you specifically now that you're a code owner, but I was hoping I could have you review this PR

Copy link
Member

@aslilacaslilac left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I wonder if we should even bother showing the "dormant" workspaces section. you can filter fordormant:true on the workspaces page to easily find offenders. and maybe the "already up to date" section could be collapsed by default?

import{BatchUpdateModalForm}from"./BatchUpdateModalForm";
import{ACTIVE_BUILD_STATUSES}from"./WorkspacesPage";

typeWriteable<T>={-readonly[KeyinkeyofT]:T[Key]};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I was so prepared to tell you to use a built-in TypeScript util but apparently somehow we don't have a standard inverse ofReadonly 🤦‍♀️ is this a useful enough thing to justify having in a different file for reuse?

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I do think it'll be useful sometime in the future. Any preferences as for where to put it? I feel like we definitely don't want to make another file likenullable.ts, where it's just a single type

};

exportconstOnlyReadyToUpdate:Story={
beforeEach:(ctx)=>{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
beforeEach:(ctx)=>{
beforeEach:(story)=>{

I think this makes it a bit clearer what object we're dealing with (it appears to be the fully normalized story)

Copy link
MemberAuthor

@ParkreinerParkreinerAug 14, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I actually disagree – the arg type isStoryContext<TRenderer, TArgs>. The type doesn't even give you access to the main story that the context was generated for

Comment on lines 615 to 624
{/*
* Because of how the Dialog component works, we need to make
* sure that at least the parent stays mounted at all times. But
* if we move all the state into ReviewForm, that means that its
* state only mounts when the user actually opens up the batch
* update form. That saves us from mounting a bunch of extra
* state and firing extra queries, when realistically, the form
* will stay closed 99% of the time while the user is on the
* workspaces page.
*/}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

you don't actually explain what it is about theDialog component that requires this tho. I think the benefits of not mounting a component when you don't need to should be relatively obvious, so this very wordy comment really just raises more questions than answer for me.

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Yeah, I think I have a bad habit of trying to explain why old code was bad. And I guess with you becoming a code owner now, there's a lot less risk of some of those sub-optimal UI patterns creeping back in

onSubmit:()=>void;
}>;

exportconstBatchUpdateModalForm:FC<BatchUpdateModalFormProps>=({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I feel weird about the titular component being the last thing in the file

Comment on lines 463 to 466
<li
key={ws.id}
className="[&:not(:last-child)]:border-b-border [&:not(:last-child)]:border-b [&:not(:last-child)]:border-solid border-0"
>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

ThisReviewPanel component is always rendered inside of this exactli, longclassName and all. could this be refactored?

Copy link
MemberAuthor

@ParkreinerParkreinerAug 14, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I extracted it out into a separate component. I really don't like havingli elements be coupled to the top level of a component definition, because it's really easy to wire them up wrong by accident and create invalid HTML (that React won't warn you about either)

id={failedValidationId}
className="m-0 text-highlight-red text-right text-sm pt-2"
>
Please acknowledge consequences to continue.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

tbh this feels a little overkill. restarting a workspacecan be destructive, but in practice it shouldn't be.

workspaces:readonlyWorkspace[];
queries:QueryEntry;
}>;
functioncreatePatchedDependencies(size:number):PatchedDependencies{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

the more I look at these stories the more I'm worried that this function is the wrong abstraction. we're doing all kinds of hoop jumping to make it work rn and I wonder if it'd just be easierand clearer to write out theworkspaces and query results like we usually do.

@aslilac
Copy link
Member

also sorry I didn't review this sooner. I have no idea how this slid under my radar, I did a ton of reviews on thursday and just absolutely missed this one.

@github-actionsgithub-actionsbot added the staleThis issue is like stale bread. labelJul 29, 2025
Parkreiner added a commit that referenced this pull requestAug 14, 2025
…tions (#18894)Precursor to#18895Splitting this off so that the changes are easier to review.## Changes made- Improve type-safety for the `withQuery` Storybook decorator- Centralized almost all queries that deal with template versions to usea shared, exported query key prefix- Updated `useFilter` and `usePagination` to have much more strictreturn types, and decoupled them from React Router at the interfacelevel- Also added some extra input validation and performance optimizationsto `useFilter` and `usePagination`- Removed a stale data when working with checked workspaces for the`/workspaces` page- Removed hacky `useEffect` call for syncing URL state to checkedworkspaces, in favor of explicit state syncs- Did some extra cleanup and removed unused values## Notes- Many of the changes here were in service of the main PR. I'll try tohighlight notable areas, but if there's anything that's not clear, feelfree to post a comment in this PR. Ideally you shouldn't really have tolook at the other PR to understand this one, so if something'sconfusing, that's a sign that something's wrong<!-- This is an auto-generated comment: release notes by coderabbit.ai-->## Summary by CodeRabbit* **Refactor*** Improved handling of URL search parameters and state synchronizationin filter and pagination features across multiple pages.* Centralized and clarified state management for workspace selection andbatch actions on the Workspaces page.* Enhanced type safety and naming consistency in batch actions andfilter components.* Updated filter and pagination hooks to accept explicit parameters andcallbacks for better maintainability.* Streamlined prop naming and menu handling in workspace filtercomponents for clarity.* **Bug Fixes*** Prevented unnecessary state updates when filter values remainunchanged.* **Tests**  * Updated tests for improved type safety and more precise assertions.<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Base automatically changed frommes/batch-update-01 tomainAugust 14, 2025 04:06
@ParkreinerParkreiner removed the staleThis issue is like stale bread. labelAug 14, 2025
@Parkreiner
Copy link
MemberAuthor

@aslilac Do you have time to pair with me next week to try simplifying the stories (and probably the component, too)? I would love to remove a bunch of thebeforeEach stuff, but I couldn't figure out a good way to do it that didn't make the code mess in other ways

@aslilac
Copy link
Member

absolutely! feel free to schedule something

@github-actionsgithub-actionsbot added the staleThis issue is like stale bread. labelAug 23, 2025
@ParkreinerParkreiner removed the staleThis issue is like stale bread. labelSep 17, 2025
onAcceptedConsequencesChange:(newValue:boolean)=>void;
checkboxRef:ForwardedRef<HTMLButtonElement>;
containerRef:ForwardedRef<HTMLDivElement>;
}>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
}>;
}>;

checked={acceptedConsequences}
onCheckedChange={onAcceptedConsequencesChange}
/>
I acknowledge these consequences.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I feel like consequences is just such a serious word here. maybe effects?

@ParkreinerParkreiner merged commit8a6852f intomainSep 18, 2025
32 checks passed
@ParkreinerParkreiner deleted the mes/batch-update-02 branchSeptember 18, 2025 00:46
@github-actionsgithub-actionsbot locked and limited conversation to collaboratorsSep 18, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account?Sign in.
Reviewers

@aslilacaslilacaslilac approved these changes

Assignees

@ParkreinerParkreiner

Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

bug(site): UI for batch-updating workspaces is confusing and has destructive race conditions
2 participants
@Parkreiner@aslilac

[8]ページ先頭

©2009-2025 Movatter.jp