'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' import classNames from '../../utils/classNames' type GroupNavigationItem = { id: string, name: string, documents: { id: string, name: string, areas: { id: string, name: string, order: number }[] }[] } 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, order: a.order }))//.sort((a, b) => a.order - b.order) })) 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, order: a.order }))//.sort((a, b) => a.order - b.order) })) return [ ...groupsWithDocuments, { id: '', name: 'Uncategorized', documents: documentsWithoutGroup } ] } function Sidebar() { const [selectedGroupId, setSelectedGroupId] = useState('') const [isAddNewDocumentInputShowing, setIsAddNewDocumentInputShowing] = useState(false) const [isEditDocumentNameInputShowing, setIsEditDocumentNameInputShowing] = useState(false) const [isAddNewGroupInputShowing, setIsAddNewGroupInputShowing] = useState(false) const [isEditAreaNameInputShowing, setIsEditAreaNameInputShowing] = useState(false) const [dragOverAreaId, setDragOverAreaId] = useState('') const addDocumentTextInput = useRef(null) const addGroupTextInput = useRef(null) const editAreaNameTextInput = useRef(null) const editDocumentNameTextInput = useRef(null) const { documents, groups, getSelectedDocument, getAreaById, requestUpdateArea, requestAddDocument, requestAddDocumentGroup, selectedAreaId, setSelectedAreaId, selectedDocumentId, setSelectedDocumentId, currentSession, requestUpdateDocument, requestChangeAreaOrder, } = 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) => { setSelectedDocumentId(getDocumentIdFromAreaId(areaId) || '') setIsEditAreaNameInputShowing(true) } const onAreaInputBlur = () => { setIsEditAreaNameInputShowing(false) } // ________________ const onAreaDragOver = (areaId: string) => { setDragOverAreaId(areaId) } const onAreaDragStart = (areaId: string) => { // setDragStartAreaId(areaId) } const onAreaDropEnd = (areaId: string) => { const areaDroppedOn = navigation.map(n => n.documents).flat().map(d => d.areas).flat().find(a => a.id === dragOverAreaId) if (!areaDroppedOn) return requestChangeAreaOrder(areaId, areaDroppedOn.order) setDragOverAreaId('') } // ________________ const onDocumentClickHandler = (itemId: string) => { setSelectedDocumentId(itemId) setSelectedGroupId(getGroupIdFromDocumentId(itemId)) setIsAddNewDocumentInputShowing(false) setIsAddNewGroupInputShowing(false) } const onDocumentDoubleClickHandler = (docuemntId: string) => { setIsEditDocumentNameInputShowing(true) } const onDocumentInputBlur = () => { setIsEditDocumentNameInputShowing(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 onConfirmDocumentNameChangeHandler = async (documentName: string) => { const documentToUpdate = { ...getSelectedDocument() } if (documentToUpdate) { documentToUpdate.name = documentName requestUpdateDocument(documentToUpdate) .then(response => console.log('onConfirmDocumentNameChangeHandler response: ', response)) .catch(console.error) } setIsEditDocumentNameInputShowing(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

{currentSession?.project?.name}

{renderNavigationItems()}
) } export default Sidebar