From 85ae67b72f80a3a93a39f1e3b1176b7fa0b167af Mon Sep 17 00:00:00 2001 From: Stephan Richter Date: Wed, 13 Aug 2025 01:28:21 +0200 Subject: [PATCH] fine-tuning notes in preparation for release Signed-off-by: Stephan Richter --- .../srsoftware/umbrella/core/model/Note.java | 4 +- frontend/src/App.svelte | 2 +- frontend/src/routes/company/Index.svelte | 2 +- frontend/src/routes/document/View.svelte | 2 +- frontend/src/routes/notes/Index.svelte | 83 ++++++++++++++++ frontend/src/routes/notes/List.svelte | 73 ++++---------- frontend/src/routes/notes/RelatedNotes.svelte | 99 +++++++++++++++++++ frontend/src/routes/project/View.svelte | 2 +- frontend/src/routes/task/View.svelte | 2 +- .../srsoftware/umbrella/notes/NoteModule.java | 49 ++++++--- .../de/srsoftware/umbrella/notes/NotesDb.java | 2 +- .../srsoftware/umbrella/notes/SqliteDb.java | 5 +- 12 files changed, 246 insertions(+), 79 deletions(-) create mode 100644 frontend/src/routes/notes/Index.svelte create mode 100644 frontend/src/routes/notes/RelatedNotes.svelte diff --git a/core/src/main/java/de/srsoftware/umbrella/core/model/Note.java b/core/src/main/java/de/srsoftware/umbrella/core/model/Note.java index 582fb66..e00b285 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/model/Note.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/model/Note.java @@ -11,12 +11,12 @@ import java.sql.SQLException; import java.time.LocalDateTime; import java.util.Map; -public record Note(long id, String module, long entityId, long authorId, String text, LocalDateTime timestamp) implements Mappable { +public record Note(long id, String module, String entityId, long authorId, String text, LocalDateTime timestamp) implements Mappable { public static Note of(ResultSet rs) throws SQLException { return new Note( rs.getLong(ID), rs.getString(MODULE), - rs.getLong(ENTITY_ID), + rs.getString(ENTITY_ID), rs.getLong(USER_ID), rs.getString(NOTE), LocalDateTime.ofEpochSecond(rs.getLong(TIMESTAMP),0, UTC) diff --git a/frontend/src/App.svelte b/frontend/src/App.svelte index 6b7144a..8d827fa 100644 --- a/frontend/src/App.svelte +++ b/frontend/src/App.svelte @@ -19,7 +19,7 @@ import Login from "./Components/Login.svelte"; import Messages from "./routes/message/Messages.svelte"; import Menu from "./Components/Menu.svelte"; - import Notes from "./routes/notes/List.svelte"; + import Notes from "./routes/notes/Index.svelte"; import ProjectList from "./routes/project/List.svelte"; import ProjectAdd from "./routes/project/Create.svelte"; import ResetPw from "./routes/user/ResetPw.svelte"; diff --git a/frontend/src/routes/company/Index.svelte b/frontend/src/routes/company/Index.svelte index 5955ec8..6c7acda 100644 --- a/frontend/src/routes/company/Index.svelte +++ b/frontend/src/routes/company/Index.svelte @@ -5,7 +5,7 @@ import Editor from './Editor.svelte'; import LineEditor from '../../Components/LineEditor.svelte'; - import Notes from '../notes/List.svelte'; + import Notes from '../notes/RelatedNotes.svelte'; let error = $state(null); let companies = $state(null); diff --git a/frontend/src/routes/document/View.svelte b/frontend/src/routes/document/View.svelte index 9df5774..505f8c4 100644 --- a/frontend/src/routes/document/View.svelte +++ b/frontend/src/routes/document/View.svelte @@ -9,7 +9,7 @@ import LineEditor from '../../Components/LineEditor.svelte'; import MarkdownEditor from '../../Components/MarkdownEditor.svelte'; import MultilineEditor from '../../Components/MultilineEditor.svelte'; - import Notes from '../notes/List.svelte'; + import Notes from '../notes/RelatedNotes.svelte'; import PositionList from './PositionList.svelte'; import PositionSelector from './PositionSelector.svelte'; import StateSelector from './StateSelector.svelte'; diff --git a/frontend/src/routes/notes/Index.svelte b/frontend/src/routes/notes/Index.svelte new file mode 100644 index 0000000..161ea5e --- /dev/null +++ b/frontend/src/routes/notes/Index.svelte @@ -0,0 +1,83 @@ + + + +{#if error} +{error} +{/if} + diff --git a/frontend/src/routes/notes/List.svelte b/frontend/src/routes/notes/List.svelte index ff62a73..3ff13d2 100644 --- a/frontend/src/routes/notes/List.svelte +++ b/frontend/src/routes/notes/List.svelte @@ -1,5 +1,4 @@ -{#if error} -{error} -{/if} {#if notes} -{#each Object.entries(notes) as [nid,note]} +{#each notes as note (note.id)}
{#if module} {authors[note.user_id].name} {:else} - goToEntity(note)}>{t(note.module)} {note.entity_id} + goToEntity(note)}>{title(note)} {/if} {note.timestamp.replace('T',' ')} {#if user.id == note.user_id} - + {/if} - update(nid,newVal)} editable={user.id == note.user_id} /> + update(note.id,newVal)} editable={user.id == note.user_id} />
{/each} -{/if} -
- - -
\ No newline at end of file +{/if} \ No newline at end of file diff --git a/frontend/src/routes/notes/RelatedNotes.svelte b/frontend/src/routes/notes/RelatedNotes.svelte new file mode 100644 index 0000000..ec5c5f1 --- /dev/null +++ b/frontend/src/routes/notes/RelatedNotes.svelte @@ -0,0 +1,99 @@ + + +{#if error} +{error} +{/if} + +
+ + +
\ No newline at end of file diff --git a/frontend/src/routes/project/View.svelte b/frontend/src/routes/project/View.svelte index c553719..bfb6f27 100644 --- a/frontend/src/routes/project/View.svelte +++ b/frontend/src/routes/project/View.svelte @@ -8,7 +8,7 @@ import LineEditor from '../../Components/LineEditor.svelte'; import MarkdownEditor from '../../Components/MarkdownEditor.svelte'; import PermissionEditor from '../../Components/PermissionEditor.svelte'; - import Notes from '../notes/List.svelte'; + import Notes from '../notes/RelatedNotes.svelte'; import StateSelector from '../../Components/StateSelector.svelte'; import Tags from '../tags/TagList.svelte'; import TaskList from '../task/TaskList.svelte'; diff --git a/frontend/src/routes/task/View.svelte b/frontend/src/routes/task/View.svelte index af4e9b1..e889c88 100644 --- a/frontend/src/routes/task/View.svelte +++ b/frontend/src/routes/task/View.svelte @@ -8,7 +8,7 @@ import LineEditor from '../../Components/LineEditor.svelte'; import MarkdownEditor from '../../Components/MarkdownEditor.svelte'; import PermissionEditor from '../../Components/PermissionEditor.svelte'; - import Notes from '../notes/List.svelte'; + import Notes from '../notes/RelatedNotes.svelte'; import StateSelector from '../../Components/StateSelector.svelte'; import TagList from '../tags/TagList.svelte'; import TaskList from './TaskList.svelte'; diff --git a/notes/src/main/java/de/srsoftware/umbrella/notes/NoteModule.java b/notes/src/main/java/de/srsoftware/umbrella/notes/NoteModule.java index 6321db3..1cd1008 100644 --- a/notes/src/main/java/de/srsoftware/umbrella/notes/NoteModule.java +++ b/notes/src/main/java/de/srsoftware/umbrella/notes/NoteModule.java @@ -2,6 +2,8 @@ package de.srsoftware.umbrella.notes; import static de.srsoftware.umbrella.core.ConnectionProvider.connect; +import static de.srsoftware.umbrella.core.Constants.LIMIT; +import static de.srsoftware.umbrella.core.Constants.OFFSET; import static de.srsoftware.umbrella.core.ResponseCode.HTTP_UNPROCESSABLE; import static de.srsoftware.umbrella.core.Util.mapValues; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*; @@ -74,15 +76,10 @@ public class NoteModule extends BaseHandler implements NoteService { var user = registry.userService().refreshSession(ex); if (user.isEmpty()) return unauthorized(ex); var module = path.pop(); - Map notes = null; - if (module == null) { - notes = notesDb.list(user.get().id()); - } else { - var head = path.pop(); - notes = getNotes(module, head); - } - var authors = notes.values().stream().map(Note::authorId).distinct().map(registry.userService()::loadUser).collect(Collectors.toMap(UmbrellaUser::id,UmbrellaUser::toMap)); - return sendContent(ex, Map.of("notes",mapValues(notes),"authors",authors)); + return switch (module){ + case null -> sendContent(ex,getUserNotes(ex,user.get())); + default -> sendContent(ex,getEntityNotes(module,path.pop())); + }; } catch (NumberFormatException e){ return sendContent(ex,HTTP_UNPROCESSABLE,"Entity id missing in path."); } catch (UmbrellaException e){ @@ -90,6 +87,28 @@ public class NoteModule extends BaseHandler implements NoteService { } } + private boolean getUserNotes(HttpExchange ex, UmbrellaUser user) throws IOException { + var param = queryParam(ex); + long offset = switch (param.get(OFFSET)){ + case String s -> Long.parseLong(s); + case Number n -> n.longValue(); + case null, default -> 0; + }; + long limit = switch (param.get(LIMIT)){ + case String s -> Long.parseLong(s); + case Number n -> n.longValue(); + case null, default -> 100; + }; + + var notes = notesDb.list(user.id(),offset,limit); + return sendContent(ex,addUsers(notes)); + } + + private Map addUsers(Map notes) { + var authors = notes.values().stream().map(Note::authorId).distinct().map(registry.userService()::loadUser).collect(Collectors.toMap(UmbrellaUser::id,UmbrellaUser::toMap)); + return Map.of("notes",mapValues(notes),"authors",authors); + } + @Override public boolean doPatch(Path path, HttpExchange ex) throws IOException { addCors(ex); @@ -122,8 +141,7 @@ public class NoteModule extends BaseHandler implements NoteService { if (user.isEmpty()) return unauthorized(ex); var module = path.pop(); if (module == null) throw unprocessable("Module missing in path."); - var head = path.pop(); - long entityId = Long.parseLong(head); + var entityId = path.pop(); String text = body(ex); if (text.isBlank()) throw missingFieldException("Note text"); var note = new Note(0,module,entityId,user.get().id(),text, LocalDateTime.now()); @@ -136,8 +154,13 @@ public class NoteModule extends BaseHandler implements NoteService { } } - public Map getNotes(String module, String entityId) throws UmbrellaException{ - return notesDb.list(module,entityId); + public Map getEntityNotes(String module, String entityId) throws UmbrellaException{ + return addUsers(getNotes(module, entityId)); + } + + @Override + public Map getNotes(String module, String entityId) throws UmbrellaException { + return notesDb.list(module, entityId); } @Override diff --git a/notes/src/main/java/de/srsoftware/umbrella/notes/NotesDb.java b/notes/src/main/java/de/srsoftware/umbrella/notes/NotesDb.java index 0583d7e..680e01e 100644 --- a/notes/src/main/java/de/srsoftware/umbrella/notes/NotesDb.java +++ b/notes/src/main/java/de/srsoftware/umbrella/notes/NotesDb.java @@ -13,7 +13,7 @@ public interface NotesDb { * get all lists of a person * @return */ - Map list(long authorId); + Map list(long authorId, long offset, long limit); /** * get the notes related to a specific entity diff --git a/notes/src/main/java/de/srsoftware/umbrella/notes/SqliteDb.java b/notes/src/main/java/de/srsoftware/umbrella/notes/SqliteDb.java index 6ac5780..430d334 100644 --- a/notes/src/main/java/de/srsoftware/umbrella/notes/SqliteDb.java +++ b/notes/src/main/java/de/srsoftware/umbrella/notes/SqliteDb.java @@ -167,10 +167,11 @@ CREATE TABLE IF NOT EXISTS "{0}" ( } @Override - public Map list(long authorId) { + public Map list(long authorId, long offset, long limit) { try { var notes = new HashMap(); - var rs = select(ALL).from(TABLE_NOTES).where(USER_ID,equal(authorId)).exec(db); + var rs = select(ALL).from(TABLE_NOTES).where(USER_ID,equal(authorId)) + .sort(format("{0} DESC",ID)).skip(offset).limit(limit).exec(db); while (rs.next()) { var note = Note.of(rs); notes.put(note.id(),note);