feat(mobile): workspace views in the top menu, taller note rows, equal header bars
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m31s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m31s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
66d6b97aff
commit
21dd5e504e
7 files changed
+99
-50
No files matched your search
@@ -1022,7 +1022,8 @@ export const SharedListsView: React.FC<SharedListsViewProps> = ({ onRefreshGloba
|
||||
</div>
|
||||
|
||||
{/* Mobile Compact Header Bar (List switching & actions live in MindSift Logo Menu) */}
|
||||
<div className="flex sm:hidden items-center justify-between gap-2 px-3 py-2 rounded-btn bg-panel border border-border !mt-0">
|
||||
{/* Same height with or without the 36 px share button (Tasks, Shopping lists) */}
|
||||
<div className="flex sm:hidden items-center justify-between gap-2 px-3 py-2 min-h-[54px] rounded-btn bg-panel border border-border !mt-0">
|
||||
<div className="flex items-center gap-2 min-w-0">
|
||||
<span className="text-sm font-semibold text-main truncate">
|
||||
{activeList ? `${activeList.icon} ${activeList.title}` : '🛒 Einkaufsliste'}
|
||||
|
||||
@@ -1589,7 +1589,8 @@ export const TasksView: React.FC<TasksViewProps> = ({
|
||||
</div>
|
||||
|
||||
{/* Mobile Compact Context Bar (replaces cluttered button rows; options live in MindSift Logo Menu) */}
|
||||
<div className="flex sm:hidden items-center justify-between gap-2 px-3 py-2 rounded-btn bg-panel border border-border !mt-0">
|
||||
{/* Same height with or without the 36 px share button (Tasks, Shopping lists) */}
|
||||
<div className="flex sm:hidden items-center justify-between gap-2 px-3 py-2 min-h-[54px] rounded-btn bg-panel border border-border !mt-0">
|
||||
<div className="flex items-center gap-2 min-w-0">
|
||||
<span className="text-sm font-semibold text-main truncate">
|
||||
{currentSelectedList ? `${currentSelectedList.icon} ${currentSelectedList.title}` : '📋 Alle Aufgaben'}
|
||||
|
||||
@@ -141,7 +141,7 @@ const FolderTreeItem: React.FC<FolderTreeItemProps> = ({
|
||||
}}
|
||||
onDrop={(e) => handleDropOnFolder(node.fullPath, e)}
|
||||
style={{ paddingLeft: `${depth * 12 + 8}px` }}
|
||||
className={`group flex items-center justify-between pr-1.5 h-7 rounded-btn text-xs cursor-pointer border-l-2 transition-colors ${
|
||||
className={`group flex items-center justify-between pr-1.5 h-11 sm:h-7 rounded-btn text-sm sm:text-xs cursor-pointer border-l-2 transition-colors ${
|
||||
isDragOver
|
||||
? 'bg-accent/20 border-accent text-main font-semibold'
|
||||
: 'border-transparent hover:bg-panel-elevated text-muted'
|
||||
@@ -262,7 +262,7 @@ const FolderTreeItem: React.FC<FolderTreeItemProps> = ({
|
||||
{...docDropProps(d.id)}
|
||||
onClick={() => onSelectDoc(d.id)}
|
||||
style={{ paddingLeft: `${(depth + 1) * 12 + 16}px` }}
|
||||
className={`w-full flex items-center gap-2 pr-2 py-1.5 rounded-btn text-left text-xs cursor-pointer border transition-colors ${
|
||||
className={`w-full flex items-center gap-2 pr-2 py-1.5 min-h-11 sm:min-h-0 rounded-btn text-left text-sm sm:text-xs cursor-pointer border transition-colors ${
|
||||
mergeHoverId === d.id
|
||||
? 'border-accent bg-accent/15 ring-2 ring-accent/30 text-main'
|
||||
: selectedDocId === d.id && subView === 'editor'
|
||||
@@ -654,43 +654,6 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
||||
setMobileShowDetail(true);
|
||||
}, [reloadTrash]);
|
||||
|
||||
// Register mobile FAB actions
|
||||
useEffect(() => {
|
||||
setPrimaryAction(() => handleCreateDocument(''));
|
||||
setGroups([
|
||||
{
|
||||
id: 'workspace-actions',
|
||||
title: 'Notizen & Ordner',
|
||||
items: [
|
||||
{
|
||||
id: 'new-note',
|
||||
label: 'Neue Notiz',
|
||||
icon: <FilePlus className="w-4 h-4" />,
|
||||
variant: 'accent',
|
||||
onClick: () => handleCreateDocument(''),
|
||||
},
|
||||
{
|
||||
id: 'new-folder',
|
||||
label: 'Neuer Ordner',
|
||||
icon: <FolderPlus className="w-4 h-4" />,
|
||||
onClick: () => setShowNewFolderModal(true),
|
||||
},
|
||||
{
|
||||
id: 'trash',
|
||||
label: 'Papierkorb',
|
||||
icon: <Trash2 className="w-4 h-4" />,
|
||||
badge: trash.length,
|
||||
onClick: openTrash,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
return () => {
|
||||
setGroups([]);
|
||||
setPrimaryAction(undefined);
|
||||
};
|
||||
}, [handleCreateDocument, setGroups, setPrimaryAction, trash.length, openTrash]);
|
||||
|
||||
const handleDeleteDocument = useCallback(
|
||||
async (docId: string) => {
|
||||
try {
|
||||
@@ -1176,6 +1139,82 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
||||
return count;
|
||||
}, [docs]);
|
||||
|
||||
// Register mobile FAB actions and the menu at the top; on phones the menu also switches between
|
||||
// notes, to-dos and hashtags (like the lists in Tasks and Shopping lists), the tab row is hidden there
|
||||
useEffect(() => {
|
||||
setPrimaryAction(() => handleCreateDocument(''));
|
||||
setGroups([
|
||||
{
|
||||
id: 'workspace-views',
|
||||
title: 'Ansicht',
|
||||
items: [
|
||||
{
|
||||
id: 'view-notes',
|
||||
label: 'Notizen',
|
||||
icon: <FileText className="w-4 h-4" />,
|
||||
active: subView === 'editor' || subView === 'journal' || subView === 'trash',
|
||||
onClick: () => {
|
||||
setSubView('editor');
|
||||
setMobileShowDetail(false);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'view-todos',
|
||||
label: 'To-Dos',
|
||||
icon: <Check className="w-4 h-4" />,
|
||||
badge: totalOpenTodos || undefined,
|
||||
active: subView === 'todos',
|
||||
onClick: () => {
|
||||
setSubView('todos');
|
||||
setMobileShowDetail(true);
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'view-tags',
|
||||
label: 'Hashtags',
|
||||
icon: <Hash className="w-4 h-4" />,
|
||||
badge: tagsSummary.length || undefined,
|
||||
active: subView === 'tags' || subView === 'tag_detail',
|
||||
onClick: () => {
|
||||
setSubView('tags');
|
||||
setMobileShowDetail(true);
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'workspace-actions',
|
||||
title: 'Notizen & Ordner',
|
||||
items: [
|
||||
{
|
||||
id: 'new-note',
|
||||
label: 'Neue Notiz',
|
||||
icon: <FilePlus className="w-4 h-4" />,
|
||||
variant: 'accent',
|
||||
onClick: () => handleCreateDocument(''),
|
||||
},
|
||||
{
|
||||
id: 'new-folder',
|
||||
label: 'Neuer Ordner',
|
||||
icon: <FolderPlus className="w-4 h-4" />,
|
||||
onClick: () => setShowNewFolderModal(true),
|
||||
},
|
||||
{
|
||||
id: 'trash',
|
||||
label: 'Papierkorb',
|
||||
icon: <Trash2 className="w-4 h-4" />,
|
||||
badge: trash.length,
|
||||
onClick: openTrash,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
return () => {
|
||||
setGroups([]);
|
||||
setPrimaryAction(undefined);
|
||||
};
|
||||
}, [handleCreateDocument, setGroups, setPrimaryAction, trash.length, openTrash, subView, totalOpenTodos, tagsSummary.length]);
|
||||
|
||||
// Real-time matched blocks and all nested children for the selected hashtag
|
||||
const activeTagGroups = useMemo(() => {
|
||||
if (!selectedTag) return [];
|
||||
@@ -1355,8 +1394,9 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
||||
return (
|
||||
<div className="w-full h-full min-h-0 flex flex-col gap-3">
|
||||
{/* Top Header: Workspace Tabs & Actions */}
|
||||
<div className="flex flex-wrap items-center justify-between gap-2 border-b border-border pb-2">
|
||||
{/* Workspace selector tabs & left sidebar toggle; on phones the three tabs share the full width */}
|
||||
{/* Phones: the views are switched in the menu at the top, so the row is hidden there */}
|
||||
<div className="hidden sm:flex flex-wrap items-center justify-between gap-2 border-b border-border pb-2">
|
||||
{/* Workspace selector tabs & left sidebar toggle */}
|
||||
<div className="grid grid-cols-3 w-full gap-1 sm:flex sm:flex-wrap sm:items-center sm:w-auto">
|
||||
<button
|
||||
type="button"
|
||||
@@ -1774,7 +1814,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
||||
setSubView('editor');
|
||||
setMobileShowDetail(true);
|
||||
}}
|
||||
className={`w-full flex items-center gap-2 px-2 py-1.5 rounded-btn text-left text-xs cursor-pointer border transition-colors ${
|
||||
className={`w-full flex items-center gap-2 px-2 py-1.5 min-h-11 sm:min-h-0 rounded-btn text-left text-sm sm:text-xs cursor-pointer border transition-colors ${
|
||||
mergeHoverId === d.id
|
||||
? 'border-accent bg-accent/15 ring-2 ring-accent/30 text-main'
|
||||
: selectedDocId === d.id && subView === 'editor'
|
||||
@@ -1837,7 +1877,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
|
||||
setSubView('editor');
|
||||
setMobileShowDetail(true);
|
||||
}}
|
||||
className={`w-full flex items-center gap-2 px-2 py-1.5 rounded-btn text-left text-xs cursor-pointer border transition-colors ${
|
||||
className={`w-full flex items-center gap-2 px-2 py-1.5 min-h-11 sm:min-h-0 rounded-btn text-left text-sm sm:text-xs cursor-pointer border transition-colors ${
|
||||
mergeHoverId === d.id
|
||||
? 'border-accent bg-accent/15 ring-2 ring-accent/30 text-main'
|
||||
: selectedDocId === d.id && subView === 'editor'
|
||||
|
||||
Reference in new issue
Block a user