docs: revise zotero import spec for fullscreen modal
This commit is contained in:
parent
3667e313a4
commit
6003300135
@ -2,30 +2,29 @@
|
|||||||
|
|
||||||
## Overview
|
## 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 main page keeps project, cards, and writing views visible until import starts
|
||||||
- the import UI moves into a modal opened from a single `导入文献` button
|
- 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.
|
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 import widgets with one `导入文献` button that opens an import modal
|
- Replace the current import widgets with one `导入文献` button that opens a full-screen modal
|
||||||
- Visualize Zotero collections as a tree inside the modal
|
- Visualize Zotero collections as a tree on the left side of the full-screen modal
|
||||||
- When a collection is selected, show the literature under that collection and all descendant collections
|
- When a collection is selected, show only the items directly contained by that collection
|
||||||
- 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, even if the modal is closed and reopened
|
- Remember previous selection state while the page remains open, even if the modal is closed and reopened
|
||||||
- Support bulk actions:
|
- Support top-bar actions:
|
||||||
- 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:
|
- Keep the item list compact by default:
|
||||||
- show checkbox and title only
|
- show checkbox, title, and year only
|
||||||
- show abstract only after hover delay
|
- show abstract only after hover delay or explicit details trigger
|
||||||
- Preserve the existing project panel, card panel, and writing panel structure
|
- Preserve the existing project panel, card panel, and writing panel structure outside the modal
|
||||||
|
|
||||||
## Non-Goals
|
## 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
|
- 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
|
- 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.
|
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:
|
will be removed and replaced with:
|
||||||
|
|
||||||
- one `导入文献` button on the main page
|
- one `导入文献` button on the main page
|
||||||
- one `Import From Zotero` modal
|
- one full-screen `Import From Zotero` modal
|
||||||
|
|
||||||
## User Flow
|
## User Flow
|
||||||
|
|
||||||
1. The user selects a project or leaves the page without selecting one yet
|
1. The user selects a project or leaves the page without selecting one yet
|
||||||
2. The user clicks `导入文献`
|
2. The user clicks `导入文献`
|
||||||
3. The modal opens
|
3. A full-screen modal opens
|
||||||
4. The user browses the Zotero collection tree
|
4. The user browses the Zotero collection tree on the left
|
||||||
5. The user clicks one collection
|
5. The user clicks one collection
|
||||||
6. The UI loads all literature from that collection and all descendants
|
6. The UI loads only the items directly contained by that collection
|
||||||
7. The user checks items to import
|
7. The user checks individual items to import
|
||||||
8. The user may switch to a different collection and continue selecting
|
8. The user may switch to a different collection and continue selecting
|
||||||
9. Previously selected items remain selected
|
9. Previously selected items remain selected
|
||||||
10. The user clicks `导入所选到当前项目`
|
10. The user clicks `导入所选到当前项目`
|
||||||
@ -81,7 +81,7 @@ will be removed and replaced with:
|
|||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
The page stays three-column.
|
The page stays three-column until the import modal opens.
|
||||||
|
|
||||||
### Main Page
|
### Main Page
|
||||||
|
|
||||||
@ -91,29 +91,32 @@ The left panel contains:
|
|||||||
2. `项目列表`
|
2. `项目列表`
|
||||||
3. `导入文献`
|
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
|
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
|
- selected count
|
||||||
- close button
|
- `清空选择`
|
||||||
|
- `导入所选`
|
||||||
|
|
||||||
|
This toolbar remains visible while the collection tree and item list scroll.
|
||||||
|
|
||||||
#### Modal Body
|
#### Modal Body
|
||||||
|
|
||||||
- desktop: two-column layout
|
- desktop: fixed two-column layout
|
||||||
- left: collection tree
|
- left: collection tree
|
||||||
- right: collection item list
|
- 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
|
#### Collection Tree
|
||||||
|
|
||||||
@ -121,36 +124,28 @@ The modal has three internal regions:
|
|||||||
- current collection highlighted
|
- current collection highlighted
|
||||||
- each node shows:
|
- each node shows:
|
||||||
- collection name
|
- collection name
|
||||||
- descendant-aware item count
|
- item count for that collection
|
||||||
|
|
||||||
#### Collection Item List
|
#### 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:
|
- each row contains:
|
||||||
- checkbox
|
- checkbox
|
||||||
- title
|
- 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
|
- 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
|
## Interaction Semantics
|
||||||
|
|
||||||
### Modal Open And Close
|
### Modal Open And Close
|
||||||
|
|
||||||
Clicking `导入文献` opens the modal.
|
Clicking `导入文献` opens the full-screen modal.
|
||||||
|
|
||||||
The modal can be closed by:
|
The modal can be closed by:
|
||||||
|
|
||||||
- clicking the close button
|
- clicking the explicit return button
|
||||||
- clicking the overlay
|
- clicking the overlay if that behavior is preserved
|
||||||
- pressing `Esc`
|
- pressing `Esc`
|
||||||
|
|
||||||
Closing the modal does not clear:
|
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:
|
Clicking a collection:
|
||||||
|
|
||||||
- sets it as the active 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
|
- does not clear already selected items
|
||||||
|
|
||||||
### Checkbox State
|
### Checkbox State
|
||||||
@ -179,14 +174,6 @@ This means:
|
|||||||
- re-entering a collection restores prior checkbox state
|
- re-entering a collection restores prior checkbox state
|
||||||
- the selected count reflects the union of all selected items across the session
|
- 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
|
### Clear Behavior
|
||||||
|
|
||||||
`清空选择` means:
|
`清空选择` means:
|
||||||
@ -213,7 +200,7 @@ The item list stays compact by default.
|
|||||||
|
|
||||||
### Desktop
|
### 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 pointer is still on the row after 3 seconds, an abstract preview popover appears
|
||||||
- if the abstract is empty, no popover appears
|
- if the abstract is empty, no popover appears
|
||||||
- moving the pointer away before 3 seconds cancels the timer
|
- moving the pointer away before 3 seconds cancels the timer
|
||||||
@ -248,6 +235,7 @@ The page should maintain these state keys:
|
|||||||
- `expandedCollectionKeys`
|
- `expandedCollectionKeys`
|
||||||
- `selectedItemKeys`
|
- `selectedItemKeys`
|
||||||
- `visibleCollectionItems`
|
- `visibleCollectionItems`
|
||||||
|
- `selectedItemMeta`
|
||||||
- `hoveredItemKey`
|
- `hoveredItemKey`
|
||||||
- `hoverTimerId`
|
- `hoverTimerId`
|
||||||
- `previewItemKey`
|
- `previewItemKey`
|
||||||
@ -259,6 +247,7 @@ The page should maintain these state keys:
|
|||||||
- `expandedCollectionKeys` changes when nodes are opened or closed
|
- `expandedCollectionKeys` changes when nodes are opened or closed
|
||||||
- `selectedItemKeys` persists across collection switches and modal reopen 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
|
||||||
|
- `selectedItemMeta` stores minimal metadata for already selected items
|
||||||
- `hoveredItemKey`, `hoverTimerId`, and `previewItemKey` control delayed abstract preview
|
- `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.
|
||||||
@ -284,9 +273,9 @@ Each node must include:
|
|||||||
|
|
||||||
### 2. Collection Items
|
### 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:
|
Each returned item must include:
|
||||||
|
|
||||||
@ -325,7 +314,6 @@ Required reader capabilities:
|
|||||||
|
|
||||||
- build normalized collection tree data
|
- build normalized collection tree data
|
||||||
- compute direct item counts per collection
|
- compute direct item counts per collection
|
||||||
- compute descendant-aware item counts per collection
|
|
||||||
- list all regular items under a collection with optional descendant inclusion
|
- 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.
|
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
|
### Reader Tests
|
||||||
|
|
||||||
- build collection tree from fixture Zotero data
|
- build collection tree from fixture Zotero data
|
||||||
- compute descendant-aware item counts
|
- compute direct item counts
|
||||||
- list collection items with descendant inclusion
|
- list collection items without descendant inclusion
|
||||||
|
|
||||||
### API Tests
|
### API Tests
|
||||||
|
|
||||||
- `GET /api/zotero/collections/tree`
|
- `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`
|
- `POST /api/projects/{project_id}/imports/item-keys`
|
||||||
|
|
||||||
### UI Tests
|
### UI Tests
|
||||||
@ -383,36 +371,41 @@ The modal must include:
|
|||||||
- collection tree container
|
- collection tree container
|
||||||
- collection item list container
|
- collection item list container
|
||||||
- selected count area
|
- selected count area
|
||||||
- select-all button
|
|
||||||
- clear-selection button
|
- clear-selection button
|
||||||
- import-selected button
|
- import-selected button
|
||||||
|
|
||||||
UI behavior must cover:
|
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
|
- import action is disabled when no project is selected
|
||||||
- closing and reopening the modal preserves selected items during the session
|
- closing and reopening the modal preserves selected items during the session
|
||||||
- import success closes the modal and refreshes cards
|
- import success closes the modal and refreshes cards
|
||||||
- abstract preview appears only after the hover delay on desktop
|
- abstract preview appears only after the hover delay on desktop
|
||||||
|
- item rows display title and year by default, not abstract text
|
||||||
|
|
||||||
## Constraints And Tradeoffs
|
## 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:
|
The user explicitly chose:
|
||||||
|
|
||||||
- collection tree on one side
|
- collection tree on the left
|
||||||
- item list shown after selecting a collection
|
- 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
|
### Why Session-Scoped Selection Memory
|
||||||
|
|
||||||
@ -428,11 +421,11 @@ This feature is complete when:
|
|||||||
|
|
||||||
- the old `导入当前选中` and `后备导入` UI sections are gone
|
- the old `导入当前选中` and `后备导入` UI sections are gone
|
||||||
- the main page shows a `导入文献` button instead of an inline importer
|
- 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
|
- 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 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 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
|
- 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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user