Browse Source

preparing moving of locations

module/document
Stephan Richter 2 weeks ago
parent
commit
7b259e7425
  1. 5
      core/src/main/java/de/srsoftware/umbrella/core/model/DbLocation.java
  2. 25
      frontend/src/routes/stock/Index.svelte
  3. 14
      frontend/src/routes/stock/Locations.svelte
  4. 1
      stock/src/main/java/de/srsoftware/umbrella/stock/Constants.java
  5. 2
      stock/src/main/java/de/srsoftware/umbrella/stock/SqliteDb.java
  6. 2
      stock/src/main/java/de/srsoftware/umbrella/stock/StockDb.java
  7. 23
      stock/src/main/java/de/srsoftware/umbrella/stock/StockModule.java

5
core/src/main/java/de/srsoftware/umbrella/core/model/DbLocation.java

@ -43,6 +43,11 @@ public class DbLocation extends Location {
return parentLocationId; return parentLocationId;
} }
public DbLocation parent(DbLocation newParent) {
parentLocationId = newParent.id();
return this;
}
@Override @Override
public DbLocation resolve() { public DbLocation resolve() {
return this; return this;

25
frontend/src/routes/stock/Index.svelte

@ -14,6 +14,7 @@
let item = $state(null); let item = $state(null);
let location = $state(null); let location = $state(null);
let draggedItem = $state(null) let draggedItem = $state(null)
let draggedLocation = $state(null)
$effect(() => { $effect(() => {
// This effect runs whenever `location` changes // This effect runs whenever `location` changes
@ -37,6 +38,16 @@
} else error(res); } else error(res);
} }
function drag_item(item){
draggedLocation = null;
draggedItem = item;
}
function drag_location(loc){
draggedItem = null;
draggedLocation = loc;
}
function dropNestedLocation(locations,loc){ function dropNestedLocation(locations,loc){
for (let [idx,entry] of locations.entries()){ for (let [idx,entry] of locations.entries()){
if (entry.id == loc.id){ if (entry.id == loc.id){
@ -49,8 +60,9 @@
} }
async function move_dragged_to(new_loc){ async function move_dragged_to(new_loc){
const data = { item : draggedItem.id, target: new_loc.id }; console.log({move_dragged_to:JSON.parse(JSON.stringify(new_loc))});
const url = api('stock/move_item'); const data = draggedItem ? { item : draggedItem.id, target: new_loc.id } : { location : draggedLocation.id, target: new_loc.id }
const url = api(draggedItem ? 'stock/move_item' : 'stock/move_location');
const res = await fetch(url,{ const res = await fetch(url,{
credentials : 'include', credentials : 'include',
method : 'PATCH', method : 'PATCH',
@ -118,7 +130,12 @@
{#each top_level as realm,idx} {#each top_level as realm,idx}
<h3>{realm.name}</h3> <h3>{realm.name}</h3>
{#if realm.locations} {#if realm.locations}
<Locations locations={realm.locations} parent={realm.parent} bind:selected={location} {move_dragged_to} /> <Locations
locations={realm.locations}
parent={realm.parent}
bind:selected={location}
{move_dragged_to}
drag_start={drag_location} />
{/if} {/if}
{/each} {/each}
{/if} {/if}
@ -130,7 +147,7 @@
{#if location} {#if location}
<h3>{location.name} <button class="symbol" title={t('delete_object',{object:t('location')})} onclick={e => deleteLocation(location)}></button></h3> <h3>{location.name} <button class="symbol" title={t('delete_object',{object:t('location')})} onclick={e => deleteLocation(location)}></button></h3>
{/if} {/if}
<ItemList items={data?.items.sort((a,b) => a.code.localeCompare(b.code))} bind:selected={item} drag_start={item => draggedItem = item} /> <ItemList items={data?.items.sort((a,b) => a.code.localeCompare(b.code))} bind:selected={item} drag_start={drag_item} />
</div> </div>
<div class="properties"> <div class="properties">
<ItemProps {item} {properties} /> <ItemProps {item} {properties} />

14
frontend/src/routes/stock/Locations.svelte

@ -5,7 +5,13 @@
import LineEditor from '../../Components/LineEditor.svelte'; import LineEditor from '../../Components/LineEditor.svelte';
let { locations, move_dragged_to = new_loc => {}, parent = null, selected = $bindable(null) } = $props(); 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 show_location_form = $state(false);
let new_location_name = $state(null); let new_location_name = $state(null);
@ -102,12 +108,14 @@
{#each locations as location} {#each locations as location}
<li onclick={e => toggleChildren(e, location)} <li onclick={e => toggleChildren(e, location)}
class="{location.locations?'expanded':'collapsed'} {location.highlight?'highlight':null}" class="{location.locations?'expanded':'collapsed'} {location.highlight?'highlight':null}"
draggable={true}
ondragover={e => drag_over(e,location)} ondragover={e => drag_over(e,location)}
ondrop={e => onDrop(e,location)} ondrop={e => onDrop(e,location)}
ondragleave={e => delete location.highlight}> ondragleave={e => delete location.highlight}
ondragstart={e => drag_start(location)} >
<span class="name">{location.name}</span> <span class="name">{location.name}</span>
{#if location.locations} {#if location.locations}
<svelte:self locations={location.locations} {move_dragged_to} parent={{location:location.id}} bind:selected /> <svelte:self locations={location.locations} {drag_start} {move_dragged_to} parent={{location:location.id}} bind:selected />
{/if} {/if}
</li> </li>
{/each} {/each}

1
stock/src/main/java/de/srsoftware/umbrella/stock/Constants.java

@ -13,6 +13,7 @@ public class Constants {
public static final String ITEMS = "items"; public static final String ITEMS = "items";
public static final String LOCATIONS = "locations"; public static final String LOCATIONS = "locations";
public static final String MOVE_ITEM = "move_item"; public static final String MOVE_ITEM = "move_item";
public static final String MOVE_LOCATION = "move_location";
public static final String OF_USER = "of_user"; public static final String OF_USER = "of_user";
public static final String PARENT = "parent"; public static final String PARENT = "parent";
public static final String PROPERTY_ID = "prop_id"; public static final String PROPERTY_ID = "prop_id";

2
stock/src/main/java/de/srsoftware/umbrella/stock/SqliteDb.java

@ -288,7 +288,7 @@ public class SqliteDb extends BaseDb implements StockDb {
} }
@Override @Override
public Location save(DbLocation location) { public DbLocation save(DbLocation location) {
if (location.id() == 0) { // new location if (location.id() == 0) { // new location
try { try {
var rs = insertInto(TABLE_LOCATIONS,OWNER,PARENT_LOCATION_ID,NAME,DESCRIPTION) var rs = insertInto(TABLE_LOCATIONS,OWNER,PARENT_LOCATION_ID,NAME,DESCRIPTION)

2
stock/src/main/java/de/srsoftware/umbrella/stock/StockDb.java

@ -15,7 +15,7 @@ public interface StockDb {
Collection<DbLocation> listUserLocations(UmbrellaUser userId); Collection<DbLocation> listUserLocations(UmbrellaUser userId);
Item loadItem(long id); Item loadItem(long id);
DbLocation loadLocation(long locationId); DbLocation loadLocation(long locationId);
Location save(DbLocation location); DbLocation save(DbLocation location);
Item save(Item item); Item save(Item item);
Property setProperty(long itemId, long existingPropId, Object value); Property setProperty(long itemId, long existingPropId, Object value);
} }

23
stock/src/main/java/de/srsoftware/umbrella/stock/StockModule.java

@ -113,7 +113,8 @@ public class StockModule extends BaseHandler implements StockService {
var user = userService().loadUser(token); var user = userService().loadUser(token);
if (user.isEmpty()) return unauthorized(ex); if (user.isEmpty()) return unauthorized(ex);
return switch (path.pop()){ return switch (path.pop()){
case MOVE_ITEM -> patchMove(user.get(), path,ex); case MOVE_ITEM -> patchMoveItem(user.get(), path,ex);
case MOVE_LOCATION -> patchMoveLocation(user.get(), path, ex);
case null -> patchItem(user.get(),ex); case null -> patchItem(user.get(),ex);
default -> super.doPatch(path,ex); default -> super.doPatch(path,ex);
}; };
@ -213,7 +214,7 @@ public class StockModule extends BaseHandler implements StockService {
return sendContent(ex,stockDb.save(item)); return sendContent(ex,stockDb.save(item));
} }
private boolean patchMove(UmbrellaUser user, Path path, HttpExchange ex) throws IOException { private boolean patchMoveItem(UmbrellaUser user, Path path, HttpExchange ex) throws IOException {
var json = json(ex); var json = json(ex);
if (!(json.get(ITEM) instanceof Number itemId)) throw missingFieldException(ITEM); if (!(json.get(ITEM) instanceof Number itemId)) throw missingFieldException(ITEM);
if (!(json.get(TARGET) instanceof Number locationId)) throw missingFieldException(TARGET); if (!(json.get(TARGET) instanceof Number locationId)) throw missingFieldException(TARGET);
@ -232,6 +233,24 @@ public class StockModule extends BaseHandler implements StockService {
return sendContent(ex,item); return sendContent(ex,item);
} }
private boolean patchMoveLocation(UmbrellaUser user, Path path, HttpExchange ex) throws IOException {
var json = json(ex);
if (!(json.get(LOCATION) instanceof Number locationId)) throw missingFieldException(LOCATION);
if (!(json.get(TARGET) instanceof Number destLocationId)) throw missingFieldException(TARGET);
var location = stockDb.loadLocation(locationId.longValue());
var owner = location.owner().resolve();
if (!assigned(owner,user)) throw forbidden("You are not allowed to alter the location of \"{0}\"!",location.name());
var target = stockDb.loadLocation(locationId.longValue());
var locOwner = target.resolve().owner().resolve();
if (!assigned(locOwner,user)) throw forbidden("You are not allowed to modify \"{0}\"!",target.name());
if (!locOwner.equals(owner)) throw unprocessable("You may not move locations from one owner ({0}) to another ({1})",owner,locOwner);
location = stockDb.save(location.parent(target));
return sendContent(ex,location);
}
private boolean postLocation(UmbrellaUser user, HttpExchange ex) throws IOException { private boolean postLocation(UmbrellaUser user, HttpExchange ex) throws IOException {
var json = json(ex); var json = json(ex);
if (!(json.get(NAME) instanceof String name)) throw missingFieldException(NAME); if (!(json.get(NAME) instanceof String name)) throw missingFieldException(NAME);

Loading…
Cancel
Save