Skip to content

Refactor frontend components: extract modals, and utilities#12954

Merged
mtsgrd merged 1 commit intomasterfrom
svelte-compound-architecture-docs
Mar 22, 2026
Merged

Refactor frontend components: extract modals, and utilities#12954
mtsgrd merged 1 commit intomasterfrom
svelte-compound-architecture-docs

Conversation

@mtsgrd
Copy link
Contributor

@mtsgrd mtsgrd commented Mar 20, 2026

What

Reduces complexity in several large Svelte components by extracting self-contained pieces into focused files. Also adds an architecture guide to document the patterns used.


Component extractions

ChangedFilesContextMenu — ~840 → ~510 lines

Three modals extracted, each owning its own state, service injections, and logic, exposed via a single show() method:

  • DiscardChangesModal.svelte
  • StashIntoBranchModal.svelte
  • AbsorbPlanModal.svelte

RulesList — ~558 → ~308 lines

  • RuleEditor.svelte — extracted a 250-line snippet that was inlined across 4 render sites

BranchCommitList — ~544 → ~398 lines

  • UpstreamIntegrationActions.svelte — upstream integration UI with mode picker and modal

BranchIntegrationModal — ~593 → ~475 lines

  • $lib/stacks/integrationStepUtils.ts — 13 pure step manipulation functions (pick, skip, squash, split, shift) made immutable (accept array → return new array)

Test plan

  • pnpm check — 0 errors
  • Manual smoke test recommended for each affected flow: discard changes, stash into branch, absorb changes, upstream integration

@vercel
Copy link

vercel bot commented Mar 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
gitbutler-web Ignored Ignored Preview Mar 22, 2026 3:17pm

Request Review

Copilot AI review requested due to automatic review settings March 20, 2026 14:20
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors several large apps/desktop Svelte components by extracting self-contained UI (modals / rows) and pure utilities into dedicated files, and adds a written architecture guide documenting the compound component pattern used in the desktop frontend.

Changes:

  • Extracts reusable UI into new focused components (e.g., RuleEditor, IrcMessageRow, upstream integration actions, and multiple modals).
  • Extracts pure helper logic into $lib utilities (integrationStepUtils.ts, irc/utils.ts) and wires consumers to use them.
  • Adds apps/desktop/src/components/ARCHITECTURE.md and links it from repo/docs guidance files.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
apps/desktop/src/lib/stacks/integrationStepUtils.ts New immutable step-manipulation helpers used by interactive upstream integration UI
apps/desktop/src/lib/irc/utils.ts New IRC formatting/grouping helpers extracted from IrcMessages
apps/desktop/src/components/UpstreamIntegrationActions.svelte New extracted upstream integration action UI (rebase vs interactive)
apps/desktop/src/components/StashIntoBranchModal.svelte New extracted modal for “stash into branch” flow
apps/desktop/src/components/RulesList.svelte Simplifies rules list by delegating edit/add UI to RuleEditor
apps/desktop/src/components/RuleEditor.svelte New extracted rule editor component reused across multiple render sites
apps/desktop/src/components/IrcMessages.svelte Refactors message rendering toward IrcMessageRow and $lib/irc/utils
apps/desktop/src/components/IrcMessageRow.svelte New extracted message-row renderer (commit/hunk/markdown/reactions)
apps/desktop/src/components/DiscardChangesModal.svelte New extracted discard confirmation modal
apps/desktop/src/components/ChangedFilesContextMenu.svelte Simplifies context menu by delegating modal logic to extracted modal components
apps/desktop/src/components/BranchIntegrationModal.svelte Refactors interactive integration logic to use extracted step utilities
apps/desktop/src/components/BranchCommitList.svelte Replaces inline upstream integration UI with extracted UpstreamIntegrationActions
apps/desktop/src/components/ARCHITECTURE.md New architecture guide describing compound component pattern and decision criteria
apps/desktop/src/components/AbsorbPlanModal.svelte New extracted absorb-plan modal + flow
apps/desktop/README.md Links to the new architecture guide
.github/copilot-instructions.md Documents/links the compound component pattern for desktop frontend work

Comment on lines +64 to +70
<Modal
width={434}
type="info"
title="Stash changes into a new branch"
bind:this={modal}
onSubmit={(_, item) => isChangedFilesItem(item) && confirmStashIntoBranch(item, slugifiedRefName)}
>
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

Modal onSubmit already calls confirmStashIntoBranch(...), and the AsyncButton also calls it via action. Since the button is type="submit", clicking it will invoke both handlers and can create the stash/branch twice. Pick a single submit path (either onSubmit or the button action) and wire loading/disabled state through that one path.

Copilot uses AI. Check for mistakes.
@mtsgrd mtsgrd force-pushed the svelte-compound-architecture-docs branch from 8561e67 to 7faff1d Compare March 20, 2026 15:52
@github-actions github-actions bot added rust Pull requests that update Rust code @gitbutler/ui labels Mar 20, 2026
Copilot AI review requested due to automatic review settings March 20, 2026 15:54
@mtsgrd mtsgrd force-pushed the svelte-compound-architecture-docs branch from 7faff1d to fb16910 Compare March 20, 2026 15:54
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

@@ -582,258 +506,6 @@
{/snippet}
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

The context menu’s malformed-data fallback message currently contains a stray leading apostrophe ('Woops! ...), which will render incorrectly. Please remove the extra ' (and consider standardizing the spelling to “Whoops”).

Copilot uses AI. Check for mistakes.
{/if}
{/if}
{:else}
<p class="text-13">Woops! Malformed data :(</p>
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

User-facing copy: “Woops!” is typically spelled “Whoops!”. Consider correcting this message since it’s shown when modal data is malformed.

Suggested change
<p class="text-13">Woops! Malformed data :(</p>
<p class="text-13">Whoops! Malformed data :(</p>

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings March 22, 2026 07:52
@mtsgrd mtsgrd force-pushed the svelte-compound-architecture-docs branch from 0ddff73 to 1ef2f99 Compare March 22, 2026 07:52
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

@mtsgrd mtsgrd force-pushed the svelte-compound-architecture-docs branch from 1ef2f99 to 5dfb5d3 Compare March 22, 2026 08:15
@mtsgrd mtsgrd changed the title Refactor frontend components: extract modals, utilities, and add architecture guide Refactor frontend components: extract modals, and utilities Mar 22, 2026
Copilot AI review requested due to automatic review settings March 22, 2026 14:59
@mtsgrd mtsgrd force-pushed the svelte-compound-architecture-docs branch from 5dfb5d3 to 3d939ad Compare March 22, 2026 14:59
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Comment on lines 66 to +70
function handleKeyDown(event: KeyboardEvent) {
if (event.key === "Escape") {
close();
}
if (event.key === "Enter") {
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

show() registers handleKeyDown on window, but the listener is never removed when the modal closes. With the new Enter-key submit logic, this can keep preventing default (and potentially triggering onSubmit / clicking the last formEl submit button) even after the modal is closed. Remove the keydown listener as part of close() (and/or guard handleKeyDown with if (!open) return;) so the handler is only active while the modal is open.

Copilot uses AI. Check for mistakes.
Break apart several oversized components into focused, reusable pieces:

- Extract AbsorbPlanModal, DiscardChangesModal, and StashIntoBranchModal
  from ChangedFilesContextMenu
- Extract RuleEditor from RulesList
- Extract UpstreamIntegrationActions from BranchCommitList
- Extract pure step manipulation functions from BranchIntegrationModal
  into integrationStepUtils

Also fix Modal Enter key handling: when focus is not on a native input
or button, pressing Enter now clicks the submit button (preserving
AsyncButton loading state) or falls back to calling onSubmit directly.
@mtsgrd mtsgrd force-pushed the svelte-compound-architecture-docs branch from 3d939ad to 5e5de7b Compare March 22, 2026 15:17
@mtsgrd mtsgrd merged commit bf809d9 into master Mar 22, 2026
37 checks passed
@mtsgrd mtsgrd deleted the svelte-compound-architecture-docs branch March 22, 2026 15:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

@gitbutler/desktop @gitbutler/ui rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants