verstak/cmd/verstak-gui/bindings_nodes.go

181 lines
4.7 KiB
Go

package main
import (
"fmt"
"time"
"verstak/internal/core/activity"
"verstak/internal/core/nodes"
syncsvc "verstak/internal/core/sync"
)
func (a *App) ListNodesBySection(section string) ([]NodeDTO, error) {
list, err := a.nodes.ListRoots(false, section)
if err != nil {
return nil, err
}
return toNodeDTOs(list), nil
}
func (a *App) ListChildren(parentID string) ([]NodeDTO, error) {
list, err := a.nodes.ListChildren(parentID, false)
if err != nil {
return nil, err
}
return toNodeDTOs(list), nil
}
func (a *App) GetNodeDetail(nodeID string) (*NodeDTO, error) {
n, err := a.nodes.GetActive(nodeID)
if err != nil {
return nil, err
}
dto := toNodeDTO(n)
return &dto, nil
}
func (a *App) CreateNode(parentID, nodeType, title, section string) (*NodeDTO, error) {
if section == "today" || section == "inbox" {
return nil, fmt.Errorf("cannot create node with section %q", section)
}
n, err := a.nodes.Create(parentID, nodeType, title, section)
if err != nil {
return nil, err
}
_ = a.activity.Record(n.ID, activity.TargetNode, n.ID, "", activity.TypeNodeCreated, title, "")
_ = a.sync.RecordOp(syncsvc.EntityNode, n.ID, syncsvc.OpCreate, nodePayload(n))
dto := toNodeDTO(n)
return &dto, nil
}
func (a *App) DeleteNode(id string) error {
n, err := a.nodes.GetActive(id)
if err != nil {
return a.nodes.SoftDelete(id)
}
pid := ""
if n.ParentID != nil {
pid = *n.ParentID
}
var entity string
var targetType string
var evType string
switch n.Type {
case nodes.TypeNote:
entity = syncsvc.EntityNote
targetType = activity.TargetNote
evType = activity.TypeNoteDeleted
case nodes.TypeFolder:
entity = syncsvc.EntityFolder
targetType = activity.TargetFolder
evType = activity.TypeFolderDeleted
case nodes.TypeFile:
entity = syncsvc.EntityFile
targetType = activity.TargetFile
evType = activity.TypeFileDeleted
default:
entity = syncsvc.EntityNode
targetType = activity.TargetNode
evType = activity.TypeNodeDeleted
}
_ = a.activity.Record(pid, targetType, id, "", evType, n.Title, "")
_ = a.sync.RecordOp(entity, id, syncsvc.OpDelete, nil)
return a.nodes.SoftDelete(id)
}
func (a *App) RenameNode(nodeID, newTitle string) error {
n, err := a.nodes.GetActive(nodeID)
if err != nil {
return err
}
oldTitle := n.Title
if err := a.nodes.UpdateTitle(nodeID, newTitle); err != nil {
return err
}
pid := ""
if n.ParentID != nil {
pid = *n.ParentID
}
var evType string
var targetType string
var syncEntity string
switch n.Type {
case nodes.TypeNote:
evType = activity.TypeNoteUpdated
targetType = activity.TargetNote
syncEntity = syncsvc.EntityNote
case nodes.TypeFile:
evType = activity.TypeFileRenamed
targetType = activity.TargetFile
syncEntity = syncsvc.EntityFile
case nodes.TypeFolder:
evType = activity.TypeFolderRenamed
targetType = activity.TargetFolder
syncEntity = syncsvc.EntityFolder
default:
evType = activity.TypeNodeUpdated
targetType = activity.TargetNode
syncEntity = syncsvc.EntityNode
}
_ = a.activity.Record(pid, targetType, nodeID, "", evType, newTitle, `{"from":"`+oldTitle+`","to":"`+newTitle+`"}`)
_ = a.sync.RecordOp(syncEntity, nodeID, syncsvc.OpUpdate, map[string]interface{}{
"title": newTitle,
"updated_at": time.Now().UTC().Format(time.RFC3339),
})
return nil
}
func (a *App) MoveNode(nodeID, newParentID string) error {
destChildren, err := a.nodes.ListChildren(newParentID, false)
if err != nil {
return err
}
node, err := a.nodes.GetActive(nodeID)
if err != nil {
return err
}
for i := range destChildren {
if destChildren[i].Title == node.Title {
newName := a.files.UniqueTitleCopy(newParentID, node.Title)
if err := a.nodes.UpdateTitle(nodeID, newName); err != nil {
return err
}
break
}
}
if err := a.nodes.Move(nodeID, newParentID, 0); err != nil {
return err
}
pid := ""
if node.ParentID != nil {
pid = *node.ParentID
}
var targetType string
var evType string
var syncEntity string
switch node.Type {
case nodes.TypeNote:
targetType = activity.TargetNote
evType = activity.TypeNoteUpdated
syncEntity = syncsvc.EntityNote
case nodes.TypeFile:
targetType = activity.TargetFile
evType = activity.TypeFileMoved
syncEntity = syncsvc.EntityFile
case nodes.TypeFolder:
targetType = activity.TargetFolder
evType = activity.TypeFolderMoved
syncEntity = syncsvc.EntityFolder
default:
targetType = activity.TargetNode
evType = activity.TypeNodeUpdated
syncEntity = syncsvc.EntityNode
}
_ = a.activity.Record(pid, targetType, nodeID, "", evType, node.Title, `{"to":"`+newParentID+`"}`)
_ = a.sync.RecordOp(syncEntity, nodeID, syncsvc.OpMove, map[string]interface{}{
"parent_id": newParentID,
"updated_at": time.Now().UTC().Format(time.RFC3339),
})
return nil
}