74 lines
2.3 KiB
Svelte
74 lines
2.3 KiB
Svelte
<script>
|
|
import { onMount } from 'svelte';
|
|
|
|
import { api } from '../urls.svelte';
|
|
import { t } from '../translations.svelte';
|
|
|
|
import Autocomplete from './Autocomplete.svelte';
|
|
import PermissionSelector from './PermissionSelector.svelte';
|
|
|
|
let {
|
|
addMember = (entry) => console.log(`no handler for addMember(${entry})`),
|
|
dropMember = (member) => console.log(`no handler for dropMember(${member})`),
|
|
getCandidates = defaultGetCandidates,
|
|
members,
|
|
updatePermission = (uid,perm) => console.log(`no handler for updatePermission(${uid}, ${perm})`)
|
|
} = $props();
|
|
|
|
let permissions = $state(null);
|
|
let sortedMembers = $derived.by(() => Object.values(members).sort((a, b) => a.user.name.localeCompare(b.user.name)));
|
|
|
|
async function defaultGetCandidates(text){
|
|
const url = api('user/search');
|
|
const resp = await fetch(url,{
|
|
credentials : 'include',
|
|
method : 'POST',
|
|
body : text
|
|
});
|
|
if (resp.ok){
|
|
var json = await resp.json();
|
|
return Object.fromEntries(Object.values(json).map(user => [user.id,user.name]));
|
|
} else {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
async function loadPermissions(){
|
|
const url = api('task/permissions');
|
|
const resp = await fetch(url,{credentials: 'include'});
|
|
if (resp.ok){
|
|
permissions = await resp.json();
|
|
} else {
|
|
message = await resp.text();
|
|
}
|
|
}
|
|
|
|
function onSelect(entry){
|
|
addMember(entry);
|
|
}
|
|
|
|
onMount(loadPermissions);
|
|
</script>
|
|
|
|
<table>
|
|
<tbody>
|
|
{#each sortedMembers as member (member.user.id)}
|
|
<tr>
|
|
<td>{member.user.name}</td>
|
|
<td>
|
|
<PermissionSelector {permissions} selected={member.permission.code} onchange={(perm) => updatePermission(member.user.id,perm)} />
|
|
{#if member.permission.name != 'OWNER'}
|
|
<button onclick={() => dropMember(member)}>x</button>
|
|
{/if}
|
|
</td>
|
|
</tr>
|
|
{/each}
|
|
<tr>
|
|
<td>{t('add_object',{object:t('member')})}</td>
|
|
<td>
|
|
<Autocomplete {getCandidates} {onSelect} />
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|