docs: revise zotero import spec for modal flow
This commit is contained in:
parent
0c0c773e61
commit
2566508b48
@ -2,43 +2,45 @@
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This design upgrades the current left-panel import area from two temporary flows:
|
This design replaces the current crowded import area with a lighter flow:
|
||||||
|
|
||||||
- import current selection from a bridge snapshot
|
- the main page keeps project, cards, and writing views visible
|
||||||
- text-search fallback import
|
- the import UI moves into a modal opened from a single `导入文献` button
|
||||||
|
|
||||||
into one unified Zotero collection importer.
|
The modal visualizes the user's current Zotero collection hierarchy, lets the user browse collections, displays the literature under the selected collection and all descendants, remembers cross-collection checkbox state for the current browser session, and batch-imports selected items into the current project.
|
||||||
|
|
||||||
The new importer must visualize the user's current Zotero collection hierarchy, let the user browse collections, display the literature under the selected collection, remember cross-collection checkbox state, and batch-import selected items into the current project.
|
|
||||||
|
|
||||||
This work is intentionally scoped to the import surface only. The project card panel and writing panel remain in place.
|
This work is intentionally scoped to the import surface only. The project card panel and writing panel remain in place.
|
||||||
|
|
||||||
## Goals
|
## Goals
|
||||||
|
|
||||||
- Replace the current left-panel import widgets with one unified `Import From Zotero` section
|
- Replace the current import widgets with one `导入文献` button that opens an import modal
|
||||||
- Visualize Zotero collections as a tree in the left panel
|
- Visualize Zotero collections as a tree inside the modal
|
||||||
- When a collection is selected, show the literature under that collection and all descendant collections
|
- When a collection is selected, show the literature under that collection and all descendant collections
|
||||||
- Support checkbox-based multi-selection across collection switches
|
- Support checkbox-based multi-selection across collection switches
|
||||||
- Remember previous selection state while the page remains open
|
- Remember previous selection state while the page remains open, even if the modal is closed and reopened
|
||||||
- Support bulk actions:
|
- Support bulk actions:
|
||||||
- select all items from the current collection plus descendants
|
- select all items from the current collection plus descendants
|
||||||
- clear all selected items
|
- clear all selected items
|
||||||
- import selected items into the current project
|
- import selected items into the current project
|
||||||
|
- Keep the item list compact by default:
|
||||||
|
- show checkbox and title only
|
||||||
|
- show abstract only after hover delay
|
||||||
- Preserve the existing project panel, card panel, and writing panel structure
|
- Preserve the existing project panel, card panel, and writing panel structure
|
||||||
|
|
||||||
## Non-Goals
|
## Non-Goals
|
||||||
|
|
||||||
- Full drag-and-drop tree editing
|
- Full drag-and-drop tree editing
|
||||||
- Editing Zotero collections
|
- Editing Zotero collections
|
||||||
- Multi-pane import wizard
|
- Multi-step import wizard
|
||||||
- Persisting import selections across browser restarts or across different users
|
- Persisting import selections across browser restarts or across different users
|
||||||
- Replacing the bridge-based current-selection import flow at the API level
|
- Replacing the bridge-based current-selection import flow at the API level
|
||||||
|
- Showing abstract text inline for every row by default
|
||||||
|
|
||||||
The bridge-based import endpoint may remain available, but it is no longer the main UI path.
|
The bridge-based import endpoint may remain available, but it is no longer the main UI path.
|
||||||
|
|
||||||
## Product Scope
|
## Product Scope
|
||||||
|
|
||||||
The importer is a left-panel replacement only.
|
The importer is a modal-based subflow launched from the main page.
|
||||||
|
|
||||||
### Unchanged Areas
|
### Unchanged Areas
|
||||||
|
|
||||||
@ -58,41 +60,61 @@ The current pair of sections:
|
|||||||
|
|
||||||
will be removed and replaced with:
|
will be removed and replaced with:
|
||||||
|
|
||||||
- `从 Zotero 导入`
|
- one `导入文献` button on the main page
|
||||||
|
- one `Import From Zotero` modal
|
||||||
|
|
||||||
## User Flow
|
## User Flow
|
||||||
|
|
||||||
1. The user selects a project
|
1. The user selects a project or leaves the page without selecting one yet
|
||||||
2. The user browses the Zotero collection tree
|
2. The user clicks `导入文献`
|
||||||
3. The user clicks one collection
|
3. The modal opens
|
||||||
4. The UI loads all literature from that collection and all descendants
|
4. The user browses the Zotero collection tree
|
||||||
5. The user checks items to import
|
5. The user clicks one collection
|
||||||
6. The user may switch to a different collection and continue selecting
|
6. The UI loads all literature from that collection and all descendants
|
||||||
7. Previously selected items remain selected
|
7. The user checks items to import
|
||||||
8. The user clicks `导入所选到当前项目`
|
8. The user may switch to a different collection and continue selecting
|
||||||
9. The backend imports all selected items into the current project
|
9. Previously selected items remain selected
|
||||||
10. The card panel refreshes with the newly imported cards
|
10. The user clicks `导入所选到当前项目`
|
||||||
|
11. The backend imports all selected items into the current project
|
||||||
|
12. The card panel refreshes with the newly imported cards
|
||||||
|
13. The modal closes on success
|
||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
The page stays three-column.
|
The page stays three-column.
|
||||||
|
|
||||||
### Left Panel
|
### Main Page
|
||||||
|
|
||||||
The left panel contains:
|
The left panel contains:
|
||||||
|
|
||||||
1. `创建项目`
|
1. `创建项目`
|
||||||
2. `项目列表`
|
2. `项目列表`
|
||||||
3. `从 Zotero 导入`
|
3. `导入文献`
|
||||||
|
|
||||||
### Import Section Structure
|
The collection tree and collection item list are no longer rendered inline on the main page.
|
||||||
|
|
||||||
The import section has three internal regions:
|
### Import Modal
|
||||||
|
|
||||||
1. collection tree
|
The modal has three internal regions:
|
||||||
2. collection item list
|
|
||||||
|
1. modal header
|
||||||
|
2. modal body
|
||||||
3. sticky action bar
|
3. sticky action bar
|
||||||
|
|
||||||
|
#### Modal Header
|
||||||
|
|
||||||
|
- title
|
||||||
|
- current project name or an explicit "未选择项目" state
|
||||||
|
- selected count
|
||||||
|
- close button
|
||||||
|
|
||||||
|
#### Modal Body
|
||||||
|
|
||||||
|
- desktop: two-column layout
|
||||||
|
- left: collection tree
|
||||||
|
- right: collection item list
|
||||||
|
- narrow screens: automatically stack into top and bottom sections
|
||||||
|
|
||||||
#### Collection Tree
|
#### Collection Tree
|
||||||
|
|
||||||
- tree view with expand/collapse state
|
- tree view with expand/collapse state
|
||||||
@ -107,9 +129,7 @@ The import section has three internal regions:
|
|||||||
- each row contains:
|
- each row contains:
|
||||||
- checkbox
|
- checkbox
|
||||||
- title
|
- title
|
||||||
- year
|
- year, item type, and abstract are not shown inline by default
|
||||||
- item type
|
|
||||||
- compact metadata
|
|
||||||
- rows already selected in other collections remain checked when shown again
|
- rows already selected in other collections remain checked when shown again
|
||||||
|
|
||||||
#### Sticky Action Bar
|
#### Sticky Action Bar
|
||||||
@ -119,10 +139,28 @@ The import section has three internal regions:
|
|||||||
- `清空选择`
|
- `清空选择`
|
||||||
- `导入所选到当前项目`
|
- `导入所选到当前项目`
|
||||||
|
|
||||||
The action bar remains visible while scrolling within the import section.
|
The action bar remains visible while scrolling within the modal.
|
||||||
|
|
||||||
## Interaction Semantics
|
## Interaction Semantics
|
||||||
|
|
||||||
|
### Modal Open And Close
|
||||||
|
|
||||||
|
Clicking `导入文献` opens the modal.
|
||||||
|
|
||||||
|
The modal can be closed by:
|
||||||
|
|
||||||
|
- clicking the close button
|
||||||
|
- clicking the overlay
|
||||||
|
- pressing `Esc`
|
||||||
|
|
||||||
|
Closing the modal does not clear:
|
||||||
|
|
||||||
|
- `selectedCollectionKey`
|
||||||
|
- `expandedCollectionKeys`
|
||||||
|
- `selectedItemKeys`
|
||||||
|
|
||||||
|
Reopening the modal restores the previous browsing and selection state for the current page session.
|
||||||
|
|
||||||
### Collection Selection
|
### Collection Selection
|
||||||
|
|
||||||
Clicking a collection:
|
Clicking a collection:
|
||||||
@ -162,26 +200,66 @@ This means:
|
|||||||
`导入所选到当前项目` means:
|
`导入所选到当前项目` means:
|
||||||
|
|
||||||
- require a currently selected project
|
- require a currently selected project
|
||||||
|
- remain disabled when no project is selected
|
||||||
- submit the full selected item key set to the backend
|
- submit the full selected item key set to the backend
|
||||||
- keep the active collection and tree expansion state
|
- keep the active collection and tree expansion state
|
||||||
- clear the selected item set on success
|
- clear the selected item set on success
|
||||||
|
- close the modal on success
|
||||||
- refresh the project card list
|
- refresh the project card list
|
||||||
|
|
||||||
|
## Abstract Preview Behavior
|
||||||
|
|
||||||
|
The item list stays compact by default.
|
||||||
|
|
||||||
|
### Desktop
|
||||||
|
|
||||||
|
- hovering an item row starts a 3 second timer
|
||||||
|
- if the pointer is still on the row after 3 seconds, an abstract preview popover appears
|
||||||
|
- if the abstract is empty, no popover appears
|
||||||
|
- moving the pointer away before 3 seconds cancels the timer
|
||||||
|
- moving the pointer away after the popover appears closes it
|
||||||
|
- only one preview popover may be open at a time
|
||||||
|
|
||||||
|
### Mobile And Narrow-Screen Fallback
|
||||||
|
|
||||||
|
Hover is not reliable on touch devices, so the UI must degrade to an explicit preview trigger such as a small details button per row.
|
||||||
|
|
||||||
|
This fallback:
|
||||||
|
|
||||||
|
- opens the same abstract preview content
|
||||||
|
- does not rely on hover timing
|
||||||
|
- does not change batch-selection behavior
|
||||||
|
|
||||||
|
### Preview Cancellation Rules
|
||||||
|
|
||||||
|
The preview timer or popover closes immediately when:
|
||||||
|
|
||||||
|
- the user leaves the row
|
||||||
|
- the user scrolls the item list
|
||||||
|
- the user changes collection
|
||||||
|
- the user clicks a checkbox
|
||||||
|
|
||||||
## Frontend State Model
|
## Frontend State Model
|
||||||
|
|
||||||
The page should maintain these state keys:
|
The page should maintain these state keys:
|
||||||
|
|
||||||
|
- `isImportModalOpen`
|
||||||
- `selectedCollectionKey`
|
- `selectedCollectionKey`
|
||||||
- `expandedCollectionKeys`
|
- `expandedCollectionKeys`
|
||||||
- `selectedItemKeys`
|
- `selectedItemKeys`
|
||||||
- `visibleCollectionItems`
|
- `visibleCollectionItems`
|
||||||
|
- `hoveredItemKey`
|
||||||
|
- `hoverTimerId`
|
||||||
|
- `previewItemKey`
|
||||||
|
|
||||||
### State Rules
|
### State Rules
|
||||||
|
|
||||||
|
- `isImportModalOpen` changes when the user opens or closes the modal
|
||||||
- `selectedCollectionKey` changes when the user clicks a tree node
|
- `selectedCollectionKey` changes when the user clicks a tree node
|
||||||
- `expandedCollectionKeys` changes when nodes are opened or closed
|
- `expandedCollectionKeys` changes when nodes are opened or closed
|
||||||
- `selectedItemKeys` persists across collection switches during the current browser session
|
- `selectedItemKeys` persists across collection switches and modal reopen during the current browser session
|
||||||
- `visibleCollectionItems` updates whenever the active collection changes
|
- `visibleCollectionItems` updates whenever the active collection changes
|
||||||
|
- `hoveredItemKey`, `hoverTimerId`, and `previewItemKey` control delayed abstract preview
|
||||||
|
|
||||||
`selectedItemKeys` is the source of truth for checkbox rendering and batch import.
|
`selectedItemKeys` is the source of truth for checkbox rendering and batch import.
|
||||||
|
|
||||||
@ -256,12 +334,13 @@ The reader should continue to ignore attachment, note, and annotation rows as im
|
|||||||
|
|
||||||
### No Project Selected
|
### No Project Selected
|
||||||
|
|
||||||
- disable import submission or return a clear UI error
|
- allow the modal to open and load Zotero data
|
||||||
|
- disable import submission with a clear UI message
|
||||||
- do not clear selected checkboxes
|
- do not clear selected checkboxes
|
||||||
|
|
||||||
### Collection Tree Load Failure
|
### Collection Tree Load Failure
|
||||||
|
|
||||||
- show error state in the import section
|
- show error state inside the modal
|
||||||
- do not affect cards or writing sections
|
- do not affect cards or writing sections
|
||||||
|
|
||||||
### Empty Collection
|
### Empty Collection
|
||||||
@ -276,7 +355,7 @@ The reader should continue to ignore attachment, note, and annotation rows as im
|
|||||||
|
|
||||||
### Missing Local Zotero Data
|
### Missing Local Zotero Data
|
||||||
|
|
||||||
- show import section unavailable
|
- disable or error the modal content clearly
|
||||||
- preserve the rest of the application
|
- preserve the rest of the application
|
||||||
|
|
||||||
## Testing Strategy
|
## Testing Strategy
|
||||||
@ -295,7 +374,11 @@ The reader should continue to ignore attachment, note, and annotation rows as im
|
|||||||
|
|
||||||
### UI Tests
|
### UI Tests
|
||||||
|
|
||||||
The index template must include:
|
The main page must include:
|
||||||
|
|
||||||
|
- import-modal trigger button
|
||||||
|
|
||||||
|
The modal must include:
|
||||||
|
|
||||||
- collection tree container
|
- collection tree container
|
||||||
- collection item list container
|
- collection item list container
|
||||||
@ -304,8 +387,20 @@ The index template must include:
|
|||||||
- clear-selection button
|
- clear-selection button
|
||||||
- import-selected button
|
- import-selected button
|
||||||
|
|
||||||
|
UI behavior must cover:
|
||||||
|
|
||||||
|
- modal can open without a selected project
|
||||||
|
- import action is disabled when no project is selected
|
||||||
|
- closing and reopening the modal preserves selected items during the session
|
||||||
|
- import success closes the modal and refreshes cards
|
||||||
|
- abstract preview appears only after the hover delay on desktop
|
||||||
|
|
||||||
## Constraints And Tradeoffs
|
## Constraints And Tradeoffs
|
||||||
|
|
||||||
|
### Why Modal Instead Of Left-Panel Inline Import
|
||||||
|
|
||||||
|
The inline importer works functionally but makes the main page too crowded. A modal keeps import as a focused subtask and preserves the readability of the project, cards, and writing columns.
|
||||||
|
|
||||||
### Why Tree + Side List Instead Of Tree-Mixed Items
|
### Why Tree + Side List Instead Of Tree-Mixed Items
|
||||||
|
|
||||||
The user explicitly chose:
|
The user explicitly chose:
|
||||||
@ -315,22 +410,29 @@ The user explicitly chose:
|
|||||||
|
|
||||||
This keeps scanning manageable for large libraries and avoids turning the tree itself into an overloaded mixed node structure.
|
This keeps scanning manageable for large libraries and avoids turning the tree itself into an overloaded mixed node structure.
|
||||||
|
|
||||||
|
### Why Title-Only Rows By Default
|
||||||
|
|
||||||
|
The user explicitly wanted a lighter list. Showing only the title in the default list keeps density under control, while delayed preview preserves access to abstracts when needed.
|
||||||
|
|
||||||
### Why Session-Scoped Selection Memory
|
### Why Session-Scoped Selection Memory
|
||||||
|
|
||||||
The user explicitly asked to remember previous selection state, but not to store durable drafts of import batches. Session-scoped state is enough for the workflow and avoids backend persistence complexity.
|
The user explicitly asked to remember previous selection state, but not to store durable drafts of import batches. Session-scoped state is enough for the workflow and avoids backend persistence complexity.
|
||||||
|
|
||||||
### Why Keep Cards And Writing Panels Unchanged
|
### Why Keep Cards And Writing Panels Unchanged
|
||||||
|
|
||||||
The import feature is a left-panel responsibility. Expanding it into a page-level mode would create unnecessary layout churn and broaden the implementation risk.
|
The import feature is a subflow. Expanding it into a permanent page layout would create unnecessary layout churn and broaden the implementation risk.
|
||||||
|
|
||||||
## Acceptance Criteria
|
## Acceptance Criteria
|
||||||
|
|
||||||
This feature is complete when:
|
This feature is complete when:
|
||||||
|
|
||||||
- the old `导入当前选中` and `后备导入` UI sections are gone
|
- the old `导入当前选中` and `后备导入` UI sections are gone
|
||||||
- the left panel shows a collection tree and descendant-aware collection item list
|
- the main page shows a `导入文献` button instead of an inline importer
|
||||||
- selecting items survives collection switches during the session
|
- clicking the button opens a modal with collection tree and descendant-aware item list
|
||||||
|
- selecting items survives collection switches and modal reopen during the session
|
||||||
- the user can select all items from a collection plus descendants
|
- the user can select all items from a collection plus descendants
|
||||||
- the user can clear all current selections
|
- the user can clear all current selections
|
||||||
- the user can batch-import the selected items into the active project
|
- the user can batch-import the selected items into the active project
|
||||||
|
- the import button is disabled when no project is selected
|
||||||
- the project card area refreshes after a successful import
|
- the project card area refreshes after a successful import
|
||||||
|
- abstract preview appears only through the delayed preview interaction, not inline by default
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user