feat(workspace): bring an extracted note back into the bullet
A bullet that is only a link to a note (as left by /extract) gets a
"Notiz zurückholen" button. POST /documents/{id}/inline returns the
linked note's blocks with fresh ids and trashes the note; the editor
puts the title back as text and inserts the blocks as an own edit, so
Strg+Z restores the link and the note. Only own notes that no other
note links to. Release 0.52.0.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
75aea4a7d4
commit
39a04082fc
15 files changed
+293
-11
No files matched your search
@@ -24,14 +24,16 @@ func (s *Server) restructureActor(r *http.Request, clientID string) collab.Actor
|
||||
}
|
||||
|
||||
func restructureStatus(err error) int {
|
||||
var stillLinked *storage.StillLinkedError
|
||||
switch {
|
||||
case errors.Is(err, storage.ErrBranchLocked):
|
||||
case errors.Is(err, storage.ErrBranchLocked), errors.As(err, &stillLinked):
|
||||
return http.StatusConflict
|
||||
case errors.Is(err, storage.ErrBlockNotFound), errors.Is(err, storage.ErrDocNotFound):
|
||||
case errors.Is(err, storage.ErrBlockNotFound), errors.Is(err, storage.ErrDocNotFound), errors.Is(err, storage.ErrLinkedMissing):
|
||||
return http.StatusNotFound
|
||||
case errors.Is(err, storage.ErrMergeSelf), errors.Is(err, storage.ErrDocInTrash), errors.Is(err, storage.ErrAlreadyNote):
|
||||
case errors.Is(err, storage.ErrMergeSelf), errors.Is(err, storage.ErrDocInTrash), errors.Is(err, storage.ErrAlreadyNote),
|
||||
errors.Is(err, storage.ErrNotNoteLink):
|
||||
return http.StatusBadRequest
|
||||
case errors.Is(err, storage.ErrMergeNotOwner):
|
||||
case errors.Is(err, storage.ErrMergeNotOwner), errors.Is(err, storage.ErrInlineOwner):
|
||||
return http.StatusForbidden
|
||||
}
|
||||
return http.StatusInternalServerError
|
||||
@@ -80,6 +82,34 @@ func (s *Server) handleUndoExtract(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, http.StatusOK, map[string]bool{"undone": true})
|
||||
}
|
||||
|
||||
// handleInlineNote: POST /documents/{id}/inline {blockId} – the way back from extracting: returns the
|
||||
// linked note's blocks for the bullet and puts that note into the trash (undo: POST /documents/{note}/restore).
|
||||
func (s *Server) handleInlineNote(w http.ResponseWriter, r *http.Request) {
|
||||
userID := auth.GetUserID(r.Context())
|
||||
docID := chi.URLParam(r, "id")
|
||||
if !storage.CanEditDoc(s.store.DocRole(userID, docID)) {
|
||||
writeError(w, http.StatusForbidden, "Keine Schreibrechte für diese Notiz")
|
||||
return
|
||||
}
|
||||
var req struct {
|
||||
BlockID string `json:"blockId"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil || req.BlockID == "" {
|
||||
writeError(w, http.StatusBadRequest, "blockId fehlt")
|
||||
return
|
||||
}
|
||||
res, err := s.store.InlineNote(userID, docID, req.BlockID)
|
||||
if err != nil {
|
||||
writeError(w, restructureStatus(err), err.Error())
|
||||
return
|
||||
}
|
||||
users, _ := s.store.GetAuthorizedDocUsers(res.SourceID)
|
||||
for _, uid := range users {
|
||||
s.wsHub.BroadcastToUser(uid, "DOC_DELETED", map[string]string{"id": res.SourceID})
|
||||
}
|
||||
writeJSON(w, http.StatusOK, res)
|
||||
}
|
||||
|
||||
// handleMergeDocuments: POST /documents/{id}/merge {sourceId, clientId} appends the source to this note.
|
||||
func (s *Server) handleMergeDocuments(w http.ResponseWriter, r *http.Request) {
|
||||
userID := auth.GetUserID(r.Context())
|
||||
|
||||
Reference in new issue
Block a user