docs: revise zotero import spec for fullscreen modal

This commit is contained in:
Saberlve 2026-04-15 14:52:25 +08:00
parent 3667e313a4
commit 6003300135

View File

@ -2,30 +2,29 @@
## Overview
This design replaces the current crowded import area with a lighter flow:
This design revises the current import flow into a true full-screen modal experience:
- the main page keeps project, cards, and writing views visible
- the import UI moves into a modal opened from a single `导入文献` button
- the main page keeps project, cards, and writing views visible until import starts
- clicking `导入文献` opens a full-screen modal layer that visually occupies the whole viewport
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 import modal visualizes the current Zotero collection hierarchy, lets the user browse collections, displays only the directly contained literature for the selected collection, remembers cross-collection checkbox state for the current browser session, and batch-imports the 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.
## Goals
- Replace the current import widgets with one `导入文献` button that opens an import modal
- Visualize Zotero collections as a tree inside the modal
- When a collection is selected, show the literature under that collection and all descendant collections
- Replace the current import widgets with one `导入文献` button that opens a full-screen modal
- Visualize Zotero collections as a tree on the left side of the full-screen modal
- When a collection is selected, show only the items directly contained by that collection
- Support checkbox-based multi-selection across collection switches
- Remember previous selection state while the page remains open, even if the modal is closed and reopened
- Support bulk actions:
- select all items from the current collection plus descendants
- Support top-bar actions:
- clear all selected items
- 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
- show checkbox, title, and year only
- show abstract only after hover delay or explicit details trigger
- Preserve the existing project panel, card panel, and writing panel structure outside the modal
## Non-Goals
@ -35,6 +34,7 @@ This work is intentionally scoped to the import surface only. The project card p
- Persisting import selections across browser restarts or across different users
- Replacing the bridge-based current-selection import flow at the API level
- Showing abstract text inline for every row by default
- Collection-level bulk selection such as “select all current collection and descendants”
The bridge-based import endpoint may remain available, but it is no longer the main UI path.
@ -61,17 +61,17 @@ The current pair of sections:
will be removed and replaced with:
- one `导入文献` button on the main page
- one `Import From Zotero` modal
- one full-screen `Import From Zotero` modal
## User Flow
1. The user selects a project or leaves the page without selecting one yet
2. The user clicks `导入文献`
3. The modal opens
4. The user browses the Zotero collection tree
3. A full-screen modal opens
4. The user browses the Zotero collection tree on the left
5. The user clicks one collection
6. The UI loads all literature from that collection and all descendants
7. The user checks items to import
6. The UI loads only the items directly contained by that collection
7. The user checks individual items to import
8. The user may switch to a different collection and continue selecting
9. Previously selected items remain selected
10. The user clicks `导入所选到当前项目`
@ -81,7 +81,7 @@ will be removed and replaced with:
## Layout
The page stays three-column.
The page stays three-column until the import modal opens.
### Main Page
@ -91,29 +91,32 @@ The left panel contains:
2. `项目列表`
3. `导入文献`
The collection tree and collection item list are no longer rendered inline on the main page.
The collection tree and collection item list are not rendered inline on the main page.
### Import Modal
### Full-Screen Modal
The modal has three internal regions:
The modal fills the viewport and has three internal regions:
1. modal header
1. top toolbar
2. modal body
3. sticky action bar
3. full-screen overlay/background layer
#### Modal Header
#### Top Toolbar
- title
- current project name or an explicit "未选择项目" state
- `返回主页面`
- current project name or explicit `未选择项目`
- selected count
- close button
- `清空选择`
- `导入所选`
This toolbar remains visible while the collection tree and item list scroll.
#### Modal Body
- desktop: two-column layout
- desktop: fixed two-column layout
- left: collection tree
- right: collection item list
- narrow screens: automatically stack into top and bottom sections
- narrow screens: may stack or collapse the tree, but the desktop target is explicitly left-tree / right-list
#### Collection Tree
@ -121,36 +124,28 @@ The modal has three internal regions:
- current collection highlighted
- each node shows:
- collection name
- descendant-aware item count
- item count for that collection
#### Collection Item List
- shows items from the current collection and all descendant collections
- shows only items directly contained in the selected collection
- each row contains:
- checkbox
- title
- year, item type, and abstract are not shown inline by default
- year
- abstract is not shown inline
- rows already selected in other collections remain checked when shown again
#### Sticky Action Bar
- selected count
- `全选当前目录及子目录`
- `清空选择`
- `导入所选到当前项目`
The action bar remains visible while scrolling within the modal.
## Interaction Semantics
### Modal Open And Close
Clicking `导入文献` opens the modal.
Clicking `导入文献` opens the full-screen modal.
The modal can be closed by:
- clicking the close button
- clicking the overlay
- clicking the explicit return button
- clicking the overlay if that behavior is preserved
- pressing `Esc`
Closing the modal does not clear:
@ -166,7 +161,7 @@ Reopening the modal restores the previous browsing and selection state for the c
Clicking a collection:
- sets it as the active collection
- loads all items under that collection plus descendants
- loads only items directly contained by that collection
- does not clear already selected items
### Checkbox State
@ -179,14 +174,6 @@ This means:
- re-entering a collection restores prior checkbox state
- the selected count reflects the union of all selected items across the session
### Select-All Behavior
`全选当前目录及子目录` means:
- take the currently displayed item set
- merge all of those item keys into the global selected set
- keep existing selections from other collections intact
### Clear Behavior
`清空选择` means:
@ -213,7 +200,7 @@ The item list stays compact by default.
### Desktop
- hovering an item row starts a 3 second timer
- hovering the title area of 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
@ -248,6 +235,7 @@ The page should maintain these state keys:
- `expandedCollectionKeys`
- `selectedItemKeys`
- `visibleCollectionItems`
- `selectedItemMeta`
- `hoveredItemKey`
- `hoverTimerId`
- `previewItemKey`
@ -259,6 +247,7 @@ The page should maintain these state keys:
- `expandedCollectionKeys` changes when nodes are opened or closed
- `selectedItemKeys` persists across collection switches and modal reopen during the current browser session
- `visibleCollectionItems` updates whenever the active collection changes
- `selectedItemMeta` stores minimal metadata for already selected items
- `hoveredItemKey`, `hoverTimerId`, and `previewItemKey` control delayed abstract preview
`selectedItemKeys` is the source of truth for checkbox rendering and batch import.
@ -284,9 +273,9 @@ Each node must include:
### 2. Collection Items
`GET /api/zotero/collections/{collection_key}/items?include_descendants=true`
`GET /api/zotero/collections/{collection_key}/items?include_descendants=false`
Returns all regular Zotero items under the selected collection. In V1 of this feature, the UI will always request `include_descendants=true`.
Returns only regular Zotero items directly contained by the selected collection.
Each returned item must include:
@ -325,7 +314,6 @@ Required reader capabilities:
- build normalized collection tree data
- compute direct item counts per collection
- compute descendant-aware item counts per collection
- list all regular items under a collection with optional descendant inclusion
The reader should continue to ignore attachment, note, and annotation rows as import roots.
@ -363,13 +351,13 @@ The reader should continue to ignore attachment, note, and annotation rows as im
### Reader Tests
- build collection tree from fixture Zotero data
- compute descendant-aware item counts
- list collection items with descendant inclusion
- compute direct item counts
- list collection items without descendant inclusion
### API Tests
- `GET /api/zotero/collections/tree`
- `GET /api/zotero/collections/{collection_key}/items?include_descendants=true`
- `GET /api/zotero/collections/{collection_key}/items?include_descendants=false`
- `POST /api/projects/{project_id}/imports/item-keys`
### UI Tests
@ -383,36 +371,41 @@ The modal must include:
- collection tree container
- collection item list container
- selected count area
- select-all button
- clear-selection button
- import-selected button
UI behavior must cover:
- modal can open without a selected project
- full-screen modal opens from the trigger button
- 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
- item rows display title and year by default, not abstract text
## Constraints And Tradeoffs
### Why Modal Instead Of Left-Panel Inline Import
### Why Full-Screen Modal Instead Of A Centered Dialog
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.
The user explicitly wants the import experience to feel like a whole-page task, not a cramped dialog anchored inside the left side of the UI. A full-screen modal preserves modal semantics while matching that expectation visually.
### Why Tree + Side List Instead Of Tree-Mixed Items
### Why Collection Tree + Direct Item List
The user explicitly chose:
- collection tree on one side
- item list shown after selecting a collection
- collection tree on the left
- item list on the right
- only direct items for the selected collection
This keeps scanning manageable for large libraries and avoids turning the tree itself into an overloaded mixed node structure.
This keeps the browsing model simple: collection chooses the scope, list chooses the individual papers.
### Why Title-Only Rows By Default
### Why No Collection-Level Bulk Select
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.
The user explicitly wants to choose papers one by one, not by collection-level bulk action. The collection tree filters the list; it does not act as a selection shortcut.
### Why Title + Year By Default
The user explicitly wanted a lighter list than the current dense layout. Showing title and year by default preserves scanning context while leaving abstracts to delayed preview.
### Why Session-Scoped Selection Memory
@ -428,11 +421,11 @@ This feature is complete when:
- the old `导入当前选中` and `后备导入` UI sections are gone
- the main page shows a `导入文献` button instead of an inline importer
- clicking the button opens a modal with collection tree and descendant-aware item list
- clicking the button opens a full-screen modal with collection tree and direct-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 clear all current selections
- 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
- abstract preview appears only through the delayed preview interaction, not inline by default
- the item list shows title and year by default, not descendant-wide result sets or collection-level bulk select actions