Browse Source

refactored moving of locations, implemented editing of location details, implemented raising locations to the top level

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
module/document
Stephan Richter 2 weeks ago
parent
commit
a73a660d43
  1. 7
      core/src/main/java/de/srsoftware/umbrella/core/model/DbLocation.java
  2. 32
      frontend/src/routes/stock/Index.svelte
  3. 5
      stock/src/main/java/de/srsoftware/umbrella/stock/SqliteDb.java
  4. 6
      stock/src/main/java/de/srsoftware/umbrella/stock/StockModule.java
  5. 1
      translations/src/main/resources/de.json
  6. 1
      translations/src/main/resources/en.json

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

@ -2,15 +2,15 @@
package de.srsoftware.umbrella.core.model; package de.srsoftware.umbrella.core.model;
import static de.srsoftware.umbrella.core.Constants.*; import static de.srsoftware.umbrella.core.Constants.*;
import static de.srsoftware.umbrella.core.Util.markdown;
import de.srsoftware.umbrella.core.api.Owner; import de.srsoftware.umbrella.core.api.Owner;
import org.json.JSONObject;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.json.JSONObject;
public class DbLocation extends Location { public class DbLocation extends Location {
private Owner owner; private Owner owner;
@ -92,7 +92,8 @@ public class DbLocation extends Location {
var map = super.toMap(); var map = super.toMap();
map.put(OWNER,owner.toMap()); map.put(OWNER,owner.toMap());
map.put(NAME,name); map.put(NAME,name);
map.put(DESCRIPTION,description); map.put(DESCRIPTION,Map.of(SOURCE,description,RENDERED,markdown(description)));
if (parentLocationId != null) map.put(PARENT_LOCATION_ID,parentLocationId);
return map; return map;
} }

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

@ -4,9 +4,11 @@
import { error, yikes } from '../../warn.svelte'; import { error, yikes } from '../../warn.svelte';
import { t } from '../../translations.svelte'; import { t } from '../../translations.svelte';
import Locations from './Locations.svelte';
import ItemList from './ItemList.svelte'; import ItemList from './ItemList.svelte';
import ItemProps from './ItemProps.svelte'; import ItemProps from './ItemProps.svelte';
import LineEditor from '../../Components/LineEditor.svelte';
import Locations from './Locations.svelte';
import MarkdownEditor from '../../Components/MarkdownEditor.svelte';
import Notes from '../notes/RelatedNotes.svelte'; import Notes from '../notes/RelatedNotes.svelte';
import Tags from '../tags/TagList.svelte'; import Tags from '../tags/TagList.svelte';
@ -122,6 +124,25 @@
loadProperties(); loadProperties();
} }
async function patchLocation(location,field,newValue){
const data = {};
data[field] = newValue;
console.log(data);
const url = api(`stock/location/${location.id}`);
const res = await fetch(url,{
credentials: 'include',
method:'PATCH',
body:JSON.stringify(data)
});
if (res.ok){
yikes();
return true;
} else {
error(res);
return false;
}
}
onMount(load); onMount(load);
</script> </script>
@ -147,7 +168,14 @@
{:then data} {:then data}
<div class="items"> <div class="items">
{#if location} {#if location}
<h3>{location.name} <button class="symbol" title={t('delete_object',{object:t('location')})} onclick={e => deleteLocation(location)}></button></h3> <h3>
<LineEditor editable={true} bind:value={location.name} type="span" onSet={newName => patchLocation(location,'name',newName)} />
<button class="symbol" title={t('delete_object',{object:t('location')})} onclick={e => deleteLocation(location)}></button>
{#if location.parent_location_id}
<button class="symbol" title={t('move_to_top')} onclick={e => patchLocation(location,'parent_location_id',0)}></button>
{/if}
</h3>
<MarkdownEditor editable={true} value={location.description} type="div" onSet={newDesc => patchLocation(location,'description',newDesc)} />
{/if} {/if}
<ItemList items={data?.items.sort((a,b) => a.code.localeCompare(b.code))} bind:selected={item} drag_start={drag_item} /> <ItemList items={data?.items.sort((a,b) => a.code.localeCompare(b.code))} bind:selected={item} drag_start={drag_item} />
</div> </div>

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

@ -289,10 +289,11 @@ public class SqliteDb extends BaseDb implements StockDb {
@Override @Override
public DbLocation save(DbLocation location) { public DbLocation save(DbLocation location) {
var parentId = location.parent() == 0 ? null : location.parent();
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)
.values(location.owner().dbCode(),location.parent(),location.name(),location.description()) .values(location.owner().dbCode(),location.parent() == 0 ? null : parentId,location.name(),location.description())
.execute(db).getGeneratedKeys(); .execute(db).getGeneratedKeys();
long id = 0; long id = 0;
if (rs.next()) id = rs.getLong(1); if (rs.next()) id = rs.getLong(1);
@ -308,7 +309,7 @@ public class SqliteDb extends BaseDb implements StockDb {
.set(OWNER, PARENT_LOCATION_ID, NAME, DESCRIPTION) .set(OWNER, PARENT_LOCATION_ID, NAME, DESCRIPTION)
.where(ID,equal(location.id())) .where(ID,equal(location.id()))
.prepare(db) .prepare(db)
.apply(location.owner().dbCode(), location.parent(), location.name(), location.description()) .apply(location.owner().dbCode(), parentId, location.name(), location.description())
.close(); .close();
return location.clear(); return location.clear();
} catch (SQLException e){ } catch (SQLException e){

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

@ -248,10 +248,12 @@ public class StockModule extends BaseHandler implements StockService {
if (!assigned(owner,user)) throw forbidden("You are not allowed to edit \"{0}\"!",location.name()); if (!assigned(owner,user)) throw forbidden("You are not allowed to edit \"{0}\"!",location.name());
if (json.has(PARENT_LOCATION_ID) && json.get(PARENT_LOCATION_ID) instanceof Number parentId){ if (json.has(PARENT_LOCATION_ID) && json.get(PARENT_LOCATION_ID) instanceof Number parentId){
if (parentId.longValue() != 0L) {
var target = stockDb.loadLocation(parentId.longValue()); var target = stockDb.loadLocation(parentId.longValue());
var targetOwner = target.owner().resolve(); var targetOwner = target.owner().resolve();
if (!assigned(targetOwner,user)) throw forbidden("You are not allowed to edit \"{0}\"!",target.name()); if (!assigned(targetOwner, user)) throw forbidden("You are not allowed to edit \"{0}\"!", target.name());
if (!targetOwner.equals(owner)) throw unprocessable("You may not move locations from one owner ({0}) to another ({1})",owner,targetOwner); if (!targetOwner.equals(owner)) throw unprocessable("You may not move locations from one owner ({0}) to another ({1})", owner, targetOwner);
}
} }
location = stockDb.save(location.patch(json)); location = stockDb.save(location.patch(json));

1
translations/src/main/resources/de.json

@ -170,6 +170,7 @@
"wiki": "Wiki" "wiki": "Wiki"
}, },
"month": "Monat", "month": "Monat",
"move_to_top": "nach ganz oben bewegen",
"must_not_be_empty": "darf nicht leer sein", "must_not_be_empty": "darf nicht leer sein",
"name": "Name", "name": "Name",

1
translations/src/main/resources/en.json

@ -169,6 +169,7 @@
"wiki": "wiki" "wiki": "wiki"
}, },
"month": "month", "month": "month",
"move_to_top": "move to top level",
"must_not_be_empty": "must not be empty", "must_not_be_empty": "must not be empty",
"name": "Name", "name": "Name",

Loading…
Cancel
Save