completed autocomplete box in permission editor for projects
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -9,11 +9,11 @@
|
||||
onSelect = dummyOnSelect,
|
||||
} = $props();
|
||||
|
||||
const ignore = ['Escape','Tab','ArrowUp','ArrowLeft','ArrowRight'];
|
||||
const ignore = ['ArrowLeft','ArrowRight'];
|
||||
let candidate = $state({ display : '' });
|
||||
let selected = $state([]);
|
||||
let candidates = $derived(getCandidates(candidate.display));
|
||||
|
||||
|
||||
async function dummyGetCandidates(text){
|
||||
console.warn(`getCandidates(${text}) not overridden!`);
|
||||
if (!text) return [];
|
||||
@@ -35,7 +35,7 @@
|
||||
// if Enter is pressed on the input field, this method gets called with
|
||||
// either the selected candidate or
|
||||
// an anonymous object with the entered text in the display field
|
||||
console.warn('onCommit not overridden!');
|
||||
console.warn(`onCommit(${JSON.stringify(candidate)}) not overridden!`);
|
||||
}
|
||||
|
||||
function dummyOnSelect(candidate){
|
||||
@@ -43,31 +43,63 @@
|
||||
}
|
||||
|
||||
async function onkeyup(ev){
|
||||
const select = ev.target;
|
||||
const key = ev.key;
|
||||
if (ignore.includes(key)) return;
|
||||
if (ignore.includes(ev.key)) return;
|
||||
if (ev.key == 'ArrowDown'){
|
||||
ev.preventDefault();
|
||||
selected = selected.length < 1 ? [0] : [selected[0]+1]
|
||||
if (selected[0] >= candidates.length) selected = [0];
|
||||
return false;
|
||||
}
|
||||
if (ev.key == 'ArrowUp'){
|
||||
ev.preventDefault();
|
||||
selected = selected.length < 1 ? [-1] : [selected[0]-1]
|
||||
if (selected[0] < 0) selected = [candidates.length-1];
|
||||
return false;
|
||||
}
|
||||
if (ev.key == 'Enter'|| ev.key == 'Tab'){
|
||||
ev.preventDefault();
|
||||
if (selected.length>0) {
|
||||
candidate = candidates[selected[0]];
|
||||
candidates = [];
|
||||
selected = [];
|
||||
onSelect(candidate);
|
||||
return false;
|
||||
}
|
||||
if (ev.key == 'Enter') {
|
||||
candidates = [];
|
||||
selected = [];
|
||||
onCommit(candidate);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (ev.key == 'Escape'){
|
||||
ev.preventDefault();
|
||||
candidates = [];
|
||||
selected = [];
|
||||
return false;
|
||||
}
|
||||
|
||||
candidates = await getCandidates(candidate.display);
|
||||
if (selected>candidates.length) selected = candidates.length;
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
div { position : relative }
|
||||
select { position : absolute; top: 30px; left: 3px; }
|
||||
|
||||
select { background: black; color: orange; border: 1px solid orange; border-radius: 5px; }
|
||||
option:checked { background: orange; color: black; }
|
||||
</style>
|
||||
|
||||
<div>
|
||||
<input type="text" bind:value={candidate.display} {onkeyup} />
|
||||
{#if candidates && candidates.length > 1}
|
||||
<select multiple>
|
||||
{#each candidates as candidate (candidate.display)}
|
||||
<option value={candidate}>{candidate.display}</option>
|
||||
{#if candidates && candidates.length > 0}
|
||||
<select bind:value={selected} multiple tabindex="-1">
|
||||
{#each candidates as candidate,i}
|
||||
<option value={i}>{candidate.display}</option>
|
||||
{/each}
|
||||
</select>
|
||||
{/if}
|
||||
</div>
|
||||
{#if candidates}
|
||||
<pre>
|
||||
{JSON.stringify(candidates,null,2)}
|
||||
</pre>
|
||||
{/if}
|
||||
{JSON.stringify(candidate)}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import { api } from '../urls.svelte';
|
||||
import { api, get, post } from '../urls.svelte';
|
||||
import { t } from '../translations.svelte';
|
||||
import { error, yikes } from '../warn.svelte';
|
||||
|
||||
import Autocomplete from './Autocomplete.svelte';
|
||||
import PermissionSelector from './PermissionSelector.svelte';
|
||||
@@ -27,7 +28,7 @@
|
||||
});
|
||||
if (resp.ok){
|
||||
var json = await resp.json();
|
||||
return Object.fromEntries(Object.values(json).map(user => [user.id,user.name]));
|
||||
return Object.values(json).map(user => { return {id:user.id,name:user.name,display:user.name}; });
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
@@ -35,12 +36,10 @@
|
||||
|
||||
async function loadPermissions(){
|
||||
const url = api('task/permissions');
|
||||
const resp = await fetch(url,{credentials: 'include'});
|
||||
const resp = await get(url);
|
||||
if (resp.ok){
|
||||
permissions = await resp.json();
|
||||
} else {
|
||||
message = await resp.text();
|
||||
}
|
||||
} else error(resp);
|
||||
}
|
||||
|
||||
function onSelect(entry){
|
||||
@@ -66,7 +65,7 @@
|
||||
<tr>
|
||||
<td>{t('add_object',{object:t('member')})}</td>
|
||||
<td>
|
||||
<Autocomplete />
|
||||
<Autocomplete {getCandidates} {onSelect} />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
@@ -28,9 +28,8 @@
|
||||
let new_state = $state({code:null,name:null})
|
||||
let state_available=$derived(new_state.name && new_state.code && !project.allowed_states[new_state.code]);
|
||||
|
||||
async function addMember(entry){
|
||||
const ids = Object.keys(entry);
|
||||
if (ids) update({new_member:+ids.pop()});
|
||||
async function addMember(user){
|
||||
update({new_member:+user.id});
|
||||
}
|
||||
|
||||
async function addState(){
|
||||
@@ -67,21 +66,6 @@
|
||||
update({drop_member:member.user.id});
|
||||
}
|
||||
|
||||
async function getCandidates(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 [];
|
||||
}
|
||||
}
|
||||
|
||||
function handleCreate(evt){
|
||||
let json = JSON.parse(evt.data);
|
||||
json.event = 'create';
|
||||
@@ -242,7 +226,7 @@
|
||||
</label>
|
||||
<div class="em">{t('members')}</div>
|
||||
<div class="em">
|
||||
<PermissionEditor members={project.members} {updatePermission} {addMember} {dropMember} {getCandidates} />
|
||||
<PermissionEditor members={project.members} {updatePermission} {addMember} {dropMember} />
|
||||
</div>
|
||||
{#if project.allowed_states}
|
||||
{#each Object.keys(project.allowed_states) as key,idx}
|
||||
|
||||
Reference in New Issue
Block a user