fix: put New group, Import and Refresh in the phone header menu of Contacts and Files

This commit is contained in:
Linus Rath
2026-10-28 05:04:13 +01:00
parent 4b243dbdbe
commit 083bb1f6bc
4 changed files with 32 additions and 2 deletions
@@ -211,4 +211,17 @@ describe('ContactsApp', () => {
act(() => { contacts!.commands.find((c) => c.id === 'new-contact')!.run(); });
expect(screen.getByPlaceholderText('middle_name')).toBeInTheDocument();
});
it('puts New group and Import in the phone header menu', () => {
const matchMedia = window.matchMedia;
window.matchMedia = ((query: string) => ({ ...matchMedia(query), matches: query.includes('max-width') })) as typeof window.matchMedia;
try {
renderContacts();
fireEvent.click(screen.getByRole('button', { name: 'more' }));
fireEvent.click(screen.getByText('import.title'));
expect(screen.getByRole('dialog', { name: 'import.title' })).toBeInTheDocument();
} finally {
window.matchMedia = matchMedia;
}
});
});
+4 -1
View File
@@ -123,6 +123,8 @@ interface ContactListProps {
onMoveContacts?: (ids: string[]) => void;
/** Show a burger button at the start that opens the (overlay) categories sidebar. */
onMenuClick?: () => void;
/** Contacts' own entries in the phone header's ⋮. */
phoneMenuItems?: (close: () => void) => React.ReactNode;
/** The first fetch is still running: show placeholders, not "No contacts yet". */
isLoading?: boolean;
}
@@ -150,6 +152,7 @@ export function ContactList({
onDuplicateContact,
onMoveContacts,
onMenuClick,
phoneMenuItems,
isLoading = false,
}: ContactListProps) {
const t = useTranslations("contacts");
@@ -439,7 +442,7 @@ export function ContactList({
</span>
)}
</IconButton>
<PhoneHeaderActions below="md" />
<PhoneHeaderActions below="md" menuItems={phoneMenuItems} />
</div>
</div>
+8
View File
@@ -6,6 +6,7 @@ import { useSearchParams } from "next/navigation";
import { useRouter } from "@/i18n/navigation";
import { ArrowLeft, Users, UsersRound, AlertTriangle, Plus, UserPlus, Upload, BookPlus } from "@/components/icons";
import { Button } from "@/components/ui/button";
import { ContextMenuItem } from "@/components/ui/context-menu";
import { ConfirmDialog } from "@/components/ui/confirm-dialog";
import { useConfirmDialog } from "@/hooks/use-confirm-dialog";
import { ContactList } from "@/components/contacts/contact-list";
@@ -1293,6 +1294,13 @@ function ContactsAppContent({ linkSegments: routeSegments }: ContactsAppProps =
onDuplicateContact={(contact) => void handleDuplicateContact(contact)}
onMoveContacts={canMoveContacts ? handleMoveContacts : undefined}
onMenuClick={isNarrow ? () => setNarrowSidebarOpen(true) : undefined}
phoneMenuItems={(close) => (
// On the phone these are otherwise only in the drawer's "+".
<>
<ContextMenuItem icon={UsersRound} label={t("groups.create")} onClick={() => { close(); guard(handleCreateGroup)(); }} />
<ContextMenuItem icon={Upload} label={t("import.title")} onClick={() => { close(); setShowImportDialog(true); }} />
</>
)}
isLoading={supportsSync && !contactsLoaded}
/>
)}
+7 -1
View File
@@ -367,7 +367,13 @@ export function FilesHeader({
</IconButton>
)}
<DetailsToggle showDetails={showDetails} onToggle={onToggleDetails} label={t("details")} />
<PhoneHeaderActions below="md" />
<PhoneHeaderActions
below="md"
menuItems={(close) => (
// The phone header has no room for Refresh as a button.
<ContextMenuItem icon={RefreshCw} label={t("refresh")} onClick={() => { close(); onRefresh(); }} disabled={isLoading} />
)}
/>
</div>
)}