'use client' import React, { useRef, useState } from 'react' import { PlusIcon, XMarkIcon, DocumentPlusIcon } from '@heroicons/react/20/solid' import { ipc } from '../../wailsjs/wailsjs/go/models' import { useProject } from '../../context/Project/provider' type GroupNavigationItem = { id: string, name: string, documents: { id: string, name: string, areas: { id: string, name: string }[] }[] } const getNavigationProps = (documents: ipc.Document[], groups: ipc.Group[]): GroupNavigationItem[] => { const groupsWithDocuments = groups.map(g => { const childrenDocuments = documents .filter(d => d.groupId === g.id) .map(d => ({ id: d.id, name: d.name, areas: d.areas.map(a => ({ id: a.id, name: a.name })) })) return { id: g.id, name: g.name, documents: childrenDocuments } }) const documentsWithoutGroup = documents .filter(d => !d.groupId || d.groupId === 'Uncategorized') .map(d => ({ id: d.id, name: d.name, areas: d.areas.map(a => ({ id: a.id, name: a.name })) })) return [ ...groupsWithDocuments, { id: 'Uncategorized', name: 'Uncategorized', documents: documentsWithoutGroup } ] } function classNames(...classes: any[]) { return classes.filter(Boolean).join(' ') } function Sidebar() { const [selectedGroupId, setSelectedGroupId] = useState('') const [isAddNewDocumentInputShowing, setIsAddNewDocumentInputShowing] = useState(false) const [isAddNewGroupInputShowing, setIsAddNewGroupInputShowing] = useState(false) const [isEditAreaNameInputShowing, setIsEditAreaNameInputShowing] = useState(false) const addDocumentTextInput = useRef(null) const addGroupTextInput = useRef(null) const editAreaNameTextInput = useRef(null) const { documents, groups, getAreaById, requestUpdateArea, requestAddDocument, requestAddDocumentGroup, selectedAreaId, setSelectedAreaId, selectedDocumentId, setSelectedDocumentId, } = useProject() const navigation = getNavigationProps(documents, groups) const getGroupIdFromDocumentId = (itemId: string) => { let groupId = '' navigation.forEach(g => { const foundDocument = g.documents.find(d => d.id === itemId) if (foundDocument) groupId = g.id }) return groupId } const getDocumentIdFromAreaId = (areaId: string) => { let documentId = '' navigation.map(g => g.documents).flat().forEach(d => { const doesDocumentIncludeArea = d.areas.map(a => a.id).includes(areaId) if (doesDocumentIncludeArea) documentId = d.id }) return documentId } const onAddNewDocumentLineItemClickHandler = (groupId: string) => { setSelectedGroupId(groupId) setIsAddNewDocumentInputShowing(true) setIsAddNewGroupInputShowing(false) } const onAddNewGroupLineItemClickHandler = () => { setIsAddNewGroupInputShowing(true) setIsAddNewDocumentInputShowing(false) } const onAreaClick = (areaId: string) => { getDocumentIdFromAreaId(areaId) setSelectedDocumentId(getDocumentIdFromAreaId(areaId) || '') setSelectedAreaId(areaId) } const onAreaDoubleclick = (areaId: string) => { const documentIdOfArea = getDocumentIdFromAreaId(areaId) setIsEditAreaNameInputShowing(true) console.log('double click') } const onAreaInputBlur = () => { setIsEditAreaNameInputShowing(false) } const onDocumentClickHandler = (itemId: string) => { setSelectedDocumentId(itemId) setSelectedGroupId(getGroupIdFromDocumentId(itemId)) setIsAddNewDocumentInputShowing(false) setIsAddNewGroupInputShowing(false) } const onCancelAddGroupClickHandler = () => { setIsAddNewGroupInputShowing(false) } const onCancelAddItemClickHandler = () => { setIsAddNewDocumentInputShowing(false) } const onConfirmAreaNameChangeHandler = async (areaDetails: { areaId: string, areaName: string }) => { const { areaId, areaName } = areaDetails const areaToUpdate = getAreaById(areaId) if (areaToUpdate) { areaToUpdate.name = areaName requestUpdateArea(areaToUpdate) .then(response => console.log(response)) .catch(console.error) } setIsEditAreaNameInputShowing(false) } const onConfirmAddDocumentClickHandler = async (groupId: string) => { const documentName = addDocumentTextInput.current?.value if (!documentName) return const response = await requestAddDocument(groupId, documentName) if (!response.id) return setSelectedDocumentId(response.id) setSelectedGroupId(groupId) setIsAddNewDocumentInputShowing(false) } const onConfirmAddGroupClickHandler = async (e: React.MouseEvent) => { const groupName = addGroupTextInput.current?.value if (!groupName) return const response = await requestAddDocumentGroup(groupName) if (!response.id) return setSelectedGroupId(response.id) setIsAddNewGroupInputShowing(false) } const onEnterHandler = (event: React.KeyboardEvent, callback: Function) => { if (event.key === 'Enter') callback() } const renderAddGroupInput = () => { return isAddNewGroupInputShowing ?
{ onEnterHandler(event, onConfirmAddGroupClickHandler) }} ref={addGroupTextInput} />
: } const renderAddNewDocument = (groupId: string) => { return isAddNewDocumentInputShowing && selectedGroupId === groupId ?
{ onEnterHandler(event, () => onConfirmAddDocumentClickHandler(groupId)) }} ref={addDocumentTextInput} />
: onAddNewDocumentLineItemClickHandler(groupId)} > } const renderNavigationItems = () => ( ) return ( <>
Textualize
{renderNavigationItems()}
) } export default Sidebar