Skip to content

refactor: update button styles#196

Merged
kmendell merged 7 commits intomainfrom
refactor/ui-tweaks
May 17, 2025
Merged

refactor: update button styles#196
kmendell merged 7 commits intomainfrom
refactor/ui-tweaks

Conversation

@kmendell
Copy link
Member

@kmendell kmendell commented May 17, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a unified button component with consistent styling, icons, and loading states across the app.
    • Added minimalist, purple-accented button styles with dark mode support for all primary, secondary, destructive, and subtle actions.
  • Refactor

    • Replaced existing button components throughout the app with the new unified button component for actions like create, save, remove, and more.
    • Updated dialog and form footers to use the new button styles and components.
    • Improved error handling and feedback in some dialogs and actions.
  • Style

    • Enhanced button appearance and theming for visual consistency.
    • Updated button classes to clearly distinguish action types and selected states.
  • Bug Fixes

    • Improved accessibility and loading feedback for action buttons.
  • Chores

    • Removed unused imports and simplified internal logic where possible.
  • Documentation

    • Updated example text for Docker Host settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 17, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

📝 Walkthrough

Walkthrough

This update introduces a new reusable ArcaneButton Svelte component, consolidating action button logic and styling across the application. Existing buttons are replaced with ArcaneButton for consistent appearance, behavior, and loading states. Supporting CSS classes are added for a unified theme. Several dialog and page components are updated to use the new button and its styles.

Changes

Files/Paths Change Summary
src/app.css Adds comprehensive CSS classes for minimalist, purple-accented button themes (arcane-button-*), including variants for primary, destructive, secondary, and subtle actions, with both normal and dark mode support.
src/lib/components/arcane-button.svelte Introduces a new Svelte component implementing a configurable action button with icon, label, loading state, accessibility, and style variant logic based on an action prop.
src/lib/components/action-buttons.svelte Replaces individual <Button> components and icon/loading logic with unified <ArcaneButton> usage for all action buttons, simplifying UI rendering and imports.
src/lib/components/confirm-dialog/confirm-dialog.svelte
src/lib/components/dialogs/prune-confirmation-dialog.svelte
src/lib/components/dialogs/registry-form-dialog.svelte
src/lib/components/dialogs/user-form-dialog.svelte
Adds arcane-button-* CSS classes to dialog footer buttons for consistent styling; in user form dialog, also removes margin class from icons.
src/lib/services/docker/auto-update-service.ts Removes unused listImages import.
src/lib/services/docker/stack-service.ts Removes unused imports and simplifies YAML parsing logic to use only js-yaml's load method.
src/routes/+page.svelte Updates button classes for "Refresh" and card titles; makes card titles clickable links; defers loading state update for stop-all action to confirmation dialog callback.
src/routes/api/containers/+server.ts Explicitly sets the Name property on the container configuration object passed to creation logic.
src/routes/auth/login/+page.svelte Adds arcane-button-restart and arcane-button-create classes to OIDC and local login buttons for styling.
src/routes/containers/+page.svelte Replaces all "Create Container" buttons with <ArcaneButton> components, updating imports and event handlers accordingly.
src/routes/containers/create-container-dialog.svelte Adds explicit validation and error toasts, logs creation options, and replaces footer buttons with <ArcaneButton> components.
src/routes/images/+page.svelte Replaces image management action buttons ("Delete Selected", "Prune Unused", "Pull Image", "Check Updates") with <ArcaneButton> components; updates imports and button logic.
src/routes/images/[imageId]/+page.svelte Replaces "Remove" and "Back to Images" buttons with <ArcaneButton> components, removing explicit icon/loading markup.
src/routes/networks/+page.svelte Replaces all network creation and deletion buttons with <ArcaneButton> components, updating props and imports.
src/routes/networks/CreateNetworkDialog.svelte Removes icon imports, introduces <ArcaneButton> for label addition, cancel, and submit actions; updates event handlers and loading state handling.
src/routes/networks/[networkId]/+page.server.ts Removes the exported actions object and all server-side network removal logic; only the load function remains exported.
src/routes/networks/[networkId]/+page.svelte Refactors network removal to use direct API calls with explicit loading/error state, replaces removal/back buttons with <ArcaneButton>, and removes form-based logic and unused imports.
src/routes/onboarding/settings/+page.svelte Removes Windows example from Docker Host input field help text.
src/routes/settings/+page.svelte Adds arcane-button-save class to the save settings button.
src/routes/settings/tabs/authentication.svelte Updates password policy selection buttons to conditionally use arcane-button-create or arcane-button-restart based on selection.
src/routes/settings/tabs/docker-settings.svelte Removes size/variant props from "Add Registry" button, adds arcane-button-save class, and removes margin from icon.
src/routes/settings/tabs/user-management.svelte Replaces button size prop with arcane-button-save class and removes margin from icon in "Create User" button.
src/routes/stacks/+page.svelte Replaces "Create Stack" and "Import" buttons with <ArcaneButton> components, adds empty state button, and updates imports.
src/routes/stacks/[stackId]/+page.svelte Replaces custom save button with <ArcaneButton>, removing internal loading logic.
src/routes/stacks/new/+page.svelte Refactors layout to move submit button to header as <ArcaneButton>, removes footer submit button, and updates imports.
src/routes/volumes/+page.svelte Replaces "Delete Selected" and "Create Volume" buttons with <ArcaneButton> components, updating imports and button props.
src/routes/volumes/[volumeName]/+page.svelte Replaces volume removal and navigation buttons with <ArcaneButton> components, updating imports and event handlers.
src/routes/volumes/create-volume-dialog.svelte Replaces dialog footer buttons with <ArcaneButton> components for cancel and create actions, updating imports and props.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🔭 Outside diff range comments (1)
src/routes/images/+page.svelte (1)

558-561: 🛠️ Refactor suggestion

Missing ArcaneButton replacement

This button in the empty state hasn't been updated to use the ArcaneButton component like other buttons in the file, creating an inconsistency in the UI.

Replace the standard Button with ArcaneButton for consistency:

-<Button variant="outline" size="sm" onclick={() => (isPullDialogOpen = true)}>
-	<Download class="size-4" />
-	Pull Image
-</Button>
+<ArcaneButton action="pull" customLabel="Pull Image" onClick={() => (isPullDialogOpen = true)} size="sm" />
🧹 Nitpick comments (13)
src/routes/settings/tabs/docker-settings.svelte (1)

148-149: Button styling updated but spacing is affected.

The button now uses the arcane-button-save class, but removing the margin-right (mr-2) from the Plus icon eliminates the spacing between the icon and text. Consider ensuring proper spacing between button content elements.

-<Plus class="size-4" /> Add Registry
+<Plus class="size-4 mr-2" /> Add Registry
src/lib/components/dialogs/user-form-dialog.svelte (1)

130-134: Icon spacing removed from button content.

The removal of the margin-right (mr-2) from both the Loader2 and SubmitIcon components eliminates the spacing between the icons and text, potentially affecting readability.

-<Loader2 class="animate-spin size-4" />
+<Loader2 class="animate-spin size-4 mr-2" />
-<SubmitIcon class="size-4" />
+<SubmitIcon class="size-4 mr-2" />
src/routes/containers/create-container-dialog.svelte (1)

164-184: Enhanced form validation and debugging.

The added validation checks for missing image and container name provide better user feedback through toast error messages. The console logging helps with debugging.

Consider extracting these validation checks into a separate function to improve code organization and testability.

-		if (!selectedImage) {
-			toast.error('Image selection is required');
-			return;
-		}
-
-		if (!containerName.trim()) {
-			toast.error('Container name is required');
-			return;
-		}
-
-		if (isCreating) {
-			return; // Already processing
-		}
+       function validateForm() {
+           if (!selectedImage) {
+               toast.error('Image selection is required');
+               return false;
+           }
+           
+           if (!containerName.trim()) {
+               toast.error('Container name is required');
+               return false;
+           }
+           
+           if (isCreating) {
+               return false; // Already processing
+           }
+           
+           return true;
+       }
+       
+       if (!validateForm()) {
+           return;
+       }
src/routes/networks/[networkId]/+page.svelte (3)

38-42: Early-exit guard is helpful, but consider surfacing it sooner.

network?.Id is validated only inside triggerRemove().
If the page ever renders without a network object (e.g. due to stale client cache) the “Remove Network” button is still shown but will just toast an error.
You could disable the button up-front when !network?.Id to avoid a confusing round-trip for the user.

-<ArcaneButton action="remove" customLabel="Remove Network"
-  onClick={triggerRemove}
-  loading={isRemoving}
-  disabled={isRemoving || isPredefined}
-  label={isPredefined ? 'Cannot remove predefined networks' : 'Delete Network'} />
+<ArcaneButton
+  action="remove"
+  customLabel="Remove Network"
+  on:click={triggerRemove}
+  loading={isRemoving}
+  disabled={isRemoving || isPredefined || !network?.Id}
+  title={isPredefined ? 'Cannot remove predefined networks' : undefined} />

Note the additional title attribute (see next comment).


111-112: Replace non-standard label attribute with title or aria-label.

label="…" is not a valid HTML attribute for <button> elements and will leak into the DOM as an unknown attribute.
Use title for tool-tips or aria-label for accessibility instead.

- label={isPredefined ? 'Cannot remove predefined networks' : 'Delete Network'}
+ title={isPredefined ? 'Cannot remove predefined networks' : undefined}

18-24: Singleton service instance could live outside component scope.

const networkApi = new NetworkAPIService(); is re-created every time the page is instantiated.
If the service maintains internal state (e.g. auth headers or interceptors) it’s more efficient & predictable to keep a shared instance in a module or DI container.

No immediate action required, just a design consideration.

src/app.css (2)

157-166: Attribute-contains selector is brittle & may produce side-effects.

[class*='arcane-button-'] matches ANY className that merely includes that substring, even in unrelated components (e.g. my-arcane-button-wrapper).
Prefer a dedicated base class (.arcane-button) with explicit modifier classes (.is-remove, .is-create, …) to avoid accidental styling collisions and to keep CSS specificity predictable.

No immediate breakage, but watch for false positives as the codebase grows.


173-197: !important everywhere reduces theme extensibility.

Most color rules end with !important, making them hard to override in downstream themes or component-specific tweaks.
Reserve !important for edge cases; otherwise rely on specificity (.arcane-button--primary:hover) so future brand changes don’t need a full stylesheet audit.

src/lib/components/arcane-button.svelte (5)

83-95: Enhance accessibility for loading state

While the component correctly handles aria-label for icon-only buttons, consider adding aria-busy attribute when the button is in a loading state to improve accessibility.

-<Button variant={config.variant} size={customSize} class={`${extraClass} ${config.customClass || ''}`} disabled={disabled || loading} onclick={onClick} aria-label={isIconOnlyButton ? displayLabel : undefined}>
+<Button variant={config.variant} size={customSize} class={`${extraClass} ${config.customClass || ''}`} disabled={disabled || loading} on:click={onClick} aria-label={isIconOnlyButton ? displayLabel : undefined} aria-busy={loading}>

54-69: Consider adding explicit color information in the configuration

Currently, the button's color is determined by the variant property and custom classes. For better maintainability, consider adding explicit color properties to the configuration object, which would make the color choices more obvious to developers.


9-26: Consider adding a 'type' prop for form buttons

For buttons used in forms, it's important to specify the type attribute (e.g., "submit", "button", "reset"). Consider adding a type prop with a default value of "button" to ensure proper form handling.


5-5: Consider using a more specific type name than 'Action'

The type name 'Action' is quite generic. Since this specifically refers to button actions, a more descriptive name like 'ButtonAction' or 'ArcaneButtonAction' would better communicate its purpose and reduce potential naming conflicts.


84-94: Consider extracting icon components to constants for better readability

The conditional rendering in the template is functional but could be more readable by extracting the icon components to derived constants.

<script lang="ts">
  // ... existing code ...
  
  // Extract icon rendering logic
  let ButtonIcon = $derived(() => {
    if (loading) {
      return { component: Loader2, classes: `animate-spin ${iconMarginClass} size-4` };
    } else {
      return { component: config.IconComponent, classes: `${iconMarginClass} size-4` };
    }
  });
</script>

<Button variant={config.variant} size={customSize} class={`${extraClass} ${config.customClass || ''}`} disabled={disabled || loading} on:click={onClick} aria-label={isIconOnlyButton ? displayLabel : undefined}>
  <svelte:component this={ButtonIcon.component} class={ButtonIcon.classes} />
  {#if !isIconOnlyButton}
    {loading ? displayLoadingLabel : displayLabel}
  {/if}
</Button>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4612271 and 90dddb1.

📒 Files selected for processing (31)
  • src/app.css (1 hunks)
  • src/lib/components/action-buttons.svelte (2 hunks)
  • src/lib/components/arcane-button.svelte (1 hunks)
  • src/lib/components/confirm-dialog/confirm-dialog.svelte (1 hunks)
  • src/lib/components/dialogs/prune-confirmation-dialog.svelte (1 hunks)
  • src/lib/components/dialogs/registry-form-dialog.svelte (1 hunks)
  • src/lib/components/dialogs/user-form-dialog.svelte (1 hunks)
  • src/lib/services/docker/auto-update-service.ts (1 hunks)
  • src/lib/services/docker/stack-service.ts (1 hunks)
  • src/routes/+page.svelte (3 hunks)
  • src/routes/api/containers/+server.ts (1 hunks)
  • src/routes/auth/login/+page.svelte (3 hunks)
  • src/routes/containers/+page.svelte (3 hunks)
  • src/routes/containers/create-container-dialog.svelte (3 hunks)
  • src/routes/images/+page.svelte (2 hunks)
  • src/routes/images/[imageId]/+page.svelte (3 hunks)
  • src/routes/networks/+page.svelte (3 hunks)
  • src/routes/networks/CreateNetworkDialog.svelte (3 hunks)
  • src/routes/networks/[networkId]/+page.server.ts (0 hunks)
  • src/routes/networks/[networkId]/+page.svelte (4 hunks)
  • src/routes/onboarding/settings/+page.svelte (0 hunks)
  • src/routes/settings/+page.svelte (1 hunks)
  • src/routes/settings/tabs/authentication.svelte (3 hunks)
  • src/routes/settings/tabs/docker-settings.svelte (1 hunks)
  • src/routes/settings/tabs/user-management.svelte (1 hunks)
  • src/routes/stacks/+page.svelte (4 hunks)
  • src/routes/stacks/[stackId]/+page.svelte (2 hunks)
  • src/routes/stacks/new/+page.svelte (2 hunks)
  • src/routes/volumes/+page.svelte (3 hunks)
  • src/routes/volumes/[volumeName]/+page.svelte (3 hunks)
  • src/routes/volumes/create-volume-dialog.svelte (2 hunks)
💤 Files with no reviewable changes (2)
  • src/routes/onboarding/settings/+page.svelte
  • src/routes/networks/[networkId]/+page.server.ts
🔇 Additional comments (53)
src/lib/services/docker/auto-update-service.ts (1)

3-3: Remove unused import for cleanliness
Good removal of the unused listImages import from image-service, which keeps the module dependencies tidy and avoids clutter.

src/routes/settings/+page.svelte (1)

65-65: LGTM: Good styling consistency

Adding the arcane-button-save class aligns this button with the new styling system being implemented across the application.

src/routes/settings/tabs/user-management.svelte (1)

109-111: LGTM: Button styling updated correctly

The button styling has been updated to use the new arcane-button-save class, and the icon styling is now consistent with the new pattern (removing the margin class).

src/lib/components/confirm-dialog/confirm-dialog.svelte (2)

30-30: LGTM: Cancel button styling is consistent

Good addition of the arcane-button-cancel class to maintain styling consistency with other cancel buttons throughout the application.


32-33: LGTM: Confirmation button styling is consistent

Good addition of the arcane-button-create class for the confirmation button, aligning with the application-wide styling update.

src/lib/components/dialogs/prune-confirmation-dialog.svelte (2)

96-96: LGTM: Cancel button styling is consistent

Good addition of the arcane-button-cancel class to maintain styling consistency with other cancel buttons throughout the application.


97-97: LGTM: Destructive action button styling is consistent

Good addition of the arcane-button-remove class for the prune button, providing a consistent destructive action styling across the app.

src/lib/components/dialogs/registry-form-dialog.svelte (1)

71-72: Button styling standardization applied successfully.

The addition of arcane-button-cancel and arcane-button-create classes aligns with the PR's goal of standardizing button styles across the application.

src/lib/components/dialogs/user-form-dialog.svelte (1)

127-128: Button styling standardization applied successfully.

The addition of arcane-button-cancel and arcane-button-create classes aligns with the PR's goal of standardizing button styles.

src/routes/auth/login/+page.svelte (3)

95-96: Button styling standardization applied correctly.

The addition of arcane-button-restart class aligns with the PR's goal of standardizing button styles, and the spacing between the icon and text is preserved with mr-3.


149-150: Button styling standardization applied correctly.

The arcane-button-create class has been properly added to maintain consistency with other submission buttons throughout the application.


172-173: Button styling standardization applied correctly.

The addition of arcane-button-restart class aligns with the PR's goal of standardizing button styles, and the spacing between the icon and text is preserved with mr-2.

src/routes/+page.svelte (3)

182-182: Good addition of standardized button styling class.

The arcane-button-restart class aligns with the button styling standardization across the application, maintaining consistent theme while preserving the existing Button component structure.


347-347: Nice UX improvement with clickable card title.

Converting the "Containers" title to a clickable link provides users with an additional navigation option beyond the "View All" button, enhancing discoverability and user experience.


412-412: Good consistency in navigation pattern.

Applying the same clickable title pattern to the "Images" section maintains consistency with the Containers section, creating a predictable navigation pattern throughout the dashboard.

src/routes/api/containers/+server.ts (1)

21-26: Good defensive coding for container name handling.

Explicitly extracting and resetting the container name in the configuration ensures consistency for downstream code. This makes the code more robust against potential inconsistencies in the incoming request data.

src/routes/containers/+page.svelte (3)

21-21: Good addition of ArcaneButton import.

Adding the new ArcaneButton component import is the first step in standardizing button components across the application.


188-188: Good implementation of standardized button component.

Replacing the Button with ArcaneButton in the empty state view improves code maintainability by:

  1. Using declarative props (action="create", label="Create Container")
  2. Moving presentation logic into the component
  3. Following React-style event handler naming (onClick vs onclick)

199-199: Good consistency in button implementation.

Using the same ArcaneButton component and prop pattern here maintains consistency with the previous instance, ensuring uniform button behavior and appearance throughout the container management UI.

src/routes/stacks/[stackId]/+page.svelte (2)

22-22: Good addition of ArcaneButton import.

Adding the ArcaneButton component import extends the button standardization to the stack management UI.


290-290: Good implementation of Save button using ArcaneButton.

The replacement of the standard Button with ArcaneButton for the save action:

  1. Uses a consistent action-based approach (action="save")
  2. Properly handles the loading state
  3. Follows the same event handler pattern as other implementations

This standardization improves both code maintainability and user experience consistency.

src/routes/settings/tabs/authentication.svelte (1)

311-311: LGTM - Button styling standardization looks good.

The conditional application of CSS classes (arcane-button-create for selected policy, arcane-button-restart for others) provides clear visual differentiation between selected and non-selected password policy options.

Also applies to: 324-324, 337-337

src/routes/networks/+page.svelte (2)

19-19: LGTM - New ArcaneButton import.

The import is correctly placed and will enable the button standardization throughout this file.


216-216: Consistent button migration to ArcaneButton component.

The implementation correctly replaces Button components with ArcaneButton, maintaining all the necessary props for functionality (action, customLabel, loading states, etc.).

Also applies to: 218-218, 288-288

src/routes/stacks/+page.svelte (2)

20-20: LGTM - New ArcaneButton import.

The import is correctly placed and will enable the button standardization throughout this file.


209-209: Consistent implementation of ArcaneButton component.

All button replacements maintain the necessary functionality while standardizing on the new ArcaneButton component. The implementation includes appropriate action types, labels, and event handlers.

Also applies to: 258-258, 336-338

src/routes/volumes/[volumeName]/+page.svelte (2)

16-16: LGTM - New ArcaneButton import.

The import is correctly placed and will enable the button standardization throughout this file.


98-98: Effective replacement of standard buttons with ArcaneButton.

Both the "Remove Volume" and "Back to Volumes" buttons have been successfully migrated to the new ArcaneButton component with appropriate action types, labels, and functionality.

Also applies to: 279-279

src/lib/services/docker/stack-service.ts (2)

1757-1758: Simplification of YAML parsing.

The change uses js-yaml's load method directly instead of potentially using CommonJS dependencies, which simplifies the code and removes unnecessary abstraction.


1766-1767: Improved variable handling.

The function now immediately returns the substituted YAML object if an environment variable getter is provided, which streamlines the logic flow.

src/routes/containers/create-container-dialog.svelte (2)

18-18: Import added for new ArcaneButton component.

The import statement properly integrates the new standardized button component, aligning with the PR's goal of updating button styling.


675-676: Replaced traditional buttons with ArcaneButton components.

The Dialog footer now uses the standardized ArcaneButton component, providing consistent styling and behavior across the application.

src/routes/stacks/new/+page.svelte (2)

17-17: Added import for ArcaneButton component.

The import statement correctly brings in the new standardized button component.


66-77: Improved UI layout with standardized button component.

The header layout has been restructured to include an ArcaneButton for form submission, replacing the button that was previously in the footer. This creates a more consistent user experience across the application.

src/routes/volumes/create-volume-dialog.svelte (2)

12-12: Added import for ArcaneButton component.

The import statement properly integrates the new standardized button component.


129-131: Replaced Dialog footer buttons with ArcaneButton components.

The footer now uses the standardized ArcaneButton components, providing consistent styling and behavior. The use of specific props like customLabel, loadingLabel, and proper disabled state handling ensures the button behavior is appropriate for the context.

src/routes/images/[imageId]/+page.svelte (3)

17-17: Appropriate ArcaneButton import added

The import for the new ArcaneButton component is correctly added to support the button replacements in this file.


79-79: Good implementation of the Remove button

The original Button component has been properly replaced with ArcaneButton, maintaining all functionality including the onClick handler, loading state, and disabled state while simplifying the markup.


188-188: Effective fallback button implementation

The "Back to Images" navigation button is properly implemented with ArcaneButton, using appropriate action type, custom label, and preserving the original onClick behavior.

src/routes/volumes/+page.svelte (4)

19-19: Appropriate ArcaneButton import added

The import for the new ArcaneButton component is correctly added to support the button replacements in this file.


220-220: Well-implemented Delete Selected button

The button appropriately uses the ArcaneButton component with "remove" action type and correctly passes loading states, disabled states, and dynamic count of selected items in the custom label.


222-222: Good implementation of Create Volume button

The header Create Volume button has been properly replaced with ArcaneButton, maintaining the original functionality while simplifying the markup.


295-297: Consistent button styling in empty state

The empty state Create Volume button implementation matches the header button styling but appropriately uses a smaller size, maintaining visual consistency while adapting to the context.

src/lib/components/action-buttons.svelte (3)

10-10: Appropriate ArcaneButton import added

The import for the new ArcaneButton component is correctly added to support the button replacements in this file.


152-156: Good implementation of primary action buttons

The start/deploy, stop, and restart buttons have been properly replaced with ArcaneButton components. Each button maintains its original functionality while using the appropriate action type and loading state.


159-164: Effective implementation of secondary action buttons

The container and stack-specific buttons (remove, redeploy, pull) have been properly replaced with ArcaneButton components, maintaining all functionality while simplifying the markup.

src/routes/images/+page.svelte (3)

25-25: Appropriate ArcaneButton import added

The import for the new ArcaneButton component is correctly added to support the button replacements in this file.


464-464: Well-implemented Delete Selected button

The button appropriately uses the ArcaneButton component with "remove" action type and correctly passes loading and disabled states.


466-468: Good implementation of action buttons

The Prune Unused, Pull Image, and Check Updates buttons are properly replaced with ArcaneButton components, maintaining the original functionality and loading states.

src/routes/networks/CreateNetworkDialog.svelte (1)

8-12: Unused icon imports cleaned up – good catch.

Plus and Loader2 no longer appear, so removing them avoids dead-code shipping.
No further action required.

src/routes/networks/[networkId]/+page.svelte (1)

50-63: Callback wrapper hides async error propagation.

handleApiResultWithCallbacks is invoked but not awaited.
If it re-throws or returns a rejected promise, the confirmation dialog’s action will swallow the error silently, making debugging harder.
Consider returning its promise so callers can still await or log unhandled rejections.

-action: async () => {
-  handleApiResultWithCallbacks({
+action: () =>            // return promise to caller
+  handleApiResultWithCallbacks({
       /* … */
-  });
-}
+  })

Would you double-check whether openConfirmDialog expects the action to return a promise? If yes, this small change will ensure the dialog can disable/enable buttons based on the promise state automatically.

src/lib/components/arcane-button.svelte (2)

1-81: Well-structured component with good documentation

The component has a clear purpose with well-documented props and type definitions. The action configuration approach provides a clean way to manage different button variants.


77-80: Good conditional class handling

The component intelligently determines when to apply margin to icons based on whether the button is icon-only or includes text. This is a good practice for responsive design.

@kmendell kmendell merged commit 14a9f78 into main May 17, 2025
7 checks passed
@kmendell kmendell deleted the refactor/ui-tweaks branch May 17, 2025 03:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant