33 * Handles lists, bibliographies, and entity management
44 */
55
6+ import type { ListType } from "@bibgraph/utils" ;
67import { logger } from "@bibgraph/utils" ;
78import { SPECIAL_LIST_IDS } from "@bibgraph/utils/storage/catalogue-db" ;
89import {
@@ -11,6 +12,7 @@ import {
1112 Card ,
1213 Container ,
1314 Group ,
15+ Menu ,
1416 Modal ,
1517 Paper ,
1618 SimpleGrid ,
@@ -24,6 +26,7 @@ import {
2426import { useHotkeys } from "@mantine/hooks" ;
2527import {
2628 IconBook ,
29+ IconChevronDown ,
2730 IconDatabase ,
2831 IconDownload ,
2932 IconEdit ,
@@ -42,6 +45,8 @@ import { CatalogueListComponent } from "@/components/catalogue/CatalogueList";
4245import { CreateListModal } from "@/components/catalogue/CreateListModal" ;
4346import { ExportModal } from "@/components/catalogue/ExportModal" ;
4447import { ImportModal } from "@/components/catalogue/ImportModal" ;
48+ import type { ListTemplate } from "@/components/catalogue/ListTemplates" ;
49+ import { ListTemplates } from "@/components/catalogue/ListTemplates" ;
4550import { ShareModal } from "@/components/catalogue/ShareModal" ;
4651import { BORDER_STYLE_GRAY_3 , ICON_SIZE } from '@/config/style-constants' ;
4752import { useCatalogueContext } from "@/contexts/catalogue-context" ;
@@ -71,6 +76,8 @@ export const CatalogueManager = ({ onNavigate, shareData, initialListId }: Catal
7176
7277 const [ activeTab , setActiveTab ] = useState < string | null > ( "lists" ) ;
7378 const [ showCreateModal , setShowCreateModal ] = useState ( false ) ;
79+ const [ showTemplatesModal , setShowTemplatesModal ] = useState ( false ) ;
80+ const [ selectedTemplate , setSelectedTemplate ] = useState < ListTemplate | null > ( null ) ;
7481 const [ showShareModal , setShowShareModal ] = useState ( false ) ;
7582 const [ showImportModal , setShowImportModal ] = useState ( false ) ;
7683 const [ showExportModal , setShowExportModal ] = useState ( false ) ;
@@ -197,6 +204,43 @@ export const CatalogueManager = ({ onNavigate, shareData, initialListId }: Catal
197204 }
198205 } ;
199206
207+ // Handle template selection
208+ const handleUseTemplate = ( template : ListTemplate ) => {
209+ setSelectedTemplate ( template ) ;
210+ setShowTemplatesModal ( false ) ;
211+ setShowCreateModal ( true ) ;
212+ } ;
213+
214+ // Handle create list from template or custom
215+ const handleCreateList = async ( params : {
216+ title : string ;
217+ description ?: string ;
218+ type : ListType ;
219+ tags ?: string [ ] ;
220+ isPublic ?: boolean ;
221+ } ) => {
222+ // Merge template tags with user-provided tags (avoiding duplicates)
223+ const mergedTags = selectedTemplate
224+ ? [ ...new Set ( [ ...selectedTemplate . tags , ...( params . tags || [ ] ) ] ) ]
225+ : params . tags ;
226+
227+ const listId = await createList ( {
228+ ...params ,
229+ tags : mergedTags ,
230+ } ) ;
231+ // Switch to the appropriate tab based on list type
232+ setActiveTab ( params . type === "bibliography" ? "bibliographies" : "lists" ) ;
233+ selectList ( listId ) ;
234+ setSelectedTemplate ( null ) ;
235+ setShowCreateModal ( false ) ;
236+ } ;
237+
238+ // Reset template when closing create modal
239+ const handleCloseCreateModal = ( ) => {
240+ setSelectedTemplate ( null ) ;
241+ setShowCreateModal ( false ) ;
242+ } ;
243+
200244 return (
201245 < Container size = "xl" py = "md" data-testid = "catalogue-manager" >
202246 < Stack gap = "lg" >
@@ -232,13 +276,36 @@ export const CatalogueManager = ({ onNavigate, shareData, initialListId }: Catal
232276 Share
233277 </ Button >
234278
235- < Button
236- leftSection = { < IconPlus size = { ICON_SIZE . MD } /> }
237- onClick = { ( ) => setShowCreateModal ( true ) }
238- aria-label = "Open modal to create a new catalogue list "
279+ < Menu
280+ shadow = "md"
281+ width = { 200 }
282+ position = "bottom-end "
239283 >
240- Create New List
241- </ Button >
284+ < Menu . Target >
285+ < Button
286+ leftSection = { < IconPlus size = { ICON_SIZE . MD } /> }
287+ rightSection = { < IconChevronDown size = { 16 } /> }
288+ aria-label = "Create new list or use templates"
289+ >
290+ Create New List
291+ </ Button >
292+ </ Menu . Target >
293+
294+ < Menu . Dropdown >
295+ < Menu . Item
296+ leftSection = { < IconBook size = { 14 } /> }
297+ onClick = { ( ) => setShowTemplatesModal ( true ) }
298+ >
299+ Use Templates
300+ </ Menu . Item >
301+ < Menu . Item
302+ leftSection = { < IconPlus size = { 14 } /> }
303+ onClick = { ( ) => setShowCreateModal ( true ) }
304+ >
305+ Create Custom List
306+ </ Menu . Item >
307+ </ Menu . Dropdown >
308+ </ Menu >
242309 </ Group >
243310 </ Group >
244311
@@ -428,21 +495,33 @@ export const CatalogueManager = ({ onNavigate, shareData, initialListId }: Catal
428495 { /* Modals */ }
429496 < Modal
430497 opened = { showCreateModal }
431- onClose = { ( ) => setShowCreateModal ( false ) }
432- title = "Create New List"
498+ onClose = { handleCloseCreateModal }
499+ title = { selectedTemplate ? `Create from Template: ${ selectedTemplate . name } ` : "Create New List" }
433500 size = "md"
434501 trapFocus
435502 returnFocus
436503 >
437504 < CreateListModal
438- onClose = { ( ) => setShowCreateModal ( false ) }
439- onSubmit = { async ( params ) => {
440- const listId = await createList ( params ) ;
441- // Switch to the appropriate tab based on list type
442- setActiveTab ( params . type === "bibliography" ? "bibliographies" : "lists" ) ;
443- selectList ( listId ) ;
444- setShowCreateModal ( false ) ;
445- } }
505+ onClose = { handleCloseCreateModal }
506+ onSubmit = { handleCreateList }
507+ initialTitle = { selectedTemplate ?. name }
508+ initialDescription = { selectedTemplate ?. description }
509+ initialType = { selectedTemplate ?. type }
510+ initialTags = { selectedTemplate ?. tags }
511+ />
512+ </ Modal >
513+
514+ < Modal
515+ opened = { showTemplatesModal }
516+ onClose = { ( ) => setShowTemplatesModal ( false ) }
517+ title = "Choose a Template"
518+ size = "xl"
519+ trapFocus
520+ returnFocus
521+ >
522+ < ListTemplates
523+ onUseTemplate = { handleUseTemplate }
524+ onClose = { ( ) => setShowTemplatesModal ( false ) }
446525 />
447526 </ Modal >
448527
0 commit comments