diff --git a/core/src/main/java/de/srsoftware/umbrella/core/Constants.java b/core/src/main/java/de/srsoftware/umbrella/core/Constants.java index 8218b81..6f85ae7 100644 --- a/core/src/main/java/de/srsoftware/umbrella/core/Constants.java +++ b/core/src/main/java/de/srsoftware/umbrella/core/Constants.java @@ -51,10 +51,13 @@ public class Constants { public static final String LOGIN = "login"; public static final String MEMBERS = "members"; public static final String MESSAGES = "messages"; + public static final String NAME = "name"; + public static final String NEW_MEMBER = "new_member"; public static final String MIME = "mime"; public static final String NO_INDEX = "no_index"; public static final String NUMBER = "number"; + public static final String OPTIONAL = "optional"; public static final String PARENT_TASK_ID = "parent_task_id"; public static final String PASS = "pass"; diff --git a/frontend/src/Components/Autocomplete.svelte b/frontend/src/Components/Autocomplete.svelte index a0b61dd..7fb0403 100644 --- a/frontend/src/Components/Autocomplete.svelte +++ b/frontend/src/Components/Autocomplete.svelte @@ -7,6 +7,16 @@ let text = $state('') let options = $state({}); + async function ondblclick(evt){ + var select = evt.target; + let key = select.value; + text = options[key]; + let result = {}; + result[key]=text; + options={}; + onSelect(result); + } + async function onkeyup(evt){ var select = evt.target; var key = evt.key; @@ -17,12 +27,7 @@ return; } if (key == 'Enter'){ - let key = select.value; - text = options[key]; - let result = {}; - result[key]=text; - options={}; - onSelect(result); + ondblclick(evt); return; } if (key == 'Backspace'){ @@ -41,7 +46,7 @@ min-width: 200px; } - {#each Object.entries(options) as [val,caption]} diff --git a/frontend/src/Components/MemberEditor.svelte b/frontend/src/Components/MemberEditor.svelte index 652601b..5e3f3de 100644 --- a/frontend/src/Components/MemberEditor.svelte +++ b/frontend/src/Components/MemberEditor.svelte @@ -3,7 +3,11 @@ import { t } from '../translations.svelte.js'; import Autocomplete from './Autocomplete.svelte'; import PermissionSelector from './PermissionSelector.svelte'; - let { members, updatePermission = (uid,perm) => console.log({user:uid,perm:perm}) } = $props(); + let { + members, + updatePermission = (uid,perm) => console.log(`no handler for updatePermission(${uid}, ${perm})`), + addMember = (entry) => console.log(`no handler for addMember(${entry})`) + } = $props(); let error = $state(null); let sortedMembers = $derived.by(() => Object.values(members).sort((a, b) => a.user.name.localeCompare(b.user.name))); @@ -34,8 +38,8 @@ } } - function onSelect(name){ - console.log({selected_user:name}) + function onSelect(entry){ + addMember(entry); } onMount(loadPermissions); diff --git a/frontend/src/routes/project/View.svelte b/frontend/src/routes/project/View.svelte index c776b10..2e0d780 100644 --- a/frontend/src/routes/project/View.svelte +++ b/frontend/src/routes/project/View.svelte @@ -14,6 +14,12 @@ let estimated_time = $state({sum:0}); let showSettings = $state(false); + async function addMember(entry){ + const ids = Object.keys(entry); + console.log({entry:entry,ids:ids}); + if (ids) update({new_member:+ids.pop()}); + } + async function loadProject(){ const url = `${location.protocol}//${location.host.replace('5173','8080')}/api/project/${id}`; const resp = await fetch(url,{credentials:'include'}); @@ -125,6 +131,6 @@ {#if showSettings}
{t('settings')} - +
{/if} \ No newline at end of file diff --git a/project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java b/project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java index d53c2c2..7421692 100644 --- a/project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java +++ b/project/src/main/java/de/srsoftware/umbrella/project/ProjectModule.java @@ -6,8 +6,7 @@ import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Paths.LIST; import static de.srsoftware.umbrella.core.Util.mapValues; import static de.srsoftware.umbrella.core.exceptions.UmbrellaException.*; -import static de.srsoftware.umbrella.core.model.Permission.EDIT; -import static de.srsoftware.umbrella.core.model.Permission.OWNER; +import static de.srsoftware.umbrella.core.model.Permission.*; import static de.srsoftware.umbrella.core.model.Status.OPEN; import static de.srsoftware.umbrella.project.Constants.CONFIG_DATABASE; import static java.lang.Boolean.TRUE; @@ -41,6 +40,14 @@ public class ProjectModule extends BaseHandler implements ProjectService { users = companies.userService(); } + private void addMember(Project project, long userId) { + var user = users.loadUser(userId); + var member = new Member(user,READ_ONLY); + project.members().put(userId,member); + project.dirtyFields().add(MEMBERS); + } + + @Override public CompanyService companyService() { return companies; @@ -188,12 +195,14 @@ public class ProjectModule extends BaseHandler implements ProjectService { if (!project.hasMember(user)) throw forbidden("You are not a member of {0}",project.name()); var json = json(ex); if (json.has(MEMBERS) && json.get(MEMBERS) instanceof JSONObject memberJson) patchMembers(project,memberJson); + if (json.has(NEW_MEMBER) && json.get(NEW_MEMBER) instanceof Number num) addMember(project,num.longValue()); projects.save(project.patch(json)); return sendContent(ex,project.toMap()); } + private boolean postProject(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException { var json = json(ex); if (!(json.has(NAME) && json.get(NAME) instanceof String name)) throw missingFieldException(NAME);