feat(workspace): add logseq outliner engine, global todo rollup, task list sharing avatars and admin toggle
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m22s

This commit is contained in:
sandrodach committed 2026-10-25 00:15:43 +02:00
1 parent 2504b48171
commit fe1d574787
9 files changed
+1604 -732

No files matched your search

+19 -14
View File
@@ -98,15 +98,18 @@ type Thought struct {
}
type TaskList struct {
ID string `json:"id"`
UserID string `json:"userId"`
SpaceID string `json:"spaceId,omitempty"`
Title string `json:"title"`
Icon string `json:"icon"`
Color string `json:"color"`
TasksCount int `json:"tasksCount,omitempty"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
ID string `json:"id"`
UserID string `json:"userId"`
SpaceID string `json:"spaceId,omitempty"`
SpaceName string `json:"spaceName,omitempty"`
OwnerName string `json:"ownerName,omitempty"`
Members []SpaceMember `json:"members,omitempty"`
Title string `json:"title"`
Icon string `json:"icon"`
Color string `json:"color"`
TasksCount int `json:"tasksCount,omitempty"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
}
type Organization struct {
@@ -149,11 +152,13 @@ type SystemSettings struct {
}
type DocumentBlock struct {
ID string `json:"id"`
Type string `json:"type"` // h1 | h2 | h3 | paragraph | todo | bullet | code | callout | divider | table | progress
Content string `json:"content"`
Checked bool `json:"checked,omitempty"`
Lang string `json:"lang,omitempty"`
ID string `json:"id"`
Type string `json:"type"` // h1 | h2 | h3 | paragraph | todo | bullet | code | callout | divider | table | progress
Content string `json:"content"`
Checked bool `json:"checked,omitempty"`
Lang string `json:"lang,omitempty"`
Level int `json:"level,omitempty"`
Collapsed bool `json:"collapsed,omitempty"`
}
type Document struct {
+30 -13
View File
@@ -923,33 +923,34 @@ func (s *Store) saveDocumentToDisk(doc *domain.Document) {
md.WriteString(fmt.Sprintf("# %s %s\n\n", doc.Icon, doc.Title))
if len(doc.Blocks) > 0 {
for _, b := range doc.Blocks {
indent := strings.Repeat(" ", b.Level)
switch b.Type {
case "h1":
md.WriteString(fmt.Sprintf("# %s\n\n", b.Content))
md.WriteString(fmt.Sprintf("%s- # %s\n", indent, b.Content))
case "h2":
md.WriteString(fmt.Sprintf("## %s\n\n", b.Content))
md.WriteString(fmt.Sprintf("%s- ## %s\n", indent, b.Content))
case "h3":
md.WriteString(fmt.Sprintf("### %s\n\n", b.Content))
md.WriteString(fmt.Sprintf("%s- ### %s\n", indent, b.Content))
case "todo":
chk := " "
if b.Checked {
chk = "x"
}
md.WriteString(fmt.Sprintf("- [%s] %s\n", chk, b.Content))
case "bullet":
md.WriteString(fmt.Sprintf("- %s\n", b.Content))
md.WriteString(fmt.Sprintf("%s- [%s] %s\n", indent, chk, b.Content))
case "bullet", "paragraph":
md.WriteString(fmt.Sprintf("%s- %s\n", indent, b.Content))
case "code":
md.WriteString(fmt.Sprintf("```%s\n%s\n```\n\n", b.Lang, b.Content))
md.WriteString(fmt.Sprintf("%s- ```%s\n%s %s\n%s ```\n", indent, b.Lang, indent, b.Content, indent))
case "callout":
md.WriteString(fmt.Sprintf("> %s\n\n", b.Content))
md.WriteString(fmt.Sprintf("%s- > %s\n", indent, b.Content))
case "divider":
md.WriteString("---\n\n")
md.WriteString(fmt.Sprintf("%s- ---\n", indent))
case "table":
md.WriteString(b.Content + "\n\n")
md.WriteString(fmt.Sprintf("%s- %s\n", indent, b.Content))
case "progress":
md.WriteString(fmt.Sprintf("<!-- progress: %s -->\n\n", b.Content))
md.WriteString(fmt.Sprintf("%s- <!-- progress: %s -->\n", indent, b.Content))
default:
md.WriteString(b.Content + "\n\n")
md.WriteString(fmt.Sprintf("%s- %s\n", indent, b.Content))
}
}
} else if doc.Content != "" {
@@ -1683,10 +1684,18 @@ func (s *Store) GetTaskLists(userID string) ([]domain.TaskList, error) {
_ = rows.Close()
for i := range list {
list[i].Members = make([]domain.SpaceMember, 0)
_ = s.db.QueryRow(
`SELECT COUNT(*) FROM thoughts WHERE task_list_id = ? AND is_completed = 0 AND (status = 'kept' OR (status = 'converted' AND converted_type = 'task'))`,
list[i].ID,
).Scan(&list[i].TasksCount)
_ = s.db.QueryRow(`SELECT display_name FROM users WHERE id = ?`, list[i].UserID).Scan(&list[i].OwnerName)
if list[i].SpaceID != "" {
_ = s.db.QueryRow(`SELECT name FROM spaces WHERE id = ?`, list[i].SpaceID).Scan(&list[i].SpaceName)
if members, err := s.GetSpaceMembers(list[i].SpaceID); err == nil && members != nil {
list[i].Members = members
}
}
}
return list, nil
}
@@ -1701,7 +1710,15 @@ func (s *Store) GetTaskListByID(userID, listID string) (*domain.TaskList, error)
if err != nil {
return nil, err
}
tl.Members = make([]domain.SpaceMember, 0)
_ = s.db.QueryRow(`SELECT COUNT(*) FROM thoughts WHERE task_list_id = ? AND is_completed = 0 AND (status = 'kept' OR (status = 'converted' AND converted_type = 'task'))`, tl.ID).Scan(&tl.TasksCount)
_ = s.db.QueryRow(`SELECT display_name FROM users WHERE id = ?`, tl.UserID).Scan(&tl.OwnerName)
if tl.SpaceID != "" {
_ = s.db.QueryRow(`SELECT name FROM spaces WHERE id = ?`, tl.SpaceID).Scan(&tl.SpaceName)
if members, err := s.GetSpaceMembers(tl.SpaceID); err == nil && members != nil {
tl.Members = members
}
}
return &tl, nil
}
@@ -1730,7 +1747,7 @@ func (s *Store) UpdateTaskList(userID, listID string, title, icon, color, spaceI
if err != nil {
return nil, err
}
return tl, nil
return s.GetTaskListByID(userID, listID)
}
func (s *Store) DeleteTaskList(userID, listID string) error {