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 MarkdownEditor from './MarkdownEditor.svelte';
|
||||||
import TimeStampInput from './TimeStampInput.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){
|
function onsubmit(e){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -14,7 +24,7 @@
|
|||||||
|
|
||||||
{#if record}
|
{#if record}
|
||||||
<form {onsubmit}>
|
<form {onsubmit}>
|
||||||
<fieldset>
|
<fieldset class="time record">
|
||||||
<legend>{t('edit_object',{object:t('record')})}</legend>
|
<legend>{t('edit_object',{object:t('record')})}</legend>
|
||||||
<label>
|
<label>
|
||||||
{t('subject')}
|
{t('subject')}
|
||||||
@@ -33,6 +43,8 @@
|
|||||||
<MarkdownEditor simple={true} bind:value={record.description} />
|
<MarkdownEditor simple={true} bind:value={record.description} />
|
||||||
</label>
|
</label>
|
||||||
<button type="submit">{t('save')}</button>
|
<button type="submit">{t('save')}</button>
|
||||||
|
<button class="cancel" onclick={cancel} >{t('cancel')}</button>
|
||||||
|
<button class="delete" onclick={drop} >{t('delete')}</button>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</form>
|
</form>
|
||||||
{record.description.source}
|
{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){
|
function openTask(tid){
|
||||||
router.navigate(`/task/${tid}/view`);
|
router.navigate(`/task/${tid}/view`);
|
||||||
}
|
}
|
||||||
@@ -148,7 +166,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
{#if detail == time.id}
|
{#if detail == time.id}
|
||||||
<td colspan="5">
|
<td colspan="5">
|
||||||
<TimeEditor record={time} onSet={update} />
|
<TimeEditor record={time} {onAbort} {onDrop} onSet={update} />
|
||||||
</td>
|
</td>
|
||||||
{:else}
|
{:else}
|
||||||
<td class="start_end" onclick={e => toggleSelect(time.id)}>
|
<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.lang.System.Logger.Level.ERROR;
|
||||||
import static java.text.MessageFormat.format;
|
import static java.text.MessageFormat.format;
|
||||||
|
|
||||||
|
import de.srsoftware.tools.jdbc.Query;
|
||||||
import de.srsoftware.umbrella.core.BaseDb;
|
import de.srsoftware.umbrella.core.BaseDb;
|
||||||
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
|
||||||
import de.srsoftware.umbrella.core.model.Time;
|
import de.srsoftware.umbrella.core.model.Time;
|
||||||
@@ -77,6 +78,19 @@ CREATE TABLE IF NOT EXISTS {0} (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Override
|
||||||
public HashMap<Long,Time> listTimes(Collection<Long> taskIds, boolean showClosed) throws UmbrellaException {
|
public HashMap<Long,Time> listTimes(Collection<Long> taskIds, boolean showClosed) throws UmbrellaException {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import java.util.Collection;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
public interface TimeDb {
|
public interface TimeDb {
|
||||||
|
Long delete(long timeId);
|
||||||
|
|
||||||
HashMap<Long,Time> listTimes(Collection<Long> taskIds, boolean showClosed) throws UmbrellaException;
|
HashMap<Long,Time> listTimes(Collection<Long> taskIds, boolean showClosed) throws UmbrellaException;
|
||||||
|
|
||||||
HashMap<Long,Time> listUserTimes(long userId, boolean showClosed);
|
HashMap<Long,Time> listUserTimes(long userId, boolean showClosed);
|
||||||
|
|||||||
@@ -34,6 +34,32 @@ public class TimeModule extends BaseHandler implements TimeService {
|
|||||||
timeDb = new SqliteDb(connect(dbFile));
|
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
|
@Override
|
||||||
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
public boolean doGet(Path path, HttpExchange ex) throws IOException {
|
||||||
addCors(ex);
|
addCors(ex);
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"bookmarks": "Lesezeichen",
|
"bookmarks": "Lesezeichen",
|
||||||
"by": "von",
|
"by": "von",
|
||||||
|
|
||||||
|
"cancel": "abbrechen",
|
||||||
"client_id": "Client-ID",
|
"client_id": "Client-ID",
|
||||||
"client_secret": "Client-Geheimnis",
|
"client_secret": "Client-Geheimnis",
|
||||||
"close_settings": "Einstellungen schließen",
|
"close_settings": "Einstellungen schließen",
|
||||||
|
|||||||
@@ -321,3 +321,7 @@ li > a > p:nth-child(1){
|
|||||||
.timetracks ul{
|
.timetracks ul{
|
||||||
margin: 0
|
margin: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.time.record button.delete{
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user