implemented deletion of times
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -4,7 +4,17 @@
|
||||
import MarkdownEditor from './MarkdownEditor.svelte';
|
||||
import TimeStampInput from './TimeStampInput.svelte';
|
||||
|
||||
let { record = null, onSet = time => {} } = $props();
|
||||
let { record = null, onAbort = () => {}, onDrop = time_id => {}, onSet = time => {} } = $props();
|
||||
|
||||
function cancel(e){
|
||||
e.preventDefault();
|
||||
onAbort();
|
||||
}
|
||||
|
||||
function drop(e){
|
||||
e.preventDefault();
|
||||
if (confirm(t('confirm_delete',{element:record.subject}))) onDrop(record.id);
|
||||
}
|
||||
|
||||
function onsubmit(e){
|
||||
e.preventDefault();
|
||||
@@ -14,7 +24,7 @@
|
||||
|
||||
{#if record}
|
||||
<form {onsubmit}>
|
||||
<fieldset>
|
||||
<fieldset class="time record">
|
||||
<legend>{t('edit_object',{object:t('record')})}</legend>
|
||||
<label>
|
||||
{t('subject')}
|
||||
@@ -33,6 +43,8 @@
|
||||
<MarkdownEditor simple={true} bind:value={record.description} />
|
||||
</label>
|
||||
<button type="submit">{t('save')}</button>
|
||||
<button class="cancel" onclick={cancel} >{t('cancel')}</button>
|
||||
<button class="delete" onclick={drop} >{t('delete')}</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
{record.description.source}
|
||||
|
||||
@@ -64,6 +64,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
function onAbort(){
|
||||
detail = null;
|
||||
}
|
||||
|
||||
async function onDrop(time_id){
|
||||
const url = api(`time/${time_id}`);
|
||||
const res = await fetch(url,{
|
||||
credentials:'include',
|
||||
method:'DELETE'
|
||||
});
|
||||
if (res.ok){
|
||||
delete times[time_id];
|
||||
error = false;
|
||||
} else {
|
||||
error = await res.text();
|
||||
}
|
||||
}
|
||||
|
||||
function openTask(tid){
|
||||
router.navigate(`/task/${tid}/view`);
|
||||
}
|
||||
@@ -148,7 +166,7 @@
|
||||
{/if}
|
||||
{#if detail == time.id}
|
||||
<td colspan="5">
|
||||
<TimeEditor record={time} onSet={update} />
|
||||
<TimeEditor record={time} {onAbort} {onDrop} onSet={update} />
|
||||
</td>
|
||||
{:else}
|
||||
<td class="start_end" onclick={e => toggleSelect(time.id)}>
|
||||
|
||||
@@ -10,6 +10,7 @@ import static de.srsoftware.umbrella.time.Constants.*;
|
||||
import static java.lang.System.Logger.Level.ERROR;
|
||||
import static java.text.MessageFormat.format;
|
||||
|
||||
import de.srsoftware.tools.jdbc.Query;
|
||||
import de.srsoftware.umbrella.core.BaseDb;
|
||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||
import de.srsoftware.umbrella.core.model.Time;
|
||||
@@ -77,7 +78,20 @@ CREATE TABLE IF NOT EXISTS {0} (
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public Long delete(long timeId) {
|
||||
try {
|
||||
db.setAutoCommit(false);
|
||||
Query.delete().from(TABLE_TASK_TIMES).where(TIME_ID,equal(timeId)).execute(db);
|
||||
Query.delete().from(TABLE_TIMES).where(ID,equal(timeId)).execute(db);
|
||||
db.setAutoCommit(false);
|
||||
return timeId;
|
||||
} catch (SQLException e) {
|
||||
throw UmbrellaException.databaseException("Failed to delete time with id = {0}",timeId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HashMap<Long,Time> listTimes(Collection<Long> taskIds, boolean showClosed) throws UmbrellaException {
|
||||
try {
|
||||
var rs = select(ALL).from(TABLE_TASK_TIMES).where(TASK_ID,in(taskIds.toArray())).exec(db);
|
||||
|
||||
@@ -7,6 +7,8 @@ import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
||||
public interface TimeDb {
|
||||
Long delete(long timeId);
|
||||
|
||||
HashMap<Long,Time> listTimes(Collection<Long> taskIds, boolean showClosed) throws UmbrellaException;
|
||||
|
||||
HashMap<Long,Time> listUserTimes(long userId, boolean showClosed);
|
||||
|
||||
@@ -34,6 +34,32 @@ public class TimeModule extends BaseHandler implements TimeService {
|
||||
timeDb = new SqliteDb(connect(dbFile));
|
||||
}
|
||||
|
||||
|
||||
private boolean deleteTime(UmbrellaUser user, long timeId, HttpExchange ex) throws IOException {
|
||||
var time = timeDb.load(timeId);
|
||||
if (time.userId() != user.id()) throw forbidden("You are not allowed to delete this time!");
|
||||
timeDb.delete(timeId);
|
||||
return sendContent(ex,time);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean doDelete(Path path, HttpExchange ex) throws IOException {
|
||||
addCors(ex);
|
||||
try {
|
||||
Optional<Token> token = SessionToken.from(ex).map(Token::of);
|
||||
var user = userService().loadUser(token);
|
||||
if (user.isEmpty()) return unauthorized(ex);
|
||||
var head = path.pop();
|
||||
var timeId = Long.parseLong(head);
|
||||
return deleteTime(user.get(),timeId,ex);
|
||||
} catch (NumberFormatException e){
|
||||
return send(ex,invalidFieldException(TIME_ID,"long value"));
|
||||
} catch (UmbrellaException e){
|
||||
return send(ex,e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
||||
addCors(ex);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"bookmarks": "Lesezeichen",
|
||||
"by": "von",
|
||||
|
||||
"cancel": "abbrechen",
|
||||
"client_id": "Client-ID",
|
||||
"client_secret": "Client-Geheimnis",
|
||||
"close_settings": "Einstellungen schließen",
|
||||
|
||||
@@ -320,4 +320,8 @@ li > a > p:nth-child(1){
|
||||
|
||||
.timetracks ul{
|
||||
margin: 0
|
||||
}
|
||||
|
||||
.time.record button.delete{
|
||||
float: right;
|
||||
}
|
||||
Reference in New Issue
Block a user