fix: allow default vault notes to move workspaces
This commit is contained in:
@@ -2,7 +2,7 @@ import type { ComponentProps, ReactElement } from 'react'
|
||||
import { render as rtlRender, screen, fireEvent } from '@testing-library/react'
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
import { Inspector } from './Inspector'
|
||||
import type { VaultEntry, GitCommit } from '../types'
|
||||
import type { VaultEntry, GitCommit, WorkspaceIdentity } from '../types'
|
||||
import { TooltipProvider } from '@/components/ui/tooltip'
|
||||
|
||||
function render(ui: ReactElement) {
|
||||
@@ -108,6 +108,21 @@ function renderSelectedInspector(overrides: Partial<InspectorProps> = {}) {
|
||||
})
|
||||
}
|
||||
|
||||
function makeWorkspace(path: string, label: string, alias = label.toLowerCase()): WorkspaceIdentity {
|
||||
return {
|
||||
id: alias,
|
||||
label,
|
||||
alias,
|
||||
path,
|
||||
shortLabel: label.slice(0, 2).toUpperCase(),
|
||||
color: null,
|
||||
icon: null,
|
||||
mounted: true,
|
||||
available: true,
|
||||
defaultForNewNotes: false,
|
||||
}
|
||||
}
|
||||
|
||||
describe('Inspector', () => {
|
||||
it('renders expanded state with "no note selected"', () => {
|
||||
render(<Inspector {...defaultProps} />)
|
||||
@@ -200,6 +215,31 @@ Status: Evergreened
|
||||
)
|
||||
})
|
||||
|
||||
it('infers the current workspace for untagged default-vault notes before moving them', () => {
|
||||
const laputaWorkspace = makeWorkspace('/Users/luca/Laputa', 'Laputa')
|
||||
const refactoringWorkspace = makeWorkspace('/Users/luca/Refactoring', 'Refactoring')
|
||||
const entry = {
|
||||
...mockEntry,
|
||||
path: '/Users/luca/Laputa/project/test.md',
|
||||
workspace: undefined,
|
||||
}
|
||||
const onChangeWorkspace = vi.fn()
|
||||
|
||||
renderSelectedInspector({
|
||||
entry,
|
||||
workspaces: [laputaWorkspace, refactoringWorkspace],
|
||||
onChangeWorkspace,
|
||||
})
|
||||
|
||||
fireEvent.pointerDown(screen.getByRole('combobox', { name: 'Laputa' }), { button: 0, pointerType: 'mouse' })
|
||||
fireEvent.click(screen.getByRole('option', { name: 'Refactoring' }))
|
||||
|
||||
expect(onChangeWorkspace).toHaveBeenCalledWith(
|
||||
expect.objectContaining({ path: entry.path, workspace: laputaWorkspace }),
|
||||
refactoringWorkspace,
|
||||
)
|
||||
})
|
||||
|
||||
it('shows cadence when present', () => {
|
||||
// Cadence is now read from frontmatter in content (already in mockContent)
|
||||
render(<Inspector {...defaultProps} entry={mockEntry} content={mockContent} />)
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
InstancesPanel,
|
||||
NoteInfoPanel,
|
||||
} from './InspectorPanels'
|
||||
import { normalizeNotePathForIdentity } from '../utils/notePathIdentity'
|
||||
import type { ReferencedByItem } from './InspectorPanels'
|
||||
import { EmptyInspector, InitializePropertiesPrompt, InspectorHeader, InvalidFrontmatterNotice } from './inspector/InspectorChrome'
|
||||
import { useBacklinks, useReferencedBy } from './inspector/useInspectorData'
|
||||
@@ -55,6 +56,26 @@ function supportsFrontmatter(entry: VaultEntry): boolean {
|
||||
return entry.fileKind === undefined || entry.fileKind === 'markdown'
|
||||
}
|
||||
|
||||
function pathBelongsToWorkspace(path: string, workspace: WorkspaceIdentity): boolean {
|
||||
const normalizedPath = normalizeNotePathForIdentity(path)
|
||||
const normalizedWorkspacePath = normalizeNotePathForIdentity(workspace.path)
|
||||
if (!normalizedWorkspacePath) return false
|
||||
return normalizedPath === normalizedWorkspacePath || normalizedPath.startsWith(`${normalizedWorkspacePath}/`)
|
||||
}
|
||||
|
||||
function inferEntryWorkspace(entry: VaultEntry, workspaces: WorkspaceIdentity[] | undefined): WorkspaceIdentity | undefined {
|
||||
if (entry.workspace) return entry.workspace
|
||||
return workspaces
|
||||
?.filter((workspace) => pathBelongsToWorkspace(entry.path, workspace))
|
||||
.sort((left, right) => right.path.length - left.path.length)
|
||||
.at(0)
|
||||
}
|
||||
|
||||
function entryWithInferredWorkspace(entry: VaultEntry, workspaces: WorkspaceIdentity[] | undefined): VaultEntry {
|
||||
const workspace = inferEntryWorkspace(entry, workspaces)
|
||||
return workspace && workspace !== entry.workspace ? { ...entry, workspace } : entry
|
||||
}
|
||||
|
||||
function ValidFrontmatterPanels({
|
||||
entry,
|
||||
entries,
|
||||
@@ -88,10 +109,11 @@ function ValidFrontmatterPanels({
|
||||
workspaces?: WorkspaceIdentity[]
|
||||
locale: AppLocale
|
||||
}) {
|
||||
const entryForWorkspaceActions = entryWithInferredWorkspace(entry, workspaces)
|
||||
return (
|
||||
<>
|
||||
<DynamicPropertiesPanel
|
||||
entry={entry}
|
||||
entry={entryForWorkspaceActions}
|
||||
frontmatter={frontmatter}
|
||||
entries={entries}
|
||||
onUpdateProperty={onUpdateProperty}
|
||||
@@ -99,7 +121,7 @@ function ValidFrontmatterPanels({
|
||||
onAddProperty={onAddProperty}
|
||||
onNavigate={onNavigate}
|
||||
onCreateMissingType={onCreateMissingType}
|
||||
onChangeWorkspace={onChangeWorkspace ? (workspace) => onChangeWorkspace(entry, workspace) : undefined}
|
||||
onChangeWorkspace={onChangeWorkspace ? (workspace) => onChangeWorkspace(entryForWorkspaceActions, workspace) : undefined}
|
||||
workspaces={workspaces}
|
||||
locale={locale}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user