131 lines
3.5 KiB
Svelte
131 lines
3.5 KiB
Svelte
<script>
|
|
import { api, get, post } from '../../urls.svelte';
|
|
import { error, yikes } from '../../warn.svelte';
|
|
import { t } from '../../translations.svelte';
|
|
|
|
import LineEditor from '../../Components/LineEditor.svelte';
|
|
|
|
let {
|
|
drag_start = loc => console.log({dragging:loc}),
|
|
locations,
|
|
move_dragged_to = new_loc => {},
|
|
parent = null,
|
|
selected = $bindable(null)
|
|
} = $props();
|
|
|
|
let show_location_form = $state(false);
|
|
let new_location_name = $state(null);
|
|
let highlight = $state(null);
|
|
|
|
function drag_over(ev,location){
|
|
ev.stopPropagation();
|
|
ev.preventDefault();
|
|
location.highlight = true;
|
|
return false;
|
|
}
|
|
|
|
function start_drag(e,loc){
|
|
e.stopPropagation();
|
|
drag_start(loc)
|
|
}
|
|
|
|
function flat(x){
|
|
return JSON.parse(JSON.stringify(x));
|
|
}
|
|
|
|
async function toggleChildren(ev, location){
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
selected = location;
|
|
if (location.locations) {
|
|
delete location.locations;
|
|
} else {
|
|
const url = api(`stock/locations/below/${location.id}`);
|
|
const res = await get(url);
|
|
if (res.ok){
|
|
yikes();
|
|
location.locations = await res.json();
|
|
} else error(res);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function reset(){
|
|
new_location_name = '';
|
|
}
|
|
|
|
function onDrop(ev, new_loc){
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
move_dragged_to(new_loc);
|
|
return false;
|
|
}
|
|
|
|
async function onSet(new_location_name){
|
|
const data = {
|
|
name: new_location_name,
|
|
parent: parent
|
|
}
|
|
const url = api('stock/location');
|
|
const res = await post(url,data);
|
|
if (res.ok){
|
|
yikes;
|
|
const saved = await res.json();
|
|
locations.push(saved);
|
|
show_location_form = false;
|
|
setTimeout(reset,500);
|
|
return true;
|
|
} else {
|
|
error(res);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function onsubmit(ev){
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
|
|
const data = {
|
|
name: new_location_name,
|
|
parent: parent
|
|
}
|
|
}
|
|
|
|
function show_loc_form(ev){
|
|
ev.preventDefault();
|
|
ev.stopPropagation();
|
|
show_location_form = true;
|
|
return false;
|
|
}
|
|
</script>
|
|
|
|
<ul>
|
|
{#each locations as location}
|
|
<li onclick={e => toggleChildren(e, location)}
|
|
class="{location.locations?'expanded':'collapsed'} {location.highlight?'highlight':null}"
|
|
draggable={true}
|
|
ondragover={e => drag_over(e,location)}
|
|
ondrop={e => onDrop(e,location)}
|
|
ondragleave={e => delete location.highlight}
|
|
ondragstart={e => start_drag(e,location)} >
|
|
<span class="name">{location.name}</span>
|
|
{#if location.locations}
|
|
<svelte:self locations={location.locations} {drag_start} {move_dragged_to} parent={{location:location.id}} bind:selected />
|
|
{/if}
|
|
</li>
|
|
{/each}
|
|
<li>
|
|
{#if show_location_form}
|
|
<form {onsubmit}>
|
|
<LineEditor simple={true} bind:value={new_location_name} {onSet} />
|
|
</form>
|
|
{:else}
|
|
<a onclick={show_loc_form}>
|
|
<span class="symbol"></span> {t('add_object',{object:t('location')})}
|
|
</a>
|
|
{/if}
|
|
|
|
</li>
|
|
</ul>
|
|
<!-- <pre>{JSON.stringify(parent,null,2)}</pre> -->
|