This commit is contained in:
2025-10-29 22:46:44 +01:00
parent 4a116e013c
commit 22f4d42c19
8 changed files with 116 additions and 35 deletions
+1 -1
View File
@@ -2037,7 +2037,7 @@ export const createDesktopSurface = ({ workspaceProps, renderSidebarToggle }) =>
<>
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={onRefresh}
aria-label="Refresh"
title="Refresh"
+6 -6
View File
@@ -1002,7 +1002,7 @@ const DetailPanel = ({
<h3 style={{ margin: 0 }}>{displayName}</h3>
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={startTitleEdit}
aria-label="Edit title"
title="Edit title"
@@ -1236,7 +1236,7 @@ const DetailPanel = ({
<div className="panel-actions">
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={onClose}
aria-label="Close detail panel"
title="Close detail panel"
@@ -1246,7 +1246,7 @@ const DetailPanel = ({
{singleDoc ? (
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={(event) => {
event.stopPropagation();
onOpenPreview(singleDoc.id);
@@ -1262,7 +1262,7 @@ const DetailPanel = ({
{isBulkSelection && onBulkReanalyze ? (
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={(event) => {
event.stopPropagation();
onBulkReanalyze(bulkDocumentIds);
@@ -1289,7 +1289,7 @@ const DetailPanel = ({
{showOcrAction ? (
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={(event) => {
event.stopPropagation();
openOcr();
@@ -1303,7 +1303,7 @@ const DetailPanel = ({
{singleDoc ? (
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={(event) => {
event.stopPropagation();
onRegenerateThumbnails(singleDoc.id);
+5 -5
View File
@@ -820,7 +820,7 @@ const DocumentsTable = ({
{folder.id !== 'root' && onFolderRename && (
<button
type="button"
className="icon-button ghost"
className="icon-button"
title="Rename"
aria-label={`Rename folder ${folder.name}`}
onClick={(event) => {
@@ -977,7 +977,7 @@ const DocumentsTable = ({
{onDocumentRename && (
<button
type="button"
className="icon-button ghost"
className="icon-button"
title="Rename"
aria-label={`Rename document ${doc.title || doc.original_name}`}
onClick={(event) => {
@@ -1090,7 +1090,7 @@ export const createDocumentsTableHeaderActions = ({
</span>
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={onRequestCreateFolder}
disabled={creatingFolder}
aria-label={creatingFolder ? 'Creating folder…' : 'Create folder'}
@@ -1100,7 +1100,7 @@ export const createDocumentsTableHeaderActions = ({
</button>
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={onRefresh}
aria-label="Refresh"
title="Refresh"
@@ -1152,7 +1152,7 @@ export const createDocumentsSurface = ({
? (
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={onNavigateParent}
aria-label="Go to parent folder"
title="Go to parent folder"
+6 -1
View File
@@ -5148,9 +5148,11 @@ const AppLayout = () => {
tags,
activeTagIds: activeTagFilters,
onToggleTagFilter: toggleTagFilter,
onCreateTag: (label) => handleTagCreate({ label }),
correspondents,
activeCorrespondentIds: activeCorrespondentFilters,
onToggleCorrespondentFilter: toggleCorrespondentFilter,
onCreateCorrespondent: (name) => handleCorrespondentCreate({ name }),
appStatus,
loading,
previewActive,
@@ -5197,6 +5199,8 @@ const AppLayout = () => {
tenantName,
toggleCorrespondentFilter,
toggleTagFilter,
handleTagCreate,
handleCorrespondentCreate,
],
);
@@ -5333,6 +5337,7 @@ const AppLayout = () => {
skeuoWorkspaceProps,
ensurePreviewData,
ensureAssetUrl,
resolveApiPath,
getDocumentAsset,
notifyApiError,
openTagsModal,
@@ -5606,7 +5611,7 @@ const DocumentsRoute = () => {
return (
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={expandSidebar}
aria-label="Expand sidebar"
title="Expand sidebar"
+3 -3
View File
@@ -137,7 +137,7 @@ export const createPreviewWorkspaceHeaderActions = ({
{hasOcr ? (
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={handleOcrClick}
aria-label="View OCR text"
title="View OCR text"
@@ -147,7 +147,7 @@ export const createPreviewWorkspaceHeaderActions = ({
) : null}
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={() => onRegenerate(document.id)}
aria-label="Re-run analysis"
title="Re-run analysis"
@@ -179,7 +179,7 @@ export const createPreviewSurface = ({
? (
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={() => onClose?.()}
aria-label="Close preview"
title="Close preview"
+74 -16
View File
@@ -9,6 +9,7 @@ import {
ChevronDownIcon,
SettingsIcon,
CheckIcon,
PlusIcon,
} from '../ui/icons';
import { getTagColorStyle } from '../utils/colors';
@@ -82,7 +83,7 @@ const FolderNode = ({
<div className="folder-row__actions">
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={(event) => {
event.stopPropagation();
if (!onRename) return;
@@ -103,7 +104,7 @@ const FolderNode = ({
</button>
<button
type="button"
className="icon-button ghost"
className="icon-button"
onClick={(event) => {
event.stopPropagation();
onDelete(node.id);
@@ -146,6 +147,8 @@ const Sidebar = ({
onToggleCorrespondentFilter,
onManageTags,
onManageCorrespondents,
onCreateTag,
onCreateCorrespondent,
searchQuery = '',
onSearchChange,
onSearchSubmit,
@@ -175,6 +178,37 @@ const Sidebar = ({
const activeTagSet = new Set(activeTagIds);
const handleManageTags = onManageTags || (() => {});
const handleManageCorrespondents = onManageCorrespondents || (() => {});
const handleCreateTag = useCallback(async () => {
const input = window.prompt('New tag name');
if (!input) {
return;
}
const trimmed = input.trim();
if (!trimmed) {
return;
}
try {
await onCreateTag?.(trimmed);
} catch (error) {
console.error('[sidebar] failed to create tag', error);
}
}, [onCreateTag]);
const handleCreateCorrespondent = useCallback(async () => {
const input = window.prompt('New correspondent name');
if (!input) {
return;
}
const trimmed = input.trim();
if (!trimmed) {
return;
}
try {
await onCreateCorrespondent?.(trimmed);
} catch (error) {
console.error('[sidebar] failed to create correspondent', error);
}
}, [onCreateCorrespondent]);
const handleSearchInputChange = useCallback(
(event) => {
onSearchChange?.(event.target.value);
@@ -408,14 +442,26 @@ const Sidebar = ({
</div>
<div className="sidebar-section">
<div className="sidebar-section__header">
<button
type="button"
className="sidebar-section__title"
onClick={handleManageTags}
>
<h3>Tags</h3>
<h3>Tags</h3>
<div className="sidebar-section__actions">
<button
type="button"
className="icon-button"
onClick={handleCreateTag}
aria-label="Create tag"
>
<PlusIcon size={16} />
</button>
<button
type="button"
className="icon-button"
onClick={handleManageTags}
aria-label="Manage tags"
>
<SettingsIcon size={16} />
</button>
<span className="meta">{tags.length}</span>
</button>
</div>
</div>
<div
className={`sidebar-tag-cloud${
@@ -460,14 +506,26 @@ const Sidebar = ({
</div>
<div className="sidebar-section">
<div className="sidebar-section__header">
<button
type="button"
className="sidebar-section__title"
onClick={handleManageCorrespondents}
>
<h3>Correspondents</h3>
<h3>Correspondents</h3>
<div className="sidebar-section__actions">
<button
type="button"
className="icon-button"
onClick={handleCreateCorrespondent}
aria-label="Create correspondent"
>
<PlusIcon size={16} />
</button>
<button
type="button"
className="icon-button"
onClick={handleManageCorrespondents}
aria-label="Manage correspondents"
>
<SettingsIcon size={16} />
</button>
<span className="meta">{correspondents.length}</span>
</button>
</div>
</div>
<ul className="sidebar-correspondent-list">
{sortedCorrespondents.map((correspondent) => {
+11 -3
View File
@@ -1406,6 +1406,17 @@ button.danger:hover:not([disabled]) {
font-weight: 600;
}
.sidebar-section__actions {
display: inline-flex;
align-items: center;
gap: 0.35rem;
}
.sidebar-section__actions .meta {
font-size: 0.75rem;
color: var(--muted);
}
.sidebar-item {
background: transparent;
padding: 0.16rem 0.26rem;
@@ -1511,7 +1522,6 @@ button.danger:hover:not([disabled]) {
.sidebar-correspondent-item:hover {
background: var(--sidebar-hover-bg);
box-shadow: 0 1px 3px var(--shadow-soft);
color: var(--fg);
}
@@ -1522,7 +1532,6 @@ button.danger:hover:not([disabled]) {
.sidebar-correspondent-item.active {
background: var(--sidebar-active-bg);
box-shadow: 0 0 0 1px var(--sidebar-active-pill-border);
color: var(--fg);
}
@@ -1917,7 +1926,6 @@ button.danger:hover:not([disabled]) {
text-decoration: underline;
text-decoration-thickness: 1.5px;
background-color: transparent;
box-shadow: none;
}
.doc-correspondent-link:not(.is-static):focus-visible {
+10
View File
@@ -23,6 +23,7 @@ import {
IconX,
IconSettings,
IconCheck,
IconPlus,
} from '@tabler/icons-react';
import FolderSvg from '../assets/folder.svg';
@@ -206,6 +207,15 @@ export const SettingsIcon = ({ className, size = '1em', stroke = 1.6, ...rest })
/>
);
export const PlusIcon = ({ className, size = '1em', stroke = 1.6, ...rest }) => (
<IconPlus
className={composeClassName('icon', className)}
size={size}
stroke={stroke}
{...rest}
/>
);
export const CheckIcon = ({ className, size = '1em', stroke = 1.6, ...rest }) => (
<IconCheck
className={composeClassName('icon', className)}