<!-- Add the related story/sub-task/bug number, like Resolves #123, or remove if NA --> **Related issue:** Resolves #46973 > **Draft:** on-device QA (Mac/iPhone/iPad) is pending hardware, expected next week. Opening as draft for early review of the approach. ## Description FMA and custom-package app icons were misaligned on the macOS setup experience ("Setting up your device") screen — icons rendered at different sizes and their "Install …" labels didn't line up. **Root cause:** `SetupSoftwareProcessCell` forced `.software-icon__small { width: $pad-xlarge }` (32px, width only). That class lands on different elements in `SoftwareIcon`'s two render paths, so it hit them differently: - **Fleet-maintained / VPP apps (icon URL)** → the class is on the wrapper `<div>`; the 24px `<img>` inside stayed 24px, left-aligned. - **Custom packages (no URL)** → the class is on the fallback **SVG** itself, which got stretched to 32px wide. Result: different icon sizes/positions by app type → the misalignment. **Fix:** remove the width override so every app type renders `SoftwareIcon` at its consistent, vertically-centered 24px "small" size. ## Testing Verified in Storybook (added `SetupSoftwareProcessCell.stories.tsx`, `MixedAlignment` story) with real matched brand icons (Chrome, 1Password, VS Code, Zoom), a generic custom-package icon, and a URL/`<img>` icon stacked together: - **Before** (with the override): icons render at mixed 24/32px sizes; "Install …" labels don't align. <img width="1135" height="398" alt="before" src="https://github.com/user-attachments/assets/fe216ab4-0a7b-4211-b8aa-96e65e6ca3f5" /> - **After** (this change): all icons render at 24px, centered, labels aligned. <img width="1185" height="425" alt="after" src="https://github.com/user-attachments/assets/28257eb8-df6e-4168-a0bb-28dda4bb40ba" /> On-device QA to follow once hardware is available. ## Notes for reviewer - The `width: $pad-xlarge` (32px) was added in #33770, so 32px may have been the *intended* icon size. This change makes them a consistent **24px**. If a larger icon is desired, that's a follow-up done properly via a real `SoftwareIcon` size (not a width-only override) — flagging for PD input since this is `:product`-labeled. - Included a Storybook story for visual verification/regression; happy to drop it if that's not wanted here. # Checklist for submitter - [x] Changes file added for user-visible changes in `changes/`. See [Changes files](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/guides/committing-changes.md#changes-files) for more information. ## Testing - [ ] QA'd all new/changed functionality manually <!-- pending on-device QA --> - Added a Storybook story for visual verification (not an automated test). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved software process cell styling for more consistent icon sizing and alignment. * **Tests** * Added Storybook scenarios covering fleet-maintained apps, custom packages, uploaded icons, and mixed app layouts. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
70 lines
2.5 KiB
TypeScript
70 lines
2.5 KiB
TypeScript
import React from "react";
|
|
import { Meta, StoryObj } from "@storybook/react";
|
|
import {
|
|
QueryClient,
|
|
QueryClientProvider,
|
|
QueryClientProviderProps,
|
|
} from "react-query";
|
|
|
|
import SetupSoftwareProcessCell from "./SetupSoftwareProcessCell";
|
|
|
|
// SoftwareIcon calls `useQuery` unconditionally (even when it doesn't fetch), so
|
|
// stories need a QueryClientProvider in scope or they throw "No QueryClient set".
|
|
const queryClient = new QueryClient({
|
|
defaultOptions: { queries: { retry: false } },
|
|
});
|
|
type CustomQueryClientProviderProps = React.PropsWithChildren<QueryClientProviderProps>;
|
|
const CustomQueryClientProvider: React.FC<CustomQueryClientProviderProps> = QueryClientProvider;
|
|
|
|
// Small inline SVG data URI to exercise the <img> render path (VPP apps or an
|
|
// app with an uploaded custom icon).
|
|
const iconURL =
|
|
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Crect width='24' height='24' rx='5' fill='%234a90d9'/%3E%3C/svg%3E";
|
|
|
|
const meta: Meta<typeof SetupSoftwareProcessCell> = {
|
|
title: "Components/TableContainer/SetupSoftwareProcessCell",
|
|
component: SetupSoftwareProcessCell,
|
|
decorators: [
|
|
(Story) => (
|
|
<CustomQueryClientProvider client={queryClient}>
|
|
<Story />
|
|
</CustomQueryClientProvider>
|
|
),
|
|
],
|
|
};
|
|
|
|
export default meta;
|
|
|
|
type Story = StoryObj<typeof SetupSoftwareProcessCell>;
|
|
|
|
// Fleet-maintained app — renders its real matched brand icon (SVG fallback).
|
|
export const FleetMaintainedApp: Story = {
|
|
args: { name: "Google Chrome" },
|
|
};
|
|
|
|
// Custom package with no matched icon — renders the generic package icon.
|
|
export const CustomPackage: Story = {
|
|
args: { name: "Acme Corp Agent" },
|
|
};
|
|
|
|
// App with an uploaded icon URL (VPP / custom icon) — renders an <img>.
|
|
export const WithIconURL: Story = {
|
|
args: { name: "Company Portal", url: iconURL },
|
|
};
|
|
|
|
// Real FMA brand icons, a custom package (generic icon), and a URL-based icon
|
|
// stacked together, to verify icons and "Install …" labels align across app
|
|
// types. Regression coverage for #46973.
|
|
export const MixedAlignment: Story = {
|
|
render: () => (
|
|
<div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
|
|
<SetupSoftwareProcessCell name="Google Chrome" />
|
|
<SetupSoftwareProcessCell name="1Password" />
|
|
<SetupSoftwareProcessCell name="Visual Studio Code" />
|
|
<SetupSoftwareProcessCell name="Zoom" />
|
|
<SetupSoftwareProcessCell name="Acme Corp Agent" />
|
|
<SetupSoftwareProcessCell name="Company Portal" url={iconURL} />
|
|
</div>
|
|
),
|
|
};
|