Merge branch 'module/contact' into dev
This commit is contained in:
@@ -6,6 +6,8 @@ import de.srsoftware.umbrella.core.model.Contact;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface ContactDb {
|
public interface ContactDb {
|
||||||
|
void drop(Contact contact);
|
||||||
|
|
||||||
Map<Long,Contact> listContactsOf(long userId) throws UmbrellaException;
|
Map<Long,Contact> listContactsOf(long userId) throws UmbrellaException;
|
||||||
|
|
||||||
Contact load(long id, long userId);
|
Contact load(long id, long userId);
|
||||||
|
|||||||
@@ -33,6 +33,30 @@ public class ContactModule extends BaseHandler implements ContactService {
|
|||||||
ModuleRegistry.add(this);
|
ModuleRegistry.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean deleteContact(long id, UmbrellaUser user, HttpExchange ex) throws IOException {
|
||||||
|
var contact = contactDb.load(id, user.id());
|
||||||
|
contactDb.drop(contact);
|
||||||
|
return sendEmptyResponse(200,ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doDelete(Path path, HttpExchange ex) throws IOException {
|
||||||
|
addCors(ex);
|
||||||
|
try {
|
||||||
|
var user = userService().refreshSession(ex);
|
||||||
|
if (user.isEmpty()) return unauthorized(ex);
|
||||||
|
var head = path.pop();
|
||||||
|
try {
|
||||||
|
var id = Long.parseLong(head);
|
||||||
|
return deleteContact(id, user.get(), ex);
|
||||||
|
} catch (Exception ignored){
|
||||||
|
return super.doPatch(path,ex);
|
||||||
|
}
|
||||||
|
} catch (UmbrellaException e) {
|
||||||
|
return send(ex,e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
||||||
addCors(ex);
|
addCors(ex);
|
||||||
@@ -54,8 +78,7 @@ public class ContactModule extends BaseHandler implements ContactService {
|
|||||||
public boolean doPatch(Path path, HttpExchange ex) throws IOException {
|
public boolean doPatch(Path path, HttpExchange ex) throws IOException {
|
||||||
addCors(ex);
|
addCors(ex);
|
||||||
try {
|
try {
|
||||||
Optional<Token> token = SessionToken.from(ex).map(Token::of);
|
var user = userService().refreshSession(ex);
|
||||||
var user = userService().loadUser(token);
|
|
||||||
if (user.isEmpty()) return unauthorized(ex);
|
if (user.isEmpty()) return unauthorized(ex);
|
||||||
var head = path.pop();
|
var head = path.pop();
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -58,6 +58,17 @@ public class SqliteDb extends BaseDb implements ContactDb{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drop(Contact contact) {
|
||||||
|
try {
|
||||||
|
db.setAutoCommit(false);
|
||||||
|
Query.delete().from(TABLE_CONTACTS).where(ID,equal(contact.id())).execute(db);
|
||||||
|
Query.delete().from(TABLE_CONTACTS_USERS).where(CONTACT_ID,equal(contact.id())).execute(db);
|
||||||
|
db.setAutoCommit(true);
|
||||||
|
} catch (SQLException e){
|
||||||
|
throw databaseException("Failed to remove contact {0}",contact.id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Long,Contact> listContactsOf(long userId) throws UmbrellaException{
|
public Map<Long,Contact> listContactsOf(long userId) throws UmbrellaException{
|
||||||
|
|||||||
@@ -15,14 +15,14 @@ public record Contact(long id, String vcard) implements Mappable {
|
|||||||
return new Contact(rs.getLong(ID),rs.getString(DATA));
|
return new Contact(rs.getLong(ID),rs.getString(DATA));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Map<String, Object> toMap() {
|
|
||||||
return Map.of(ID,id,VCARD,vcard);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Contact patch(JSONObject json) {
|
public Contact patch(JSONObject json) {
|
||||||
if (!(json.get(FROM) instanceof String from)) throw missingFieldException(FROM);
|
if (!(json.get(FROM) instanceof String from)) throw missingFieldException(FROM);
|
||||||
if (!(json.get(TO) instanceof String to)) throw missingFieldException(TO);
|
if (!(json.get(TO) instanceof String to)) throw missingFieldException(TO);
|
||||||
return new Contact(id,vcard.replace(from, to));
|
return new Contact(id,vcard.replace(from, to));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> toMap() {
|
||||||
|
return Map.of(ID,id,VCARD,vcard);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { api } from '../../urls.svelte';
|
import { api } from '../../urls.svelte';
|
||||||
import { error, yikes } from '../../warn.svelte';
|
import { error, yikes } from '../../warn.svelte';
|
||||||
|
import { name } from '../../vcard.js';
|
||||||
import { t } from '../../translations.svelte';
|
import { t } from '../../translations.svelte';
|
||||||
|
|
||||||
|
|
||||||
@@ -25,6 +26,26 @@
|
|||||||
let orgs = $derived(contact.vcard.match(/^ORG.*:.+$/gm));
|
let orgs = $derived(contact.vcard.match(/^ORG.*:.+$/gm));
|
||||||
let urls = $derived(contact.vcard.match(/^URL.*:.+$/gm));
|
let urls = $derived(contact.vcard.match(/^URL.*:.+$/gm));
|
||||||
|
|
||||||
|
async function drop(){
|
||||||
|
for (let n of names){
|
||||||
|
n = name(n);
|
||||||
|
n = (n.given + ' ' + n.family).trim();
|
||||||
|
if (confirm(t('confirm_delete',{element:n}))) break;
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const url = api(`contact/${contact.id}`);
|
||||||
|
const res = await fetch(url,{
|
||||||
|
credentials:'include',
|
||||||
|
method:'DELETE'
|
||||||
|
});
|
||||||
|
if (res.ok){
|
||||||
|
yikes();
|
||||||
|
contact = null;
|
||||||
|
} else {
|
||||||
|
error(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function patch(from,to){
|
async function patch(from,to){
|
||||||
if (from == to) return;
|
if (from == to) return;
|
||||||
const newContact = contact.id == 0;
|
const newContact = contact.id == 0;
|
||||||
@@ -49,6 +70,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
{#if contact}
|
||||||
<fieldset class="vcard">
|
<fieldset class="vcard">
|
||||||
<legend>
|
<legend>
|
||||||
{#if contact.id}
|
{#if contact.id}
|
||||||
@@ -57,6 +79,9 @@
|
|||||||
{t('new_contact')}
|
{t('new_contact')}
|
||||||
{/if}
|
{/if}
|
||||||
<button class="symbol" onclick={toggleCode}></button>
|
<button class="symbol" onclick={toggleCode}></button>
|
||||||
|
{#if contact.id}
|
||||||
|
<button class="symbol" onclick={drop}></button>
|
||||||
|
{/if}
|
||||||
</legend>
|
</legend>
|
||||||
<table>
|
<table>
|
||||||
<thead></thead>
|
<thead></thead>
|
||||||
@@ -125,3 +150,4 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
{/if}
|
||||||
Reference in New Issue
Block a user