feat(FN-1956): merge fusion/fn-1956
This commit is contained in:
@@ -320,6 +320,15 @@ export function MailboxModal({
|
||||
)}
|
||||
</div>
|
||||
<div className="mailbox-header-actions">
|
||||
<button
|
||||
className="btn-sm btn-primary"
|
||||
onClick={handleOpenCompose}
|
||||
title="Compose message"
|
||||
data-testid="mailbox-header-compose"
|
||||
>
|
||||
<MessageSquare size={14} />
|
||||
<span>Compose</span>
|
||||
</button>
|
||||
{activeTab === "inbox" && unreadCount > 0 && (
|
||||
<button
|
||||
className="btn-sm btn-secondary"
|
||||
@@ -631,17 +640,6 @@ export function MailboxModal({
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Compose FAB (only when viewing inbox/outbox, not in detail view or agents tab) */}
|
||||
{!selectedMessage && !showComposer && activeTab !== "agents" && (
|
||||
<button
|
||||
className="mailbox-compose-fab"
|
||||
onClick={handleOpenCompose}
|
||||
title="Compose message"
|
||||
data-testid="mailbox-compose-fab"
|
||||
>
|
||||
<MessageSquare size={20} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -379,6 +379,15 @@ export function MailboxView({
|
||||
)}
|
||||
</div>
|
||||
<div className="mailbox-header-actions">
|
||||
<button
|
||||
className="btn-sm btn-primary"
|
||||
onClick={handleOpenCompose}
|
||||
title="Compose message"
|
||||
data-testid="mailbox-header-compose"
|
||||
>
|
||||
<MessageSquare size={14} />
|
||||
<span>Compose</span>
|
||||
</button>
|
||||
{activeTab === "inbox" && unreadCount > 0 && (
|
||||
<button
|
||||
className="btn-sm btn-secondary"
|
||||
@@ -694,17 +703,6 @@ export function MailboxView({
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Compose FAB (only when viewing inbox/outbox, not in detail view or agents tab) */}
|
||||
{!selectedMessage && !showComposer && activeTab !== "agents" && (
|
||||
<button
|
||||
className="mailbox-compose-fab"
|
||||
onClick={handleOpenCompose}
|
||||
title="Compose message"
|
||||
data-testid="mailbox-compose-fab"
|
||||
>
|
||||
<MessageSquare size={20} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -329,18 +329,18 @@ describe("MailboxModal", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("shows compose FAB in inbox tab", async () => {
|
||||
it("shows compose button in header on inbox tab", async () => {
|
||||
render(<MailboxModal {...defaultProps} />);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("mailbox-compose-fab")).toBeDefined();
|
||||
expect(screen.getByTestId("mailbox-header-compose")).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("does not show compose FAB in agents tab", async () => {
|
||||
it("shows compose button in header on agents tab", async () => {
|
||||
render(<MailboxModal {...defaultProps} />);
|
||||
fireEvent.click(screen.getByTestId("mailbox-tab-agents"));
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByTestId("mailbox-compose-fab")).toBeNull();
|
||||
expect(screen.getByTestId("mailbox-header-compose")).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -516,9 +516,6 @@ describe("MailboxModal", () => {
|
||||
expect(mailboxMobileSection).toContain("max-width: 100%;");
|
||||
expect(mailboxMobileSection).toContain(".mailbox-modal .mailbox-agents");
|
||||
expect(mailboxMobileSection).toContain("min-height: 200px;");
|
||||
expect(mailboxMobileSection).toContain(".mailbox-modal .mailbox-compose-fab");
|
||||
expect(mailboxMobileSection).toContain("bottom: 16px;");
|
||||
expect(mailboxMobileSection).toContain("right: 16px;");
|
||||
expect(mailboxMobileSection).toContain(".mailbox-modal .mailbox-empty");
|
||||
expect(mailboxMobileSection).toContain("padding: 32px 12px;");
|
||||
});
|
||||
@@ -564,21 +561,6 @@ describe("MailboxModal", () => {
|
||||
expect(blockMatch![1]).not.toContain("color: white");
|
||||
});
|
||||
|
||||
it("mailbox compose FAB uses theme-aware tokens", () => {
|
||||
const blockMatch = css.match(/\.mailbox-compose-fab\s*\{([^}]*)\}/);
|
||||
expect(blockMatch).toBeTruthy();
|
||||
expect(blockMatch![1]).toContain("var(--fab-bg)");
|
||||
expect(blockMatch![1]).toContain("var(--fab-text)");
|
||||
expect(blockMatch![1]).not.toContain("background: var(--todo)");
|
||||
expect(blockMatch![1]).not.toContain("color: white");
|
||||
|
||||
// Check hover state
|
||||
const hoverMatch = css.match(/\.mailbox-compose-fab:hover\s*\{([^}]*)\}/);
|
||||
expect(hoverMatch).toBeTruthy();
|
||||
expect(hoverMatch![1]).toContain("var(--fab-bg)");
|
||||
expect(hoverMatch![1]).toContain("var(--fab-text)");
|
||||
});
|
||||
|
||||
it("mission event type error uses CSS custom properties", () => {
|
||||
const blockMatch = css.match(/\.mission-event__type--error\s*\{([^}]*)\}/);
|
||||
expect(blockMatch).toBeTruthy();
|
||||
|
||||
@@ -361,7 +361,7 @@ describe("MailboxView", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("shows compose FAB in inbox tab", async () => {
|
||||
it("shows compose button in header on inbox tab", async () => {
|
||||
mockFetchInbox.mockResolvedValue({
|
||||
messages: [],
|
||||
unreadCount: 0,
|
||||
@@ -370,11 +370,11 @@ describe("MailboxView", () => {
|
||||
render(<MailboxView {...defaultProps} />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("mailbox-compose-fab")).toBeDefined();
|
||||
expect(screen.getByTestId("mailbox-header-compose")).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it("does not show compose FAB in agents tab", async () => {
|
||||
it("shows compose button in header on agents tab", async () => {
|
||||
mockFetchInbox.mockResolvedValue({
|
||||
messages: [],
|
||||
unreadCount: 0,
|
||||
@@ -388,7 +388,7 @@ describe("MailboxView", () => {
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByTestId("mailbox-compose-fab")).toBeNull();
|
||||
expect(screen.getByTestId("mailbox-header-compose")).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -446,7 +446,7 @@ describe("MailboxView", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("shows MessageComposer with agents when clicking compose FAB from inbox tab", async () => {
|
||||
it("shows MessageComposer with agents when clicking compose button from header", async () => {
|
||||
mockFetchInbox.mockResolvedValue({
|
||||
messages: [],
|
||||
unreadCount: 0,
|
||||
@@ -454,14 +454,14 @@ describe("MailboxView", () => {
|
||||
|
||||
render(<MailboxView {...defaultProps} />);
|
||||
|
||||
// Verify compose FAB is visible in inbox tab
|
||||
// Verify compose button is visible in header
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId("mailbox-compose-fab")).toBeDefined();
|
||||
expect(screen.getByTestId("mailbox-header-compose")).toBeDefined();
|
||||
});
|
||||
|
||||
// Click compose FAB
|
||||
// Click compose button
|
||||
await act(async () => {
|
||||
fireEvent.click(screen.getByTestId("mailbox-compose-fab"));
|
||||
fireEvent.click(screen.getByTestId("mailbox-header-compose"));
|
||||
});
|
||||
|
||||
// Verify MessageComposer is shown
|
||||
@@ -516,7 +516,6 @@ describe("MailboxView", () => {
|
||||
expect(mailboxMobileSection).toContain(".mailbox-view .mailbox-header");
|
||||
expect(mailboxMobileSection).toContain(".mailbox-view .mailbox-tabs");
|
||||
expect(mailboxMobileSection).toContain(".mailbox-view .mailbox-content");
|
||||
expect(mailboxMobileSection).toContain(".mailbox-view .mailbox-compose-fab");
|
||||
expect(mailboxMobileSection).toContain(".mailbox-view .mailbox-empty");
|
||||
});
|
||||
|
||||
@@ -542,13 +541,6 @@ describe("MailboxView", () => {
|
||||
// Content should have padding-bottom accounting for mobile nav
|
||||
expect(contentRuleMatch![0]).toContain("padding-bottom");
|
||||
|
||||
// FAB should account for mobile nav height
|
||||
expect(mailboxMobileSection).toContain(".mailbox-view .mailbox-compose-fab");
|
||||
const fabRuleMatch = mailboxMobileSection.match(/\.mailbox-view\s+\.mailbox-compose-fab\s*\{[^}]*\}/);
|
||||
expect(fabRuleMatch).toBeTruthy();
|
||||
expect(fabRuleMatch![0]).toContain("--mobile-nav-height");
|
||||
expect(fabRuleMatch![0]).toContain("safe-area-inset-bottom");
|
||||
expect(fabRuleMatch![0]).toContain("--standalone-bottom-gap");
|
||||
});
|
||||
|
||||
it("renders structural elements that mobile CSS targets", async () => {
|
||||
|
||||
@@ -28409,31 +28409,6 @@ html .column.drag-over * {
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
/* Compose FAB */
|
||||
.mailbox-compose-fab {
|
||||
position: absolute;
|
||||
bottom: 24px;
|
||||
right: 24px;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
background: var(--fab-bg);
|
||||
color: var(--fab-text);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||
transition: background-color 0.15s, transform 0.15s;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.mailbox-compose-fab:hover {
|
||||
background: color-mix(in srgb, var(--fab-bg) 80%, var(--fab-text));
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* Skeleton loading */
|
||||
.mailbox-skeleton {
|
||||
display: flex;
|
||||
@@ -28565,11 +28540,6 @@ html .column.drag-over * {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.mailbox-modal .mailbox-compose-fab {
|
||||
bottom: 16px;
|
||||
right: 16px;
|
||||
}
|
||||
|
||||
.mailbox-modal .mailbox-empty {
|
||||
padding: 32px 12px;
|
||||
}
|
||||
@@ -28638,11 +28608,6 @@ html .column.drag-over * {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.mailbox-view .mailbox-compose-fab {
|
||||
bottom: calc(var(--mobile-nav-height) + env(safe-area-inset-bottom, 0px) + var(--standalone-bottom-gap) + var(--space-lg));
|
||||
right: var(--space-lg);
|
||||
}
|
||||
|
||||
.mailbox-view .mailbox-empty {
|
||||
padding: 32px 12px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user