This commit is contained in:
2025-11-14 02:35:17 +01:00
parent 6f4ff68062
commit a3c5494bf7
53 changed files with 269 additions and 340 deletions
@@ -89,6 +89,13 @@ const normalizeDocumentList = (selectedIds?: SelectedIdList): DocumentId[] =>
? selectedIds.filter((value): value is DocumentId => value !== null && value !== undefined)
: [];
const isRecord = (value: unknown): value is Record<string, unknown> => value != null && Object(value) === value;
const splitLabelSegments = (input: unknown): string[] => {
const text = `${input ?? ''}`.trim();
return text ? text.split('/') : [];
};
const buildFolderTreeOptions = (tree?: FolderTreeNode[] | null): SelectionAssignmentMenuItem[] => {
const entries: SelectionAssignmentMenuItem[] = [];
@@ -346,7 +353,9 @@ const SelectionFloatingActions: React.FC<SelectionFloatingActionsProps> = ({
const documentCount = documentIdList.length;
const folderCount = folderIdList.length;
const totalCount = typeof selectionCount === 'number' ? selectionCount : documentCount + folderCount;
const totalCount = Number.isFinite(selectionCount)
? Number(selectionCount)
: documentCount + folderCount;
const selectedDocuments = useMemo<DocumentLike[]>(() => {
if (!documentIdList.length || !(documentLookupMap instanceof Map)) {
@@ -370,7 +379,7 @@ const SelectionFloatingActions: React.FC<SelectionFloatingActionsProps> = ({
return null;
}
const label = option?.label || option?.payload?.label || option?.name || String(id);
const segments = typeof label === 'string' ? label.split('/') : [label];
const segments = splitLabelSegments(label);
const depth = Math.max(segments.length - 1, 0);
return {
id,
@@ -399,7 +408,7 @@ const SelectionFloatingActions: React.FC<SelectionFloatingActionsProps> = ({
const renderFolderLabel = useCallback((item: SelectionAssignmentMenuItem) => {
const payload = (item?.payload as { segments?: string[]; depth?: number }) || {};
const segments = payload.segments || (typeof item.label === 'string' ? item.label.split('/') : []);
const segments = payload.segments || splitLabelSegments(item.label);
const depth = payload.depth ?? Math.max(segments.length - 1, 0);
const clampedDepth = Math.min(depth, 6);
const indentWidth = clampedDepth > 0 ? clampedDepth * 0.9 : 0;
@@ -481,12 +490,12 @@ const SelectionFloatingActions: React.FC<SelectionFloatingActionsProps> = ({
const handleMoveSelectionToFolder = useCallback(
async (option: unknown) => {
if (!documentIdList.length || typeof onMoveDocumentsToFolder !== 'function') {
if (!documentIdList.length || !onMoveDocumentsToFolder) {
return;
}
const candidate = option as { id?: DocumentId; value?: DocumentId } | DocumentId | null | undefined;
const value = typeof candidate === 'object'
? candidate?.id ?? candidate?.value ?? null
const value = isRecord(candidate)
? (candidate?.id ?? candidate?.value ?? null)
: candidate;
if (!value && value !== 0) {
return;
@@ -506,7 +515,7 @@ const SelectionFloatingActions: React.FC<SelectionFloatingActionsProps> = ({
const showPrimaryButtons = Boolean(onBulkReanalyze || onDeleteSelection || onClearSelection);
const moveMenu = typeof onMoveDocumentsToFolder === 'function' ? (
const moveMenu = onMoveDocumentsToFolder ? (
<SelectionAssignmentMenu
label="Move"
triggerContent={(
@@ -534,7 +543,7 @@ const SelectionFloatingActions: React.FC<SelectionFloatingActionsProps> = ({
const primaryButtons = showPrimaryButtons ? (
<div className="panel-floating__buttons">
{typeof onBulkReanalyze === 'function' ? (
{onBulkReanalyze ? (
<button
type="button"
className="icon-button panel-floating-actions__button"
@@ -546,7 +555,7 @@ const SelectionFloatingActions: React.FC<SelectionFloatingActionsProps> = ({
<AnalyzeIcon className="icon-inline" />
</button>
) : null}
{typeof onDeleteSelection === 'function' ? (
{onDeleteSelection ? (
<button
type="button"
className="icon-button danger panel-floating-actions__button"
@@ -557,7 +566,7 @@ const SelectionFloatingActions: React.FC<SelectionFloatingActionsProps> = ({
<TrashIcon className="icon-inline" />
</button>
) : null}
{typeof onClearSelection === 'function' ? (
{onClearSelection ? (
<button
type="button"
className="icon-button panel-floating-actions__button"