fix(FN-2331): normalize usage modal footer layout
- Update UsageIndicator footer markup to use consistent button grouping and alignment - Adjust dashboard CSS for usage modal footer spacing and responsive behavior - Add regression tests covering footer layout and action placement in UsageIndicator
This commit is contained in:
@@ -355,6 +355,38 @@ describe("UsageIndicator", () => {
|
||||
expect(screen.getByText(/10:30:00/)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("keeps footer metadata on the left and action buttons on the right", () => {
|
||||
const lastUpdated = new Date("2024-01-15T10:30:00");
|
||||
mockUseUsageData.mockReturnValue({
|
||||
providers: mockProviders,
|
||||
loading: false,
|
||||
error: null,
|
||||
lastUpdated,
|
||||
refresh: mockRefresh,
|
||||
});
|
||||
|
||||
render(<UsageIndicator isOpen={true} onClose={mockOnClose} projectId={TEST_PROJECT_ID} />);
|
||||
|
||||
const footer = document.querySelector(".usage-actions");
|
||||
const leftGroup = document.querySelector(".usage-actions-left");
|
||||
const rightGroup = document.querySelector(".usage-actions-right");
|
||||
|
||||
expect(footer).toBeInTheDocument();
|
||||
expect(leftGroup).toBeInTheDocument();
|
||||
expect(rightGroup).toBeInTheDocument();
|
||||
|
||||
const lastUpdatedLabel = screen.getByText(/Last updated:/);
|
||||
const refreshButton = screen.getByTestId("usage-refresh-btn");
|
||||
const closeButton = screen.getByRole("button", { name: "Close" });
|
||||
|
||||
expect(leftGroup).toContainElement(lastUpdatedLabel);
|
||||
expect(rightGroup).toContainElement(refreshButton);
|
||||
expect(rightGroup).toContainElement(closeButton);
|
||||
|
||||
expect(footer?.firstElementChild).toBe(leftGroup);
|
||||
expect(footer?.lastElementChild).toBe(rightGroup);
|
||||
});
|
||||
|
||||
it("renders usage windows with correct percentage text", () => {
|
||||
mockUseUsageData.mockReturnValue({
|
||||
providers: [
|
||||
|
||||
@@ -488,12 +488,14 @@ export function UsageIndicator({ isOpen, onClose, projectId }: UsageIndicatorPro
|
||||
</div>
|
||||
|
||||
<div className="modal-actions usage-actions">
|
||||
<div className="usage-last-updated">
|
||||
{lastUpdated && (
|
||||
<span>Last updated: {lastUpdated.toLocaleTimeString()}</span>
|
||||
)}
|
||||
<div className="modal-actions-left usage-actions-left">
|
||||
<div className="usage-last-updated">
|
||||
{lastUpdated && (
|
||||
<span>Last updated: {lastUpdated.toLocaleTimeString()}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="usage-actions-right">
|
||||
<div className="modal-actions-right usage-actions-right">
|
||||
<button
|
||||
className="btn btn-sm"
|
||||
onClick={handleRefresh}
|
||||
|
||||
@@ -14932,22 +14932,23 @@ html .column.drag-over * {
|
||||
/* Actions */
|
||||
.usage-actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: var(--space-md);
|
||||
}
|
||||
|
||||
.usage-actions-left {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.usage-last-updated {
|
||||
font-size: 11px;
|
||||
color: var(--text-dim);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.usage-actions-right {
|
||||
display: flex;
|
||||
gap: var(--space-sm);
|
||||
align-items: center;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
/* Mobile responsive */
|
||||
@@ -14964,14 +14965,11 @@ html .column.drag-over * {
|
||||
}
|
||||
|
||||
.usage-actions {
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.usage-last-updated {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
order: 3;
|
||||
margin-top: var(--space-sm);
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user