horizontal expansion

UI_CHANGES
ahmed.mujtaba 2026-08-19 19:12:42 +05:00
parent 24f3c5df53
commit 63a0fbf857
2 changed files with 63 additions and 23 deletions

View File

@ -463,39 +463,39 @@ function BulkReadBar({ rows, selection, onSetRead, onSetAllRead, busy, canEdit,
}
return (
<div
className="flex items-center gap-12"
style={{ padding: '10px 16px', borderBottom: '1px solid var(--border)', flexWrap: 'wrap' }}
>
<div className="inbox-bulk-bar">
<RowCheck
checked={allSelected}
onToggle={toggleAll}
label={allSelected ? 'Clear selection' : 'Select all'}
/>
<span className="text-muted text-sm">
<span className="inbox-bulk-count" title={n > 0
? `${n} selected`
: `${total} ${total === 1 ? 'message' : 'messages'}${unreadCount ? ` · ${unreadCount} unread` : ''}`}
>
{n > 0
? `${n} selected`
: `${total} ${total === 1 ? 'message' : 'messages'}${unreadCount ? ` · ${unreadCount} unread` : ''}`}
: `${total}${unreadCount ? ` · ${unreadCount}` : ''}`}
</span>
<div className="flex gap-8" style={{ marginLeft: 'auto', flexWrap: 'wrap' }}>
<div className="inbox-bulk-actions">
{n > 0 ? (
<>
<button
className="btn btn-secondary btn-sm"
disabled={blocked || unreadCount === 0}
title={unreadCount === 0 ? nothingTo('read') : tip}
title={unreadCount === 0 ? nothingTo('read') : tip || 'Mark selected read'}
onClick={() => flashRead('selected', () => onSetRead(true))}
>
{ticked === 'selected' && <Icon name="check" />}
Mark read{unreadCount ? ` (${unreadCount})` : ''}
Read
</button>
<button
className="btn btn-secondary btn-sm"
disabled={blocked || readCount === 0}
title={readCount === 0 ? nothingTo('unread') : tip}
title={readCount === 0 ? nothingTo('unread') : tip || 'Mark selected unread'}
onClick={() => onSetRead(false)}
>
<Icon name="mail" /> Mark unread{readCount ? ` (${readCount})` : ''}
Unread
</button>
<button className="btn btn-ghost btn-sm" onClick={clear}>Clear</button>
</>
@ -508,7 +508,7 @@ function BulkReadBar({ rows, selection, onSetRead, onSetAllRead, busy, canEdit,
onClick={() => flashRead('all', () => onSetAllRead(true))}
>
{ticked === 'all' && <Icon name="check" />}
Mark all read{unreadCount ? ` (${unreadCount})` : ''}
Read
</button>
<button
className="btn btn-secondary btn-sm"
@ -516,7 +516,7 @@ function BulkReadBar({ rows, selection, onSetRead, onSetAllRead, busy, canEdit,
title={readCount === 0 ? nothingTo('unread') : scopeTip}
onClick={() => onSetAllRead(false)}
>
<Icon name="mail" /> Mark all unread{readCount ? ` (${readCount})` : ''}
Unread
</button>
</>
)}
@ -756,14 +756,8 @@ export default function Inbox() {
{tab === 'Email' ? (
<EmailTab query={emailsQuery} toast={toast} />
) : (
<div className="split">
<div className="split-list">
<div style={{ padding: '12px 16px', borderBottom: '1px solid var(--border)' }}>
<div className="toolbar-search" style={{ maxWidth: 'none' }}>
<Icon name="search" />
<input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search applications…" />
</div>
</div>
<div className="split inbox-split">
<div className="split-list inbox-queue">
{applicationsQuery.isSuccess && (
<BulkReadBar
rows={list}
@ -775,6 +769,12 @@ export default function Inbox() {
scopeLabel={scopeLabel}
/>
)}
<div style={{ padding: '12px 16px', borderBottom: '1px solid var(--border)' }}>
<div className="toolbar-search" style={{ maxWidth: 'none' }}>
<Icon name="search" />
<input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search applications…" />
</div>
</div>
<div>
{applicationsQuery.isPending && (
<EmptyState icon="inbox" title="Loading…">Fetching applications from the server.</EmptyState>
@ -1429,8 +1429,8 @@ function EmailTab({ query, toast }) {
</button>
</div>
<div className="split">
<div className="split-list">
<div className="split inbox-split">
<div className="split-list inbox-queue">
{query.isSuccess && emails.length > 0 && (
<BulkReadBar
rows={emails}

View File

@ -835,6 +835,46 @@ canvas { width: 100%; max-width: 100%; display: block; }
.ii-pos { font-size: 12.5px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ii-meta { display: flex; align-items: center; gap: 8px; margin-top: 5px; }
.ii-time { font-size: 11px; color: var(--text-3); white-space: nowrap; }
/* Inbox sidebar only: fit the list instead of scrolling sideways.
Username (.ii-name) and subject (.ii-pos) are left alone. */
.inbox-split { grid-template-columns: minmax(0, 380px) 1fr; }
.inbox-queue { overflow-x: hidden; min-width: 0; }
.inbox-queue .inbox-item { min-width: 0; }
.inbox-queue .ii-meta { flex-wrap: wrap; min-width: 0; }
.inbox-queue .source-chip {
min-width: 0; max-width: 100%;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.inbox-queue .toolbar-search { min-width: 0; }
.inbox-bulk-bar {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
border-bottom: 1px solid var(--border);
flex-wrap: nowrap;
min-width: 0;
}
.inbox-bulk-count {
flex: 1 1 auto;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 12px;
color: var(--text-3);
}
.inbox-bulk-actions {
display: flex;
align-items: center;
gap: 4px;
flex-shrink: 0;
}
.inbox-bulk-actions .btn-sm {
padding: 5px 8px;
font-size: 12px;
white-space: nowrap;
}
/* `--chip` is the source's own brand colour, set inline. It tints the
background and fills the dot, while the label stays on theme text so
11px copy keeps its contrast in both modes. */