implemented changing set of selected times, display of closed times
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
let router = useTinyRouter();
|
let router = useTinyRouter();
|
||||||
|
|
||||||
let times = $state(null);
|
let times = $state(null);
|
||||||
|
let closed = $state(false);
|
||||||
let tasks = {};
|
let tasks = {};
|
||||||
let projects = {};
|
let projects = {};
|
||||||
let project_filter = $state(null);
|
let project_filter = $state(null);
|
||||||
@@ -94,9 +95,11 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function loadTimes(){
|
async function loadTimes(){
|
||||||
const url = api('time');
|
const url = api('time');
|
||||||
const resp = await fetch(url,{credentials:'include'});
|
const resp = await post(url,{closed:closed});
|
||||||
if (resp.ok){
|
if (resp.ok){
|
||||||
var json = await resp.json();
|
var json = await resp.json();
|
||||||
times = json.times;
|
times = json.times;
|
||||||
@@ -160,6 +163,10 @@
|
|||||||
router.navigate(`/task/${tid}/view`);
|
router.navigate(`/task/${tid}/view`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reload(ev){
|
||||||
|
loadTimes();
|
||||||
|
}
|
||||||
|
|
||||||
function toggleRange(range){
|
function toggleRange(range){
|
||||||
let affected = sortedTimes.filter(time => time.start.startsWith(range));
|
let affected = sortedTimes.filter(time => time.start.startsWith(range));
|
||||||
if (ranges[range]){
|
if (ranges[range]){
|
||||||
@@ -217,6 +224,12 @@
|
|||||||
<button class="symbol" title={t('complete')} onclick={e => multi_update({state:'Complete'})} ></button>
|
<button class="symbol" title={t('complete')} onclick={e => multi_update({state:'Complete'})} ></button>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
<div class="switch">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" bind:checked={closed} onchange={reload} />
|
||||||
|
{t('show_closed')}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<table class="timetracks">
|
<table class="timetracks">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@@ -235,12 +248,12 @@
|
|||||||
{#if match_prj_filter(time)}
|
{#if match_prj_filter(time)}
|
||||||
<tr class={selected[time.id]?'selected':''}>
|
<tr class={selected[time.id]?'selected':''}>
|
||||||
{#if timeMap.years[line]}
|
{#if timeMap.years[line]}
|
||||||
<td class="year" rowspan={timeMap.years[line]} onclick={e => toggleRange(time.start.substring(0,4))}>
|
<td class="year" rowspan={timeMap.years[line]} onclick={e => toggleRange(time.start.substring(0,4))} title={time.start.substring(0,4)} >
|
||||||
{time.start.substring(0,4)}
|
{time.start.substring(0,4)}
|
||||||
</td>
|
</td>
|
||||||
{/if}
|
{/if}
|
||||||
{#if timeMap.months[line]}
|
{#if timeMap.months[line]}
|
||||||
<td class="month" rowspan={timeMap.months[line]} onclick={e => toggleRange(time.start.substring(0,7))}>
|
<td class="month" rowspan={timeMap.months[line]} onclick={e => toggleRange(time.start.substring(0,7))} title={time.start.substring(5,7)} >
|
||||||
{time.start.substring(5,7)}
|
{time.start.substring(5,7)}
|
||||||
</td>
|
</td>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ public class Constants {
|
|||||||
private Constants(){}
|
private Constants(){}
|
||||||
|
|
||||||
public static final String CHILDREN = "children";
|
public static final String CHILDREN = "children";
|
||||||
|
public static final String CLOSED = "closed";
|
||||||
public static final String CONFIG_DATABASE = "umbrella.modules.time.database";
|
public static final String CONFIG_DATABASE = "umbrella.modules.time.database";
|
||||||
public static final String DOCUMENTS = "documents";
|
public static final String DOCUMENTS = "documents";
|
||||||
public static final String IDS = "ids";
|
public static final String IDS = "ids";
|
||||||
|
|||||||
@@ -75,8 +75,7 @@ public class TimeModule extends BaseHandler implements TimeService {
|
|||||||
var head = path.pop();
|
var head = path.pop();
|
||||||
return switch (head) {
|
return switch (head) {
|
||||||
case STARTED -> getStartedTime(user.get(),ex);
|
case STARTED -> getStartedTime(user.get(),ex);
|
||||||
case null -> getUserTimes(user.get(),ex);
|
case null, default -> super.doGet(path,ex);
|
||||||
default -> super.doGet(path,ex);
|
|
||||||
};
|
};
|
||||||
} catch (UmbrellaException e){
|
} catch (UmbrellaException e){
|
||||||
return send(ex,e);
|
return send(ex,e);
|
||||||
@@ -119,6 +118,7 @@ public class TimeModule extends BaseHandler implements TimeService {
|
|||||||
case LIST -> listTimes(ex,user.get());
|
case LIST -> listTimes(ex,user.get());
|
||||||
case SEARCH -> postSearch(ex, user.get());
|
case SEARCH -> postSearch(ex, user.get());
|
||||||
case TRACK_TASK -> trackTask(user.get(),path,ex);
|
case TRACK_TASK -> trackTask(user.get(),path,ex);
|
||||||
|
case null -> postUserTimeList(user.get(),ex);
|
||||||
default -> {
|
default -> {
|
||||||
try {
|
try {
|
||||||
long timeId = Long.parseLong(head);
|
long timeId = Long.parseLong(head);
|
||||||
@@ -199,31 +199,6 @@ public class TimeModule extends BaseHandler implements TimeService {
|
|||||||
return send(ex,UmbrellaException.notFound("no started time"));
|
return send(ex,UmbrellaException.notFound("no started time"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean getUserTimes(UmbrellaUser user, HttpExchange ex) throws IOException {
|
|
||||||
Set<Long> taskIds = new HashSet<>();
|
|
||||||
Map<Long, Project> projects = projectService().listUserProjects(user.id(), true);
|
|
||||||
for (var pid : projects.keySet()) taskIds.addAll(taskService().listProjectTasks(pid).keySet());
|
|
||||||
boolean showClosed = false;
|
|
||||||
var times = timeDb.listTimes(taskIds, showClosed);
|
|
||||||
times.putAll(timeDb.listUserTimes(user.id(), showClosed));
|
|
||||||
taskIds.clear();
|
|
||||||
var userIds = new HashSet<Long>();
|
|
||||||
times.values().forEach(time -> {
|
|
||||||
taskIds.addAll(time.taskIds());
|
|
||||||
userIds.add(time.userId());
|
|
||||||
});
|
|
||||||
var tasks = taskService().load(taskIds);
|
|
||||||
var users = userService().list(null,null,userIds);
|
|
||||||
var result = new HashMap<String,Object>();
|
|
||||||
var docList = documentService().docsReferencedByTimes(times.keySet());
|
|
||||||
result.put(DOCUMENTS,docList);
|
|
||||||
result.put(TIMES,mapValues(times));
|
|
||||||
result.put(TASKS,mapValues(tasks));
|
|
||||||
result.put(PROJECTS,mapValues(projects));
|
|
||||||
result.put(USERS,mapValues(users));
|
|
||||||
return sendContent(ex,result);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean listTimes(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException {
|
private boolean listTimes(HttpExchange ex, UmbrellaUser user) throws IOException, UmbrellaException {
|
||||||
var json = json(ex);
|
var json = json(ex);
|
||||||
if (!(json.has(COMPANY_ID) && json.get(COMPANY_ID) instanceof Number cid)) throw missingFieldException(COMPANY_ID);
|
if (!(json.has(COMPANY_ID) && json.get(COMPANY_ID) instanceof Number cid)) throw missingFieldException(COMPANY_ID);
|
||||||
@@ -281,6 +256,32 @@ public class TimeModule extends BaseHandler implements TimeService {
|
|||||||
return sendContent(ex,mapValues(notes));
|
return sendContent(ex,mapValues(notes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean postUserTimeList(UmbrellaUser user, HttpExchange ex) throws IOException {
|
||||||
|
var json = json(ex);
|
||||||
|
var showClosed = json.has(CLOSED) && json.get(CLOSED) instanceof Boolean b ? b : false;
|
||||||
|
Set<Long> taskIds = new HashSet<>();
|
||||||
|
Map<Long, Project> projects = projectService().listUserProjects(user.id(), true);
|
||||||
|
for (var pid : projects.keySet()) taskIds.addAll(taskService().listProjectTasks(pid).keySet());
|
||||||
|
var times = timeDb.listTimes(taskIds, showClosed);
|
||||||
|
times.putAll(timeDb.listUserTimes(user.id(), showClosed));
|
||||||
|
taskIds.clear();
|
||||||
|
var userIds = new HashSet<Long>();
|
||||||
|
times.values().forEach(time -> {
|
||||||
|
taskIds.addAll(time.taskIds());
|
||||||
|
userIds.add(time.userId());
|
||||||
|
});
|
||||||
|
var tasks = taskService().load(taskIds);
|
||||||
|
var users = userService().list(null,null,userIds);
|
||||||
|
var result = new HashMap<String,Object>();
|
||||||
|
var docList = documentService().docsReferencedByTimes(times.keySet());
|
||||||
|
result.put(DOCUMENTS,docList);
|
||||||
|
result.put(TIMES,mapValues(times));
|
||||||
|
result.put(TASKS,mapValues(tasks));
|
||||||
|
result.put(PROJECTS,mapValues(projects));
|
||||||
|
result.put(USERS,mapValues(users));
|
||||||
|
return sendContent(ex,result);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean trackTask(UmbrellaUser user, Path path, HttpExchange ex) throws IOException {
|
private boolean trackTask(UmbrellaUser user, Path path, HttpExchange ex) throws IOException {
|
||||||
if (path.empty()) throw missingFieldException(TASK_ID);
|
if (path.empty()) throw missingFieldException(TASK_ID);
|
||||||
Task task;
|
Task task;
|
||||||
|
|||||||
Reference in New Issue
Block a user